@@ -424,7 +424,7 @@ msgstr ""
424
424
msgid ""
425
425
"For now, let's avoid the issue: we will block repeated initialization by "
426
426
"raising an :py:exc:`ImportError`::"
427
- msgstr "对于现在,让我们来避免这个问题 :我们将通过引发 :py:exc:`ImportError` 来阻止重复的初始化::"
427
+ msgstr "在目前,让我们避免这个问题 :我们将通过引发 :py:exc:`ImportError` 来阻止重复的初始化::"
428
428
429
429
#: ../../extending/extending.rst:223
430
430
msgid ""
@@ -532,6 +532,8 @@ msgid ""
532
532
" variable will not be garbage-collected. It will \" leak\" . We did, however, "
533
533
"ensure that this will happen at most once per process."
534
534
msgstr ""
535
+ "在目前,用于移除该引用的 :c:func:`Py_DECREF` 调用是缺失的。 即使是在 Python 解释器关闭时,全局变量 "
536
+ ":c:data:`!SpamError` 也不会被当作垃圾回收。 它将会“泄漏”。 不过,我们确实能保证这在每个进程中最多发生一次。"
535
537
536
538
#: ../../extending/extending.rst:276
537
539
msgid ""
@@ -692,6 +694,13 @@ msgid ""
692
694
" {NULL, NULL, 0, NULL} /* Sentinel */\n"
693
695
"};"
694
696
msgstr ""
697
+ "static PyMethodDef spam_methods[] = {\n"
698
+ " ...\n"
699
+ " {\" system\" , spam_system, METH_VARARGS,\n"
700
+ " \" Execute a shell command.\" },\n"
701
+ " ...\n"
702
+ " {NULL, NULL, 0, NULL} /* Sentinel */\n"
703
+ "};"
695
704
696
705
#: ../../extending/extending.rst:360
697
706
msgid ""
@@ -740,6 +749,11 @@ msgid ""
740
749
" ...\n"
741
750
"};"
742
751
msgstr ""
752
+ "static struct PyModuleDef spam_module = {\n"
753
+ " ...\n"
754
+ " .m_methods = spam_methods,\n"
755
+ " ...\n"
756
+ "};"
743
757
744
758
#: ../../extending/extending.rst:383
745
759
msgid ""
@@ -759,6 +773,11 @@ msgid ""
759
773
" return PyModuleDef_Init(&spam_module);\n"
760
774
"}"
761
775
msgstr ""
776
+ "PyMODINIT_FUNC\n"
777
+ "PyInit_spam(void)\n"
778
+ "{\n"
779
+ " return PyModuleDef_Init(&spam_module);\n"
780
+ "}"
762
781
763
782
#: ../../extending/extending.rst:394
764
783
msgid ""
@@ -777,6 +796,9 @@ msgid ""
777
796
":c:func:`PyModuleDef_Init`, so that the import machinery can create the "
778
797
"module and store it in ``sys.modules``."
779
798
msgstr ""
799
+ ":c:func:`!PyInit_spam` 会在每个解释器首次导入其 :mod:`!spam` 模块时被调用。 (请参看下文中有关嵌入式 Python"
800
+ " 的说明。) 必须通过 :c:func:`PyModuleDef_Init` 返回一个指向模块定义的指针,以便导入机制能够创建该模块并将其保存到 "
801
+ "``sys.modules`` 中。"
780
802
781
803
#: ../../extending/extending.rst:403
782
804
msgid ""
@@ -899,13 +921,20 @@ msgid ""
899
921
"marking the module as having no support for subinterpreters (via "
900
922
":c:macro:`Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED`)."
901
923
msgstr ""
924
+ "如果你声明一个全局变量或局部静态变量,模块可能在重新初始化时出现预料之外的附带影响,例如在从 ``sys.modules`` "
925
+ "中移除条目或将已编译的模块导入到一个进程中的多个解释器(或者在未干预 :c:func:`exec` 的情况下执行 :c:func:`fork` "
926
+ "之后)的时候。 如果模块状态没有被完全 :ref:`隔离<isolating-extensions-"
927
+ "howto>`,开发者应当考虑将模块标记为不支持子解释器 (通过 "
928
+ ":c:macro:`Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED`)。"
902
929
903
930
#: ../../extending/extending.rst:467
904
931
msgid ""
905
932
"A more substantial example module is included in the Python source "
906
933
"distribution as :file:`Modules/xxlimited.c`. This file may be used as a "
907
934
"template or simply read as an example."
908
935
msgstr ""
936
+ "在 Python 源代码发布包的 :file:`Modules/xxlimited.c` 中包括了一个更详细的示例。 "
937
+ "此文件可被用作代码模板或是学习样例。"
909
938
910
939
#: ../../extending/extending.rst:475
911
940
msgid "Compilation and Linkage"
@@ -1489,6 +1518,52 @@ msgid ""
1489
1518
" return PyModuleDef_Init(&keywdarg_module);\n"
1490
1519
"}"
1491
1520
msgstr ""
1521
+ "#define PY_SSIZE_T_CLEAN\n"
1522
+ "#include <Python.h>\n"
1523
+ "\n"
1524
+ "static PyObject *\n"
1525
+ "keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)\n"
1526
+ "{\n"
1527
+ "int voltage;\n"
1528
+ "const char *state = \" a stiff\" ;\n"
1529
+ "const char *action = \" voom\" ;\n"
1530
+ "const char *type = \" Norwegian Blue\" ;\n"
1531
+ "\n"
1532
+ "static char *kwlist[] = {\" voltage\" , \" state\" , \" action\" , \" type\" , NULL};\n"
1533
+ "\n"
1534
+ "if (!PyArg_ParseTupleAndKeywords(args, keywds, \" i|sss\" , kwlist,\n"
1535
+ "&voltage, &state, &action, &type))\n"
1536
+ "return NULL;\n"
1537
+ "\n"
1538
+ "printf(\" -- This parrot wouldn't %s if you put %i Volts through it.\\ n\" ,\n"
1539
+ "action, voltage);\n"
1540
+ "printf(\" -- Lovely plumage, the %s -- It's %s!\\ n\" , type, state);\n"
1541
+ "\n"
1542
+ "Py_RETURN_NONE;\n"
1543
+ "}\n"
1544
+ "\n"
1545
+ "static PyMethodDef keywdarg_methods[] = {\n"
1546
+ "/* 函数的转换是必要的因为 PyCFunction 值\n"
1547
+ "* 仅接受两个 PyObject* 形参,而 keywdarg_parrot()\n"
1548
+ "* 接受三个。\n"
1549
+ "*/\n"
1550
+ "{\" parrot\" , (PyCFunction)(void(*)(void))keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,\n"
1551
+ "\" Print a lovely skit to standard output.\" },\n"
1552
+ "{NULL, NULL, 0, NULL} /* sentinel */\n"
1553
+ "};\n"
1554
+ "\n"
1555
+ "static struct PyModuleDef keywdarg_module = {\n"
1556
+ ".m_base = PyModuleDef_HEAD_INIT,\n"
1557
+ ".m_name = \" keywdarg\" ,\n"
1558
+ ".m_size = 0,\n"
1559
+ ".m_methods = keywdarg_methods,\n"
1560
+ "};\n"
1561
+ "\n"
1562
+ "PyMODINIT_FUNC\n"
1563
+ "PyInit_keywdarg(void)\n"
1564
+ "{\n"
1565
+ "return PyModuleDef_Init(&keywdarg_module);\n"
1566
+ "}"
1492
1567
1493
1568
#: ../../extending/extending.rst:828
1494
1569
msgid "Building Arbitrary Values"
@@ -1964,6 +2039,11 @@ msgid ""
1964
2039
"complete. Obviously, the following function has the same problem as the "
1965
2040
"previous one::"
1966
2041
msgstr ""
2042
+ "有关借入引用的问题的第二种情况是涉及线程的变种。 通常, Python 解释器中的多个线程不会相互影响,因为有一个 :term:`全局锁 <global"
2043
+ " interpreter lock>` 在保护 Python 的整个对象空间。 不过,有可能使用宏 "
2044
+ ":c:macro:`Py_BEGIN_ALLOW_THREADS` 来临时释放这个锁,并使用 "
2045
+ ":c:macro:`Py_END_ALLOW_THREADS` 来重新获取它。 这在阻塞型 I/O 调用操作中很常见,可以让其他线程在等待 I/O "
2046
+ "结束期间使用处理器。 显然,下面的函数与之前那个存在相同的问题::"
1967
2047
1968
2048
#: ../../extending/extending.rst:1100
1969
2049
msgid ""
@@ -2286,6 +2366,8 @@ msgid ""
2286
2366
":c:data:`mod_exec <Py_mod_exec>` function must take care of initializing the"
2287
2367
" C API pointer array::"
2288
2368
msgstr ""
2369
+ "``#define`` 被用来告知头文件它被包括在导出的模块中,而不是客户端模块。 最终,模块的 :c:data:`mod_exec "
2370
+ "<Py_mod_exec>` 函数必须负责初始化 C API 指针数组::"
2289
2371
2290
2372
#: ../../extending/extending.rst:1283
2291
2373
msgid ""
@@ -2308,6 +2390,24 @@ msgid ""
2308
2390
" return 0;\n"
2309
2391
"}"
2310
2392
msgstr ""
2393
+ "static int\n"
2394
+ "spam_module_exec(PyObject *m)\n"
2395
+ "{\n"
2396
+ " static void *PySpam_API[PySpam_API_pointers];\n"
2397
+ " PyObject *c_api_object;\n"
2398
+ "\n"
2399
+ " /* 初始化 C API 指针数组 */\n"
2400
+ " PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;\n"
2401
+ "\n"
2402
+ " /* 创建包含 API 指针数组地址的 Capsule */\n"
2403
+ " c_api_object = PyCapsule_New((void *)PySpam_API, \" spam._C_API\" , NULL);\n"
2404
+ "\n"
2405
+ " if (PyModule_Add(m, \" _C_API\" , c_api_object) < 0) {\n"
2406
+ " return -1;\n"
2407
+ " }\n"
2408
+ "\n"
2409
+ " return 0;\n"
2410
+ "}"
2311
2411
2312
2412
#: ../../extending/extending.rst:1302
2313
2413
msgid ""
@@ -2426,6 +2526,8 @@ msgid ""
2426
2526
":c:func:`!PySpam_System` is to call the function (or rather macro) "
2427
2527
":c:func:`!import_spam` in its :c:data:`mod_exec <Py_mod_exec>` function::"
2428
2528
msgstr ""
2529
+ "客户端模块要访问函数 :c:func:`!PySpam_System` 所必须做的全部事情就是在其 :c:data:`mod_exec "
2530
+ "<Py_mod_exec>` 函数中调用函数 :c:func:`!import_spam` (更准确地说是宏)::"
2429
2531
2430
2532
#: ../../extending/extending.rst:1360
2431
2533
msgid ""
@@ -2439,6 +2541,15 @@ msgid ""
2439
2541
" return 0;\n"
2440
2542
"}"
2441
2543
msgstr ""
2544
+ "static int\n"
2545
+ "client_module_exec(PyObject *m)\n"
2546
+ "{\n"
2547
+ " if (import_spam() < 0) {\n"
2548
+ " return -1;\n"
2549
+ " }\n"
2550
+ " /* 额外的初始化可在此进行 */\n"
2551
+ " return 0;\n"
2552
+ "}"
2442
2553
2443
2554
#: ../../extending/extending.rst:1370
2444
2555
msgid ""
0 commit comments