Według PEP-343, A with
oświadczenie przekłada od:
with EXPR as VAR:
BLOCK
do:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
Jak widać, nie jest niczym oczywistym można zrobić na podstawie zaproszenia do sposobu __enter__()
menedżer kontekstu, który może pominąć treść ("BLOCK
") instrukcji with.
Ludzie wykonali specyficzne dla implementacji Pythona rzeczy, takie jak manipulowanie stosem wywołań wewnątrz __enter__()
, w projektach takich jak withhacks. Pamiętam, jak Alex Martelli opublikował bardzo interesujący wywiad z hackem na stackoverflow za rok lub dwa z powrotem (nie pamiętam wystarczająco dużo postu z ręki, aby go znaleźć i znaleźć).
Ale prostą odpowiedzią na twoje pytanie/problem jest to, że nie możesz zrobić tego, o co prosisz, pomijając treść instrukcji, bez uciekania się do tak zwanej "głębokiej magii" (która niekoniecznie jest przenośna między pythonami wdrożenia). Z głęboką magią możesz być w stanie to zrobić, ale zalecam robić tylko takie rzeczy, jak ćwiczenie, aby zobaczyć, jak można to zrobić, nigdy w "kodzie produkcyjnym".
Znalazłem to, ale nie wiem, jak to zrozumieć, ani jak go wdrożyć. http://www.python.org/dev/peps/pep-0377/ Czy istnieją inne, bardziej eleganckie sposoby? –
Fakt, że jest to PEP (i dyskusja nad zmianami semantycznymi) sugeruje, że nie można go wdrożyć bez uciekania się do zmiany zachowania tłumacza. – nneonneo
ma obsesję na punkcie schludności? :) z A(), B(): gdzie B __enter__ może podnieść coś wydaje mi się w porządku. – swang