2016-12-06 43 views
7

關於在Python的Python的open()與.close()

語法爲什麼我們使用open("file")打開,但不"file".close()關閉它?
爲什麼不是"file".open()或相反close("file")

+1

這是一種風格的東西。與對象一起工作的函數通常是該對象的方法,但是您首先需要一種生成對象的方法...... –

+2

'「file」.open()* *對我來說似乎是錯誤的 - 並非所有的字符串都是有效的文件打開,所以'str.open()'看起來好像是糟糕的設計,而所有的字符串都可以是'split()'等。 – Aurora0001

+1

它不是''file「.close()',所以''file」 .open()'不匹配。我想這很容易可能是'close(file_object)'。 – user2357112

回答

1

僅略低於新的比你,但我給這個一來一去,基本上打開和關閉在像Python語言非常不同的動作。當你打開文件時,你真正在做的是在你的應用程序中創建一個代表文件的對象,所以你用一個函數來創建它,通知操作系統文件已經打開並創建一個python可以對象的對象用於讀取和寫入文件。當需要關閉文件時,基本上需要完成的工作是讓您的應用程序告訴操作系統它已完成文件並處理代表文件內存的對象,最簡單的方法是對象本身的一種方法。另外請注意,像"file".open這樣的語法會要求字符串類型包含打開文件的方法,這將是一個非常奇怪的設計,並且需要對字符串類型進行大量擴展以用於您希望用該語法實現的任何其他功能。 close(file)將使更多的意義,但仍然會釋放該對象/讓OS知道文件已不再是開放的笨重的方式,你會路過代表,當你打開文件,而不是創建的對象的變量file指向文件路徑的字符串。

+1

我有幾個更正我想對你的解釋:'open'函數不會將你的文件讀入內存。 'read'和'readlines'這樣做。此外,您打開的任何文件都不一定有「鎖定」。這取決於操作系統如何處理打開的文件引用。我明白你的意思,但我會避免使用「鎖定」一詞。 – skrrgwasme

+0

謝謝!我的MS背景通過那裏顯示,我忘記了一些操作系統的處理打開文件句柄的差異。真的很感謝澄清,我已經更新了我的答案。 –

8

這是因爲open()是一個函數,和.close()是一個對象的方法。 "file".open()沒有任何意義,因爲你暗示open()函數實際上是字符串"file"的類或實例方法。並非所有的字符串都是有效的文件或設備打開,所以解釋器如何處理"not a file-like device".open()將是不明確的。出於同樣的原因,我們不使用"file".close()

close("file")將需要的文件名查找,然後又查找,看是否有文件句柄,當前進程所擁有的,連接到該文件。這將是非常低效的,可能有隱藏的陷阱,這將使它不可靠(例如,如果它不是一個文件,而是一個TTY設備呢?)。只保留對已打開文件或設備的引用並通過該引用關閉文件(也稱爲句柄)會更快更簡單。

許多語言採取這種做法:

f = open("file") # open a file and return a file object or handle 
# stuff... 
close(f)   # close the file, using the file handle or object as a reference 

這類似於你close("file")結構,但不要被愚弄了:它關閉該文件通過直接引用它,而不是文件名存儲在一個字符串。

的Python開發者都選擇了做同樣的事情,但看起來不同,因爲他們已經用面向對象的方法來實現它,而不是。部分原因是Python文件對象have a lot of methods對其可用,例如read(),flush(),等。如果我們使用了close(f),那麼我們必須將的所有的其餘文件對象方法更改爲函數,或者讓它成爲一個隨機函數,其行爲與其餘的原因不同。

TL; DR
open()file.close()的設計是面向對象的校長和好的文件引用慣例相一致。open()是一種類似工廠的功能,可以創建引用文件或其他設備的對象。一旦創建了對象,那麼該對象上的所有其他操作都是通過類或實例方法完成的。

1

通常情況下,您不應該明確使用"file".close(),而應該使用open(file)作爲上下文管理器,因此如果發生異常,文件句柄也會關閉。問題結束:-)

但實際上回答你的問題,我認爲其原因是open支持的許多選項和返回的類依賴於這些選項的不同(見io module)。所以最終用戶要記住他想要的課程,然後使用"class".open以及正確的課程本身就更簡單了。請注意,您也可以傳遞「要包裝的文件的整數文件描述符」。到open,這意味着除了有一個str.open()方法,你也會得到一個int.open()。這將是非常糟糕的OO設計,但也令人困惑。我不會在意猜測會在StackOverflow上詢問什麼樣的問題("door".open(),(1).open())...

但是我必須承認有一個pathlib.Path.open函數。但是如果你有一條路徑,它就不會再模糊了。

至於close()函數:每個實例已經有一個close()方法,並且不同的類之間沒有區別,所以爲什麼要創建一個額外的函數?根本沒有優勢。

1

除了已經說過的內容之外,我引用Python中的changelog刪除了內置的file類型。它(簡要地)解釋了爲什麼在Python 3中刪除了使用類型爲file(Python 2中提供)的類構造函數方法:

刪除了文件類型。使用open()。現在有幾種不同類型的流可以在io模塊中返回。

基本上,而file("filename")將創建的file一個實例,open("filename")可以返回不同的流類的實例,這取決於模式。

https://docs.python.org/3.4/whatsnew/3.0.html#builtins

相關問題