2017-09-26 49 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,我們可以發現這一點:

# 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() 

quit方法被調用,因此我認爲我們不必使用closing方法爲Python 3.因此,我們可以只使用:

with (ftplib.FTP()) as ftp: 

__exit__由於方法在Python 2丟失,closing是必要的Python 2代碼。

這是正確的嗎?

+1

你已經回答了你自己的問題:)在Python2中,就像你說的。沒有'__enter__'函數或'__exit__'函數,那裏的上下文句柄在進入或退出時不會做任何事情,除非在你的情況下分配變量'ftp'。所以這是一個繼承和向後兼容的遵從性事情。如果你不想成爲逆向忍者,你可以跳過它。 – Torxed

+0

@Toxxed由於互聯網上充斥着不正確的代碼示例(我明白,在很多一次性小腳本中,您不需要打擾這些細節),所以很容易混淆,所以我想要確認。 –

+0

問這是一個完全正確的問題:)我寫了一個更長的答案,以防人們在這個問題上磕磕絆絆。 – Torxed

回答

1

你的確大部分都回答了你自己的問題。
並按照在評論中討論的那樣,這是一個合法的問題,因爲互聯網是「充滿了不正確的代碼示例」

要澄清我的答案很簡單,這是一個傳統問題,即在Python2預期Python3代碼不會執行。因此,互聯網上的(好的)例子有望包含對在Python2中運行代碼的危險性的解釋。或者他們會通過小的修改使代碼向後兼容。

這是當代碼上運行Python2 closing()用於從Python3模擬新的功能這樣的實例。

Python2(ftplib)沒有__enter____exit__函數,因此呈現上下文句柄「無用」(除了使它向前兼容,更容易讀取IMO並且它還將該調用分配給變量)這種情況下ftp)。
爲了避免這種情況發生,編寫者在調用時使用了closing()來根據Python3獲取自動閉包。

如果souly使用Python3是,這是多餘的,可能會減慢你的代碼(極少)。如果你不想向後兼容,那麼你可以跳過那段代碼。