-
-
Notifications
You must be signed in to change notification settings - Fork 224
Expand file tree
/
Copy pathextending.po
More file actions
2879 lines (2653 loc) · 127 KB
/
extending.po
File metadata and controls
2879 lines (2653 loc) · 127 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Copyright (C) 2001 Python Software Foundation
# This file is distributed under the same license as the Python package.
#
# Translators:
# Leon H., 2017
# Adrian Liaw <adrianliaw2000@gmail.com>, 2018
# Matt Wang <mattwang44@gmail.com>, 2025
msgid ""
msgstr ""
"Project-Id-Version: Python 3.14\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-25 00:13+0000\n"
"PO-Revision-Date: 2025-02-17 14:34+0000\n"
"Last-Translator: Matt Wang <mattwang44@gmail.com>\n"
"Language-Team: Chinese - TAIWAN (https://github.com/python/python-docs-zh-"
"tw)\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: ../../extending/extending.rst:8
msgid "Extending Python with C or C++"
msgstr "以 C 或 C++ 擴充 Python"
#: ../../extending/extending.rst:10
msgid ""
"It is quite easy to add new built-in modules to Python, if you know how to "
"program in C. Such :dfn:`extension modules` can do two things that can't be "
"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 ""
"To support extensions, the Python API (Application Programmers Interface) "
"defines a set of functions, macros and variables that provide access to most "
"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 ""
"The C extension interface is specific to CPython, and extension modules do "
"not work on other Python implementations. In many cases, it is possible to "
"avoid writing C extensions and preserve portability to other "
"implementations. For example, if your use case is calling C library "
"functions or system calls, you should consider using the :mod:`ctypes` "
"module or the `cffi <https://cffi.readthedocs.io/>`_ library rather than "
"writing custom C code. These modules let you write Python code to interface "
"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 "
"<https://cffi.readthedocs.io/>`_ 函式庫,而不是編寫自訂的 C 程式碼。這些模組"
"讓你可以撰寫 Python 程式碼來與 C 程式碼介接,而且比起撰寫和編譯 C 擴充模組,"
"這些模組在 Python 實作之間更容易移植。"
#: ../../extending/extending.rst:40
msgid "A Simple Example"
msgstr "一個簡單範例"
#: ../../extending/extending.rst:42
msgid ""
"Let's create an extension module called ``spam`` (the favorite food of Monty "
"Python fans...) and let's say we want to create a Python interface to the C "
"library function :c:func:`system` [#]_. This function takes a null-"
"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 ""
">>> import spam\n"
">>> status = spam.system(\"ls -l\")"
msgstr ""
">>> import spam\n"
">>> status = spam.system(\"ls -l\")"
#: ../../extending/extending.rst:53
msgid ""
"Begin by creating a file :file:`spammodule.c`. (Historically, if a module "
"is called ``spam``, the C file containing its implementation is called :file:"
"`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 "我們檔案的前兩列可以為: ::"
#: ../../extending/extending.rst:60 ../../extending/extending.rst:706
msgid ""
"#define PY_SSIZE_T_CLEAN\n"
"#include <Python.h>"
msgstr ""
"#define PY_SSIZE_T_CLEAN\n"
"#include <Python.h>"
#: ../../extending/extending.rst:63
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 ""
"Since Python may define some pre-processor definitions which affect the "
"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 ""
"``#define PY_SSIZE_T_CLEAN`` was used to indicate that ``Py_ssize_t`` should "
"be used in some APIs instead of ``int``. It is not necessary since Python "
"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 ""
"All user-visible symbols defined by :file:`Python.h` have a prefix of ``Py`` "
"or ``PY``, except those defined in standard header files."
msgstr ""
"所有由 :file:`Python.h` 定義的使用者可見符號都具有 ``Py`` 或 ``PY`` 的前綴,"
"在標準標頭檔中定義的除外。"
#: ../../extending/extending.rst:82
msgid ""
"For backward compatibility, :file:`Python.h` includes several standard "
"header files. C extensions should include the standard headers that they "
"use, and should not rely on these implicit includes. If using the limited C "
"API version 3.13 or newer, the implicit includes are:"
msgstr ""
"為了向後相容,:file:`Python.h` 引入了數個標準標頭檔。C 擴充應該引入它們使用的"
"標準標頭檔,而不應依賴這些隱式的引入。如果使用限定 C API 版本 3.13 或更新版"
"本,隱式引入的有:"
#: ../../extending/extending.rst:87
msgid "``<assert.h>``"
msgstr "``<assert.h>``"
#: ../../extending/extending.rst:88
msgid "``<intrin.h>`` (on Windows)"
msgstr "``<intrin.h>``\\ (在 Windows 上)"
#: ../../extending/extending.rst:89
msgid "``<inttypes.h>``"
msgstr "``<inttypes.h>``"
#: ../../extending/extending.rst:90
msgid "``<limits.h>``"
msgstr "``<limits.h>``"
#: ../../extending/extending.rst:91
msgid "``<math.h>``"
msgstr "``<math.h>``"
#: ../../extending/extending.rst:92
msgid "``<stdarg.h>``"
msgstr "``<stdarg.h>``"
#: ../../extending/extending.rst:93
msgid "``<wchar.h>``"
msgstr "``<wchar.h>``"
#: ../../extending/extending.rst:94
msgid "``<sys/types.h>`` (if present)"
msgstr "``<sys/types.h>``\\ (如果存在)"
#: ../../extending/extending.rst:96
msgid ""
"If :c:macro:`Py_LIMITED_API` is not defined, or is set to version 3.12 or "
"older, the headers below are also included:"
msgstr ""
"如果 :c:macro:`Py_LIMITED_API` 未被定義,或是被設定為版本 3.12 或更舊,則也會"
"引入以下標頭檔:"
#: ../../extending/extending.rst:99
msgid "``<ctype.h>``"
msgstr "``<ctype.h>``"
#: ../../extending/extending.rst:100
msgid "``<unistd.h>`` (on POSIX)"
msgstr "``<unistd.h>``\\ (在 POSIX 上)"
#: ../../extending/extending.rst:102
msgid ""
"If :c:macro:`Py_LIMITED_API` is not defined, or is set to version 3.10 or "
"older, the headers below are also included:"
msgstr ""
"如果 :c:macro:`Py_LIMITED_API` 未被定義,或是被設定為版本 3.10 或更舊,則也會"
"引入以下標頭檔:"
#: ../../extending/extending.rst:105
msgid "``<errno.h>``"
msgstr "``<errno.h>``"
#: ../../extending/extending.rst:106
msgid "``<stdio.h>``"
msgstr "``<stdio.h>``"
#: ../../extending/extending.rst:107
msgid "``<stdlib.h>``"
msgstr "``<stdlib.h>``"
#: ../../extending/extending.rst:108
msgid "``<string.h>``"
msgstr "``<string.h>``"
#: ../../extending/extending.rst:110
msgid ""
"The next thing we add to our module file is the C function that will be "
"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:114
msgid ""
"static PyObject *\n"
"spam_system(PyObject *self, PyObject *args)\n"
"{\n"
" const char *command;\n"
" int sts;\n"
"\n"
" if (!PyArg_ParseTuple(args, \"s\", &command))\n"
" return NULL;\n"
" sts = system(command);\n"
" return PyLong_FromLong(sts);\n"
"}"
msgstr ""
"static PyObject *\n"
"spam_system(PyObject *self, PyObject *args)\n"
"{\n"
" const char *command;\n"
" int sts;\n"
"\n"
" if (!PyArg_ParseTuple(args, \"s\", &command))\n"
" return NULL;\n"
" sts = system(command);\n"
" return PyLong_FromLong(sts);\n"
"}"
#: ../../extending/extending.rst:126
msgid ""
"There is a straightforward translation from the argument list in Python (for "
"example, the single expression ``\"ls -l\"``) to the arguments passed to the "
"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:131
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:134
msgid ""
"The *args* argument will be a pointer to a Python tuple object containing "
"the arguments. Each item of the tuple corresponds to an argument in the "
"call's argument list. The arguments are Python objects --- in order to do "
"anything with them in our C function we have to convert them to C values. "
"The function :c:func:`PyArg_ParseTuple` in the Python API checks the "
"argument types and converts them to C values. It uses a template string to "
"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:143
msgid ""
":c:func:`PyArg_ParseTuple` returns true (nonzero) if all arguments have the "
"right type and its components have been stored in the variables whose "
"addresses are passed. It returns false (zero) if an invalid argument list "
"was passed. In the latter case it also raises an appropriate exception so "
"the calling function can return ``NULL`` immediately (as we saw in the "
"example)."
msgstr ""
"如果所有的引數都有正確的型別,且其元件已儲存在傳入位址的變數中,則 :c:func:"
"`PyArg_ParseTuple` 會回傳 true(非零)。如果傳入的是無效引數串列則回傳 false"
"(零)。在後者情況下,它也會產生適當的例外,因此呼叫函式可以立即回傳 "
"``NULL``\\ (就像我們在範例中所看到的)。"
#: ../../extending/extending.rst:153
msgid "Intermezzo: Errors and Exceptions"
msgstr "插曲:錯誤與例外"
#: ../../extending/extending.rst:155
msgid ""
"An important convention throughout the Python interpreter is the following: "
"when a function fails, it should set an exception condition and return an "
"error value (usually ``-1`` or a ``NULL`` pointer). Exception information "
"is stored in three members of the interpreter's thread state. These are "
"``NULL`` if there is no exception. Otherwise they are the C equivalents of "
"the members of the Python tuple returned by :meth:`sys.exc_info`. These are "
"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:164
msgid ""
"The Python API defines a number of functions to set various types of "
"exceptions."
msgstr "Python API 定義了許多能夠設定各種類型例外的函式。"
#: ../../extending/extending.rst:166
msgid ""
"The most common one is :c:func:`PyErr_SetString`. Its arguments are an "
"exception object and a C string. The exception object is usually a "
"predefined object like :c:data:`PyExc_ZeroDivisionError`. The C string "
"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:172
msgid ""
"Another useful function is :c:func:`PyErr_SetFromErrno`, which only takes an "
"exception argument and constructs the associated value by inspection of the "
"global variable :c:data:`errno`. The most general function is :c:func:"
"`PyErr_SetObject`, which takes two object arguments, the exception and its "
"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:179
msgid ""
"You can test non-destructively whether an exception has been set with :c:"
"func:`PyErr_Occurred`. This returns the current exception object, or "
"``NULL`` if no exception has occurred. You normally don't need to call :c:"
"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:185
msgid ""
"When a function *f* that calls another function *g* detects that the latter "
"fails, *f* should itself return an error value (usually ``NULL`` or "
"``-1``). It should *not* call one of the ``PyErr_*`` functions --- one has "
"already been called by *g*. *f*'s caller is then supposed to also return an "
"error indication to *its* caller, again *without* calling ``PyErr_*``, and "
"so on --- the most detailed cause of the error was already reported by the "
"function that first detected it. Once the error reaches the Python "
"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:195
msgid ""
"(There are situations where a module can actually give a more detailed error "
"message by calling another ``PyErr_*`` function, and in such cases it is "
"fine to do so. As a general rule, however, this is not necessary, and can "
"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:201
msgid ""
"To ignore an exception set by a function call that failed, the exception "
"condition must be cleared explicitly by calling :c:func:`PyErr_Clear`. The "
"only time C code should call :c:func:`PyErr_Clear` is if it doesn't want to "
"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:207
msgid ""
"Every failing :c:func:`malloc` call must be turned into an exception --- the "
"direct caller of :c:func:`malloc` (or :c:func:`realloc`) must call :c:func:"
"`PyErr_NoMemory` and return a failure indicator itself. All the object-"
"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:213
msgid ""
"Also note that, with the important exception of :c:func:`PyArg_ParseTuple` "
"and friends, functions that return an integer status usually return a "
"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:217
msgid ""
"Finally, be careful to clean up garbage (by making :c:func:`Py_XDECREF` or :"
"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:221
msgid ""
"The choice of which exception to raise is entirely yours. There are "
"predeclared C objects corresponding to all built-in Python exceptions, such "
"as :c:data:`PyExc_ZeroDivisionError`, which you can use directly. Of course, "
"you should choose exceptions wisely --- don't use :c:data:`PyExc_TypeError` "
"to mean that a file couldn't be opened (that should probably be :c:data:"
"`PyExc_OSError`). If something's wrong with the argument list, the :c:func:"
"`PyArg_ParseTuple` function usually raises :c:data:`PyExc_TypeError`. If "
"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:231
msgid ""
"You can also define a new exception that is unique to your module. The "
"simplest way to do this is to declare a static global object variable at the "
"beginning of the file::"
msgstr ""
"你也可以定義一個你的模組特有的新例外。最簡單的方式是在檔案的開頭宣告一個靜態"
"全域物件變數: ::"
#: ../../extending/extending.rst:235
msgid "static PyObject *SpamError = NULL;"
msgstr "static PyObject *SpamError = NULL;"
#: ../../extending/extending.rst:237
msgid ""
"and initialize it by calling :c:func:`PyErr_NewException` in the module's :c:"
"data:`Py_mod_exec` function (:c:func:`!spam_module_exec`)::"
msgstr ""
"並透過在模組的 :c:data:`Py_mod_exec` 函式(:c:func:`!spam_module_exec`)中呼"
"叫 :c:func:`PyErr_NewException` 來初始化它: ::"
#: ../../extending/extending.rst:240
msgid "SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);"
msgstr "SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);"
#: ../../extending/extending.rst:242
msgid ""
"Since :c:data:`!SpamError` is a global variable, it will be overwritten "
"every time the module is reinitialized, when the :c:data:`Py_mod_exec` "
"function is called."
msgstr ""
"由於 :c:data:`!SpamError` 是一個全域變數,每次模組被重新初始化、即 :c:data:"
"`Py_mod_exec` 函式被呼叫時,它都會被覆寫。"
#: ../../extending/extending.rst:245
msgid ""
"For now, let's avoid the issue: we will block repeated initialization by "
"raising an :py:exc:`ImportError`::"
msgstr ""
"目前,讓我們先避免這個問題:我們會透過引發 :py:exc:`ImportError` 來阻止重複初"
"始化: ::"
#: ../../extending/extending.rst:248
msgid ""
"static PyObject *SpamError = NULL;\n"
"\n"
"static int\n"
"spam_module_exec(PyObject *m)\n"
"{\n"
" if (SpamError != NULL) {\n"
" PyErr_SetString(PyExc_ImportError,\n"
" \"cannot initialize spam module more than once\");\n"
" return -1;\n"
" }\n"
" SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);\n"
" if (PyModule_AddObjectRef(m, \"SpamError\", SpamError) < 0) {\n"
" return -1;\n"
" }\n"
"\n"
" return 0;\n"
"}\n"
"\n"
"static PyModuleDef_Slot spam_module_slots[] = {\n"
" {Py_mod_exec, spam_module_exec},\n"
" {0, NULL}\n"
"};\n"
"\n"
"static struct PyModuleDef spam_module = {\n"
" .m_base = PyModuleDef_HEAD_INIT,\n"
" .m_name = \"spam\",\n"
" .m_size = 0, // non-negative\n"
" .m_slots = spam_module_slots,\n"
"};\n"
"\n"
"PyMODINIT_FUNC\n"
"PyInit_spam(void)\n"
"{\n"
" return PyModuleDef_Init(&spam_module);\n"
"}"
msgstr ""
"static PyObject *SpamError = NULL;\n"
"\n"
"static int\n"
"spam_module_exec(PyObject *m)\n"
"{\n"
" if (SpamError != NULL) {\n"
" PyErr_SetString(PyExc_ImportError,\n"
" \"cannot initialize spam module more than once\");\n"
" return -1;\n"
" }\n"
" SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);\n"
" if (PyModule_AddObjectRef(m, \"SpamError\", SpamError) < 0) {\n"
" return -1;\n"
" }\n"
"\n"
" return 0;\n"
"}\n"
"\n"
"static PyModuleDef_Slot spam_module_slots[] = {\n"
" {Py_mod_exec, spam_module_exec},\n"
" {0, NULL}\n"
"};\n"
"\n"
"static struct PyModuleDef spam_module = {\n"
" .m_base = PyModuleDef_HEAD_INIT,\n"
" .m_name = \"spam\",\n"
" .m_size = 0, // 非負數\n"
" .m_slots = spam_module_slots,\n"
"};\n"
"\n"
"PyMODINIT_FUNC\n"
"PyInit_spam(void)\n"
"{\n"
" return PyModuleDef_Init(&spam_module);\n"
"}"
#: ../../extending/extending.rst:284
msgid ""
"Note that the Python name for the exception object is :exc:`!spam.error`. "
"The :c:func:`PyErr_NewException` function may create a class with the base "
"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:289
msgid ""
"Note also that the :c:data:`!SpamError` variable retains a reference to the "
"newly created exception class; this is intentional! Since the exception "
"could be removed from the module by external code, an owned reference to the "
"class is needed to ensure that it will not be discarded, causing :c:data:`!"
"SpamError` to become a dangling pointer. Should it become a dangling "
"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:296
msgid ""
"For now, the :c:func:`Py_DECREF` call to remove this reference is missing. "
"Even when the Python interpreter shuts down, the global :c:data:`!SpamError` "
"variable will not be garbage-collected. It will \"leak\". We did, however, "
"ensure that this will happen at most once per process."
msgstr ""
"目前,用來移除此參照的 :c:func:`Py_DECREF` 呼叫是缺失的。即使 Python 直譯器關"
"閉時,全域的 :c:data:`!SpamError` 變數也不會被垃圾回收。它會「洩漏」。然而,"
"我們確實有確保這每個行程最多只會發生一次。"
#: ../../extending/extending.rst:301
msgid ""
"We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type "
"later in this sample."
msgstr "我們稍後會討論 :c:macro:`PyMODINIT_FUNC` 作為函式回傳型別的用法。"
#: ../../extending/extending.rst:304
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:307
msgid ""
"static PyObject *\n"
"spam_system(PyObject *self, PyObject *args)\n"
"{\n"
" const char *command;\n"
" int sts;\n"
"\n"
" if (!PyArg_ParseTuple(args, \"s\", &command))\n"
" return NULL;\n"
" sts = system(command);\n"
" if (sts < 0) {\n"
" PyErr_SetString(SpamError, \"System command failed\");\n"
" return NULL;\n"
" }\n"
" return PyLong_FromLong(sts);\n"
"}"
msgstr ""
"static PyObject *\n"
"spam_system(PyObject *self, PyObject *args)\n"
"{\n"
" const char *command;\n"
" int sts;\n"
"\n"
" if (!PyArg_ParseTuple(args, \"s\", &command))\n"
" return NULL;\n"
" sts = system(command);\n"
" if (sts < 0) {\n"
" PyErr_SetString(SpamError, \"System command failed\");\n"
" return NULL;\n"
" }\n"
" return PyLong_FromLong(sts);\n"
"}"
#: ../../extending/extending.rst:327
msgid "Back to the Example"
msgstr "回到範例"
#: ../../extending/extending.rst:329
msgid ""
"Going back to our example function, you should now be able to understand "
"this statement::"
msgstr "回到我們的範例函式,現在你應該可以理解這個陳述式了: ::"
#: ../../extending/extending.rst:332
msgid ""
"if (!PyArg_ParseTuple(args, \"s\", &command))\n"
" return NULL;"
msgstr ""
"if (!PyArg_ParseTuple(args, \"s\", &command))\n"
" return NULL;"
#: ../../extending/extending.rst:335
msgid ""
"It returns ``NULL`` (the error indicator for functions returning object "
"pointers) if an error is detected in the argument list, relying on the "
"exception set by :c:func:`PyArg_ParseTuple`. Otherwise the string value of "
"the argument has been copied to the local variable :c:data:`!command`. This "
"is a pointer assignment and you are not supposed to modify the string to "
"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:343
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:346
msgid "sts = system(command);"
msgstr "sts = system(command);"
#: ../../extending/extending.rst:348
msgid ""
"Our :func:`!spam.system` function must return the value of :c:data:`!sts` as "
"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:351
msgid "return PyLong_FromLong(sts);"
msgstr "return PyLong_FromLong(sts);"
#: ../../extending/extending.rst:353
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:356
msgid ""
"If you have a C function that returns no useful argument (a function "
"returning :c:expr:`void`), the corresponding Python function must return "
"``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:361
msgid ""
"Py_INCREF(Py_None);\n"
"return Py_None;"
msgstr ""
"Py_INCREF(Py_None);\n"
"return Py_None;"
#: ../../extending/extending.rst:364
msgid ""
":c:data:`Py_None` is the C name for the special Python object ``None``. It "
"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:372
msgid "The Module's Method Table and Initialization Function"
msgstr "模組的方法表和初始化函式"
#: ../../extending/extending.rst:374
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:377
msgid ""
"static PyMethodDef spam_methods[] = {\n"
" ...\n"
" {\"system\", spam_system, METH_VARARGS,\n"
" \"Execute a shell command.\"},\n"
" ...\n"
" {NULL, NULL, 0, NULL} /* Sentinel */\n"
"};"
msgstr ""
"static PyMethodDef spam_methods[] = {\n"
" ...\n"
" {\"system\", spam_system, METH_VARARGS,\n"
" \"Execute a shell command.\"},\n"
" ...\n"
" {NULL, NULL, 0, NULL} /* Sentinel */\n"
"};"
#: ../../extending/extending.rst:385
msgid ""
"Note the third entry (``METH_VARARGS``). This is a flag telling the "
"interpreter the calling convention to be used for the C function. It should "
"normally always be ``METH_VARARGS`` or ``METH_VARARGS | METH_KEYWORDS``; a "
"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:390
msgid ""
"When using only ``METH_VARARGS``, the function should expect the Python-"
"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:394
msgid ""
"The :c:macro:`METH_KEYWORDS` bit may be set in the third field if keyword "
"arguments should be passed to the function. In this case, the C function "
"should accept a third ``PyObject *`` parameter which will be a dictionary of "
"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:400
msgid ""
"The method table must be referenced in the module definition structure::"
msgstr "方法表必須在模組定義結構中被參照: ::"
#: ../../extending/extending.rst:402
msgid ""
"static struct PyModuleDef spam_module = {\n"
" ...\n"
" .m_methods = spam_methods,\n"
" ...\n"
"};"
msgstr ""
"static struct PyModuleDef spam_module = {\n"
" ...\n"
" .m_methods = spam_methods,\n"
" ...\n"
"};"
#: ../../extending/extending.rst:408
msgid ""
"This structure, in turn, must be passed to the interpreter in the module's "
"initialization function. The initialization function must be named :c:func:"
"`!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:413
msgid ""
"PyMODINIT_FUNC\n"
"PyInit_spam(void)\n"
"{\n"
" return PyModuleDef_Init(&spam_module);\n"
"}"
msgstr ""
"PyMODINIT_FUNC\n"
"PyInit_spam(void)\n"
"{\n"
" return PyModuleDef_Init(&spam_module);\n"
"}"
#: ../../extending/extending.rst:419
msgid ""
"Note that :c:macro:`PyMODINIT_FUNC` declares the function as ``PyObject *`` "
"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:423
msgid ""
":c:func:`!PyInit_spam` is called when each interpreter imports its module :"
"mod:`!spam` for the first time. (See below for comments about embedding "
"Python.) A pointer to the module definition must be returned via :c:func:"
"`PyModuleDef_Init`, so that the import machinery can create the module and "
"store it in ``sys.modules``."
msgstr ""
"當每個直譯器首次 import 其 :mod:`!spam` 模組時,就會呼叫 :c:func:`!"
"PyInit_spam`。(關於嵌入 Python 的說明請見下方。)必須透過 :c:func:"
"`PyModuleDef_Init` 回傳一個指向模組定義的指標,好讓 import 機制可以建立模組並"
"將其儲存在 ``sys.modules`` 中。"
#: ../../extending/extending.rst:428
msgid ""
"When embedding Python, the :c:func:`!PyInit_spam` function is not called "
"automatically unless there's an entry in the :c:data:`PyImport_Inittab` "
"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:433
msgid ""
"#define PY_SSIZE_T_CLEAN\n"
"#include <Python.h>\n"
"\n"
"int\n"
"main(int argc, char *argv[])\n"
"{\n"
" PyStatus status;\n"
" PyConfig config;\n"
" PyConfig_InitPythonConfig(&config);\n"
"\n"
" /* Add a built-in module, before 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"
" /* Pass argv[0] to the Python interpreter */\n"
" status = PyConfig_SetBytesString(&config, &config.program_name, "
"argv[0]);\n"
" if (PyStatus_Exception(status)) {\n"
" goto exception;\n"
" }\n"
"\n"
" /* Initialize the Python interpreter. Required.\n"
" If this step fails, it will be a fatal error. */\n"
" status = Py_InitializeFromConfig(&config);\n"
" if (PyStatus_Exception(status)) {\n"
" goto exception;\n"
" }\n"
" PyConfig_Clear(&config);\n"
"\n"
" /* Optionally import the module; alternatively,\n"
" import can be deferred until the embedded script\n"
" imports it. */\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"
" // ... use Python C API here ...\n"
"\n"
" return 0;\n"
"\n"
" exception:\n"
" PyConfig_Clear(&config);\n"
" Py_ExitStatusException(status);\n"
"}"
msgstr ""
"#define PY_SSIZE_T_CLEAN\n"
"#include <Python.h>\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"