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

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

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

该模块可以创建临时文件和目录。 它适用于所有受支持的平台。
"TemporaryFile", "NamedTemporaryFile", "TemporaryDirectory" 和
"SpooledTemporaryFile" 是提供自动清理功能的高层级接口并可用作 *上下文
管理器*。 "mkstemp()" 和 "mkdtemp()" 是需要执行手动清理的低层级函数。

所有可被使用者呼叫的函式和建構函式都帶有可以設定臨時檔案和臨時目錄的路
徑和名稱的引數。此 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 下，該檔案所在
   的目錄可能根本不被建立、或者在建立檔案後立即就被刪除，其他平臺不支
   援此功能；你的程式不應依賴使用此功能建立的臨時檔案名稱，因為它在檔
   案系統中的名稱有可能是不可見的。

   结果对象可以用作 *context manager* (参见 範例)。 上下文结束或文件对
   象销毁后会将临时文件从文件系统中移除。

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

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

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

   在可用且有效时将使用 "os.O_TMPFILE" 旗标（Linux 专属，需要 Linux 内
   核版本为 3.11 或更高）。

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

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

   在 3.5 版的變更: 在可以时现在将使用 "os.O_TMPFILE" 旗标。

   在 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" 陳述句中使用。

   （只有）在 POSIX 上，一个用 SIGKILL 突然终止的进程无法自动删除它所
   创建的任何 NamedTemporaryFiles。

   引發一個附帶引數 "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)

   这个类执行的操作与 "TemporaryFile()" 完全相同，但会将数据放入内存池
   直到文件大小超过 *max_size*，或者直到文件的 "fileno()" 方法被调用，
   这时文件内容会被写入磁盘并如使用 "TemporaryFile()" 时一样执行后续操
   作。

   rollover()

      结果文件有一个额外的方法 "rollover()"，它可以忽略文件大小将其立
      即写入到磁盘文件。

   返回的对象是一个文件型对象，它的 "_file" 属性是 "io.BytesIO" 或
   "io.TextIOWrapper" 对象（这取决于所指定的 *mode* 是二进制还是文本）
   或真实的文件对象，这取决于 "rollover()" 是否已被调用。 这个文件型对
   象可以像普通文件一样在 "with" 语句中使用。

   在 3.3 版的變更: 现在 truncate 方法可接受一个 *size* 参数。

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

   在 3.11 版的變更: 完整实现 "io.BufferedIOBase" 和 "io.TextIOBase"
   抽象基类（取决于二进制或文本 *mode* 是否已指定）。

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

   这个类会使用与 "mkdtemp()" 相同的规则安全地创建一个临时目录。 结果
   对象可以被用作 *context manager* (参见 範例)。 在完成上下文或销毁临
   时目录对象时，新创建的临时目录及其所有内容会从文件系统中被移除。

   name

      可以从所返回对象的 "name" 属性中提取目录名称。 当返回的对象被用
      作 *context manager* 时，这个 "name" 将被作为 "with" 语句中 "as"
      子句的目标，如果存在该子句的话。

   cleanup()

      此目录可通过调用 "cleanup()" 方法来显式地清理。 如果
      *ignore_cleanup_errors* 为真值，则在显式或隐式清理（例如在
      Windows 上 "PermissionError" 移除打开的文件）期间出现的未处理异
      常将被忽略，并且剩余的可移除条目会被“尽可能”地删除。 在其他情况
      下，错误将在任何上下文清理发生时被引发（如 "cleanup()" 调用，退
      出上下文管理器、对象被作为垃圾回收或解释器关闭等情况）。

   引發一個附帶引數 "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
