2017-09-26 6 views
1

私はこの(Pythonの3コード)のようなコードを見てきました:Python ftplib:接続オブジェクトを正しく解放するには?

import ftplib 
from contextlib import closing 

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

が必要closingメソッドの使い方ですか?興味深いanswerでは、データベース接続オブジェクトでコンテキストマネージャの__exit__メソッドが(少なくともSQLiteではなく)接続を閉じず、代わりにトランザクションをコミットすることが読み取れます。したがって、closingメソッドを使用する必要があります。

PythonのFTPクラスではどうですか? Pythonのftplibののsourcesを見ると

、我々はこれを見つけることができます:

quit方法は、私たちは、Python 3用 closing方法を使用する必要はありませんと思いますので、呼ばれ
# 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() 

だから我々ちょうど使用することができます。

with (ftplib.FTP()) as ftp: 

__exit__方法は、Python 2に欠けているので、closingは、Python 2のコードのために必要です。

これは間違いありませんか?

+1

あなた自身の質問に答えました:) Python2では、あなたが述べたとおりです。 '__enter__'関数も' __exit__'関数もありません。コンテキストハンドルは、あなたの場合に変数 'ftp'を代入する以外は何もしません。これは継承であり、後方互換性のあるコンプライアンスです。あなたが後方の忍者に興味がないなら、あなたはそれをスキップすることができます。 – Torxed

+0

@Torxedインターネットは間違ったコード例ではぎとられているので(私は、多くの1回限りの小さなスクリプトではそのような詳細を気にする必要はないと理解しています)、簡単に混乱するので、確認したいと思います。 –

+0

これは完全にうまくいく質問です:)私は人々がこの質問に遭遇した場合に、少し長い答えを書きました。 – Torxed

答えて

1

ほとんどの場合、自分の質問に答えました。
コメントに記載されているとおり、インターネットがであり、「不正なコード例が散在している」なので正当な質問です。

私の短い答えを明確にするために、これはPython3のコードがPython2で期待通りに機能しないという遺産の問題です。インターネット上の(良い)例は、うまくいけばPython2でコードを実行する危険性についての説明を含んでいます。あるいは、コードを小さな修正と後方互換性にするでしょう。

これは、コードがPython2で実行されているときに、Python3から新しい関数をエミュレートするためにclosing()が使用されるようなインスタンスです。

Python2(ftplibのは)ので、それはで、変数への呼び出しを割り当て扱う読みやすく、それは前方互換作りを除いて(「役に立たない」IMOと、コンテキストをレンダリング、__enter__または__exit__機能のいずれかを持っていません。この場合ftp)。
作者はそれを無用にするために、呼び出しの回りにclosing()を使用して、Python3のように自動終了を取得しました。

あなたがの場合、Python3を使用している場合、これは冗長であり、おそらくコードが遅くなります(ごくわずかです)。下位互換性がないと思われる場合は、特定のコードをスキップすることができます。

関連する問題