J'ai vu ça dans le code de quelqu'un. Qu'est-ce que ça veut dire?
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
python
oop
with-statement
zjm1126
la source
la source
Réponses:
L'utilisation de ces méthodes magiques (
__enter__
,__exit__
) vous permet d'implémenter des objets qui peuvent être utilisés facilement avec l'with
instruction.L'idée est qu'il facilite la construction de code qui nécessite un peu de code de «nettoyage» (pensez-y comme un
try-finally
bloc). Quelques explications supplémentaires ici .Un exemple utile pourrait être un objet de connexion à une base de données (qui ferme ensuite automatiquement la connexion une fois que l'instruction «with» correspondante est hors de portée):
Comme expliqué ci-dessus, utilisez cet objet avec l'
with
instruction (vous devrez peut-être le fairefrom __future__ import with_statement
en haut du fichier si vous êtes sur Python 2.5).PEP343 - La déclaration "avec" a également une belle écriture.
la source
__enter__
devraitself
toujours retourner comme alors seules les autres méthodes de la classe peuvent être appelées dans le contexte.def __enter__(self)
dans PEP 343 et personne ne le faitreturn self
: python.org/dev/peps/pep-0343 . Pourquoi penses-tu ça?self
objet comme expliqué ici: stackoverflow.com/questions/38281853/… 2) self.XYZ est juste une partie de self object et revenir à la poignée uniquement pour cela me semble inapproprié du point de vue de la maintenance. Je préférerais plutôt retourner le descripteur de l'objet complet, puis fournir des API publiques uniquement à cesself
objets composants , que je souhaite exposer à l'utilisateur comme danswith open(abc.txt, 'r') as fin: content = fin.read()
self
de__enter__
, c'estf
with open(...) as f
Si vous savez ce que sont les gestionnaires de contexte, vous n'avez plus besoin de comprendre
__enter__
et de__exit__
méthodes magiques. Voyons un exemple très simple.Dans cet exemple, j'ouvre myfile.txt à l'aide de la fonction open . Le bloc try / finally garantit que même si une exception inattendue se produit, myfile.txt sera fermé.
Maintenant, j'ouvre le même fichier avec une déclaration:
Si vous regardez le code, je n'ai pas fermé le fichier et il n'y a pas de bloc try / finally . Parce que l' instruction ferme automatiquement monfichier.txt . Vous pouvez même le vérifier en appelant l'
print(fp.closed)
attribut - qui renvoieTrue
.En effet, les objets fichier (fp dans mon exemple) renvoyés par la fonction open ont deux méthodes intégrées
__enter__
et__exit__
. Il est également appelé gestionnaire de contexte.__enter__
La méthode est appelée au début de with block et la__exit__
méthode est appelée à la fin. Remarque: avec l' instruction ne fonctionne qu'avec des objets qui prennent en charge le protocole de mamangement de contexte, c'est-à-dire qu'ils ont__enter__
et des__exit__
méthodes. Une classe qui implémente les deux méthodes est appelée classe de gestionnaire de contexte.Permet maintenant de définir notre propre classe de gestionnaire de contexte .
J'espère que vous avez maintenant une compréhension de base des deux
__enter__
et__exit__
des méthodes magiques.la source
J'ai trouvé étrangement difficile de localiser les documents
__enter__
et les__exit__
méthodes de python par Google, donc pour 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 le même pour les deux versions)
J'espérais une description claire des
__exit__
arguments de la méthode. Cela fait défaut mais on peut les déduire ...C'est probablement
exc_type
la classe de l'exception.Il indique que vous ne devez pas relancer l'exception transmise. Cela nous suggère que l'un des arguments pourrait être une instance d'exception réelle ... ou peut-être êtes-vous censé l'instancier vous-même à partir du type et de la valeur?
Nous pouvons répondre en consultant cet article:
http://effbot.org/zone/python-with-statement.htm
... est donc clairement
value
une instance d'exception.Et
traceback
est probablement un objet traceback Python .la source
En plus des réponses ci-dessus pour illustrer l'ordre d'invocation, un exemple d'exécution simple
Produit la sortie:
Un rappel: lors de l'utilisation de la syntaxe
with myclass() as mc
, la variable mc obtient la valeur retournée par__enter__()
, dans le cas ci-dessusNone
! Pour une telle utilisation, vous devez définir une valeur de retour, telle que:la source
essayez d'ajouter mes réponses (ma pensée d'apprendre):
__enter__
et les[__exit__]
deux sont des méthodes qui sont appelées à l'entrée et à la sortie du corps de " l'instruction with " ( PEP 343 ) et leur mise en œuvre est appelée gestionnaire de contexte.l'instruction with a pour but de masquer le contrôle de flux de la clause try finally et de rendre le code impénétrable.
la syntaxe de l'instruction with est:
qui se traduisent par (comme mentionné dans PEP 343):
essayez du code:
et essayez maintenant manuellement (suivant la syntaxe de traduction):
le résultat du côté serveur comme avant
désolé pour mon mauvais anglais et mes explications peu claires, merci ....
la source
C'est ce qu'on appelle le gestionnaire de contexte et je veux juste ajouter que des approches similaires existent pour d'autres langages de programmation. Les comparer pourrait être utile pour comprendre le gestionnaire de contexte en python. Fondamentalement, un gestionnaire de contexte est utilisé lorsque nous avons affaire à certaines ressources (fichier, réseau, base de données) qui doivent être initialisées et, à un moment donné, détruites (éliminées). Dans Java 7 et supérieur, nous avons une gestion automatique des ressources qui prend la forme de:
Notez que Session doit implémenter
AutoClosable
ou l'une de ses (nombreuses) sous-interfaces.En C # , nous utilisons des instructions pour gérer les ressources qui prennent la forme de:
Dans lequel
Session
devrait mettre en œuvreIDisposable
.En python , la classe que nous utilisons doit implémenter
__enter__
et__exit__
. Il prend donc la forme de:Et comme d'autres l'ont souligné, vous pouvez toujours utiliser l'instruction try / finally dans toutes les langues pour implémenter le même mécanisme. Ce n'est que du sucre syntaxique.
la source