with-block 외부에서 사용할 수있는 with-statement로 정의 된 변수?


90

다음 예를 고려하십시오.

with open('a.txt') as f:
    pass
# Is f supposed to be defined here?

나는 PEP-343뿐만 아니라 with-statement에 대한 언어 문서 (2.7)를 읽었지만 내가 말할 수있는 한 그들은이 문제에 대해 아무 말도하지 않는다.

CPython 2.6.5 f에서는 with-block 외부에서 정의 된 것처럼 보이지만 변경 될 수있는 구현 세부 사항에 의존하지 않습니다.


8
f를 둘러싸는 범위에서 사용할 수 있는지 여부에 대한 질문은 이미 답변되었습니다. 나는의 개념 것을 깨달았을 때 나를 위해 상황에 맞는 관리자의 전체 개념은 클릭 문맥 의 그것과 다르다 범위 . 다음은 제 웹 사이트에 대한 링크입니다. markus-gattol.name/ws/python.html#context_manager
Tom

1
정확히-컨텍스트는 현재 상태 (파일 열기, 파일 닫힘 또는 스레드 잠금 / 잠금 해제)를 변경하는 문제입니다. 장치가 할당 / 할당 취소되었습니다. 범위에 이름이 지정된 모든 변수는 여전히 존재하지만 이제 할당 해제 / 닫힘 / 잠금 해제 핸들을 가리 킵니다.
Danny Staple

답변:


159

예, 컨텍스트 관리자는 with 문 외부에서 사용할 수 있으며 구현이나 버전에 종속되지 않습니다. with 문 새 실행 범위를 생성 하지 않습니다 .


3
이것은 제 생각에 가장 명확한 설명이므로 받아 들인 답변을 수여합니다. 추가로 유용한 정보를 얻기 위해 Alex 및 TokenMacGuy에게 포인트를 제공합니다.
Heikki Toivonen

한동안 파이썬으로 작업하지 않았다면 쉽게 잊을 수있는 것, 들여 쓰기, 이름 및 물건과 같은 기능은 당신이 그것에 접근 할 수 없어야하지만 아직 할 수 있다는 것을 암시합니다.
Vitaliy Terziev

28

with구문 :

with foo as bar:
    baz()

대략 설탕입니다 :

try:
    bar = foo.__enter__()
    baz()
finally:
    if foo.__exit__(*sys.exc_info()) and sys.exc_info():
        raise

이것은 종종 유용합니다. 예를 들면

import threading
with threading.Lock() as myLock:
    frob()

with myLock:
    frob_some_more()

컨텍스트 관리자는 두 번 이상 사용할 수 있습니다.


글쎄요, 잠금 재사용은 그렇지 않을 수도 있습니다 (모르겠지만, 그것들이 다르면 버그가 될 것입니다)-그러나 파이썬 범위 지정 규칙은 여기에서 구현 전반에 걸쳐 확실히 동일 할 것입니다.
fuzzyman

1
이것은 다시 범위 문제가 아닙니다. 범위는 동일합니다. 그러나 foo .__ exit__ 구현이 스레드를 중지 된 상태로 만드는 경우 잠금에 다시 잠그는 입력 이 없으면 두 번째 문은 스레드 잠금에 유용한 작업을 수행하지 않는 것처럼 보입니다.
Danny Staple 2013

16

f파일 인 경우 with문 밖에 닫혀있는 것처럼 보입니다 .

예를 들어,

f = 42
print f
with open('6432134.py') as f:
    print f
print f

인쇄합니다 :

42
<open file '6432134.py', mode 'r' at 0x10050fb70>
<closed file '6432134.py', mode 'r' at 0x10050fb70>

PEP-0343사양 : 'with'설명 섹션 에서 자세한 내용을 확인할 수 있습니다 . ( 짜증나게 할 수있는 ) 파이썬 범위 규칙도 적용됩니다 .f


나는 이것을 알고 있으며 질문에서 언급했습니다. CPython 2.6.5 이상. 그러나 Jython, IronPython 및 PyPy에도 이와 동일하게 적용된다는 것을 보장 할 수 있습니까?
Heikki Toivonen 2011 년

파이썬의 범위 규칙도 항상 그렇게 명확하지는 않습니다. CPython 2.6.5에서 이것을 고려하십시오 [x for x in [1]]. x그 밖에 사용할 수 있습니다. 생성기로 만들기 : (x for x in [1]). 지금 x은 사용할 수 없습니다. 나는 이것이 Python 3에서 변경되어 목록 이해력으로 x도 누출되지 않도록 기억하는 것 같지만 지금은 참조를 찾을 수 없습니다.
Heikki Toivonen 2011 년

검색했지만 지금은 중요한 것을 찾지 못했습니다. 그래도 흥미로운 질문입니다.
miku

실제로 이것은 범위 문제가 아닙니다. 변수 f는 여전히 사용할 수 있지만 이제는 이전에 열려 있던 동일한 파일 인 닫힌 상태의 파일에 대한 핸들입니다. 컨텍스트가 남아있을 때 종료 호출은이 상태를 변경합니다.
Danny Staple 2013

11

주석에서 Heikki의 질문에 답하기 위해 : 예,이 범위 지정 동작은 Python 언어 사양의 일부이며 모든 호환 Python (PyPy, Jython 및 IronPython 포함)에서 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.