2015-11-05 67 views
1

什麼是os.close(3)?什麼是os.close(3)?

我正在閱讀python cookbook 2nd第2.9章,它解釋了python zip文件是如何工作的。其中有一小段代碼,我真的不明白。

import zipfile, tempfile, os, sys 
handle, filename = tempfile.mkstemp('.zip') 
os.close(handle) # <- handle is int 3 here 
z = zipfile.ZipFile(filename, 'w') 
z.writestr('hello.py', 'def f(): return "hello world from "+__file__\n') 
z.close() 
sys.path.insert(0, filename) 
import hello 
print hello.f() 
os.unlink(filename) 

os.close()的解釋在python文檔:

此功能用於低級別的I/O,並且必須被應用到如由os.open返回文件描述符()或管()。要關閉由內建函數open()或popen()或fdopen()返回的「文件對象」,請使用其close()方法。

在Linux中文件描述符0,1 & 2標準輸入,標準輸出& stderror,我沒有得到什麼FD 3?即使我已經閱讀了這個「What is the file descriptor 3 assigned by default?」。

我評論os.close(handle)出來,但輸出沒有什麼不同。

+4

你從'tempfile.mkstemp'得到'handle',那你爲什麼不讀這個文檔呢?顯然你正在關閉臨時文件,爲什麼你會期望它是in/out/err中的三個標準文件句柄之一?另外,您應該閱讀樣式指南:http://www.python.org/dev/peps/pep-0008/。 – jonrsharpe

+2

'3'完全沒有什麼魔力 - 如果你的程序是在已經使用FD 3的情況下啓動的,或者在打開另一個文件(並且該文件未被關閉)之前被分配了句柄號,那麼你將得到一個此處分配了不同的句柄號。 –

+0

答案中沒有涉及到的一件事是,儘管你可以取消鏈接文件(即從目錄列表中刪除它的名字),但當有人仍然有句柄時,其內容不會消失。特別是,空間不會被釋放。 (通常的真實情況是「我刪除了3 gig logfile,爲什麼我沒有得到3 gig的可用空間?」 - 「因爲你的prorgam仍然打開刪除的文件」。) –

回答

4

儘管Python主要處理「文件對象」,但它們是OS級文件句柄的抽象;當在操作系統級別上實際讀取或寫入內容到文件(或網絡流或其他類似文件的對象)時,會向操作系統傳遞與想要與之交互的文件相關聯的句柄號。因此,Python中實際由操作系統級文件句柄支持的每個文件對象都具有關聯的文件描述符號。

文件句柄存儲在一個表中,每個表都與一個整數相關聯。在Linux上,您可以查看目錄/proc/self/fds(用self的PID號代替另一個進程)以查看哪些句柄具有給定進程的哪些數字。

handle, filename = tempfile.mkstemp('.zip'); os.close(handle)因此會關閉由mkstemp返回給您的操作系統級文件句柄。


順便說一句:要注意,但絕對沒有什麼特別的3號,並且沒有違約或常規行爲同樣在操作系統級別實現是非常重要的;當調用mkstemp(或更確切地說,當mkstemp的C標準庫實現稱爲OS級系統調用open)時,它恰好是文件句柄表中下一個可用位置。

0

您正在獲取文件描述符3,因爲在這種情況下,它是下一個可用的文件描述符。如您所述,stdin(0),stdout(1)和stderr(2)會自動爲您打開。你引用的鏈接(https://unix.stackexchange.com/questions/41421/what-is-the-file-descriptor-3-assigned-by-default)也指出了這一點。

+1

這並不能保證FD 3將被分配給程序打開的第一個文件句柄;它可能繼承比其父進程標準集更多或更少的描述符(前者肯定比後者更普遍)。 –

+1

...例如,通過'flock()'風格的鎖定文件從外部強制執行只保留一個實例的程序將被調用,繼承該鎖的句柄。 –

+0

@CharlesDuffy好點,顯然OP理解你更全面的答案。 – davejagoda