답변:
예, 그것은 finally
블록 이후의 try
블록 처럼 작동합니다 . 즉, 파이썬 프로세스가 비정상적으로 종료되지 않는 한 항상 실행됩니다.
또한의 사례 중 하나에 언급 된 PEP-343 에 대한 사양입니다 with
문 :
with locked(myLock):
# Code here executes with myLock held. The lock is
# guaranteed to be released when the block is left (even
# if via return or by an uncaught exception).
그러나 언급 할 가치가있는 것은 일반적으로 원하는 블록이 아닌 블록 안에 open()
전체 with
블록 을 넣지 않으면 호출 에서 발생한 예외를 쉽게 포착 할 수 try..except
없다는 것입니다.
Process.terminate()
에 따르면 finally
명령문 의 호출을 보장하지 않는 몇 가지 (유일한가?) 시나리오 중 하나입니다 . "종료 처리기 및 finally 절 등은 처형. "
with
블록 내에서 생성기 표현식을 반환하면 생성기 가 값을 계속 유지하는 한 보증은 유지됩니까? 아무것도 참조하는 한? 즉 del
, 생성기 객체를 보유하는 변수에 다른 값 을 사용 하거나 할당 해야 합니까?
ValueError: I/O operation on closed file.
합니다.
예.
def example(path, mode):
with open(path, mode) as f:
return [line for line in f if condition]
..은 다음과 거의 같습니다.
def example(path, mode):
f = open(path, mode)
try:
return [line for line in f if condition]
finally:
f.close()
더 정확하게 말하면, __exit__
컨텍스트 관리자 의 메소드는 예외를 리턴하거나 리턴하지 않고 블록을 종료 할 때 항상 호출됩니다. 파일 객체의 __exit__
메소드는 방금 호출합니다 f.close()
(예 : 여기 CPython에서 )
finally
keywrod 로부터 얻는 보장을 보여주는 흥미로운 실험 은 다음과 같습니다 def test(): try: return True; finally: return False
.
예. 더 일반적으로, With Statement Context Manager 의 __exit__
메소드 는 실제로 컨텍스트 내부 에서 발생하는 경우 호출됩니다 . 다음과 같이 테스트 할 수 있습니다.return
class MyResource:
def __enter__(self):
print('Entering context.')
return self
def __exit__(self, *exc):
print('EXITING context.')
def fun():
with MyResource():
print('Returning inside with-statement.')
return
print('Returning outside with-statement.')
fun()
출력은 다음과 같습니다.
Entering context.
Returning inside with-statement.
EXITING context.
위의 결과 __exit__
는 초기에도 불구하고 호출 되었음을 확인합니다 return
. 따라서 컨텍스트 관리자는 무시되지 않습니다.
예, 그러나 다른 경우에는 부작용이있을 수 있습니다. __exit__
블록 에서 플러싱 버퍼와 같은 작업을 수행해야하기 때문입니다.
import gzip
import io
def test(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
def test1(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
print(test(b"test"), test1(b"test"))
# b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff' b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff+I-.\x01\x00\x0c~\x7f\xd8\x04\x00\x00\x00'
else
이 문제with
를 해결하기 위해 추가 될 수 있습니다try with except
. 편집 : 언어에 추가