檔案物件 (File Objects)
***********************

這些 API 是用於內建檔案物件的 Python 2 C API 的最小模擬 (minimal
emulation)，它過去依賴於 C 標準函式庫對於緩衝 I/O (FILE*) 的支援。在
Python 3 中，檔案和串流使用新的 "io" 模組，它在作業系統的低階無緩衝
I/O 上定義了多個層級。下面描述的函式是這些新 API 的便捷 C 包裝器，主要
用於直譯器中的內部錯誤報告；建議第三方程式碼改為存取 "io" API。

PyObject *PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd)
    *回傳值：新的參照。** 為 穩定 ABI 的一部分.*

   從已打開檔案 *fd* 的檔案描述器建立一個 Python 檔案物件。引數 *name*
   、*encoding*、*errors* 和 *newline* 可以為 "NULL" 以使用預設值；
   *buffering* 可以是 *-1* 以使用預設值。 *name* 被忽略並保留以實作向
   後相容性。失敗時回傳 "NULL"。有關引數的更全面描述，請參閱
   "io.open()" 函式文件。

   警告:

     由於 Python 串流有自己的緩衝層，將它們與作業系統層級檔案描述器混
     合使用會產生各種問題（例如資料的排序不符合預期）。

   在 3.2 版的變更: 忽略 *name* 屬性。

int PyObject_AsFileDescriptor(PyObject *p)
    * 為 穩定 ABI 的一部分.*

   回傳與 *p* 關聯的檔案描述器作為 int。如果物件是整數，則回傳其值。如
   果不是整數，則呼叫物件的 "fileno()" 方法（如果存在）；該方法必須回
   傳一個整數，它作為檔案描述器值回傳。設定例外並在失敗時回傳 "-1"。

PyObject *PyFile_GetLine(PyObject *p, int n)
    *回傳值：新的參照。** 為 穩定 ABI 的一部分.*

   相當於 "p.readline([n])"，這個函式從物件 *p* 中讀取一行。 *p* 可以
   是檔案物件或任何具有 "readline()" 方法的物件。如果 *n* 為 "0"，則不
   管該行的長度都只會讀取一行。如果 *n* 大於 "0"，則不會從檔案中讀取超
   過 *n* 個位元組；可以回傳該行的一部分。在這兩種情況下，如果立即到達
   檔案末尾，則回傳一個空字串。但是，如果 *n* 小於 "0"，無論長度如何，
   都會讀取一行，但如果立即到達檔案末尾，則會引發 "EOFError"。

int PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction handler)

   覆蓋 "io.open_code()" 的正常行為以透過提供的處理程式 (handler) 傳遞
   其參數。

   *handler* 是以下類型的函式：

   typedef PyObject *(*Py_OpenCodeHookFunction)(PyObject*, void*)

      相當於 PyObject *(*)(PyObject *path, void *userData)，其中
      *path* 保證為 "PyUnicodeObject"。

   *userData* 指標被傳遞到掛鉤函式 (hook function) 中。由於可能會從不
   同的執行環境 (runtime) 呼叫掛鉤函式，因此該指標不應直接指向 Python
   狀態。

   由於此掛鉤函式是在導入期間有意使用的，因此請避免在其執行期間導入新
   模組，除非它們已知有被凍結或在 "sys.modules" 中可用。

   一旦設定了一個掛鉤函式，它就不能被刪除或替換，且後續對
   "PyFile_SetOpenCodeHook()" 的呼叫將會失敗。失敗時，函式回傳 -1 且若
   直譯器已初始化便會設定例外。

   在 "Py_Initialize()" 之前呼叫此函式是安全的。

   不帶引數地引發一個稽核事件 (auditing event) "setopencodehook"。

   在 3.8 版被加入.

PyObject *PyFile_OpenCodeObject(PyObject *path)

   以模式 "'rb'" 開啟 *path*。*path* 必須是 Python "str" 物件。此函式
   的行為可能會被 "PyFile_SetOpenCodeHook()" 覆蓋，以允許對文字進行某
   些預處理。

   這類似於 Python 中的 "io.open_code()"。

   成功時，此函式回傳對 Python 檔案物件的 *strong reference*。失敗時，
   回傳 "NULL" 並設定例外。

   在 3.8 版被加入.

PyObject *PyFile_OpenCode(const char *path)

   類似於 "PyFile_OpenCodeObject()"，但 *path* 是 UTF-8 編碼的 const
   char*。

   在 3.8 版被加入.

int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)
    * 為 穩定 ABI 的一部分.*

   將物件 *obj* 寫入檔案物件 *p*。 *flags* 唯一支援的旗標是
   "Py_PRINT_RAW"；如果有給定，則寫入物件的 "str()" 而不是 "repr()"。
   在成功回傳 "0" 或在失敗回傳 "-1"；將設定適當的例外。

int PyFile_WriteString(const char *s, PyObject *p)
    * 為 穩定 ABI 的一部分.*

   寫入字串 *s* 到 檔案物件 *p*。當成功時回傳 0，而當失敗時回傳 -1，並
   會設定合適的例外狀況。


已棄用的 API
============

這些是被錯誤地包含在 Python C API 中的*軟性棄用* API。它們僅為了完整性
而記錄於文件中；請改用其他 "PyFile*" API。

PyObject *PyFile_NewStdPrinter(int fd)

   請改用帶有預設值 ("fd, NULL, "w", -1, NULL, NULL, NULL, 0") 的
   "PyFile_FromFd()"。

PyTypeObject PyStdPrinter_Type

   在 Python 啟動期間，當 "io" 尚不可用時會在內部使用的類檔案物件的型
   別。請改用 Python "open()" 或 "PyFile_FromFd()" 來建立檔案物件。
