Rozważmy następujący przykład:
with open('a.txt') as f:
pass
# Is f supposed to be defined here?
Przeczytałem dokumentację językową (2.7) dotyczącą instrukcji with oraz PEP-343, ale o ile wiem, nie mówią nic na ten temat.
W CPythonie 2.6.5 f
wydaje się być zdefiniowany poza with-block, ale wolałbym nie polegać na szczegółach implementacji, które mogą się zmienić.
Odpowiedzi:
Tak, menedżer kontekstu będzie dostępny poza instrukcją with i nie jest to zależne od implementacji ani wersji. z instrukcjami nie tworzą nowego zakresu wykonania.
źródło
with
składnia:with foo as bar: baz()
to w przybliżeniu cukier dla:
try: bar = foo.__enter__() baz() finally: if foo.__exit__(*sys.exc_info()) and sys.exc_info(): raise
Jest to często przydatne. Na przykład
import threading with threading.Lock() as myLock: frob() with myLock: frob_some_more()
Menedżer kontekstu może być używany więcej niż raz.
źródło
W przypadku, gdy
f
jest to plik, zostanie on zamknięty pozawith
wyciągiem.Na przykład this
f = 42 print f with open('6432134.py') as f: print f print f
wydrukowałby:
42 <open file '6432134.py', mode 'r' at 0x10050fb70> <closed file '6432134.py', mode 'r' at 0x10050fb70>
Szczegóły można znaleźć w PEP-0343 w sekcji Specyfikacja: Oświadczenie „z” . Zasady zakresu Pythona (co może być irytujące ) również mają zastosowanie
f
.źródło
[x for x in [1]]
.x
jest dostępny poza tym. Uczynić go generatora:(x for x in [1])
. Terazx
nie jest dostępny. Wydaje mi się, że zostało to zmienione w Pythonie 3, więc nawet przy zrozumieniu listyx
nie wycieka, ale nie mogę teraz znaleźć odniesienia.Aby odpowiedzieć na pytanie Heikkiego w komentarzach: tak, to zachowanie zakresu jest częścią specyfikacji języka Python i będzie działać na wszystkich zgodnych Pythonach (w tym PyPy, Jython i IronPython).
źródło