Quel est le Python « avec » déclaration utilisé?
Question
Je suis en train de comprendre la déclaration avec en python. Partout où je regarde, il parle d'ouverture et de fermeture d'un fichier, et est destiné à remplacer le bloc try-finally. Quelqu'un pourrait-il poster d'autres exemples aussi. Je suis juste essayer ballon et il y a des déclarations à gogo en elle. certainement demander à quelqu'un de fournir des éclaircissements à ce sujet.
La solution
Il y a une très belle explication . En fait, avec la déclaration appelle deux méthodes spéciales sur l'objet associé. Les méthodes de __enter__ et __exit__. La méthode entrer renvoie la variable associée à la « par » déclaration. Bien que la méthode de __exit__ est appelée après l'exécution d'une instruction pour gérer tout nettoyage (telles que la fermeture d'un pointeur de fichier).
Autres conseils
L'idée de la déclaration de with
est de faire « faire la bonne chose » le chemin de moindre résistance. Bien que l'exemple de fichier est le plus simple, les serrures de filetage fournissent en fait un exemple plus classique de code non évidemment bogué:
try:
lock.acquire()
# do stuff
finally:
lock.release()
Ce code est cassé - si l'acquisition de verrouillage ne jamais, que ce soit la mauvaise exception sera levée (puisque le code va tenter de libérer un verrou qu'il n'a jamais acquis), ou, pire, si cela est un verrou récursive, il sera publié au début. Le code correct ressemble à ceci:
lock.acquire()
try:
# do stuff
finally:
# If lock.acquire() fails, this *doesn't* run
lock.release()
En utilisant une instruction with
, il devient impossible de se tromper, car il est intégré dans le gestionnaire de contexte:
with lock: # The lock *knows* how to correctly handle acquisition and release
# do stuff
L'autre endroit où la déclaration de with
aide est grandement similaire à l'avantage majeur de la fonction et décorateurs classe: il faut code « deux pièces », qui peut être séparé par un nombre arbitraire de lignes de code (la définition de fonction pour les décorateurs , le bloc try
dans le cas présent) et le transforme en « un seul morceau » code où le programmeur déclare simplement à l'avance ce qu'ils essaient de faire.
Pour des exemples courts, cela ne ressemble pas à un grand gain, mais il est en fait une énorme différence lors de l'examen du code. Quand je vois lock.acquire()
dans un morceau de code, je dois faire défiler vers le bas et vérifier une lock.release()
correspondante. Quand je vois with lock:
, cependant, aucune vérification est nécessaire -. Je peux voir immédiatement que le verrou sera libéré correctement
Il y a douze exemples d'utilisation with
PEP343 , y compris le fichier exemple -open:
- Un modèle pour assurer qu'un verrou, acquis au début d'une bloc, est libéré lorsque le bloc reste
- Un modèle pour l'ouverture d'un fichier qui assure la fermeture du fichier lorsque le bloc reste
- Un modèle pour valider ou une base de données transaction
- Exemple 1 réécrite sans générateur
- Rediriger temporairement stdout
- Une variante ouvert () qui renvoie également une condition d'erreur
- Un autre exemple utile serait une opération qui bloque signaux
- Une autre utilisation de cette fonction est le contexte décimal
- Voici un gestionnaire de contexte simple pour le module décimal
- Un gestionnaire de contexte « fermeture de l'objet » générique
- un contexte libéré () pour libérer temporairement un verrou acquis précédemment en échangeant l'acquisition () et la libération () appelle
- Un gestionnaire de contexte « imbriqué » qui niche automatiquement contextes fournis de gauche à droite pour éviter excessive indentation