Il s'agit peut-être d'une question stupide (et pas très pratique), mais je la pose parce que je n'arrive pas à m'y retrouver.
En cherchant à savoir si un return
à l'intérieur d'un appel à un gestionnaire de contexte empêcherait __exit__
d'être appelé (non, ce n'est pas le cas), j'ai constaté qu'il semble courant de faire une analogie entre __exit__
y finally
en un try/finally
(par exemple ici : https://stackoverflow.com/a/9885287/3471881 ) parce que :
def test():
try:
return True
finally:
print("Good bye")
Exécuterait la même chose que :
class MyContextManager:
def __enter__(self):
return self
def __exit__(self, *args):
print('Good bye')
def test():
with MyContextManager():
return True
Cela m'a vraiment aidé à comprendre le fonctionnement des cm:s, mais après avoir joué un peu, j'ai réalisé que cette analogie ne fonctionnerait pas si nous retournions quelque chose plutôt que d'imprimer.
def test():
try:
return True
finally:
return False
test()
--> False
Alors que __exit__
ne reviendront apparemment pas du tout :
class MyContextManager:
def __enter__(self):
return self
def __exit__(self, *args):
return False
def test():
with MyContextManager():
return True
test()
--> True
Cela m'a conduit à penser que peut-être vous ne pouvez pas retourner quoi que ce soit à l'intérieur. __exit__
mais vous pouvez :
class MyContextManager:
def __enter__(self):
return self
def __exit__(self, *args):
return self.last_goodbye()
def last_goodbye(self):
print('Good bye')
def test():
with MyContextManager():
return True
test()
--> Good bye
--> True
Notez que cela n'a pas d'importance si nous ne retournons rien à l'intérieur de la balise test()
fonction.
Cela m'amène à ma question :
- Est-il impossible de retourner une valeur à partir de l'intérieur
__exit__
et si oui, pourquoi ?