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 "" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy