Es gibt Code wie diesen.
def yielder():
#try:
print('yielder setup')
yield 'text'
#finally:
print('yielder teardown')
def yielder_with_finally():
try:
print('yielder setup')
yield 'text'
finally:
print('yielder teardown')
def f(text):
print(text)
Wenn Sie beim Aufruf von yielder "für y in yielder (): f (y)" sagen, wird die Ausgabe ausgeführt
yielder setup
text
yielder teardown
Wenn Sie es jedoch so verwenden, dass next nur einmal aufgerufen wird (* 3 der 4 am Ende beschriebenen Methoden mit Ausnahme der ersteren),
yielder setup
text
so werden. Teardown wird nicht aufgerufen. Durch das endgültige Hinzufügen wird Teardown aufgerufen.
Beim Aufrufen dieser Funktion jedoch mit "für y in yielder_with_finally (): f (y)" oder "y = yielder_with_finally (); f (next (y))"
yielder setup
text
yielder teardown
Wenn Sie jedoch "t = next (yielder_with_finally ()); f (t)" oder "f (next (yielder_with_finally ())") aufrufen,
yielder setup
yielder teardown
text
Es wird eine unerwartete Ausführungsreihenfolge. In CPython2 / 3 verhielt es sich ähnlich. Wenn das Herunterfahren jedoch nur durch einmaliges Aufrufen von next ausgeführt wird, ist das Debuggen schwierig (in IPython usw.), sodass es möglicherweise überhaupt nicht möglich ist, es auf diese Weise zu verwenden. ** Es kann eine gute Idee sein, beim Nachgeben nicht endgültig zum Abreißen zu verwenden. ** ** **
Die Ertragsvorrichtung von pytest ist so implementiert, dass sie zweimal richtig gedreht werden kann, so dass dieses Problem nicht auftritt. https://docs.pytest.org/en/latest/_modules/_pytest/fixtures.html
In PyPy war das Verhalten mit oder ohne endgültig das gleiche wie ohne endgültig in CPython.
Ich habe es mit Ruby überprüft, aber das Verhalten hat sich nicht mit oder ohne Gewähr geändert (ähnlich wie bei PyPy).
def yielder()
return to_enum(:yielder) if !block_given?
#begin
puts('yielder setup')
yield 'text'
#ensure
puts('yielder teardown')
#end
end
def yielder_with_ensure()
return to_enum(:yielder_with_ensure) if !block_given?
begin
puts('yielder setup')
yield 'text'
ensure
puts('yielder teardown')
end
end
def f(text)
puts(text)
end
Recommended Posts