"tempfile" --- 生成臨時檔案和目錄
*********************************

**原始碼：**Lib/tempfile.py

======================================================================

This module creates temporary files and directories.  It works on all
supported platforms. "TemporaryFile", "NamedTemporaryFile",
"TemporaryDirectory", and "SpooledTemporaryFile" are high-level
interfaces which provide automatic cleanup and can be used as *context
managers*. "mkstemp()" and "mkdtemp()" are lower-level functions which
require manual cleanup.

所有可被使用者呼叫的函式和建構函式都帶有可以設定臨時檔案和臨時目錄的路
徑和名稱的引數。此 module 所使用的檔名為一個隨機字元組成的字串，這讓檔
案可以更安全地在共享的臨時目錄中被建立。為了維持向後相容性，引數的順序
會稍微奇怪，所以為了讓程式更容易被理解，建議使用關鍵字引數。

這個 module 定義了以下可供使用者呼叫的項目：

tempfile.TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

   回傳一個可當作臨時儲存區域的 *file-like object*。建立該檔案使用了與
   "mkstemp()" 相同的安全規則。它將在關閉（包括當物件被垃圾回收
   (garbage collect) 時的隱式關閉）後立即銷毀。在 Unix 下，該檔案所在
   的目錄可能根本不被建立、或者在建立檔案後立即就被刪除，其他平臺不支
   援此功能；你的程式不應依賴使用此功能建立的臨時檔案名稱，因為它在檔
   案系統中的名稱有可能是不可見的。

   The resulting object can be used as a *context manager* (see 範例).
   On completion of the context or destruction of the file object the
   temporary file will be removed from the filesystem.

   *mode* 參數預設為 "'w+b'"，所以建立的檔案不用關閉就可以讀取或寫入。
   因為用的是二進位制模式，所以無論存的是什麼資料，它在所有平臺上的行
   為都一致。*buffering*、*encoding*、*errors* 和 *newline* 的含義與
   "open()" 中的相同。

   參數 *dir*、*prefix* 和 *suffix* 的含義和預設值都與它們在
   "mkstemp()" 中的相同。

   在 POSIX 平臺上，回傳物件是真實的檔案物件。在其他平臺上，它是一個
   file-like object，它的 "file" 屬性為底層的真實檔案物件。

   The "os.O_TMPFILE" flag is used if it is available and works
   (Linux-specific, requires Linux kernel 3.11 or later).

   在不是 Posix 或 Cygwin 的平臺上，TemporaryFile 是
   NamedTemporaryFile 的別名。

   引發一個附帶引數 "fullpath" 的 "tempfile.mkstemp" 稽核事件。

   在 3.5 版的變更: The "os.O_TMPFILE" flag is now used if available.

   在 3.8 版的變更: 新增 *errors* 參數。

tempfile.NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None)

   此函式執行的操作與 "TemporaryFile()" 幾乎相同，不同之處為確保該臨時
   檔案在檔案系統中具有可見的名稱（在 Unix 上目錄條目不會被 unlink）。
   檔名可以由回傳 file-like object 的 "name" 屬性取得。在臨時檔案仍開
   啟時，是否允許用檔名第二次開啟檔案，在各個平臺上是不同的（在 Unix
   上可以；在 Windows NT 版本以上不行）。如果 *delete* 為 true（預設值
   ），則檔案會在關閉後立即被刪除。該函式回傳的物件始終是 file-like
   object，它的 "file" 屬性是底層的真實檔案物件。file-like object 可以
   像普通檔案一樣在 "with" 陳述句中使用。

   On POSIX (only), a process that is terminated abruptly with SIGKILL
   cannot automatically delete any NamedTemporaryFiles it created.

   引發一個附帶引數 "fullpath" 的 "tempfile.mkstemp" 稽核事件。

   在 3.8 版的變更: 新增 *errors* 參數。

class tempfile.SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

   This class operates exactly as "TemporaryFile()" does, except that
   data is spooled in memory until the file size exceeds *max_size*,
   or until the file's "fileno()" method is called, at which point the
   contents are written to disk and operation proceeds as with
   "TemporaryFile()".

   rollover()

      The resulting file has one additional method, "rollover()",
      which causes the file to roll over to an on-disk file regardless
      of its size.

   The returned object is a file-like object whose "_file" attribute
   is either an "io.BytesIO" or "io.TextIOWrapper" object (depending
   on whether binary or text *mode* was specified) or a true file
   object, depending on whether "rollover()" has been called.  This
   file-like object can be used in a "with" statement, just like a
   normal file.

   在 3.3 版的變更: the truncate method now accepts a *size* argument.

   在 3.8 版的變更: 新增 *errors* 參數。

   在 3.11 版的變更: Fully implements the "io.BufferedIOBase" and
   "io.TextIOBase" abstract base classes (depending on whether binary
   or text *mode* was specified).

