Considérer ce qui suit:
with open(path, mode) as f:
return [line for line in f if condition]
Le fichier sera-t-il fermé correctement, ou l'utilisation d'une returnmanière ou d'une autre contourne-t-elle le gestionnaire de contexte ?
Considérer ce qui suit:
with open(path, mode) as f:
return [line for line in f if condition]
Le fichier sera-t-il fermé correctement, ou l'utilisation d'une returnmanière ou d'une autre contourne-t-elle le gestionnaire de contexte ?
Réponses:
Oui, il agit comme le finallybloc après un trybloc, c'est-à-dire qu'il s'exécute toujours (sauf si le processus python se termine de manière inhabituelle bien sûr).
Il est également mentionné dans l'un des exemples de PEP-343 qui est la spécification de la withdéclaration:
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).
Cependant, il convient de mentionner que vous ne pouvez pas facilement détecter les exceptions levées par l' open()appel sans placer le withbloc entier dans un try..exceptbloc qui n'est généralement pas ce que vous voulez .
Process.terminate()est l'un des rares (le seul?) Scénario qui ne garantit pas l'appel d'une finallyinstruction: "Notez que les gestionnaires de sortie et enfin les clauses, etc., ne seront pas réalisé."
withbloc, la garantie est-elle valable aussi longtemps que le générateur continue de produire des valeurs? aussi longtemps que quelque chose y fait référence? Est-ce que j'ai besoin d'utiliser delou d'attribuer une valeur différente à la variable qui contient l'objet générateur?
ValueError: I/O operation on closed file..
Oui.
def example(path, mode):
with open(path, mode) as f:
return [line for line in f if condition]
..est à peu près équivalent à:
def example(path, mode):
f = open(path, mode)
try:
return [line for line in f if condition]
finally:
f.close()
Plus précisément, la __exit__méthode dans un gestionnaire de contexte est toujours appelée lors de la sortie du bloc (quelles que soient les exceptions, les retours, etc.). La __exit__méthode de l'objet fichier appelle simplement f.close()(par exemple ici en CPython )
finallykeywrod est: def test(): try: return True; finally: return False.
Oui. Plus généralement, la __exit__méthode d'un With Statement Context Manager sera en effet appelée en cas de returnde l'intérieur du contexte. Cela peut être testé avec les éléments suivants:
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()
La sortie est:
Entering context.
Returning inside with-statement.
EXITING context.
La sortie ci-dessus confirme qu'elle a __exit__été appelée malgré le début return. En tant que tel, le gestionnaire de contexte n'est pas contourné.
Oui, mais il peut y avoir des effets secondaires dans d'autres cas, car cela peut faire quelque chose (comme le vidage du tampon) dans le __exit__bloc
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'
elsepourrait être ajoutéwithpour résoudre cetry with exceptproblème. edit: ajouté à la langue