diff --git a/extending/extending.po b/extending/extending.po index 6ff3917736..2daee5badc 100644 --- a/extending/extending.po +++ b/extending/extending.po @@ -1,16 +1,17 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2001-202DESCRIPTIVE TITLE., Python Software Foundation +# Copyright (C) 2001-2025, Python Software Foundation # This file is distributed under the same license as the Python package. # # Translators: # Leon H., 2017 +# Adrian Liaw , 2018 +# Matt Wang , 2025 msgid "" msgstr "" "Project-Id-Version: Python 3.13\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-23 07:52+0800\n" -"PO-Revision-Date: 2018-05-23 14:34+0000\n" -"Last-Translator: Adrian Liaw \n" +"POT-Creation-Date: 2025-02-07 15:02+0800\n" +"PO-Revision-Date: 2025-02-17 14:34+0000\n" +"Last-Translator: Matt Wang \n" "Language-Team: Chinese - TAIWAN (https://github.com/python/python-docs-zh-" "tw)\n" "Language: zh_TW\n" @@ -30,6 +31,9 @@ msgid "" "done directly in Python: they can implement new built-in object types, and " "they can call C library functions and system calls." msgstr "" +"如果你會撰寫 C 程式語言,那要向 Python 新增內建模組就不困難。這種\\ :dfn:`擴" +"充模組 (extension modules)` 可以做兩件在 Python 中無法直接完成的事:它們可以" +"實作新的內建物件型別,並且可以呼叫 C 的函式庫函式和系統呼叫。" #: ../../extending/extending.rst:15 msgid "" @@ -38,12 +42,17 @@ msgid "" "aspects of the Python run-time system. The Python API is incorporated in a " "C source file by including the header ``\"Python.h\"``." msgstr "" +"為了支援擴充,Python API (Application Programmers Interface) 定義了一組函式、" +"巨集和變數,提供對 Python run-time 系統大部分面向的存取。Python API 是透過引" +"入標頭檔 ``\"Python.h\"`` 來被納入到一個 C 原始碼檔案中。" #: ../../extending/extending.rst:20 msgid "" "The compilation of an extension module depends on its intended use as well " "as on your system setup; details are given in later chapters." msgstr "" +"擴充模組的編譯取決於其預期用途以及你的系統設定;詳細資訊將在後面的章節中提" +"供。" #: ../../extending/extending.rst:25 msgid "" @@ -57,6 +66,12 @@ msgid "" "with C code and are more portable between implementations of Python than " "writing and compiling a C extension module." msgstr "" +"C 擴充介面是 CPython 所特有的,擴充模組在其他 Python 實作上無法運作。在許多情" +"況下,可以避免撰寫 C 擴充並保留對其他實作的可移植性。例如,如果你的用例是呼" +"叫 C 函式庫函式或系統呼叫,你應該考慮使用 :mod:`ctypes` 模組或 `cffi " +"`_ 函式庫,而不是編寫自定義的 C 程式碼。這些模" +"組讓你可以撰寫 Python 程式碼來與 C 程式碼介接,而且比起撰寫和編譯 C 擴充模" +"組,這些模組在 Python 實作之間更容易移植。" #: ../../extending/extending.rst:40 msgid "A Simple Example" @@ -70,6 +85,10 @@ msgid "" "terminated character string as argument and returns an integer. We want " "this function to be callable from Python as follows:" msgstr "" +"讓我們來建立一個叫做 ``spam``\\ (Monty Python 粉絲最愛的食物...)的擴充模" +"組。假設我們要建立一個 Python 介面給 C 函式庫的函式 :c:func:`system` [#]_ 使" +"用,這個函式接受一個以 null 終止的 (null-terminated) 字元字串做為引數,並回傳" +"一個整數。我們希望這個函式可以在 Python 中被呼叫,如下所示:" #: ../../extending/extending.rst:48 msgid "" @@ -86,10 +105,13 @@ msgid "" "`spammodule.c`; if the module name is very long, like ``spammify``, the " "module name can be just :file:`spammify.c`.)" msgstr "" +"首先建立一個檔案 :file:`spammodule.c`。(從過去歷史來看,如果一個模組叫做 " +"``spam``,包含其實作的 C 檔案就會叫做 :file:`spammodule.c`;如果模組名稱很" +"長,像是 ``spammify``,模組名稱也可以只是 :file:`spammify.c`)。" #: ../../extending/extending.rst:58 msgid "The first two lines of our file can be::" -msgstr "" +msgstr "我們檔案的前兩列可以為: ::" #: ../../extending/extending.rst:60 ../../extending/extending.rst:663 msgid "" @@ -104,6 +126,8 @@ msgid "" "which pulls in the Python API (you can add a comment describing the purpose " "of the module and a copyright notice if you like)." msgstr "" +"這會將 Python API 拉進來(你可以加入註解來說明模組的目的,也可以加入版權聲" +"明)。" #: ../../extending/extending.rst:68 msgid "" @@ -111,6 +135,8 @@ msgid "" "standard headers on some systems, you *must* include :file:`Python.h` before " "any standard headers are included." msgstr "" +"由於 Python 可能定義一些影響系統上某些標準標頭檔的預處理器定義,你\\ *必須" +"*\\ 在引入任何標準標頭檔之前引入 :file:`Python.h`。" #: ../../extending/extending.rst:72 msgid "" @@ -119,6 +145,9 @@ msgid "" "3.13, but we keep it here for backward compatibility. See :ref:`arg-parsing-" "string-and-buffers` for a description of this macro." msgstr "" +"``#define PY_SSIZE_T_CLEAN`` 被用來表示在某些 API 中應該使用 ``Py_ssize_t`` " +"而不是 ``int``。自 Python 3.13 起,它就不再是必要的了,但我們在此保留它以便向" +"後相容。關於這個巨集的描述請參閱 :ref:`arg-parsing-string-and-buffers`。" #: ../../extending/extending.rst:77 msgid "" @@ -130,6 +159,12 @@ msgid "" "on your system, it declares the functions :c:func:`malloc`, :c:func:`free` " "and :c:func:`realloc` directly." msgstr "" +"除了那些在標準標頭檔中定義的符號以外,所有由 :file:`Python.h` 定義的使用者可" +"見符號 (user-visible symbols) 的前綴都是 ``Py`` 或 ``PY``。為了方便,也因為 " +"Python 直譯器的大量使用,``\"Python.h\"`` 也引入了一些標準的標頭檔:" +"````、````、```` 和 ````。如果 " +"```` 在你的系統上不存在,它會直接宣" +"告 :c:func:`malloc`、:c:func:`free` 和 :c:func:`realloc` 函式。" #: ../../extending/extending.rst:85 msgid "" @@ -137,6 +172,9 @@ msgid "" "called when the Python expression ``spam.system(string)`` is evaluated " "(we'll see shortly how it ends up being called)::" msgstr "" +"接下來我們要加入到模組檔案的是 C 函式,當 Python 運算式 " +"``spam.system(string)`` 要被求值 (evaluated) 時就會被呼叫(我們很快就會看到它" +"最後是如何被呼叫的): ::" #: ../../extending/extending.rst:89 msgid "" @@ -171,12 +209,16 @@ msgid "" "C function. The C function always has two arguments, conventionally named " "*self* and *args*." msgstr "" +"可以很直觀地從 Python 的引數串列(例如單一的運算式 ``\"ls -l\"``)直接轉換成" +"傳給 C 函式的引數。C 函式總是有兩個引數,習慣上會命名為 *self* 和 *args*。" #: ../../extending/extending.rst:106 msgid "" "The *self* argument points to the module object for module-level functions; " "for a method it would point to the object instance." msgstr "" +"對於模組層級的函式,*self* 引數會指向模組物件;而對於方法來說則是指向物件的實" +"例。" #: ../../extending/extending.rst:109 msgid "" @@ -189,6 +231,11 @@ msgid "" "determine the required types of the arguments as well as the types of the C " "variables into which to store the converted values. More about this later." msgstr "" +"*args* 引數會是一個指向包含引數的 Python 元組物件的指標。元組中的每一項都對應" +"於呼叫的引數串列中的一個引數。引數是 Python 物件 --- 為了在我們的 C 函式中對" +"它們做任何事情,我們必須先將它們轉換成 C 值。Python API 中" +"的 :c:func:`PyArg_ParseTuple` 函式能夠檢查引數型別並將他們轉換為 C 值。它使用" +"模板字串來決定所需的引數型別以及儲存轉換值的 C 變數型別。稍後會再詳細說明。" #: ../../extending/extending.rst:118 msgid "" @@ -199,10 +246,14 @@ msgid "" "the calling function can return ``NULL`` immediately (as we saw in the " "example)." msgstr "" +"如果所有的引數都有正確的型別,且其元件已儲存在傳入位址的變數中," +"則 :c:func:`PyArg_ParseTuple` 會回傳 true(非零)。如果傳入的是無效引數串列則" +"回傳 false(零)。在後者情況下,它也會產生適當的例外,因此呼叫函式可以立即回" +"傳 ``NULL``\\ (就像我們在範例中所看到的)。" #: ../../extending/extending.rst:128 msgid "Intermezzo: Errors and Exceptions" -msgstr "" +msgstr "插曲:錯誤與例外" #: ../../extending/extending.rst:130 msgid "" @@ -215,12 +266,17 @@ msgid "" "the exception type, exception instance, and a traceback object. It is " "important to know about them to understand how errors are passed around." msgstr "" +"在整個 Python 直譯器中的一個重要慣例為:當一個函式失敗時,它就應該設定一個例" +"外條件,並回傳一個錯誤值(通常是 ``-1`` 或一個 ``NULL`` 指標)。例外資訊會儲" +"存在直譯器執行緒狀態的三個成員中。如果沒有例外,它們就會是 ``NULL``。否則,它" +"們是由 :meth:`sys.exc_info` 所回傳的 Python 元組中的 C 等效元組。它們是例外型" +"別、例外實例和回溯物件。了解它們對於理解錯誤是如何傳遞是很重要的。" #: ../../extending/extending.rst:139 msgid "" "The Python API defines a number of functions to set various types of " "exceptions." -msgstr "" +msgstr "Python API 定義了許多能夠設定各種類型例外的函式。" #: ../../extending/extending.rst:141 msgid "" @@ -230,6 +286,10 @@ msgid "" "indicates the cause of the error and is converted to a Python string object " "and stored as the \"associated value\" of the exception." msgstr "" +"最常見的是 :c:func:`PyErr_SetString`。它的引數是一個例外物件和一個 C 字串。例" +"外物件通常是預先定義的物件,例如 :c:data:`PyExc_ZeroDivisionError`。C 字串則" +"指出錯誤的原因,並被轉換為 Python 字串物件且被儲存為例外的「關聯值 " +"(associated value)」。" #: ../../extending/extending.rst:147 msgid "" @@ -240,6 +300,10 @@ msgid "" "associated value. You don't need to :c:func:`Py_INCREF` the objects passed " "to any of these functions." msgstr "" +"另一個有用的函式是 :c:func:`PyErr_SetFromErrno`,它只接受一個例外引數,並透過" +"檢查全域變數 :c:data:`errno` 來建立關聯值。最一般的函式" +"是 :c:func:`PyErr_SetObject`,它接受兩個物件引數,即例外和它的關聯值。你不需" +"要對傳給任何這些函式的物件呼叫 :c:func:`Py_INCREF`。" #: ../../extending/extending.rst:154 msgid "" @@ -249,6 +313,10 @@ msgid "" "func:`PyErr_Occurred` to see whether an error occurred in a function call, " "since you should be able to tell from the return value." msgstr "" +"你可以使用 :c:func:`PyErr_Occurred` 來不具破壞性地測試例外是否已被設定。這會" +"回傳當前的例外物件,如果沒有例外發生則回傳 ``NULL``。你通常不需要呼" +"叫 :c:func:`PyErr_Occurred` 來查看函式呼叫是否發生錯誤,因為你應可從回傳值就" +"得知。" #: ../../extending/extending.rst:160 msgid "" @@ -262,6 +330,12 @@ msgid "" "interpreter's main loop, this aborts the currently executing Python code and " "tries to find an exception handler specified by the Python programmer." msgstr "" +"當函式 *f* 呼叫另一個函式 *g* 時檢測到後者失敗,*f* 本身應該回傳一個錯誤值" +"(通常是 ``NULL`` 或 ``-1``)。它\\ *不*\\ 應該呼叫 ``PyErr_*`` 函式的其中一" +"個,這會已被 *g* 呼叫過。*f* 的呼叫者然後也應該回傳一個錯誤指示給\\ *它的*\\ " +"呼叫者,同樣\\ *不會*\\ 呼叫 ``PyErr_*``,依此類推 --- 最詳細的錯誤原因已經被" +"首先檢測到它的函式回報了。一旦錯誤到達 Python 直譯器的主要迴圈,這會中止目前" +"執行的 Python 程式碼,並嘗試尋找 Python 程式設計者指定的例外處理程式。" #: ../../extending/extending.rst:170 msgid "" @@ -271,6 +345,9 @@ msgid "" "cause information about the cause of the error to be lost: most operations " "can fail for a variety of reasons.)" msgstr "" +"(在某些情況下,模組可以透過呼叫另一個 ``PyErr_*`` 函式來提供更詳細的錯誤訊" +"息,在這種情況下這樣做是沒問題的。然而這一般來說並非必要,而且可能會導致錯誤" +"原因資訊的遺失:大多數的操作都可能因為各種原因而失敗。)" #: ../../extending/extending.rst:176 msgid "" @@ -280,6 +357,10 @@ msgid "" "pass the error on to the interpreter but wants to handle it completely by " "itself (possibly by trying something else, or pretending nothing went wrong)." msgstr "" +"要忽略由函式呼叫失敗所設定的例外,必須明確地呼叫 :c:func:`PyErr_Clear` 來清除" +"例外條件。C 程式碼唯一要呼叫 :c:func:`PyErr_Clear` 的情況為當它不想將錯誤傳遞" +"給直譯器而想要完全是自己來處理它時(可能是要再嘗試其他東西,或者假裝什麼都沒" +"出錯)。" #: ../../extending/extending.rst:182 msgid "" @@ -289,6 +370,11 @@ msgid "" "creating functions (for example, :c:func:`PyLong_FromLong`) already do this, " "so this note is only relevant to those who call :c:func:`malloc` directly." msgstr "" +"每個失敗的 :c:func:`malloc` 呼叫都必須被轉換成一個例外 " +"--- :c:func:`malloc`\\ (或 :c:func:`realloc`)的直接呼叫者必須呼" +"叫 :c:func:`PyErr_NoMemory` 並回傳一個失敗指示器。所有建立物件的函式(例" +"如 :c:func:`PyLong_FromLong`)都已經這麼做了,所以這個注意事項只和那些直接呼" +"叫 :c:func:`malloc` 的函式有關。" #: ../../extending/extending.rst:188 msgid "" @@ -297,6 +383,9 @@ msgid "" "positive value or zero for success and ``-1`` for failure, like Unix system " "calls." msgstr "" +"還要注意的是,有 :c:func:`PyArg_ParseTuple` 及同系列函式的這些重要例外,回傳" +"整數狀態的函式通常會回傳一個正值或 0 表示成功、回傳 ``-1`` 表示失敗,就像 " +"Unix 系統呼叫一樣。" #: ../../extending/extending.rst:192 msgid "" @@ -304,6 +393,8 @@ msgid "" "c:func:`Py_DECREF` calls for objects you have already created) when you " "return an error indicator!" msgstr "" +"最後,在回傳錯誤指示器時要注意垃圾清理(透過對你已經建立的物件呼" +"叫 :c:func:`Py_XDECREF` 或 :c:func:`Py_DECREF`)!" #: ../../extending/extending.rst:196 msgid "" @@ -317,12 +408,21 @@ msgid "" "you have an argument whose value must be in a particular range or must " "satisfy other conditions, :c:data:`PyExc_ValueError` is appropriate." msgstr "" +"你完全可以自行選擇要產生的例外。有一些預先宣告的 C 物件會對應到所有內建的 " +"Python 例外,例如 :c:data:`PyExc_ZeroDivisionError`,你可以直接使用它們。當" +"然,你應該明智地選擇例外,像是不要使用 :c:data:`PyExc_TypeError` 來表示檔案無" +"法打開(應該是 :c:data:`PyExc_OSError`)。如果引數串列有問" +"題,:c:func:`PyArg_ParseTuple` 函式通常會引發 :c:data:`PyExc_TypeError`。如果" +"你有一個引數的值必須在一個特定的範圍內或必須滿足其他條件,則可以使" +"用 :c:data:`PyExc_ValueError`。" #: ../../extending/extending.rst:206 msgid "" "You can also define a new exception that is unique to your module. For this, " "you usually declare a static object variable at the beginning of your file::" msgstr "" +"你也可以定義一個你的模組特有的新例外。為此你通常會在檔案開頭宣告一個靜態物件" +"變數: ::" #: ../../extending/extending.rst:209 msgid "static PyObject *SpamError;" @@ -333,9 +433,10 @@ msgid "" "and initialize it in your module's initialization function (:c:func:`!" "PyInit_spam`) with an exception object::" msgstr "" +"並在你的模組初始化函式中使用一個例外物件來初始化它 (:c:func:`!" +"PyInit_spam`): ::" #: ../../extending/extending.rst:214 -#, fuzzy msgid "" "PyMODINIT_FUNC\n" "PyInit_spam(void)\n" @@ -366,9 +467,7 @@ msgstr "" " return NULL;\n" "\n" " SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);\n" -" Py_XINCREF(SpamError);\n" -" if (PyModule_AddObject(m, \"error\", SpamError) < 0) {\n" -" Py_XDECREF(SpamError);\n" +" if (PyModule_AddObjectRef(m, \"error\", SpamError) < 0) {\n" " Py_CLEAR(SpamError);\n" " Py_DECREF(m);\n" " return NULL;\n" @@ -384,6 +483,9 @@ msgid "" "class being :exc:`Exception` (unless another class is passed in instead of " "``NULL``), described in :ref:`bltin-exceptions`." msgstr "" +"請注意,例外物件的 Python 名稱是 :exc:`!spam.error`。如同\\ :ref:`bltin-" +"exceptions`\\ 所述,:c:func:`PyErr_NewException` 函式可能會建立一個基底類別" +"為 :exc:`Exception` 的類別(除非傳入另一個類別來代替 ``NULL``)。" #: ../../extending/extending.rst:238 msgid "" @@ -395,18 +497,25 @@ msgid "" "pointer, C code which raises the exception could cause a core dump or other " "unintended side effects." msgstr "" +"請注意,:c:data:`!SpamError` 變數保留了對新建立的例外類別的參照;這是故意的!" +"因為外部程式碼可能會從模組中移除這個例外,所以需要一個對這個類別的參照來確保" +"它不會被丟棄而導致 :c:data:`!SpamError` 變成一個迷途指標 (dangling pointer)。" +"如果它變成迷途指標,那產生例外的 C 程式碼可能會導致核心轉儲 (core dump) 或其" +"他不預期的 side effect。" #: ../../extending/extending.rst:245 msgid "" "We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type " "later in this sample." -msgstr "" +msgstr "我們稍後會討論 :c:macro:`PyMODINIT_FUNC` 作為函式回傳型別的用法。" #: ../../extending/extending.rst:248 msgid "" "The :exc:`!spam.error` exception can be raised in your extension module " "using a call to :c:func:`PyErr_SetString` as shown below::" msgstr "" +"可以在你的擴充模組中呼叫 :c:func:`PyErr_SetString` 來引發 :exc:`!spam.error` " +"例外,如下所示: ::" #: ../../extending/extending.rst:251 msgid "" @@ -450,7 +559,7 @@ msgstr "回到範例" msgid "" "Going back to our example function, you should now be able to understand " "this statement::" -msgstr "" +msgstr "回到我們的範例函式,現在你應該可以理解這個陳述式了: ::" #: ../../extending/extending.rst:276 msgid "" @@ -470,12 +579,19 @@ msgid "" "which it points (so in Standard C, the variable :c:data:`!command` should " "properly be declared as ``const char *command``)." msgstr "" +"如果在引數串列中檢測到錯誤則會回傳 ``NULL``\\ (回傳物件指標之函式的錯誤指示" +"器),其依賴於 :c:func:`PyArg_ParseTuple` 設定的例外,否則引數的字串值會已被" +"複製到區域變數 :c:data:`!command` 中。這是一個指標賦值,你不應該修改它所指向" +"的字串(所以在標準 C 中,:c:data:`!command` 變數應該正確地被宣告為 ``const " +"char *command``)。" #: ../../extending/extending.rst:287 msgid "" "The next statement is a call to the Unix function :c:func:`system`, passing " "it the string we just got from :c:func:`PyArg_ParseTuple`::" msgstr "" +"接下來的陳述式會呼叫 Unix 函式 :c:func:`system`,並將剛才" +"從 :c:func:`PyArg_ParseTuple` 得到的字串傳給它:" #: ../../extending/extending.rst:290 msgid "sts = system(command);" @@ -487,6 +603,8 @@ msgid "" "a Python object. This is done using the function :c:func:" "`PyLong_FromLong`. ::" msgstr "" +"我們的 :func:`!spam.system` 函式必須以 Python 物件的形式來回傳 :c:data:`!" +"sts` 的值。這是透過 :c:func:`PyLong_FromLong` 函式來達成。 ::" #: ../../extending/extending.rst:295 msgid "return PyLong_FromLong(sts);" @@ -497,6 +615,8 @@ msgid "" "In this case, it will return an integer object. (Yes, even integers are " "objects on the heap in Python!)" msgstr "" +"在這種情況下它會回傳一個整數物件。(是的,在 Python 中連整數也是堆積 (heap) 上" +"的物件!)" #: ../../extending/extending.rst:300 msgid "" @@ -505,6 +625,9 @@ msgid "" "``None``. You need this idiom to do so (which is implemented by the :c:" "macro:`Py_RETURN_NONE` macro)::" msgstr "" +"如果你有一個不回傳任何有用引數的 C 函式(一個回傳 :c:expr:`void` 的函式),對" +"應的 Python 函式必須回傳 ``None``。你需要以下這個慣例來達成" +"(由 :c:macro:`Py_RETURN_NONE` 巨集實作): ::" #: ../../extending/extending.rst:305 msgid "" @@ -520,16 +643,21 @@ msgid "" "is a genuine Python object rather than a ``NULL`` pointer, which means " "\"error\" in most contexts, as we have seen." msgstr "" +":c:data:`Py_None` 是特殊 Python 物件 ``None`` 的 C 名稱。它是一個真正的 " +"Python 物件而不是一個 ``NULL`` 指標,在大多數的情況下它的意思是「錯誤」,如我" +"們所見過的那樣。" #: ../../extending/extending.rst:316 msgid "The Module's Method Table and Initialization Function" -msgstr "" +msgstr "模組的方法表和初始化函式" #: ../../extending/extending.rst:318 msgid "" "I promised to show how :c:func:`!spam_system` is called from Python " "programs. First, we need to list its name and address in a \"method table\"::" msgstr "" +"我承諾過要展示 :c:func:`!spam_system` 是如何從 Python 程式中呼叫的。首先,我" +"們需要在「方法表」中列出它的名稱和位址: ::" #: ../../extending/extending.rst:321 msgid "" @@ -541,6 +669,13 @@ msgid "" " {NULL, NULL, 0, NULL} /* Sentinel */\n" "};" msgstr "" +"static PyMethodDef SpamMethods[] = {\n" +" ...\n" +" {\"system\", spam_system, METH_VARARGS,\n" +" \"Execute a shell command.\"},\n" +" ...\n" +" {NULL, NULL, 0, NULL} /* Sentinel */\n" +"};" #: ../../extending/extending.rst:329 msgid "" @@ -550,6 +685,9 @@ msgid "" "value of ``0`` means that an obsolete variant of :c:func:`PyArg_ParseTuple` " "is used." msgstr "" +"請注意第三個項目 (``METH_VARARGS``)。這是一個告訴直譯器 C 函式之呼叫方式的旗" +"標。通常應該是 ``METH_VARARGS`` 或 ``METH_VARARGS | METH_KEYWORDS``;``0`` 表" +"示是使用 :c:func:`PyArg_ParseTuple` 的一個過時變體。" #: ../../extending/extending.rst:334 msgid "" @@ -557,6 +695,9 @@ msgid "" "level parameters to be passed in as a tuple acceptable for parsing via :c:" "func:`PyArg_ParseTuple`; more information on this function is provided below." msgstr "" +"當只使用 ``METH_VARARGS`` 時,函式應預期 Python 層級的參數是以元組形式傳入且" +"能夠接受以 :c:func:`PyArg_ParseTuple` 進行剖析;有關此函式的更多資訊將在下面" +"提供。" #: ../../extending/extending.rst:338 msgid "" @@ -566,11 +707,15 @@ msgid "" "keywords. Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments " "to such a function." msgstr "" +"如果要將關鍵字引數傳給函式,可以在第三個欄位設定 :c:macro:`METH_KEYWORDS` 位" +"元。在這種情況下,C 函式應該要能接受第三個 ``PyObject *`` 參數,這個參數將會" +"是關鍵字的字典。可使用 :c:func:`PyArg_ParseTupleAndKeywords` 來剖析這種函式的" +"引數。" #: ../../extending/extending.rst:344 msgid "" "The method table must be referenced in the module definition structure::" -msgstr "" +msgstr "方法表必須在模組定義結構中被參照: ::" #: ../../extending/extending.rst:346 msgid "" @@ -583,6 +728,14 @@ msgid "" " SpamMethods\n" "};" msgstr "" +"static struct PyModuleDef spammodule = {\n" +" PyModuleDef_HEAD_INIT,\n" +" \"spam\", /* 模組名稱 */\n" +" spam_doc, /* 模組文件,可能為 NULL */\n" +" -1, /* 模組的個別直譯器狀態的大小,\n" +" 如果模組將狀態保存在全域變數中則為 -1 */\n" +" SpamMethods\n" +"};" #: ../../extending/extending.rst:355 msgid "" @@ -591,6 +744,9 @@ msgid "" "`!PyInit_name`, where *name* is the name of the module, and should be the " "only non-\\ ``static`` item defined in the module file::" msgstr "" +"反過來說,這個結構必須在模組的初始化函式中被傳給直譯器。初始化函式必須被命名" +"為 :c:func:`!PyInit_name`,其中 *name* 是模組的名稱,且應該是模組檔案中唯一定" +"義的非「靜態 (``static``)」項目: ::" #: ../../extending/extending.rst:360 msgid "" @@ -612,6 +768,8 @@ msgid "" "return type, declares any special linkage declarations required by the " "platform, and for C++ declares the function as ``extern \"C\"``." msgstr "" +"請注意,:c:macro:`PyMODINIT_FUNC` 宣告函式的回傳型別為 `PyObject *``、宣告平" +"台所需的任何特殊連結宣告、並針對 C++ 宣告函式為 ``extern \"C\"``。" #: ../../extending/extending.rst:370 msgid "" @@ -626,6 +784,14 @@ msgid "" "The init function must return the module object to its caller, so that it " "then gets inserted into ``sys.modules``." msgstr "" +"當 Python 程式第一次引入模組 :mod:`!spam` 時,:c:func:`!PyInit_spam` 會被呼" +"叫。(有關嵌入 Python 的註解請參見下文。)它會呼叫回傳一個模組物件" +"的 :c:func:`PyModule_Create`,並根據在模組定義中所找到的表(一" +"個 :c:type:`PyMethodDef` 結構的陣列)將內建的函式物件插入到新建立的模組" +"中。:c:func:`PyModule_Create` 會回傳一個指向它建立之模組物件的指標。對於某些" +"錯誤情況,它可能會以嚴重錯誤的形式來中止;如果模組無法令人滿意地被初始化,它" +"也會回傳 ``NULL``。初始化函式必須把模組物件回傳給它的呼叫者,這樣它才會被插入" +"到 ``sys.modules`` 中。" #: ../../extending/extending.rst:381 msgid "" @@ -634,6 +800,9 @@ msgid "" "table. To add the module to the initialization table, use :c:func:" "`PyImport_AppendInittab`, optionally followed by an import of the module::" msgstr "" +"嵌入 Python 時,除非在 :c:data:`PyImport_Inittab` 表中有相關條目,否則不會自" +"動呼叫 :c:func:`!PyInit_spam` 函式。要將模組加入初始化表,請使" +"用 :c:func:`PyImport_AppendInittab` 並在隨後選擇性地將該模組引入: ::" #: ../../extending/extending.rst:386 msgid "" @@ -687,6 +856,55 @@ msgid "" " Py_ExitStatusException(status);\n" "}" msgstr "" +"#define PY_SSIZE_T_CLEAN\n" +"#include \n" +"\n" +"int\n" +"main(int argc, char *argv[])\n" +"{\n" +" PyStatus status;\n" +" PyConfig config;\n" +" PyConfig_InitPythonConfig(&config);\n" +"\n" +" /* 在 Py_Initialize 之前加入內建模組 */\n" +" if (PyImport_AppendInittab(\"spam\", PyInit_spam) == -1) {\n" +" fprintf(stderr, \"Error: could not extend in-built modules " +"table\\n\");\n" +" exit(1);\n" +" }\n" +"\n" +" /* 將 argv[0] 傳給 Python 直譯器 */\n" +" status = PyConfig_SetBytesString(&config, &config.program_name, " +"argv[0]);\n" +" if (PyStatus_Exception(status)) {\n" +" goto exception;\n" +" }\n" +"\n" +" /* 初始化 Python 直譯器。這會是必要的。\n" +" 如果此步驟失敗就會導致嚴重錯誤。*/\n" +" status = Py_InitializeFromConfig(&config);\n" +" if (PyStatus_Exception(status)) {\n" +" goto exception;\n" +" }\n" +" PyConfig_Clear(&config);\n" +"\n" +" /* 可選擇引入模組;或者\n" +" 可以延遲引入,直至嵌入式腳本\n" +" 將其引入。*/\n" +" PyObject *pmodule = PyImport_ImportModule(\"spam\");\n" +" if (!pmodule) {\n" +" PyErr_Print();\n" +" fprintf(stderr, \"Error: could not import module 'spam'\\n\");\n" +" }\n" +"\n" +" // ... 在此使用 Python C API ...\n" +"\n" +" return 0;\n" +"\n" +" exception:\n" +" PyConfig_Clear(&config);\n" +" Py_ExitStatusException(status);\n" +"}" #: ../../extending/extending.rst:436 msgid "" @@ -696,6 +914,9 @@ msgid "" "extension modules. Extension module authors should exercise caution when " "initializing internal data structures." msgstr "" +"從 ``sys.modules`` 中移除項目,或在一個行程中將已編譯模組引入到多個直譯器中" +"(或在沒有 :c:func:`exec` 介入的情況下使用 :c:func:`fork`)可能會對某些擴充模" +"組造成問題。擴充模組作者在初始化內部資料結構時應特別小心。" #: ../../extending/extending.rst:442 msgid "" @@ -703,6 +924,8 @@ msgid "" "distribution as :file:`Modules/xxmodule.c`. This file may be used as a " "template or simply read as an example." msgstr "" +"Python 原始碼發行版本中包含了一個更實質的範例模組 :file:`Modules/" +"xxmodule.c`。這個檔案可以當作模板使用,也可以簡單地當作範例來閱讀。" #: ../../extending/extending.rst:448 msgid "" @@ -711,6 +934,10 @@ msgid "" "``PyInit_spam``, and creation of the module is left to the import machinery. " "For details on multi-phase initialization, see :PEP:`489`." msgstr "" +"不像我們的 ``spam`` 範例,``xxmodule`` 使用了\\ *多階段初始化 (multi-phase " +"initialization)*\\ (Python 3.5 新增),其中的 PyModuleDef 結構會從 " +"``PyInit_spam`` 回傳,而模組的建立則交由引入機制來完成。關於多階段初始化的詳" +"細資訊請參閱 :PEP:`489`。" #: ../../extending/extending.rst:457 msgid "Compilation and Linkage" @@ -1078,14 +1305,14 @@ msgid "" msgstr "" #: ../../extending/extending.rst:737 -#, fuzzy msgid "" "int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,\n" " const char *format, char * const " "*kwlist, ...);" msgstr "" "int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,\n" -" const char *format, char *kwlist[], ...);" +" const char *format, char * const " +"*kwlist, ...);" #: ../../extending/extending.rst:740 msgid ""