2017-09-26 4 views
1

J'ai le code vu comme celui-ci (code Python 3):Python ftplib: Comment libérer correctement l'objet connexion?

import ftplib 
from contextlib import closing 

with closing(ftplib.FTP()) as ftp: 

est l'utilisation de la méthode closing nécessaire? Dans un intéressant answer, nous pouvons lire que dans les objets de connexion de base de données, la méthode __exit__ du gestionnaire de contexte ne ferme pas la connexion (au moins pour SQLite), mais valide une transaction à la place. Par conséquent, l'utilisation de la méthode closing est nécessaire.

Comment ça se passe avec la classe FTP de Python?

En regardant le sources du ftplib Python, nous pouvons trouver ceci:

# Context management protocol: try to quit() if active 
def __exit__(self, *args): 
    if self.sock is not None: 
     try: 
      self.quit() 
     except (OSError, EOFError): 
      pass 
     finally: 
      if self.sock is not None: 
       self.close() 

La méthode quit est appelée donc je pense que nous ne devons pas utiliser la méthode closing pour Python 3. Nous peut utiliser simplement:

with (ftplib.FTP()) as ftp: 

Comme méthode __exit__ manque en Python 2, closing est nécessaire pour le code Python 2.

Est-ce correct?

+1

Vous avez répondu à votre propre question :) Dans Python2, comme vous l'avez indiqué. Il n'y a pas de fonction '__enter__' ou de fonction' __exit__', là, le handle de contexte ne fera rien lors de l'entrée ou de la sortie, sauf assigner la variable 'ftp' dans votre cas. Il s'agit donc d'un héritage et d'une compatibilité descendante. Vous pouvez l'ignorer si vous n'êtes pas intéressé à être un ninja à rebours. – Torxed

+0

@Torxed Puisque Internet est jonché d'exemples de codes incorrects (je comprends que dans de nombreux petits scripts ponctuels, vous n'avez pas besoin de vous préoccuper de tels détails), on est facilement confus, alors je voulais avoir une confirmation. –

+0

C'est une très bonne question à poser :) J'ai écrit une réponse un peu plus longue au cas où les gens trébucheraient à travers cette question. – Torxed

Répondre

1

Vous avez répondu à votre question pour la plupart.
Et comme discuté dans les commentaires, c'est une question légitime puisque l'Internet est "jonché d'exemples de code incorrect".

Pour clarifier ma réponse courte, il s'agit d'un problème d'héritage où le code Python3 ne fonctionnera pas comme prévu sur Python2. Donc, de (bons) exemples sur internet devraient soit inclure une explication des dangers de l'exécution du code dans Python2, soit rendre le code rétrocompatible avec une petite modification.

Il s'agit d'une instance dans laquelle closing() est utilisé pour émuler les nouvelles fonctions à partir de Python3 lorsque le code est exécuté sur Python2.

python2 (ftplib) n'a pas non plus une __enter__ ou une fonction __exit__, rendant ainsi le contexte a « inutile » (sauf le rendant compatible avant, plus facile à lire l'OMI et également affecté l'appel à une variable, en ce cas ftp).
Pour rendre inutilisable l'écrivain utilisé closing() autour de l'appel pour obtenir la fermeture automatique selon Python3.

Si vous êtes en utilisant Python3, ceci est redondant et ralentit probablement votre code (extrêmement peu). Et là pour vous pouvez passer ce morceau de code si vous ne cherchez pas à être rétrocompatible.