Expliquant Python '__enter__ " et " __exit__'
J'ai vu ça dans un code. Ça veut dire quoi?
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.stream.close()
from __future__ import with_statement#for python2.5
class a(object):
def __enter__(self):
print 'sss'
return 'sss111'
def __exit__(self ,type, value, traceback):
print 'ok'
return False
with a() as s:
print s
print s
- Une bonne explication ici : effbot.org/zone/python-with-statement.htm
- Modifiant le code de la question est généralement une mauvaise idée, surtout quand il y a des erreurs dans le code. Cette question a été posée avec Py2 à l'esprit, et il n'y a pas de raison de le mettre à jour à Py3.
Vous devez vous connecter pour publier un commentaire.
À l'aide de ces méthodes magiques (
__enter__
,__exit__
) permet d'implémenter des objets qui peuvent être utilisés facilement avec lewith
déclaration.L'idée est qu'il simplifie la création de code qui a besoin de quelques 'cleandown code exécuté (pensez-y comme un
try-finally
bloc). De plus d'explications ici.Un bon exemple pourrait être une connexion de base de données objet (qui a ensuite automatiquement ferme la connexion une fois que le "avec" -déclaration est hors de portée):
Comme expliqué ci-dessus, l'utilisation de cet objet avec le
with
déclaration (vous devrez peut-être fairefrom __future__ import with_statement
en haut de la fiche, si vous êtes sur Python 2.5).PEP343, La "avec la "déclaration" a une belle description ainsi.
__enter__
doit retournerself
toujours comme à l'époque, seulement les autres méthodes de la classe peut être appelée sur le contexte.def __enter__(self)
en PEP 343 et personne nereturn self
: python.org/dev/peps/pep-0343 . Pourquoi pensez-vous ainsi?self
objet, comme expliqué ici : stackoverflow.com/questions/38281853/... 2) auto.XYZ est juste une partie de l'auto objet et le retour de la poignée seulement qui semble inapproprié pour moi de maintenance, de point de vue. Je préférerais retourner poignée complète de l'objet, puis de fournir des Api publiques pour que les composantsself
objet,que je tiens à exposer à l'utilisateur comme danswith open(abc.txt, 'r') as fin: content = fin.read()
self
de__enter__
, qui est comment vous pouvez traiter le fichier en tant quef
à l'intérieur dewith open(...) as f
self
et en tout cas que vous avez besoin de le contexte, l'objet lui-même, vous pouvez toujours instancier le contexte sur la ligne avant de lawith inst
.Si vous savez ce que contexte gestionnaires sont alors vous avez besoin de rien de plus pour comprendre
__enter__
et__exit__
méthodes magiques. Permet de voir un exemple très simple.Dans cet exemple, je vais ouvrir myfile.txt avec l'aide de ouvrir fonction. Le try/finally bloc garantit que, même si une exception inattendue se produit myfile.txt sera fermé.
Maintenant, je vais ouvrir le même fichier avec avec déclaration:
Si vous regardez le code, je n'ai pas de fermer le fichier & il n'y a pas de try/finally bloc. Parce que avec déclaration ferme automatiquement myfile.txt . Vous pouvez même vérifier en appelant
print(fp.closed)
attribut -- qui renvoieTrue
.C'est parce que le fichier des objets (fp dans mon exemple) retournés par ouvrir fonction a deux méthodes intégrées
__enter__
et__exit__
. Il est également connu en tant que gestionnaire de contexte.__enter__
méthode est appelée au début de avec bloc et__exit__
méthode est appelée à la fin. Remarque: avec déclaration ne fonctionne qu'avec des objets qui prennent en charge le contexte mamangement protocole c'est à dire qu'ils ont__enter__
et__exit__
méthodes. Une classe permettant de mettre en œuvre des deux méthodes est connu en tant que gestionnaire de contexte de la classe.Maintenant permet de définir notre propre gestionnaire de contexte classe.
J'espère que maintenant vous avez une compréhension de base des deux
__enter__
et__exit__
méthodes magiques.Je l'ai trouvé étrangement difficile de trouver le python docs pour
__enter__
et__exit__
méthodes par Googler, afin d'aider les autres voici le lien:https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
(le détail est la même pour les deux versions)
J'espérais une description claire de la
__exit__
arguments de méthode. C'est manque, mais nous pouvons déduire...Sans doute
exc_type
est la classe de l'exception.Il est dit que vous ne devrait pas relancer le passé-exception à la règle. Cela nous suggère que l'un des arguments peut-être une Exception réelle instance ...ou peut-être vous êtes censé pour instancier vous-même à partir du type et de la valeur?
Nous pouvons répondre en regardant cet article:
http://effbot.org/zone/python-with-statement.htm
...donc clairement
value
est une instance Exception.Et sans doute
traceback
est un Python traceback objet.En plus les réponses ci-dessus pour illustrer l'invocation de l'ordre, une course simple exemple
Produit de la sortie:
Un rappel: lors de l'utilisation de la syntaxe
with myclass() as mc
, variable mc obtient la valeur retournée par__enter__()
, dans le cas ci-dessusNone
! Pour un tel usage, nécessité de définir la valeur de retour, tels que:essayez d'ajouter mes réponses (ma pensée d'apprentissage) :
__enter__
et[__exit__]
les deux sont des méthodes qui sont appelées à l'entrée et à la sortie de l'organe de "l'instruction" (PEP 343) et la mise en œuvre des deux est appelé gestionnaire de contexte.l'instruction est l'intention de cacher le contrôle de flux d'essayer enfin de la clause et de rendre le code de l'insondable.
la syntaxe de l'instruction :
qui se traduisent par (comme mentionné dans le PEP 343) :
essayez un peu de code:
et maintenant essayer manuellement (à la suite de traduire la syntaxe):
le résultat de la partie serveur comme avant
désolé pour mon mauvais anglais et mes confusions, je vous remercie....