Skip to content

Commit ef944ec

Browse files
authoredFeb 23, 2025··
translate extending/extending.po - part 1 (#1023)
1 parent cc8bdcc commit ef944ec

File tree

1 file changed

+245
-18
lines changed

1 file changed

+245
-18
lines changed
 

‎extending/extending.po

+245-18
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
# SOME DESCRIPTIVE TITLE.
2-
# Copyright (C) 2001-202DESCRIPTIVE TITLE., Python Software Foundation
1+
# Copyright (C) 2001-2025, Python Software Foundation
32
# This file is distributed under the same license as the Python package.
43
#
54
# Translators:
65
# Leon H., 2017
6+
# Adrian Liaw <adrianliaw2000@gmail.com>, 2018
7+
# Matt Wang <mattwang44@gmail.com>, 2025
78
msgid ""
89
msgstr ""
910
"Project-Id-Version: Python 3.13\n"
1011
"Report-Msgid-Bugs-To: \n"
11-
"POT-Creation-Date: 2024-09-23 07:52+0800\n"
12-
"PO-Revision-Date: 2018-05-23 14:34+0000\n"
13-
"Last-Translator: Adrian Liaw <adrianliaw2000@gmail.com>\n"
12+
"POT-Creation-Date: 2025-02-07 15:02+0800\n"
13+
"PO-Revision-Date: 2025-02-17 14:34+0000\n"
14+
"Last-Translator: Matt Wang <mattwang44@gmail.com>\n"
1415
"Language-Team: Chinese - TAIWAN (https://github.com/python/python-docs-zh-"
1516
"tw)\n"
1617
"Language: zh_TW\n"
@@ -30,6 +31,9 @@ msgid ""
3031
"done directly in Python: they can implement new built-in object types, and "
3132
"they can call C library functions and system calls."
3233
msgstr ""
34+
"如果你會撰寫 C 程式語言,那要向 Python 新增內建模組就不困難。這種\\ :dfn:`擴"
35+
"充模組 (extension modules)` 可以做兩件在 Python 中無法直接完成的事:它們可以"
36+
"實作新的內建物件型別,並且可以呼叫 C 的函式庫函式和系統呼叫。"
3337

3438
#: ../../extending/extending.rst:15
3539
msgid ""
@@ -38,12 +42,17 @@ msgid ""
3842
"aspects of the Python run-time system. The Python API is incorporated in a "
3943
"C source file by including the header ``\"Python.h\"``."
4044
msgstr ""
45+
"為了支援擴充,Python API (Application Programmers Interface) 定義了一組函式、"
46+
"巨集和變數,提供對 Python run-time 系統大部分面向的存取。Python API 是透過引"
47+
"入標頭檔 ``\"Python.h\"`` 來被納入到一個 C 原始碼檔案中。"
4148

4249
#: ../../extending/extending.rst:20
4350
msgid ""
4451
"The compilation of an extension module depends on its intended use as well "
4552
"as on your system setup; details are given in later chapters."
4653
msgstr ""
54+
"擴充模組的編譯取決於其預期用途以及你的系統設定;詳細資訊將在後面的章節中提"
55+
"供。"
4756

4857
#: ../../extending/extending.rst:25
4958
msgid ""
@@ -57,6 +66,12 @@ msgid ""
5766
"with C code and are more portable between implementations of Python than "
5867
"writing and compiling a C extension module."
5968
msgstr ""
69+
"C 擴充介面是 CPython 所特有的,擴充模組在其他 Python 實作上無法運作。在許多情"
70+
"況下,可以避免撰寫 C 擴充並保留對其他實作的可移植性。例如,如果你的用例是呼"
71+
"叫 C 函式庫函式或系統呼叫,你應該考慮使用 :mod:`ctypes` 模組或 `cffi "
72+
"<https://cffi.readthedocs.io/>`_ 函式庫,而不是編寫自定義的 C 程式碼。這些模"
73+
"組讓你可以撰寫 Python 程式碼來與 C 程式碼介接,而且比起撰寫和編譯 C 擴充模"
74+
"組,這些模組在 Python 實作之間更容易移植。"
6075

6176
#: ../../extending/extending.rst:40
6277
msgid "A Simple Example"
@@ -70,6 +85,10 @@ msgid ""
7085
"terminated character string as argument and returns an integer. We want "
7186
"this function to be callable from Python as follows:"
7287
msgstr ""
88+
"讓我們來建立一個叫做 ``spam``\\ (Monty Python 粉絲最愛的食物...)的擴充模"
89+
"組。假設我們要建立一個 Python 介面給 C 函式庫的函式 :c:func:`system` [#]_ 使"
90+
"用,這個函式接受一個以 null 終止的 (null-terminated) 字元字串做為引數,並回傳"
91+
"一個整數。我們希望這個函式可以在 Python 中被呼叫,如下所示:"
7392

7493
#: ../../extending/extending.rst:48
7594
msgid ""
@@ -86,10 +105,13 @@ msgid ""
86105
"`spammodule.c`; if the module name is very long, like ``spammify``, the "
87106
"module name can be just :file:`spammify.c`.)"
88107
msgstr ""
108+
"首先建立一個檔案 :file:`spammodule.c`。(從過去歷史來看,如果一個模組叫做 "
109+
"``spam``,包含其實作的 C 檔案就會叫做 :file:`spammodule.c`;如果模組名稱很"
110+
"長,像是 ``spammify``,模組名稱也可以只是 :file:`spammify.c`)。"
89111

90112
#: ../../extending/extending.rst:58
91113
msgid "The first two lines of our file can be::"
92-
msgstr ""
114+
msgstr "我們檔案的前兩列可以為: ::"
93115

94116
#: ../../extending/extending.rst:60 ../../extending/extending.rst:663
95117
msgid ""
@@ -104,13 +126,17 @@ msgid ""
104126
"which pulls in the Python API (you can add a comment describing the purpose "
105127
"of the module and a copyright notice if you like)."
106128
msgstr ""
129+
"這會將 Python API 拉進來(你可以加入註解來說明模組的目的,也可以加入版權聲"
130+
"明)。"
107131

108132
#: ../../extending/extending.rst:68
109133
msgid ""
110134
"Since Python may define some pre-processor definitions which affect the "
111135
"standard headers on some systems, you *must* include :file:`Python.h` before "
112136
"any standard headers are included."
113137
msgstr ""
138+
"由於 Python 可能定義一些影響系統上某些標準標頭檔的預處理器定義,你\\ *必須"
139+
"*\\ 在引入任何標準標頭檔之前引入 :file:`Python.h`。"
114140

115141
#: ../../extending/extending.rst:72
116142
msgid ""
@@ -119,6 +145,9 @@ msgid ""
119145
"3.13, but we keep it here for backward compatibility. See :ref:`arg-parsing-"
120146
"string-and-buffers` for a description of this macro."
121147
msgstr ""
148+
"``#define PY_SSIZE_T_CLEAN`` 被用來表示在某些 API 中應該使用 ``Py_ssize_t`` "
149+
"而不是 ``int``。自 Python 3.13 起,它就不再是必要的了,但我們在此保留它以便向"
150+
"後相容。關於這個巨集的描述請參閱 :ref:`arg-parsing-string-and-buffers`。"
122151

123152
#: ../../extending/extending.rst:77
124153
msgid ""
@@ -130,13 +159,22 @@ msgid ""
130159
"on your system, it declares the functions :c:func:`malloc`, :c:func:`free` "
131160
"and :c:func:`realloc` directly."
132161
msgstr ""
162+
"除了那些在標準標頭檔中定義的符號以外,所有由 :file:`Python.h` 定義的使用者可"
163+
"見符號 (user-visible symbols) 的前綴都是 ``Py`` 或 ``PY``。為了方便,也因為 "
164+
"Python 直譯器的大量使用,``\"Python.h\"`` 也引入了一些標準的標頭檔:"
165+
"``<stdio.h>``、``<string.h>``、``<errno.h>`` 和 ``<stdlib.h>``。如果 "
166+
"``<stdlib.h>`` 在你的系統上不存在,它會直接宣"
167+
"告 :c:func:`malloc`、:c:func:`free` 和 :c:func:`realloc` 函式。"
133168

134169
#: ../../extending/extending.rst:85
135170
msgid ""
136171
"The next thing we add to our module file is the C function that will be "
137172
"called when the Python expression ``spam.system(string)`` is evaluated "
138173
"(we'll see shortly how it ends up being called)::"
139174
msgstr ""
175+
"接下來我們要加入到模組檔案的是 C 函式,當 Python 運算式 "
176+
"``spam.system(string)`` 要被求值 (evaluated) 時就會被呼叫(我們很快就會看到它"
177+
"最後是如何被呼叫的): ::"
140178

141179
#: ../../extending/extending.rst:89
142180
msgid ""
@@ -171,12 +209,16 @@ msgid ""
171209
"C function. The C function always has two arguments, conventionally named "
172210
"*self* and *args*."
173211
msgstr ""
212+
"可以很直觀地從 Python 的引數串列(例如單一的運算式 ``\"ls -l\"``)直接轉換成"
213+
"傳給 C 函式的引數。C 函式總是有兩個引數,習慣上會命名為 *self* 和 *args*。"
174214

175215
#: ../../extending/extending.rst:106
176216
msgid ""
177217
"The *self* argument points to the module object for module-level functions; "
178218
"for a method it would point to the object instance."
179219
msgstr ""
220+
"對於模組層級的函式,*self* 引數會指向模組物件;而對於方法來說則是指向物件的實"
221+
"例。"
180222

181223
#: ../../extending/extending.rst:109
182224
msgid ""
@@ -189,6 +231,11 @@ msgid ""
189231
"determine the required types of the arguments as well as the types of the C "
190232
"variables into which to store the converted values. More about this later."
191233
msgstr ""
234+
"*args* 引數會是一個指向包含引數的 Python 元組物件的指標。元組中的每一項都對應"
235+
"於呼叫的引數串列中的一個引數。引數是 Python 物件 --- 為了在我們的 C 函式中對"
236+
"它們做任何事情,我們必須先將它們轉換成 C 值。Python API 中"
237+
"的 :c:func:`PyArg_ParseTuple` 函式能夠檢查引數型別並將他們轉換為 C 值。它使用"
238+
"模板字串來決定所需的引數型別以及儲存轉換值的 C 變數型別。稍後會再詳細說明。"
192239

193240
#: ../../extending/extending.rst:118
194241
msgid ""
@@ -199,10 +246,14 @@ msgid ""
199246
"the calling function can return ``NULL`` immediately (as we saw in the "
200247
"example)."
201248
msgstr ""
249+
"如果所有的引數都有正確的型別,且其元件已儲存在傳入位址的變數中,"
250+
"則 :c:func:`PyArg_ParseTuple` 會回傳 true(非零)。如果傳入的是無效引數串列則"
251+
"回傳 false(零)。在後者情況下,它也會產生適當的例外,因此呼叫函式可以立即回"
252+
"傳 ``NULL``\\ (就像我們在範例中所看到的)。"
202253

203254
#: ../../extending/extending.rst:128
204255
msgid "Intermezzo: Errors and Exceptions"
205-
msgstr ""
256+
msgstr "插曲:錯誤與例外"
206257

207258
#: ../../extending/extending.rst:130
208259
msgid ""
@@ -215,12 +266,17 @@ msgid ""
215266
"the exception type, exception instance, and a traceback object. It is "
216267
"important to know about them to understand how errors are passed around."
217268
msgstr ""
269+
"在整個 Python 直譯器中的一個重要慣例為:當一個函式失敗時,它就應該設定一個例"
270+
"外條件,並回傳一個錯誤值(通常是 ``-1`` 或一個 ``NULL`` 指標)。例外資訊會儲"
271+
"存在直譯器執行緒狀態的三個成員中。如果沒有例外,它們就會是 ``NULL``。否則,它"
272+
"們是由 :meth:`sys.exc_info` 所回傳的 Python 元組中的 C 等效元組。它們是例外型"
273+
"別、例外實例和回溯物件。了解它們對於理解錯誤是如何傳遞是很重要的。"
218274

219275
#: ../../extending/extending.rst:139
220276
msgid ""
221277
"The Python API defines a number of functions to set various types of "
222278
"exceptions."
223-
msgstr ""
279+
msgstr "Python API 定義了許多能夠設定各種類型例外的函式。"
224280

225281
#: ../../extending/extending.rst:141
226282
msgid ""
@@ -230,6 +286,10 @@ msgid ""
230286
"indicates the cause of the error and is converted to a Python string object "
231287
"and stored as the \"associated value\" of the exception."
232288
msgstr ""
289+
"最常見的是 :c:func:`PyErr_SetString`。它的引數是一個例外物件和一個 C 字串。例"
290+
"外物件通常是預先定義的物件,例如 :c:data:`PyExc_ZeroDivisionError`。C 字串則"
291+
"指出錯誤的原因,並被轉換為 Python 字串物件且被儲存為例外的「關聯值 "
292+
"(associated value)」。"
233293

234294
#: ../../extending/extending.rst:147
235295
msgid ""
@@ -240,6 +300,10 @@ msgid ""
240300
"associated value. You don't need to :c:func:`Py_INCREF` the objects passed "
241301
"to any of these functions."
242302
msgstr ""
303+
"另一個有用的函式是 :c:func:`PyErr_SetFromErrno`,它只接受一個例外引數,並透過"
304+
"檢查全域變數 :c:data:`errno` 來建立關聯值。最一般的函式"
305+
"是 :c:func:`PyErr_SetObject`,它接受兩個物件引數,即例外和它的關聯值。你不需"
306+
"要對傳給任何這些函式的物件呼叫 :c:func:`Py_INCREF`。"
243307

244308
#: ../../extending/extending.rst:154
245309
msgid ""
@@ -249,6 +313,10 @@ msgid ""
249313
"func:`PyErr_Occurred` to see whether an error occurred in a function call, "
250314
"since you should be able to tell from the return value."
251315
msgstr ""
316+
"你可以使用 :c:func:`PyErr_Occurred` 來不具破壞性地測試例外是否已被設定。這會"
317+
"回傳當前的例外物件,如果沒有例外發生則回傳 ``NULL``。你通常不需要呼"
318+
"叫 :c:func:`PyErr_Occurred` 來查看函式呼叫是否發生錯誤,因為你應可從回傳值就"
319+
"得知。"
252320

253321
#: ../../extending/extending.rst:160
254322
msgid ""
@@ -262,6 +330,12 @@ msgid ""
262330
"interpreter's main loop, this aborts the currently executing Python code and "
263331
"tries to find an exception handler specified by the Python programmer."
264332
msgstr ""
333+
"當函式 *f* 呼叫另一個函式 *g* 時檢測到後者失敗,*f* 本身應該回傳一個錯誤值"
334+
"(通常是 ``NULL`` 或 ``-1``)。它\\ *不*\\ 應該呼叫 ``PyErr_*`` 函式的其中一"
335+
"個,這會已被 *g* 呼叫過。*f* 的呼叫者然後也應該回傳一個錯誤指示給\\ *它的*\\ "
336+
"呼叫者,同樣\\ *不會*\\ 呼叫 ``PyErr_*``,依此類推 --- 最詳細的錯誤原因已經被"
337+
"首先檢測到它的函式回報了。一旦錯誤到達 Python 直譯器的主要迴圈,這會中止目前"
338+
"執行的 Python 程式碼,並嘗試尋找 Python 程式設計者指定的例外處理程式。"
265339

266340
#: ../../extending/extending.rst:170
267341
msgid ""
@@ -271,6 +345,9 @@ msgid ""
271345
"cause information about the cause of the error to be lost: most operations "
272346
"can fail for a variety of reasons.)"
273347
msgstr ""
348+
"(在某些情況下,模組可以透過呼叫另一個 ``PyErr_*`` 函式來提供更詳細的錯誤訊"
349+
"息,在這種情況下這樣做是沒問題的。然而這一般來說並非必要,而且可能會導致錯誤"
350+
"原因資訊的遺失:大多數的操作都可能因為各種原因而失敗。)"
274351

275352
#: ../../extending/extending.rst:176
276353
msgid ""
@@ -280,6 +357,10 @@ msgid ""
280357
"pass the error on to the interpreter but wants to handle it completely by "
281358
"itself (possibly by trying something else, or pretending nothing went wrong)."
282359
msgstr ""
360+
"要忽略由函式呼叫失敗所設定的例外,必須明確地呼叫 :c:func:`PyErr_Clear` 來清除"
361+
"例外條件。C 程式碼唯一要呼叫 :c:func:`PyErr_Clear` 的情況為當它不想將錯誤傳遞"
362+
"給直譯器而想要完全是自己來處理它時(可能是要再嘗試其他東西,或者假裝什麼都沒"
363+
"出錯)。"
283364

284365
#: ../../extending/extending.rst:182
285366
msgid ""
@@ -289,6 +370,11 @@ msgid ""
289370
"creating functions (for example, :c:func:`PyLong_FromLong`) already do this, "
290371
"so this note is only relevant to those who call :c:func:`malloc` directly."
291372
msgstr ""
373+
"每個失敗的 :c:func:`malloc` 呼叫都必須被轉換成一個例外 "
374+
"--- :c:func:`malloc`\\ (或 :c:func:`realloc`)的直接呼叫者必須呼"
375+
"叫 :c:func:`PyErr_NoMemory` 並回傳一個失敗指示器。所有建立物件的函式(例"
376+
"如 :c:func:`PyLong_FromLong`)都已經這麼做了,所以這個注意事項只和那些直接呼"
377+
"叫 :c:func:`malloc` 的函式有關。"
292378

293379
#: ../../extending/extending.rst:188
294380
msgid ""
@@ -297,13 +383,18 @@ msgid ""
297383
"positive value or zero for success and ``-1`` for failure, like Unix system "
298384
"calls."
299385
msgstr ""
386+
"還要注意的是,有 :c:func:`PyArg_ParseTuple` 及同系列函式的這些重要例外,回傳"
387+
"整數狀態的函式通常會回傳一個正值或 0 表示成功、回傳 ``-1`` 表示失敗,就像 "
388+
"Unix 系統呼叫一樣。"
300389

301390
#: ../../extending/extending.rst:192
302391
msgid ""
303392
"Finally, be careful to clean up garbage (by making :c:func:`Py_XDECREF` or :"
304393
"c:func:`Py_DECREF` calls for objects you have already created) when you "
305394
"return an error indicator!"
306395
msgstr ""
396+
"最後,在回傳錯誤指示器時要注意垃圾清理(透過對你已經建立的物件呼"
397+
"叫 :c:func:`Py_XDECREF` 或 :c:func:`Py_DECREF`)!"
307398

308399
#: ../../extending/extending.rst:196
309400
msgid ""
@@ -317,12 +408,21 @@ msgid ""
317408
"you have an argument whose value must be in a particular range or must "
318409
"satisfy other conditions, :c:data:`PyExc_ValueError` is appropriate."
319410
msgstr ""
411+
"你完全可以自行選擇要產生的例外。有一些預先宣告的 C 物件會對應到所有內建的 "
412+
"Python 例外,例如 :c:data:`PyExc_ZeroDivisionError`,你可以直接使用它們。當"
413+
"然,你應該明智地選擇例外,像是不要使用 :c:data:`PyExc_TypeError` 來表示檔案無"
414+
"法打開(應該是 :c:data:`PyExc_OSError`)。如果引數串列有問"
415+
"題,:c:func:`PyArg_ParseTuple` 函式通常會引發 :c:data:`PyExc_TypeError`。如果"
416+
"你有一個引數的值必須在一個特定的範圍內或必須滿足其他條件,則可以使"
417+
"用 :c:data:`PyExc_ValueError`。"
320418

321419
#: ../../extending/extending.rst:206
322420
msgid ""
323421
"You can also define a new exception that is unique to your module. For this, "
324422
"you usually declare a static object variable at the beginning of your file::"
325423
msgstr ""
424+
"你也可以定義一個你的模組特有的新例外。為此你通常會在檔案開頭宣告一個靜態物件"
425+
"變數: ::"
326426

327427
#: ../../extending/extending.rst:209
328428
msgid "static PyObject *SpamError;"
@@ -333,9 +433,10 @@ msgid ""
333433
"and initialize it in your module's initialization function (:c:func:`!"
334434
"PyInit_spam`) with an exception object::"
335435
msgstr ""
436+
"並在你的模組初始化函式中使用一個例外物件來初始化它 (:c:func:`!"
437+
"PyInit_spam`): ::"
336438

337439
#: ../../extending/extending.rst:214
338-
#, fuzzy
339440
msgid ""
340441
"PyMODINIT_FUNC\n"
341442
"PyInit_spam(void)\n"
@@ -366,9 +467,7 @@ msgstr ""
366467
" return NULL;\n"
367468
"\n"
368469
" SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);\n"
369-
" Py_XINCREF(SpamError);\n"
370-
" if (PyModule_AddObject(m, \"error\", SpamError) < 0) {\n"
371-
" Py_XDECREF(SpamError);\n"
470+
" if (PyModule_AddObjectRef(m, \"error\", SpamError) < 0) {\n"
372471
" Py_CLEAR(SpamError);\n"
373472
" Py_DECREF(m);\n"
374473
" return NULL;\n"
@@ -384,6 +483,9 @@ msgid ""
384483
"class being :exc:`Exception` (unless another class is passed in instead of "
385484
"``NULL``), described in :ref:`bltin-exceptions`."
386485
msgstr ""
486+
"請注意,例外物件的 Python 名稱是 :exc:`!spam.error`。如同\\ :ref:`bltin-"
487+
"exceptions`\\ 所述,:c:func:`PyErr_NewException` 函式可能會建立一個基底類別"
488+
"為 :exc:`Exception` 的類別(除非傳入另一個類別來代替 ``NULL``)。"
387489

388490
#: ../../extending/extending.rst:238
389491
msgid ""
@@ -395,18 +497,25 @@ msgid ""
395497
"pointer, C code which raises the exception could cause a core dump or other "
396498
"unintended side effects."
397499
msgstr ""
500+
"請注意,:c:data:`!SpamError` 變數保留了對新建立的例外類別的參照;這是故意的!"
501+
"因為外部程式碼可能會從模組中移除這個例外,所以需要一個對這個類別的參照來確保"
502+
"它不會被丟棄而導致 :c:data:`!SpamError` 變成一個迷途指標 (dangling pointer)。"
503+
"如果它變成迷途指標,那產生例外的 C 程式碼可能會導致核心轉儲 (core dump) 或其"
504+
"他不預期的 side effect。"
398505

399506
#: ../../extending/extending.rst:245
400507
msgid ""
401508
"We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type "
402509
"later in this sample."
403-
msgstr ""
510+
msgstr "我們稍後會討論 :c:macro:`PyMODINIT_FUNC` 作為函式回傳型別的用法。"
404511

405512
#: ../../extending/extending.rst:248
406513
msgid ""
407514
"The :exc:`!spam.error` exception can be raised in your extension module "
408515
"using a call to :c:func:`PyErr_SetString` as shown below::"
409516
msgstr ""
517+
"可以在你的擴充模組中呼叫 :c:func:`PyErr_SetString` 來引發 :exc:`!spam.error` "
518+
"例外,如下所示: ::"
410519

411520
#: ../../extending/extending.rst:251
412521
msgid ""
@@ -450,7 +559,7 @@ msgstr "回到範例"
450559
msgid ""
451560
"Going back to our example function, you should now be able to understand "
452561
"this statement::"
453-
msgstr ""
562+
msgstr "回到我們的範例函式,現在你應該可以理解這個陳述式了: ::"
454563

455564
#: ../../extending/extending.rst:276
456565
msgid ""
@@ -470,12 +579,19 @@ msgid ""
470579
"which it points (so in Standard C, the variable :c:data:`!command` should "
471580
"properly be declared as ``const char *command``)."
472581
msgstr ""
582+
"如果在引數串列中檢測到錯誤則會回傳 ``NULL``\\ (回傳物件指標之函式的錯誤指示"
583+
"器),其依賴於 :c:func:`PyArg_ParseTuple` 設定的例外,否則引數的字串值會已被"
584+
"複製到區域變數 :c:data:`!command` 中。這是一個指標賦值,你不應該修改它所指向"
585+
"的字串(所以在標準 C 中,:c:data:`!command` 變數應該正確地被宣告為 ``const "
586+
"char *command``)。"
473587

474588
#: ../../extending/extending.rst:287
475589
msgid ""
476590
"The next statement is a call to the Unix function :c:func:`system`, passing "
477591
"it the string we just got from :c:func:`PyArg_ParseTuple`::"
478592
msgstr ""
593+
"接下來的陳述式會呼叫 Unix 函式 :c:func:`system`,並將剛才"
594+
"從 :c:func:`PyArg_ParseTuple` 得到的字串傳給它:"
479595

480596
#: ../../extending/extending.rst:290
481597
msgid "sts = system(command);"
@@ -487,6 +603,8 @@ msgid ""
487603
"a Python object. This is done using the function :c:func:"
488604
"`PyLong_FromLong`. ::"
489605
msgstr ""
606+
"我們的 :func:`!spam.system` 函式必須以 Python 物件的形式來回傳 :c:data:`!"
607+
"sts` 的值。這是透過 :c:func:`PyLong_FromLong` 函式來達成。 ::"
490608

491609
#: ../../extending/extending.rst:295
492610
msgid "return PyLong_FromLong(sts);"
@@ -497,6 +615,8 @@ msgid ""
497615
"In this case, it will return an integer object. (Yes, even integers are "
498616
"objects on the heap in Python!)"
499617
msgstr ""
618+
"在這種情況下它會回傳一個整數物件。(是的,在 Python 中連整數也是堆積 (heap) 上"
619+
"的物件!)"
500620

501621
#: ../../extending/extending.rst:300
502622
msgid ""
@@ -505,6 +625,9 @@ msgid ""
505625
"``None``. You need this idiom to do so (which is implemented by the :c:"
506626
"macro:`Py_RETURN_NONE` macro)::"
507627
msgstr ""
628+
"如果你有一個不回傳任何有用引數的 C 函式(一個回傳 :c:expr:`void` 的函式),對"
629+
"應的 Python 函式必須回傳 ``None``。你需要以下這個慣例來達成"
630+
"(由 :c:macro:`Py_RETURN_NONE` 巨集實作): ::"
508631

509632
#: ../../extending/extending.rst:305
510633
msgid ""
@@ -520,16 +643,21 @@ msgid ""
520643
"is a genuine Python object rather than a ``NULL`` pointer, which means "
521644
"\"error\" in most contexts, as we have seen."
522645
msgstr ""
646+
":c:data:`Py_None` 是特殊 Python 物件 ``None`` 的 C 名稱。它是一個真正的 "
647+
"Python 物件而不是一個 ``NULL`` 指標,在大多數的情況下它的意思是「錯誤」,如我"
648+
"們所見過的那樣。"
523649

524650
#: ../../extending/extending.rst:316
525651
msgid "The Module's Method Table and Initialization Function"
526-
msgstr ""
652+
msgstr "模組的方法表和初始化函式"
527653

528654
#: ../../extending/extending.rst:318
529655
msgid ""
530656
"I promised to show how :c:func:`!spam_system` is called from Python "
531657
"programs. First, we need to list its name and address in a \"method table\"::"
532658
msgstr ""
659+
"我承諾過要展示 :c:func:`!spam_system` 是如何從 Python 程式中呼叫的。首先,我"
660+
"們需要在「方法表」中列出它的名稱和位址: ::"
533661

534662
#: ../../extending/extending.rst:321
535663
msgid ""
@@ -541,6 +669,13 @@ msgid ""
541669
" {NULL, NULL, 0, NULL} /* Sentinel */\n"
542670
"};"
543671
msgstr ""
672+
"static PyMethodDef SpamMethods[] = {\n"
673+
" ...\n"
674+
" {\"system\", spam_system, METH_VARARGS,\n"
675+
" \"Execute a shell command.\"},\n"
676+
" ...\n"
677+
" {NULL, NULL, 0, NULL} /* Sentinel */\n"
678+
"};"
544679

545680
#: ../../extending/extending.rst:329
546681
msgid ""
@@ -550,13 +685,19 @@ msgid ""
550685
"value of ``0`` means that an obsolete variant of :c:func:`PyArg_ParseTuple` "
551686
"is used."
552687
msgstr ""
688+
"請注意第三個項目 (``METH_VARARGS``)。這是一個告訴直譯器 C 函式之呼叫方式的旗"
689+
"標。通常應該是 ``METH_VARARGS`` 或 ``METH_VARARGS | METH_KEYWORDS``;``0`` 表"
690+
"示是使用 :c:func:`PyArg_ParseTuple` 的一個過時變體。"
553691

554692
#: ../../extending/extending.rst:334
555693
msgid ""
556694
"When using only ``METH_VARARGS``, the function should expect the Python-"
557695
"level parameters to be passed in as a tuple acceptable for parsing via :c:"
558696
"func:`PyArg_ParseTuple`; more information on this function is provided below."
559697
msgstr ""
698+
"當只使用 ``METH_VARARGS`` 時,函式應預期 Python 層級的參數是以元組形式傳入且"
699+
"能夠接受以 :c:func:`PyArg_ParseTuple` 進行剖析;有關此函式的更多資訊將在下面"
700+
"提供。"
560701

561702
#: ../../extending/extending.rst:338
562703
msgid ""
@@ -566,11 +707,15 @@ msgid ""
566707
"keywords. Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments "
567708
"to such a function."
568709
msgstr ""
710+
"如果要將關鍵字引數傳給函式,可以在第三個欄位設定 :c:macro:`METH_KEYWORDS` 位"
711+
"元。在這種情況下,C 函式應該要能接受第三個 ``PyObject *`` 參數,這個參數將會"
712+
"是關鍵字的字典。可使用 :c:func:`PyArg_ParseTupleAndKeywords` 來剖析這種函式的"
713+
"引數。"
569714

570715
#: ../../extending/extending.rst:344
571716
msgid ""
572717
"The method table must be referenced in the module definition structure::"
573-
msgstr ""
718+
msgstr "方法表必須在模組定義結構中被參照: ::"
574719

575720
#: ../../extending/extending.rst:346
576721
msgid ""
@@ -583,6 +728,14 @@ msgid ""
583728
" SpamMethods\n"
584729
"};"
585730
msgstr ""
731+
"static struct PyModuleDef spammodule = {\n"
732+
" PyModuleDef_HEAD_INIT,\n"
733+
" \"spam\", /* 模組名稱 */\n"
734+
" spam_doc, /* 模組文件,可能為 NULL */\n"
735+
" -1, /* 模組的個別直譯器狀態的大小,\n"
736+
" 如果模組將狀態保存在全域變數中則為 -1 */\n"
737+
" SpamMethods\n"
738+
"};"
586739

587740
#: ../../extending/extending.rst:355
588741
msgid ""
@@ -591,6 +744,9 @@ msgid ""
591744
"`!PyInit_name`, where *name* is the name of the module, and should be the "
592745
"only non-\\ ``static`` item defined in the module file::"
593746
msgstr ""
747+
"反過來說,這個結構必須在模組的初始化函式中被傳給直譯器。初始化函式必須被命名"
748+
"為 :c:func:`!PyInit_name`,其中 *name* 是模組的名稱,且應該是模組檔案中唯一定"
749+
"義的非「靜態 (``static``)」項目: ::"
594750

595751
#: ../../extending/extending.rst:360
596752
msgid ""
@@ -612,6 +768,8 @@ msgid ""
612768
"return type, declares any special linkage declarations required by the "
613769
"platform, and for C++ declares the function as ``extern \"C\"``."
614770
msgstr ""
771+
"請注意,:c:macro:`PyMODINIT_FUNC` 宣告函式的回傳型別為 `PyObject *``、宣告平"
772+
"台所需的任何特殊連結宣告、並針對 C++ 宣告函式為 ``extern \"C\"``。"
615773

616774
#: ../../extending/extending.rst:370
617775
msgid ""
@@ -626,6 +784,14 @@ msgid ""
626784
"The init function must return the module object to its caller, so that it "
627785
"then gets inserted into ``sys.modules``."
628786
msgstr ""
787+
"當 Python 程式第一次引入模組 :mod:`!spam` 時,:c:func:`!PyInit_spam` 會被呼"
788+
"叫。(有關嵌入 Python 的註解請參見下文。)它會呼叫回傳一個模組物件"
789+
"的 :c:func:`PyModule_Create`,並根據在模組定義中所找到的表(一"
790+
"個 :c:type:`PyMethodDef` 結構的陣列)將內建的函式物件插入到新建立的模組"
791+
"中。:c:func:`PyModule_Create` 會回傳一個指向它建立之模組物件的指標。對於某些"
792+
"錯誤情況,它可能會以嚴重錯誤的形式來中止;如果模組無法令人滿意地被初始化,它"
793+
"也會回傳 ``NULL``。初始化函式必須把模組物件回傳給它的呼叫者,這樣它才會被插入"
794+
"到 ``sys.modules`` 中。"
629795

630796
#: ../../extending/extending.rst:381
631797
msgid ""
@@ -634,6 +800,9 @@ msgid ""
634800
"table. To add the module to the initialization table, use :c:func:"
635801
"`PyImport_AppendInittab`, optionally followed by an import of the module::"
636802
msgstr ""
803+
"嵌入 Python 時,除非在 :c:data:`PyImport_Inittab` 表中有相關條目,否則不會自"
804+
"動呼叫 :c:func:`!PyInit_spam` 函式。要將模組加入初始化表,請使"
805+
"用 :c:func:`PyImport_AppendInittab` 並在隨後選擇性地將該模組引入: ::"
637806

638807
#: ../../extending/extending.rst:386
639808
msgid ""
@@ -687,6 +856,55 @@ msgid ""
687856
" Py_ExitStatusException(status);\n"
688857
"}"
689858
msgstr ""
859+
"#define PY_SSIZE_T_CLEAN\n"
860+
"#include <Python.h>\n"
861+
"\n"
862+
"int\n"
863+
"main(int argc, char *argv[])\n"
864+
"{\n"
865+
" PyStatus status;\n"
866+
" PyConfig config;\n"
867+
" PyConfig_InitPythonConfig(&config);\n"
868+
"\n"
869+
" /* 在 Py_Initialize 之前加入內建模組 */\n"
870+
" if (PyImport_AppendInittab(\"spam\", PyInit_spam) == -1) {\n"
871+
" fprintf(stderr, \"Error: could not extend in-built modules "
872+
"table\\n\");\n"
873+
" exit(1);\n"
874+
" }\n"
875+
"\n"
876+
" /* 將 argv[0] 傳給 Python 直譯器 */\n"
877+
" status = PyConfig_SetBytesString(&config, &config.program_name, "
878+
"argv[0]);\n"
879+
" if (PyStatus_Exception(status)) {\n"
880+
" goto exception;\n"
881+
" }\n"
882+
"\n"
883+
" /* 初始化 Python 直譯器。這會是必要的。\n"
884+
" 如果此步驟失敗就會導致嚴重錯誤。*/\n"
885+
" status = Py_InitializeFromConfig(&config);\n"
886+
" if (PyStatus_Exception(status)) {\n"
887+
" goto exception;\n"
888+
" }\n"
889+
" PyConfig_Clear(&config);\n"
890+
"\n"
891+
" /* 可選擇引入模組;或者\n"
892+
" 可以延遲引入,直至嵌入式腳本\n"
893+
" 將其引入。*/\n"
894+
" PyObject *pmodule = PyImport_ImportModule(\"spam\");\n"
895+
" if (!pmodule) {\n"
896+
" PyErr_Print();\n"
897+
" fprintf(stderr, \"Error: could not import module 'spam'\\n\");\n"
898+
" }\n"
899+
"\n"
900+
" // ... 在此使用 Python C API ...\n"
901+
"\n"
902+
" return 0;\n"
903+
"\n"
904+
" exception:\n"
905+
" PyConfig_Clear(&config);\n"
906+
" Py_ExitStatusException(status);\n"
907+
"}"
690908

691909
#: ../../extending/extending.rst:436
692910
msgid ""
@@ -696,13 +914,18 @@ msgid ""
696914
"extension modules. Extension module authors should exercise caution when "
697915
"initializing internal data structures."
698916
msgstr ""
917+
"從 ``sys.modules`` 中移除項目,或在一個行程中將已編譯模組引入到多個直譯器中"
918+
"(或在沒有 :c:func:`exec` 介入的情況下使用 :c:func:`fork`)可能會對某些擴充模"
919+
"組造成問題。擴充模組作者在初始化內部資料結構時應特別小心。"
699920

700921
#: ../../extending/extending.rst:442
701922
msgid ""
702923
"A more substantial example module is included in the Python source "
703924
"distribution as :file:`Modules/xxmodule.c`. This file may be used as a "
704925
"template or simply read as an example."
705926
msgstr ""
927+
"Python 原始碼發行版本中包含了一個更實質的範例模組 :file:`Modules/"
928+
"xxmodule.c`。這個檔案可以當作模板使用,也可以簡單地當作範例來閱讀。"
706929

707930
#: ../../extending/extending.rst:448
708931
msgid ""
@@ -711,6 +934,10 @@ msgid ""
711934
"``PyInit_spam``, and creation of the module is left to the import machinery. "
712935
"For details on multi-phase initialization, see :PEP:`489`."
713936
msgstr ""
937+
"不像我們的 ``spam`` 範例,``xxmodule`` 使用了\\ *多階段初始化 (multi-phase "
938+
"initialization)*\\ (Python 3.5 新增),其中的 PyModuleDef 結構會從 "
939+
"``PyInit_spam`` 回傳,而模組的建立則交由引入機制來完成。關於多階段初始化的詳"
940+
"細資訊請參閱 :PEP:`489`。"
714941

715942
#: ../../extending/extending.rst:457
716943
msgid "Compilation and Linkage"
@@ -1078,14 +1305,14 @@ msgid ""
10781305
msgstr ""
10791306

10801307
#: ../../extending/extending.rst:737
1081-
#, fuzzy
10821308
msgid ""
10831309
"int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,\n"
10841310
" const char *format, char * const "
10851311
"*kwlist, ...);"
10861312
msgstr ""
10871313
"int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,\n"
1088-
" const char *format, char *kwlist[], ...);"
1314+
" const char *format, char * const "
1315+
"*kwlist, ...);"
10891316

10901317
#: ../../extending/extending.rst:740
10911318
msgid ""

0 commit comments

Comments
 (0)
Please sign in to comment.