class tempfile.TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False)

   This class securely creates a temporary directory using the same
   rules as "mkdtemp()". The resulting object can be used as a
   *context manager* (see 範例).  On completion of the context or
   destruction of the temporary directory object, the newly created
   temporary directory and all its contents are removed from the
   filesystem.

   name

      The directory name can be retrieved from the "name" attribute of
      the returned object.  When the returned object is used as a
      *context manager*, the "name" will be assigned to the target of
      the "as" clause in the "with" statement, if there is one.

   cleanup()

      The directory can be explicitly cleaned up by calling the
      "cleanup()" method. If *ignore_cleanup_errors* is true, any
      unhandled exceptions during explicit or implicit cleanup (such
      as a "PermissionError" removing open files on Windows) will be
      ignored, and the remaining removable items deleted on a "best-
      effort" basis. Otherwise, errors will be raised in whatever
      context cleanup occurs (the "cleanup()" call, exiting the
      context manager, when the object is garbage-collected or during
      interpreter shutdown).

   引發一個附帶引數 "fullpath" 的 "tempfile.mkdtemp" 稽核事件。

   在 3.2 版新加入.

   在 3.10 版的變更: 新增 *ignore_cleanup_errors* 參數。

tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)

   盡可能以最安全的方式建立一個臨時檔案。假設所在平臺正確實作了
   "os.open()" 的 "os.O_EXCL" 旗標，則建立檔案時不會有 race condition
   （競爭條件）的情況。該檔案只能由建立者讀寫，如果所在平臺用
   permission bit（許可權位元）來表示檔案是否可執行，則沒有人有執行權
   。檔案描述器不會被子行程繼承。

   與 "TemporaryFile()" 不同，"mkstemp()" 使用者用完臨時檔案後需要自行
   將其刪除。

   如果 *suffix* 不是 "None" 則檔名將以該後綴結尾，若為 "None" 則沒有
   後綴。"mkstemp()" 不會在檔名和後綴之間加點 (dot)，如果需要加一個點
   號，請將其放在 *suffix* 的開頭。

   如果 *prefix* 不是 "None" 則檔名將以該字首開頭，若為 "None" 則使用
   預設前綴。預設前綴是 "gettempprefix()" 或 "gettempprefixb()" 函式的
   回傳值（自動呼叫合適的函式）。

   如果 *dir* 不為 "None" 則在指定的目錄建立檔案，若為 "None" 則使用預
   設目錄。預設目錄是從一個相依於平臺的列表中選擇出來的，但是使用者可
   以設定 *TMPDIR*、*TEMP* 或 *TMP* 環境變數來設定目錄的位置。因此，不
   能保證生成的臨時檔案路徑是使用者友善的，比如透過 "os.popen()" 將路
   徑傳遞給外部命令時仍需要加引號 (quoting)。

   如果 *suffix*、*prefix* 和 *dir* 中的任何一個不是 "None"，就要保證
   它們資料型別相同。如果它們是位元組串，則回傳名稱的型別就是位元組串
   而非字串。如果不想遵循預設行為但又想要回傳值是位元組串型別，請傳入
   "suffix=b''"。

   如果指定了 *text* 且為真值，檔案會以文字模式開啟。否則，檔案（預設
   ）以二進位制模式開啟。

   "mkstemp()" 回傳一個 tuple，tuple 中，第一個元素是一個作業系統層級
   (OS-level) 控制代碼，指向一個開啟的檔案（如同 "os.open()" 的回傳值
   ），第二元素是該檔案的絕對路徑。

   引發一個附帶引數 "fullpath" 的 "tempfile.mkstemp" 稽核事件。

   在 3.5 版的變更: 現在，*suffix*、*prefix* 和 *dir* 可以以位元組串型
   別按順序提供，以獲得位元組串型別的回傳值。在之前只允許使用字串。
   *suffix* 和 *prefix* 現在可以接受 "None"，並且預設為 "None" 以使用
   合適的預設值。

   在 3.6 版的變更: *dir* 參數現在可接受一個類路徑物件 (*path-like
   object*)。

tempfile.mkdtemp(suffix=None, prefix=None, dir=None)

   盡可能以最安全的方式建立一個臨時目錄，建立該目錄時不會有 race
   condition 的情況，該目錄只能由建立者讀取、寫入和搜尋。

   "mkdtemp()" 的使用者用完臨時目錄後需要自行將其刪除。

   引數 *prefix*、*suffix* 和 *dir* 的含義與它們在 "mkstemp()" 中相同
   。

   "mkdtemp()" returns the absolute pathname of the new directory if
   *dir* is "None" or is an absolute path. If *dir* is a relative
   path, "mkdtemp()" returns a relative path on Python 3.11 and lower.
   However, on 3.12 it will return an absolute path in all situations.

   引發一個附帶引數 "fullpath" 的 "tempfile.mkdtemp" 稽核事件。

   在 3.5 版的變更: 現在，*suffix*、*prefix* 和 *dir* 可以以位元組串型
   別按順序提供，以獲得位元組串型別的回傳值。在之前只允許使用字串。
   *suffix* 和 *prefix* 現在可以接受 "None"，並且預設為 "None" 以使用
   合適的預設值。

   在 3.6 版的變更: *dir* 參數現在可接受一個類路徑物件 (*path-like
   object*)。

tempfile.gettempdir()

   回傳儲存臨時檔案的目錄名稱。這設定了此 module 所有函式 *dir* 引數的
   預設值。

   Python 搜尋標準目錄列表來找到呼叫者可以在其中建立檔案的目錄。這個列
   表是：

   1. "TMPDIR" 環境變數指向的目錄。

   2. "TEMP" 環境變數指向的目錄。

   3. "TMP" 環境變數指向的目錄。

   4. 與平臺相關的位置：

      * 在 Windows 上，目錄依次為 "C:\TEMP"、"C:\TMP"、"\TEMP" 和
        "\TMP"。

      * 在所有其他平臺上，目錄依次為 "/tmp"、"/var/tmp" 和 "/usr/tmp"
        。

   5. 不得已時，使用當前工作目錄。

   搜尋的結果會被 cache（快取）起來，請見下面 "tempdir" 的描述。

   在 3.10 版的變更: 回傳一個字串。在之前的版本中它會回傳任意
   "tempdir" 的值而不考慮它的型別，只要它不為 "None"。

tempfile.gettempdirb()

   與 "gettempdir()" 相同，但回傳值為位元組串型別。

   在 3.5 版新加入.

tempfile.gettempprefix()

   回傳用於建立臨時檔案的檔名前綴，它不包含目錄部分。

tempfile.gettempprefixb()

   與 "gettempprefix()" 相同，但回傳值為位元組串型別。

   在 3.5 版新加入.

此 module 使用一個全域性變數來儲存由 "gettempdir()" 回傳的臨時檔案使用
的目錄路徑。它可被直接設定以覆蓋選擇過程，但不建議這樣做。此 module 中
的所有函式都接受一個 *dir* 引數，它可被用於指定目錄。這是個推薦的做法
，它不會透過改變全域性 API 行為而對其他不預期此行為的程式造成影響。

tempfile.tempdir

   當被設為 "None" 以外的值時，此變數會為此 module 所定義函式的引數
   *dir* 定義預設值，包括確定其型別為位元組串還是字串。它不可以為
   *path-like object*。

   如果在呼叫除 "gettempprefix()" 外的上述任何函式時 "tempdir" 為
   "None" (預設值) 則它會按照 "gettempdir()" 中所描述的演算法來初始化
   。

   備註:

     請注意如果你將 "tempdir" 設為位元組串值，會有一個麻煩的副作用：
     "mkstemp()" 和 "mkdtemp()" 的全域性預設回傳型別會在沒有提供明顯字
     串型別的 "prefix"、"suffix" 或 "dir" 時被改為位元組串。請不要編寫
     預期此行為或依賴於此行為的程式。這個奇怪的行為是為了維持與以往實
     作版本的相容性。


範例
====

以下是 "tempfile" module 的一些常見用法範例：

   >>> import tempfile

   # create a temporary file and write some data to it
   >>> fp = tempfile.TemporaryFile()
   >>> fp.write(b'Hello world!')
   # read data from file
   >>> fp.seek(0)
   >>> fp.read()
   b'Hello world!'
   # close the file, it will be removed
   >>> fp.close()

   # create a temporary file using a context manager
   >>> with tempfile.TemporaryFile() as fp:
   ...     fp.write(b'Hello world!')
   ...     fp.seek(0)
   ...     fp.read()
   b'Hello world!'
   >>>
   # file is now closed and removed

   # create a temporary directory using the context manager
   >>> with tempfile.TemporaryDirectory() as tmpdirname:
   ...     print('created temporary directory', tmpdirname)
   >>>
   # directory and contents have been removed


已棄用的函式和變數
==================

在過去，建立臨時檔案首先使用 "mktemp()" 函式生成一個檔名，然後使用該檔
名建立檔案。不幸的是這並不安全的，因為在呼叫 "mktemp()" 與隨後嘗試建立
檔案之間的時間裡，其他程式可能會使用該名稱建立檔案。解決方案是將兩個步
驟結合起來，並立即建立檔案。這個方案目前被 "mkstemp()" 和上述其他函式
所採用。

tempfile.mktemp(suffix='', prefix='tmp', dir=None)

   在 2.3 版之後被棄用: 使用 "mkstemp()" 代替。

   回傳一個在呼叫本方法時不存在檔案的絕對路徑。引數 *prefix*、*suffix*
   和 *dir* 與 "mkstemp()" 中所用的類似，除了在於不支援位元組串型別的
   檔名且不支援 "suffix=None" 和 "prefix=None"。

   警告:

     使用此功能可能會在程式中引入安全漏洞。當你開始使用本方法回傳的檔
     案執行任何操作時，可能有人已經捷足先登了。"mktemp()" 的功能可以很
     輕鬆地用帶有 "delete=False" 參數的 "NamedTemporaryFile()" 代替：

        >>> f = NamedTemporaryFile(delete=False)
        >>> f.name
        '/tmp/tmptjujjt'
        >>> f.write(b"Hello World!\n")
        13
        >>> f.close()
        >>> os.unlink(f.name)
        >>> os.path.exists(f.name)
        False
