이 글은 파이썬에서 with의 사용법을 공유합니다. 필요하신 분들은 참고하세요
미리 설정해야 할 작업이 있습니다. .나중에 정리하세요. 이 시나리오의 경우 Python의 with 문은 이를 처리하는 매우 편리한 방법을 제공합니다. 좋은 예는 파일 핸들을 가져와서 파일에서 데이터를 읽은 다음 파일 핸들을 닫아야 하는 파일 처리입니다.
with 문을 사용하지 않는 경우 코드는 다음과 같습니다.
file = open("/tmp/foo.txt") data = file.read()file.close()
여기에는 두 가지 문제가 있습니다.
첫째, 파일 핸들을 닫는 것을 잊어버릴 수 있습니다.
두 번째, 파일에서 데이터를 읽을 때 예외가 발생합니다. 이며 처리가 수행되지 않습니다.
예외를 처리하는 향상된 버전은 다음과 같습니다.
try: f = open('xxx')except: print 'fail to open' exit(-1)try: do somethingexcept: do somethingfinally: f.close()
이 코드는 잘 작동하지만 너무 장황합니다.
위드가 실력을 뽐낼 시간입니다. 더 우아한 구문을 갖는 것 외에도 with는 컨텍스트에서 생성된 예외를 매우 잘 처리할 수도 있습니다.
다음은 with 버전의 코드입니다:
with open("/tmp/foo.txt") as file: data = file.read()
with 바로 뒤에 오는 문이 평가된 후 반환된 객체의 __enter__() 메서드가 호출되고, 이 메소드는 할당될 것입니다. as 뒤에 변수를 제공하십시오.
다음의 모든 코드 블록이 실행되면 이전에 반환된 객체의 __exit__() 메서드가 호출됩니다.
다음 예에서는 작동 방식을 구체적으로 설명할 수 있습니다.
#!/usr/bin/env python# with_example01.pyclass Sample: def __enter__(self): print "In __enter__()" return "Foo" def __exit__(self, type, value, trace): print "In __exit__()"def get_sample(): return Sample()with get_sample() as sample: print "sample:", sample
코드를 실행하면 출력은 다음과 같습니다
bash-3.2$ ./with_example01.pyIn __enter__()sample: FooIn __exit__()
正如你看到的: 1. __enter__()方法被执行 2. __enter__()方法返回的值 - 这个例子中是”Foo”,赋值给变量’sample’ 3. 执行代码块,打印变量”sample”的值为 “Foo” 4. __exit__()方法被调用
with真正强大之处是它可以处理异常。可能你已经注意到Sample类的 __exit__ 方法有三个参数 val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。
#!/usr/bin/env python# with_example02.pyclass Sample: def __enter__(self): return self def __exit__(self, type, value, trace): print "type:", type print "value:", value print "trace:", trace def do_something(self): bar = 1/0 return bar + 10with Sample() as sample: sample.do_something()
这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有 __enter__() 和 __exit__() 方法即可。此例中,Sample()的 __enter__() 方法返回新创建的Sample对象,并赋值给变量sample。
代码执行后:
bash-3.2$ ./with_example02.py type: <type 'exceptions.ZeropisionError'>value: integer pision or modulo by zerotrace: <traceback object at 0x1004a8128> Traceback (most recent call last): File "./with_example02.py", line 19, in <module> sample.do_something() File "./with_example02.py", line 15, in do_something bar = 1/0ZeropisionError: integer pision or modulo by zero
实际上,在with后面的代码块抛出任何异常时,__exit__() 方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给 __exit__() 方法,因此抛出的ZeropisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在 __exit__ 方法当中。
另外,__exit__ 除了用于tear things down,还可以进行异常的监控和处理,注意后几个参数。要跳过一个异常,只需要返回该函数True即可。
下面的样例代码跳过了所有的TypeError,而让其他异常正常抛出。
def __exit__(self, type, value, traceback): return isinstance(value, TypeError)
上文说了 __exit__ 函数可以进行部分异常的处理,如果我们不在这个函数中处理异常,他会正常抛出,这时候我们可以这样写(python 2.7及以上版本,之前的版本参考使用contextlib.nested这个库函数):
try: with open( "a.txt" ) as f : do something except xxxError: do something about exception
总之,with-as表达式极大的简化了每次写finally的工作,这对保持代码的优雅性是有极大帮助的。
如果有多个项,我们可以这么写:
with open("x.txt") as f1, open('xxx.txt') as f2: do something with f1,f2
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
with 문을 사용하려면 먼저 컨텍스트 관리자의 개념을 이해해야 합니다. 컨텍스트 관리자를 사용하면 with 문이 작동할 수 있습니다.
다음은 컨텍스트 관리자 및 with 문과 관련된 개념 집합입니다.
컨텍스트 관리 프로토콜: __enter__() 및 __exit__() 메서드를 포함합니다. 이 프로토콜을 지원하는 개체는 이 두 가지 메서드를 구현해야 합니다.
컨텍스트 관리자: 컨텍스트 관리 프로토콜을 지원하는 객체입니다. 이 객체는 __enter__() 및 __exit__() 메서드를 구현합니다. 컨텍스트 관리자는 with 문을 실행할 때 설정될 런타임 컨텍스트를 정의하고 with 문 블록의 컨텍스트에서 시작 및 종료 작업을 실행하는 역할을 담당합니다. 컨텍스트 관리자는 일반적으로 with 문을 사용하여 호출되지만 해당 메서드를 직접 호출하여 사용할 수도 있습니다.
런타임 컨텍스트: 컨텍스트 관리자에 의해 생성되고 컨텍스트 관리자의 __enter__() 및 __exit__() 메서드를 통해 구현됩니다. __enter__() 메서드는 명령문 본문이 실행되기 전에 런타임 컨텍스트에 들어갑니다. __exit__() 런타임 컨텍스트에서 종료됩니다. 명령문 본문이 실행된 후. with 문은 런타임 컨텍스트 개념을 지원합니다.
컨텍스트 표현식: with 문에서 with 키워드 뒤에 오는 표현식으로, 컨텍스트 관리자 객체를 반환합니다.
문 본문(with-body): with 문에 래핑된 코드 블록은 문 본문을 실행하기 전에 컨텍스트 관리자의 __enter__() 메서드를 호출하고, 문 본문이 실행된 후에 __exit__() 메서드가 실행됩니다.
관련 링크:
1.http://blog.kissdata.com/2014/05/23/python-with.html
2.https://www.ibm.com/developerworks/cn/opensource/os -cn-pythonwith/
관련 권장 사항:
위 내용은 Python에서의 with 사용법에 대해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!