# SOME DESCRIPTIVE TITLE. # Copyright (C) 2001-2025, Python Software Foundation # This file is distributed under the same license as the Python package. # FIRST AUTHOR , YEAR. # # Translators: # Rafael Fontenelle , 2025 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Python 3.12\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-07-25 16:03+0000\n" "PO-Revision-Date: 2025-07-18 19:57+0000\n" "Last-Translator: Rafael Fontenelle , 2025\n" "Language-Team: Chinese (China) (https://app.transifex.com/python-doc/teams/5390/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: ../../extending/newtypes.rst:7 msgid "Defining Extension Types: Assorted Topics" msgstr "定义扩展类型:已分类主题" #: ../../extending/newtypes.rst:11 msgid "" "This section aims to give a quick fly-by on the various type methods you can" " implement and what they do." msgstr "本章节目标是提供一个各种你可以实现的类型方法及其功能的简短介绍。" #: ../../extending/newtypes.rst:14 msgid "" "Here is the definition of :c:type:`PyTypeObject`, with some fields only used" " in :ref:`debug builds ` omitted:" msgstr "" "这是 C 类型 :c:type:`PyTypeObject` 的定义,省略了只用于 :ref:`调试构建 ` 的字段:" #: ../../extending/newtypes.rst:17 msgid "" "typedef struct _typeobject {\n" " PyObject_VAR_HEAD\n" " const char *tp_name; /* For printing, in format \".\" */\n" " Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */\n" "\n" " /* Methods to implement standard operations */\n" "\n" " destructor tp_dealloc;\n" " Py_ssize_t tp_vectorcall_offset;\n" " getattrfunc tp_getattr;\n" " setattrfunc tp_setattr;\n" " PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)\n" " or tp_reserved (Python 3) */\n" " reprfunc tp_repr;\n" "\n" " /* Method suites for standard classes */\n" "\n" " PyNumberMethods *tp_as_number;\n" " PySequenceMethods *tp_as_sequence;\n" " PyMappingMethods *tp_as_mapping;\n" "\n" " /* More standard operations (here for binary compatibility) */\n" "\n" " hashfunc tp_hash;\n" " ternaryfunc tp_call;\n" " reprfunc tp_str;\n" " getattrofunc tp_getattro;\n" " setattrofunc tp_setattro;\n" "\n" " /* Functions to access object as input/output buffer */\n" " PyBufferProcs *tp_as_buffer;\n" "\n" " /* Flags to define presence of optional/expanded features */\n" " unsigned long tp_flags;\n" "\n" " const char *tp_doc; /* Documentation string */\n" "\n" " /* Assigned meaning in release 2.0 */\n" " /* call function for all accessible objects */\n" " traverseproc tp_traverse;\n" "\n" " /* delete references to contained objects */\n" " inquiry tp_clear;\n" "\n" " /* Assigned meaning in release 2.1 */\n" " /* rich comparisons */\n" " richcmpfunc tp_richcompare;\n" "\n" " /* weak reference enabler */\n" " Py_ssize_t tp_weaklistoffset;\n" "\n" " /* Iterators */\n" " getiterfunc tp_iter;\n" " iternextfunc tp_iternext;\n" "\n" " /* Attribute descriptor and subclassing stuff */\n" " struct PyMethodDef *tp_methods;\n" " struct PyMemberDef *tp_members;\n" " struct PyGetSetDef *tp_getset;\n" " // Strong reference on a heap type, borrowed reference on a static type\n" " struct _typeobject *tp_base;\n" " PyObject *tp_dict;\n" " descrgetfunc tp_descr_get;\n" " descrsetfunc tp_descr_set;\n" " Py_ssize_t tp_dictoffset;\n" " initproc tp_init;\n" " allocfunc tp_alloc;\n" " newfunc tp_new;\n" " freefunc tp_free; /* Low-level free-memory routine */\n" " inquiry tp_is_gc; /* For PyObject_IS_GC */\n" " PyObject *tp_bases;\n" " PyObject *tp_mro; /* method resolution order */\n" " PyObject *tp_cache;\n" " PyObject *tp_subclasses;\n" " PyObject *tp_weaklist;\n" " destructor tp_del;\n" "\n" " /* Type attribute cache version tag. Added in version 2.6 */\n" " unsigned int tp_version_tag;\n" "\n" " destructor tp_finalize;\n" " vectorcallfunc tp_vectorcall;\n" "\n" " /* bitset of which type-watchers care about this type */\n" " unsigned char tp_watched;\n" "} PyTypeObject;\n" msgstr "" "typedef struct _typeobject {\n" " PyObject_VAR_HEAD\n" " const char *tp_name; /* 用于打印,格式为 \".\" */\n" " Py_ssize_t tp_basicsize, tp_itemsize; /* 用于分配 */\n" "\n" " /* 用于实现标准操作的方法 */\n" "\n" " destructor tp_dealloc;\n" " Py_ssize_t tp_vectorcall_offset;\n" " getattrfunc tp_getattr;\n" " setattrfunc tp_setattr;\n" " PyAsyncMethods *tp_as_async; /* 原名为 tp_compare (Python 2)\n" " 或 tp_reserved (Python 3) */\n" " reprfunc tp_repr;\n" "\n" " /* 用于标准类的方法集 */\n" "\n" " PyNumberMethods *tp_as_number;\n" " PySequenceMethods *tp_as_sequence;\n" " PyMappingMethods *tp_as_mapping;\n" "\n" " /* 更多标准操作(这些用于二进制兼容) */\n" "\n" " hashfunc tp_hash;\n" " ternaryfunc tp_call;\n" " reprfunc tp_str;\n" " getattrofunc tp_getattro;\n" " setattrofunc tp_setattro;\n" "\n" " /* 用于以输入/输出缓冲区方式访问对象的函数 */\n" " PyBufferProcs *tp_as_buffer;\n" "\n" " /* 用于定义可选/扩展特性是否存在的旗标 */\n" " unsigned long tp_flags;\n" "\n" " const char *tp_doc; /* 文档字符串 */\n" "\n" " /* 在 2.0 发布版中分配的含义 */\n" " /* 为所有可访问的对象调用函数 */\n" " traverseproc tp_traverse;\n" "\n" " /* 删除对所包含对象的引用 */\n" " inquiry tp_clear;\n" "\n" " /* 在 2.1 发布版中分配的含义 */\n" " /* 富比较操作 */\n" " richcmpfunc tp_richcompare;\n" "\n" " /* 弱引用的启用 */\n" " Py_ssize_t tp_weaklistoffset;\n" "\n" " /* 迭代器 */\n" " getiterfunc tp_iter;\n" " iternextfunc tp_iternext;\n" "\n" " /* 属性描述器和子类化内容 */\n" " struct PyMethodDef *tp_methods;\n" " struct PyMemberDef *tp_members;\n" " struct PyGetSetDef *tp_getset;\n" " // 堆类型的强引用,静态类型的借入引用\n" " struct _typeobject *tp_base;\n" " PyObject *tp_dict;\n" " descrgetfunc tp_descr_get;\n" " descrsetfunc tp_descr_set;\n" " Py_ssize_t tp_dictoffset;\n" " initproc tp_init;\n" " allocfunc tp_alloc;\n" " newfunc tp_new;\n" " freefunc tp_free; /* 低层级的释放内存例程 */\n" " inquiry tp_is_gc; /* For PyObject_IS_GC */\n" " PyObject *tp_bases;\n" " PyObject *tp_mro; /* 方法解析顺序 */\n" " PyObject *tp_cache;\n" " PyObject *tp_subclasses;\n" " PyObject *tp_weaklist;\n" " destructor tp_del;\n" "\n" " /* 类型属性缓存版本标签。 在 2.6 版中添加 */\n" " unsigned int tp_version_tag;\n" "\n" " destructor tp_finalize;\n" " vectorcallfunc tp_vectorcall;\n" "\n" " /* 类型监视器针对此类型的位设置 */\n" " unsigned char tp_watched;\n" "} PyTypeObject;\n" #: ../../extending/newtypes.rst:20 msgid "" "Now that's a *lot* of methods. Don't worry too much though -- if you have a" " type you want to define, the chances are very good that you will only " "implement a handful of these." msgstr "这里有 *很多* 方法。但是不要太担心,如果你要定义一个类型,通常只需要实现少量的方法。" #: ../../extending/newtypes.rst:24 msgid "" "As you probably expect by now, we're going to go over this and give more " "information about the various handlers. We won't go in the order they are " "defined in the structure, because there is a lot of historical baggage that " "impacts the ordering of the fields. It's often easiest to find an example " "that includes the fields you need and then change the values to suit your " "new type. ::" msgstr "" "正如你猜到的一样,我们正要一步一步详细介绍各种处理程序。因为有大量的历史包袱影响字段的排序,所以我们不会根据它们在结构体里定义的顺序讲解。通常非常容易找到一个包含你需要的字段的例子,然后改变值去适应你新的类型。" #: ../../extending/newtypes.rst:31 msgid "const char *tp_name; /* For printing */" msgstr "const char *tp_name; /* 用于打印 */" #: ../../extending/newtypes.rst:33 msgid "" "The name of the type -- as mentioned in the previous chapter, this will " "appear in various places, almost entirely for diagnostic purposes. Try to " "choose something that will be helpful in such a situation! ::" msgstr "类型的名字 - 上一章提到过的,会出现在很多地方,几乎全部都是为了诊断目的。尝试选择一个好名字,对于诊断很有帮助。" #: ../../extending/newtypes.rst:37 msgid "Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */" msgstr "Py_ssize_t tp_basicsize, tp_itemsize; /* 用于分配 */" #: ../../extending/newtypes.rst:39 msgid "" "These fields tell the runtime how much memory to allocate when new objects " "of this type are created. Python has some built-in support for variable " "length structures (think: strings, tuples) which is where the " ":c:member:`~PyTypeObject.tp_itemsize` field comes in. This will be dealt " "with later. ::" msgstr "" "这些字段告诉运行时在创造这个类型的新对象时需要分配多少内存。Python为了可变长度的结构(想下:字符串,元组)有些内置支持,这是 " ":c:member:`~PyTypeObject.tp_itemsize` 字段存在的原由。这部分稍后解释。" #: ../../extending/newtypes.rst:44 msgid "const char *tp_doc;" msgstr "const char *tp_doc;" #: ../../extending/newtypes.rst:46 msgid "" "Here you can put a string (or its address) that you want returned when the " "Python script references ``obj.__doc__`` to retrieve the doc string." msgstr "这里你可以放置一段字符串(或者它的地址),当你想在Python脚本引用 ``obj.__doc__`` 时返回这段文档字符串。" #: ../../extending/newtypes.rst:49 msgid "" "Now we come to the basic type methods -- the ones most extension types will " "implement." msgstr "现在我们来看一下基本类型方法 - 大多数扩展类型将实现的方法。" #: ../../extending/newtypes.rst:54 msgid "Finalization and De-allocation" msgstr "终结和内存释放" #: ../../extending/newtypes.rst:64 msgid "destructor tp_dealloc;" msgstr "destructor tp_dealloc;" #: ../../extending/newtypes.rst:66 msgid "" "This function is called when the reference count of the instance of your " "type is reduced to zero and the Python interpreter wants to reclaim it. If " "your type has memory to free or other clean-up to perform, you can put it " "here. The object itself needs to be freed here as well. Here is an example" " of this function::" msgstr "" "当您的类型实例的引用计数减少为零并且Python解释器想要回收它时,将调用此函数。如果你的类型有内存可供释放或执行其他清理,你可以把它放在这里。 " "对象本身也需要在这里释放。 以下是此函数的示例:" #: ../../extending/newtypes.rst:72 msgid "" "static void\n" "newdatatype_dealloc(newdatatypeobject *obj)\n" "{\n" " free(obj->obj_UnderlyingDatatypePtr);\n" " Py_TYPE(obj)->tp_free((PyObject *)obj);\n" "}" msgstr "" "static void\n" "newdatatype_dealloc(newdatatypeobject *obj)\n" "{\n" " free(obj->obj_UnderlyingDatatypePtr);\n" " Py_TYPE(obj)->tp_free((PyObject *)obj);\n" "}" #: ../../extending/newtypes.rst:79 msgid "" "If your type supports garbage collection, the destructor should call " ":c:func:`PyObject_GC_UnTrack` before clearing any member fields::" msgstr "如果你的类型支持垃圾回收,则析构器应当在清理任何成员字段之前调用 :c:func:`PyObject_GC_UnTrack`::" #: ../../extending/newtypes.rst:82 msgid "" "static void\n" "newdatatype_dealloc(newdatatypeobject *obj)\n" "{\n" " PyObject_GC_UnTrack(obj);\n" " Py_CLEAR(obj->other_obj);\n" " ...\n" " Py_TYPE(obj)->tp_free((PyObject *)obj);\n" "}" msgstr "" "static void\n" "newdatatype_dealloc(newdatatypeobject *obj)\n" "{\n" " PyObject_GC_UnTrack(obj);\n" " Py_CLEAR(obj->other_obj);\n" " ...\n" " Py_TYPE(obj)->tp_free((PyObject *)obj);\n" "}" #: ../../extending/newtypes.rst:95 msgid "" "One important requirement of the deallocator function is that it leaves any " "pending exceptions alone. This is important since deallocators are " "frequently called as the interpreter unwinds the Python stack; when the " "stack is unwound due to an exception (rather than normal returns), nothing " "is done to protect the deallocators from seeing that an exception has " "already been set. Any actions which a deallocator performs which may cause " "additional Python code to be executed may detect that an exception has been " "set. This can lead to misleading errors from the interpreter. The proper " "way to protect against this is to save a pending exception before performing" " the unsafe action, and restoring it when done. This can be done using the " ":c:func:`PyErr_Fetch` and :c:func:`PyErr_Restore` functions::" msgstr "" "一个重要的释放器函数实现要求是把所有未决异常放着不动。这很重要是因为释放器会被解释器频繁的调用,当栈异常退出时(而非正常返回),不会有任何办法保护释放器看到一个异常尚未被设置。此事释放器的任何行为都会导致额外增加的Python代码来检查异常是否被设置。这可能导致解释器的误导性错误。正确的保护方法是,在任何不安全的操作前,保存未决异常,然后在其完成后恢复。者可以通过" " :c:func:`PyErr_Fetch` 和 :c:func:`PyErr_Restore` 函数来实现::" #: ../../extending/newtypes.rst:107 msgid "" "static void\n" "my_dealloc(PyObject *obj)\n" "{\n" " MyObject *self = (MyObject *) obj;\n" " PyObject *cbresult;\n" "\n" " if (self->my_callback != NULL) {\n" " PyObject *err_type, *err_value, *err_traceback;\n" "\n" " /* This saves the current exception state */\n" " PyErr_Fetch(&err_type, &err_value, &err_traceback);\n" "\n" " cbresult = PyObject_CallNoArgs(self->my_callback);\n" " if (cbresult == NULL)\n" " PyErr_WriteUnraisable(self->my_callback);\n" " else\n" " Py_DECREF(cbresult);\n" "\n" " /* This restores the saved exception state */\n" " PyErr_Restore(err_type, err_value, err_traceback);\n" "\n" " Py_DECREF(self->my_callback);\n" " }\n" " Py_TYPE(obj)->tp_free((PyObject*)self);\n" "}" msgstr "" "static void\n" "my_dealloc(PyObject *obj)\n" "{\n" " MyObject *self = (MyObject *) obj;\n" " PyObject *cbresult;\n" "\n" " if (self->my_callback != NULL) {\n" " PyObject *err_type, *err_value, *err_traceback;\n" "\n" " /* 这里保存当前异常状态 */\n" " PyErr_Fetch(&err_type, &err_value, &err_traceback);\n" "\n" " cbresult = PyObject_CallNoArgs(self->my_callback);\n" " if (cbresult == NULL)\n" " PyErr_WriteUnraisable(self->my_callback);\n" " else\n" " Py_DECREF(cbresult);\n" "\n" " /* 这里恢复被保存的异常状态 */\n" " PyErr_Restore(err_type, err_value, err_traceback);\n" "\n" " Py_DECREF(self->my_callback);\n" " }\n" " Py_TYPE(obj)->tp_free((PyObject*)self);\n" "}" #: ../../extending/newtypes.rst:134 msgid "" "There are limitations to what you can safely do in a deallocator function. " "First, if your type supports garbage collection (using " ":c:member:`~PyTypeObject.tp_traverse` and/or " ":c:member:`~PyTypeObject.tp_clear`), some of the object's members can have " "been cleared or finalized by the time :c:member:`~PyTypeObject.tp_dealloc` " "is called. Second, in :c:member:`~PyTypeObject.tp_dealloc`, your object is " "in an unstable state: its reference count is equal to zero. Any call to a " "non-trivial object or API (as in the example above) might end up calling " ":c:member:`~PyTypeObject.tp_dealloc` again, causing a double free and a " "crash." msgstr "" "你能在释放器函数中安全执行的操作是有限的。 首先,如果你的类型支持垃圾回收 (使用 " ":c:member:`~PyTypeObject.tp_traverse` 和/或 " ":c:member:`~PyTypeObject.tp_clear`),对象的部分成员可以在调用 " ":c:member:`~PyTypeObject.tp_dealloc` 时被清空或终结。 其次,在 " ":c:member:`~PyTypeObject.tp_dealloc` 中,你的对象将处于不稳定状态:它的引用计数等于零。 任何对非琐碎对象或 API" " 的调用 (如上面的示例所做的) 最终都可能会再次调用 " ":c:member:`~PyTypeObject.tp_dealloc`,导致双重释放并发生崩溃。" #: ../../extending/newtypes.rst:143 msgid "" "Starting with Python 3.4, it is recommended not to put any complex " "finalization code in :c:member:`~PyTypeObject.tp_dealloc`, and instead use " "the new :c:member:`~PyTypeObject.tp_finalize` type method." msgstr "" "从 Python 3.4 开始,推荐不要在 :c:member:`~PyTypeObject.tp_dealloc` 放复杂的终结代码,而是使用新的 " ":c:member:`~PyTypeObject.tp_finalize` 类型方法。" #: ../../extending/newtypes.rst:148 msgid ":pep:`442` explains the new finalization scheme." msgstr ":pep:`442` 解释了新的终结方案。" #: ../../extending/newtypes.rst:155 msgid "Object Presentation" msgstr "对象展示" #: ../../extending/newtypes.rst:157 msgid "" "In Python, there are two ways to generate a textual representation of an " "object: the :func:`repr` function, and the :func:`str` function. (The " ":func:`print` function just calls :func:`str`.) These handlers are both " "optional." msgstr "" "在 Python 中,有两种方式可以生成对象的文本表示: :func:`repr` 函数和 :func:`str` 函数。 (:func:`print`" " 函数会直接调用 :func:`str`。) 这些处理程序都是可选的。" #: ../../extending/newtypes.rst:163 msgid "" "reprfunc tp_repr;\n" "reprfunc tp_str;" msgstr "" "reprfunc tp_repr;\n" "reprfunc tp_str;" #: ../../extending/newtypes.rst:166 msgid "" "The :c:member:`~PyTypeObject.tp_repr` handler should return a string object " "containing a representation of the instance for which it is called. Here is" " a simple example::" msgstr "" ":c:member:`~PyTypeObject.tp_repr` 处理程序应该返回一个字符串对象,其中包含调用它的实例的表示形式。 " "下面是一个简单的例子::" #: ../../extending/newtypes.rst:170 msgid "" "static PyObject *\n" "newdatatype_repr(newdatatypeobject *obj)\n" "{\n" " return PyUnicode_FromFormat(\"Repr-ified_newdatatype{{size:%d}}\",\n" " obj->obj_UnderlyingDatatypePtr->size);\n" "}" msgstr "" "static PyObject *\n" "newdatatype_repr(newdatatypeobject *obj)\n" "{\n" " return PyUnicode_FromFormat(\"Repr-ified_newdatatype{{size:%d}}\",\n" " obj->obj_UnderlyingDatatypePtr->size);\n" "}" #: ../../extending/newtypes.rst:177 msgid "" "If no :c:member:`~PyTypeObject.tp_repr` handler is specified, the " "interpreter will supply a representation that uses the type's " ":c:member:`~PyTypeObject.tp_name` and a uniquely identifying value for the " "object." msgstr "" "如果没有指定 :c:member:`~PyTypeObject.tp_repr` 处理器,解释器将提供一个使用类型的 " ":c:member:`~PyTypeObject.tp_name` 的表示形式以及对象的唯一标识值。" #: ../../extending/newtypes.rst:181 msgid "" "The :c:member:`~PyTypeObject.tp_str` handler is to :func:`str` what the " ":c:member:`~PyTypeObject.tp_repr` handler described above is to " ":func:`repr`; that is, it is called when Python code calls :func:`str` on an" " instance of your object. Its implementation is very similar to the " ":c:member:`~PyTypeObject.tp_repr` function, but the resulting string is " "intended for human consumption. If :c:member:`~PyTypeObject.tp_str` is not " "specified, the :c:member:`~PyTypeObject.tp_repr` handler is used instead." msgstr "" ":c:member:`~PyTypeObject.tp_str` 处理器对于 :func:`str` 就如上述的 " ":c:member:`~PyTypeObject.tp_repr` 处理器对于 :func:`repr` 一样;也就是说,它会在当 Python " "代码在你的对象的某个实例上调用 :func:`str` 时被调用。 它的实现与 :c:member:`~PyTypeObject.tp_repr` " "函数非常相似,但其结果字符串是供人类查看的。 如果未指定 :c:member:`~PyTypeObject.tp_str`,则会使用 " ":c:member:`~PyTypeObject.tp_repr` 处理器来代替。" #: ../../extending/newtypes.rst:188 msgid "Here is a simple example::" msgstr "下面是一个简单的例子::" #: ../../extending/newtypes.rst:190 msgid "" "static PyObject *\n" "newdatatype_str(newdatatypeobject *obj)\n" "{\n" " return PyUnicode_FromFormat(\"Stringified_newdatatype{{size:%d}}\",\n" " obj->obj_UnderlyingDatatypePtr->size);\n" "}" msgstr "" "static PyObject *\n" "newdatatype_str(newdatatypeobject *obj)\n" "{\n" " return PyUnicode_FromFormat(\"Stringified_newdatatype{{size:%d}}\",\n" " obj->obj_UnderlyingDatatypePtr->size);\n" "}" #: ../../extending/newtypes.rst:200 msgid "Attribute Management" msgstr "属性管理" #: ../../extending/newtypes.rst:202 msgid "" "For every object which can support attributes, the corresponding type must " "provide the functions that control how the attributes are resolved. There " "needs to be a function which can retrieve attributes (if any are defined), " "and another to set attributes (if setting attributes is allowed). Removing " "an attribute is a special case, for which the new value passed to the " "handler is ``NULL``." msgstr "" "对于每个可支持属性操作的对象,相应的类型必须提供用于控制属性获取方式的函数。 " "需要有一个能够检索属性的函数(如果定义了任何属性)还要有另一个函数负责设置属性(如果允许设置属性)。 " "移除属性是一种特殊情况,在此情况下要传给处理器的新值为 ``NULL``。" #: ../../extending/newtypes.rst:208 msgid "" "Python supports two pairs of attribute handlers; a type that supports " "attributes only needs to implement the functions for one pair. The " "difference is that one pair takes the name of the attribute as a " ":c:expr:`char\\*`, while the other accepts a :c:expr:`PyObject*`. Each type" " can use whichever pair makes more sense for the implementation's " "convenience. ::" msgstr "" "Python 支持两对属性处理器;一个支持属性操作的类型只需要实现其中一对的函数。 两者的差别在于一对接受 :c:expr:`char\\*` " "作为属性名称,而另一对则接受 :c:expr:`PyObject*`。 每种类型都可以选择使用对于实现的便利性来说更有意义的那一对。 ::" #: ../../extending/newtypes.rst:214 msgid "" "getattrfunc tp_getattr; /* char * version */\n" "setattrfunc tp_setattr;\n" "/* ... */\n" "getattrofunc tp_getattro; /* PyObject * version */\n" "setattrofunc tp_setattro;" msgstr "" "getattrfunc tp_getattr; /* char * 版本 */\n" "setattrfunc tp_setattr;\n" "/* ... */\n" "getattrofunc tp_getattro; /* PyObject * 版本 */\n" "setattrofunc tp_setattro;" #: ../../extending/newtypes.rst:220 msgid "" "If accessing attributes of an object is always a simple operation (this will" " be explained shortly), there are generic implementations which can be used " "to provide the :c:expr:`PyObject*` version of the attribute management " "functions. The actual need for type-specific attribute handlers almost " "completely disappeared starting with Python 2.2, though there are many " "examples which have not been updated to use some of the new generic " "mechanism that is available." msgstr "" "如果访问一个对象的属性总是为简单操作(这将在下文进行解释),则有一些泛用实现可被用来提供 :c:expr:`PyObject*` 版本的属性管理函数。 " "从 Python 2.2 开始对于类型专属的属性处理器的实际需要几乎已完全消失,尽管还存在着许多尚未理新为使用某种新的可选泛用机制的例子。" #: ../../extending/newtypes.rst:231 msgid "Generic Attribute Management" msgstr "泛型属性管理" #: ../../extending/newtypes.rst:233 msgid "" "Most extension types only use *simple* attributes. So, what makes the " "attributes simple? There are only a couple of conditions that must be met:" msgstr "大多数扩展类型只使用 **简单** 属性,那么,是什么让属性变得“简单”呢?只需要满足下面几个条件:" #: ../../extending/newtypes.rst:236 msgid "" "The name of the attributes must be known when :c:func:`PyType_Ready` is " "called." msgstr "当调用 :c:func:`PyType_Ready` 时,必须知道属性的名称。" #: ../../extending/newtypes.rst:239 msgid "" "No special processing is needed to record that an attribute was looked up or" " set, nor do actions need to be taken based on the value." msgstr "不需要特殊的处理来记录属性是否被查找或设置,也不需要根据值采取操作。" #: ../../extending/newtypes.rst:242 msgid "" "Note that this list does not place any restrictions on the values of the " "attributes, when the values are computed, or how relevant data is stored." msgstr "请注意,此列表不对属性的值、值的计算时间或相关数据的存储方式施加任何限制。" #: ../../extending/newtypes.rst:245 msgid "" "When :c:func:`PyType_Ready` is called, it uses three tables referenced by " "the type object to create :term:`descriptor`\\s which are placed in the " "dictionary of the type object. Each descriptor controls access to one " "attribute of the instance object. Each of the tables is optional; if all " "three are ``NULL``, instances of the type will only have attributes that are" " inherited from their base type, and should leave the " ":c:member:`~PyTypeObject.tp_getattro` and " ":c:member:`~PyTypeObject.tp_setattro` fields ``NULL`` as well, allowing the " "base type to handle attributes." msgstr "" "当 :c:func:`PyType_Ready` 被调用时,它会使用由类型对象所引用的三个表来创建要放置到类型对象的字典中的 " ":term:`descriptor`。 每个描述器控制对实例对象的一个属性的访问。 每个表都是可选的;如果三个表全都为 " "``NULL``,则该类型的实例将只有从它们的基础类型继承来的属性,并且还应当让 " ":c:member:`~PyTypeObject.tp_getattro` 和 " ":c:member:`~PyTypeObject.tp_setattro` 字段保持为 ``NULL``,以允许由基础类型处理这些属性。" #: ../../extending/newtypes.rst:253 msgid "The tables are declared as three fields of the type object::" msgstr "表被声明为object::类型的三个字段::" #: ../../extending/newtypes.rst:255 msgid "" "struct PyMethodDef *tp_methods;\n" "struct PyMemberDef *tp_members;\n" "struct PyGetSetDef *tp_getset;" msgstr "" "struct PyMethodDef *tp_methods;\n" "struct PyMemberDef *tp_members;\n" "struct PyGetSetDef *tp_getset;" #: ../../extending/newtypes.rst:259 msgid "" "If :c:member:`~PyTypeObject.tp_methods` is not ``NULL``, it must refer to an" " array of :c:type:`PyMethodDef` structures. Each entry in the table is an " "instance of this structure::" msgstr "" "如果 :c:member:`~PyTypeObject.tp_methods` 不为 ``NULL``,则它必须指向一个由 " ":c:type:`PyMethodDef` 结构体组成的数组。 表中的每个条目都是该结构体的一个实例::" #: ../../extending/newtypes.rst:263 msgid "" "typedef struct PyMethodDef {\n" " const char *ml_name; /* method name */\n" " PyCFunction ml_meth; /* implementation function */\n" " int ml_flags; /* flags */\n" " const char *ml_doc; /* docstring */\n" "} PyMethodDef;" msgstr "" "typedef struct PyMethodDef {\n" " const char *ml_name; /* 方法名称 */\n" " PyCFunction ml_meth; /* 实现函数 */\n" " int ml_flags; /* 旗标 */\n" " const char *ml_doc; /* 文档字符串 */\n" "} PyMethodDef;" #: ../../extending/newtypes.rst:270 msgid "" "One entry should be defined for each method provided by the type; no entries" " are needed for methods inherited from a base type. One additional entry is" " needed at the end; it is a sentinel that marks the end of the array. The " ":c:member:`~PyMethodDef.ml_name` field of the sentinel must be ``NULL``." msgstr "" "应当为该类型所提供的每个方法都应定义一个条目;从基类型继承来的方法无需定义条目。 还需要在末尾加一个额外的条目;它是一个标记数组结束的哨兵条目。 " "该哨兵条目的 :c:member:`~PyMethodDef.ml_name` 字段必须为 ``NULL``。" #: ../../extending/newtypes.rst:275 msgid "" "The second table is used to define attributes which map directly to data " "stored in the instance. A variety of primitive C types are supported, and " "access may be read-only or read-write. The structures in the table are " "defined as::" msgstr "第二个表被用来定义要直接映射到实例中的数据的属性。 各种原始 C 类型均受到支持,并且访问方式可以为只读或读写。 表中的结构体被定义为::" #: ../../extending/newtypes.rst:279 msgid "" "typedef struct PyMemberDef {\n" " const char *name;\n" " int type;\n" " int offset;\n" " int flags;\n" " const char *doc;\n" "} PyMemberDef;" msgstr "" "typedef struct PyMemberDef {\n" " const char *name;\n" " int type;\n" " int offset;\n" " int flags;\n" " const char *doc;\n" "} PyMemberDef;" #: ../../extending/newtypes.rst:287 msgid "" "For each entry in the table, a :term:`descriptor` will be constructed and " "added to the type which will be able to extract a value from the instance " "structure. The :c:member:`~PyMemberDef.type` field should contain a type " "code like :c:macro:`Py_T_INT` or :c:macro:`Py_T_DOUBLE`; the value will be " "used to determine how to convert Python values to and from C values. The " ":c:member:`~PyMemberDef.flags` field is used to store flags which control " "how the attribute can be accessed: you can set it to :c:macro:`Py_READONLY` " "to prevent Python code from setting it." msgstr "" "对于表中的每个条目,都将构建一个 :term:`descriptor` 并添加到类型中使其能够从实例结构体中提取值。 " ":c:member:`~PyMemberDef.type` 字段应包含一个类型代码如 :c:macro:`Py_T_INT` 或 " ":c:macro:`Py_T_DOUBLE`;该值将用于确定如何将 Python 值转换为 C 值或反之。 " ":c:member:`~PyMemberDef.flags` 字段用于保存控制属性要如何被访问的旗标:你可以将其设为 " ":c:macro:`Py_READONLY` 以防止 Python 代码设置它。" #: ../../extending/newtypes.rst:295 msgid "" "An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` " "table to build descriptors that are used at runtime is that any attribute " "defined this way can have an associated doc string simply by providing the " "text in the table. An application can use the introspection API to retrieve" " the descriptor from the class object, and get the doc string using its " ":attr:`~type.__doc__` attribute." msgstr "" "使用 :c:member:`~PyTypeObject.tp_members` " "表来构建用于运行时的描述器还有一个有趣的优点是任何以这种方式定义的属性都可以简单地通过在表中提供文本来设置一个相关联的文档字符串。 " "一个应用程序可以使用自省 API 从类对象获取描述器,并使用其 :attr:`~type.__doc__` 属性来获取文档字符串。" #: ../../extending/newtypes.rst:301 msgid "" "As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry " "with a :c:member:`~PyMethodDef.ml_name` value of ``NULL`` is required." msgstr "" "与 :c:member:`~PyTypeObject.tp_methods` 表一样,需要有一个值为 ``NULL`` 的 " ":c:member:`~PyMethodDef.ml_name` 哨兵条目。" #: ../../extending/newtypes.rst:315 msgid "Type-specific Attribute Management" msgstr "类型专属的属性管理" #: ../../extending/newtypes.rst:317 msgid "" "For simplicity, only the :c:expr:`char\\*` version will be demonstrated " "here; the type of the name parameter is the only difference between the " ":c:expr:`char\\*` and :c:expr:`PyObject*` flavors of the interface. This " "example effectively does the same thing as the generic example above, but " "does not use the generic support added in Python 2.2. It explains how the " "handler functions are called, so that if you do need to extend their " "functionality, you'll understand what needs to be done." msgstr "" "为了简单起见,这里只演示 :c:expr:`char\\*` 版本; name 形参的类型是 :c:expr:`char\\*` 和 " ":c:expr:`PyObject*` 风格接口之间的唯一区别。 这个示例实际上做了与上面的泛用示例相同的事情,但没有使用在 Python 2.2 " "中增加的泛用支持。 它解释了处理器函数是如何被调用的,因此如果你确实需要扩展它们的功能,你就会明白有什么是需要做的。" #: ../../extending/newtypes.rst:325 msgid "" "The :c:member:`~PyTypeObject.tp_getattr` handler is called when the object " "requires an attribute look-up. It is called in the same situations where " "the :meth:`~object.__getattr__` method of a class would be called." msgstr "" ":c:member:`~PyTypeObject.tp_getattr` 处理器会在对象需要进行属性查找时被调用。 它被调用的场合与一个类的 " ":meth:`~object.__getattr__` 方法要被调用的场合相同。" #: ../../extending/newtypes.rst:329 msgid "Here is an example::" msgstr "例如:" #: ../../extending/newtypes.rst:331 msgid "" "static PyObject *\n" "newdatatype_getattr(newdatatypeobject *obj, char *name)\n" "{\n" " if (strcmp(name, \"data\") == 0)\n" " {\n" " return PyLong_FromLong(obj->data);\n" " }\n" "\n" " PyErr_Format(PyExc_AttributeError,\n" " \"'%.100s' object has no attribute '%.400s'\",\n" " Py_TYPE(obj)->tp_name, name);\n" " return NULL;\n" "}" msgstr "" "static PyObject *\n" "newdatatype_getattr(newdatatypeobject *obj, char *name)\n" "{\n" " if (strcmp(name, \"data\") == 0)\n" " {\n" " return PyLong_FromLong(obj->data);\n" " }\n" "\n" " PyErr_Format(PyExc_AttributeError,\n" " \"'%.100s' object has no attribute '%.400s'\",\n" " Py_TYPE(obj)->tp_name, name);\n" " return NULL;\n" "}" #: ../../extending/newtypes.rst:345 msgid "" "The :c:member:`~PyTypeObject.tp_setattr` handler is called when the " ":meth:`~object.__setattr__` or :meth:`~object.__delattr__` method of a class" " instance would be called. When an attribute should be deleted, the third " "parameter will be ``NULL``. Here is an example that simply raises an " "exception; if this were really all you wanted, the " ":c:member:`~PyTypeObject.tp_setattr` handler should be set to ``NULL``. ::" msgstr "" "当调用类实例的 :meth:`~object.__setattr__` 或 :meth:`~object.__delattr__` 方法时会调用 " ":c:member:`~PyTypeObject.tp_setattr` 处理器。 当需要删除一个属性时,第三个形参将为 ``NULL``。 " "下面是一个简单地引发异常的例子;如果这确实是你想要的,则 :c:member:`~PyTypeObject.tp_setattr` 处理器应当被设为 " "``NULL``。 ::" #: ../../extending/newtypes.rst:351 msgid "" "static int\n" "newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)\n" "{\n" " PyErr_Format(PyExc_RuntimeError, \"Read-only attribute: %s\", name);\n" " return -1;\n" "}" msgstr "" "static int\n" "newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)\n" "{\n" " PyErr_Format(PyExc_RuntimeError, \"Read-only attribute: %s\", name);\n" " return -1;\n" "}" #: ../../extending/newtypes.rst:359 msgid "Object Comparison" msgstr "对象比较" #: ../../extending/newtypes.rst:363 msgid "richcmpfunc tp_richcompare;" msgstr "richcmpfunc tp_richcompare;" #: ../../extending/newtypes.rst:365 msgid "" "The :c:member:`~PyTypeObject.tp_richcompare` handler is called when " "comparisons are needed. It is analogous to the :ref:`rich comparison " "methods `, like :meth:`!__lt__`, and also called by " ":c:func:`PyObject_RichCompare` and :c:func:`PyObject_RichCompareBool`." msgstr "" ":c:member:`~PyTypeObject.tp_richcompare` 处理器会在需要进行比较时被调用。 它类似于 :ref:`富比较方法 " "`,例如 :meth:`!__lt__`,并会被 :c:func:`PyObject_RichCompare` 和 " ":c:func:`PyObject_RichCompareBool` 调用。" #: ../../extending/newtypes.rst:370 msgid "" "This function is called with two Python objects and the operator as " "arguments, where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, " "``Py_GE``, ``Py_LT`` or ``Py_GT``. It should compare the two objects with " "respect to the specified operator and return ``Py_True`` or ``Py_False`` if " "the comparison is successful, ``Py_NotImplemented`` to indicate that " "comparison is not implemented and the other object's comparison method " "should be tried, or ``NULL`` if an exception was set." msgstr "" "此函数被调用时将传入两个 Python 对象和运算符作为参数,其中运算符为 ``Py_EQ``, ``Py_NE``, ``Py_LE``, " "``Py_GE``, ``Py_LT`` 或 ``Py_GT`` 之一。 它应当使用指定的运算符来比较两个对象并在比较操作成功时返回 " "``Py_True`` 或 ``Py_False``,如果比较操作未被实现并应尝试其他对象比较方法时则返回 " "``Py_NotImplemented``,或者如果设置了异常则返回 ``NULL``。" #: ../../extending/newtypes.rst:378 msgid "" "Here is a sample implementation, for a datatype that is considered equal if " "the size of an internal pointer is equal::" msgstr "下面是一个示例实现,该数据类型如果内部指针的大小相等就认为是相等的::" #: ../../extending/newtypes.rst:381 msgid "" "static PyObject *\n" "newdatatype_richcmp(newdatatypeobject *obj1, newdatatypeobject *obj2, int op)\n" "{\n" " PyObject *result;\n" " int c, size1, size2;\n" "\n" " /* code to make sure that both arguments are of type\n" " newdatatype omitted */\n" "\n" " size1 = obj1->obj_UnderlyingDatatypePtr->size;\n" " size2 = obj2->obj_UnderlyingDatatypePtr->size;\n" "\n" " switch (op) {\n" " case Py_LT: c = size1 < size2; break;\n" " case Py_LE: c = size1 <= size2; break;\n" " case Py_EQ: c = size1 == size2; break;\n" " case Py_NE: c = size1 != size2; break;\n" " case Py_GT: c = size1 > size2; break;\n" " case Py_GE: c = size1 >= size2; break;\n" " }\n" " result = c ? Py_True : Py_False;\n" " Py_INCREF(result);\n" " return result;\n" " }" msgstr "" "static PyObject *\n" "newdatatype_richcmp(newdatatypeobject *obj1, newdatatypeobject *obj2, int op)\n" "{\n" " PyObject *result;\n" " int c, size1, size2;\n" "\n" " /* 省略了确保两个参数均为 newdatatype 类型的代码 */\n" "\n" " size1 = obj1->obj_UnderlyingDatatypePtr->size;\n" " size2 = obj2->obj_UnderlyingDatatypePtr->size;\n" "\n" " switch (op) {\n" " case Py_LT: c = size1 < size2; break;\n" " case Py_LE: c = size1 <= size2; break;\n" " case Py_EQ: c = size1 == size2; break;\n" " case Py_NE: c = size1 != size2; break;\n" " case Py_GT: c = size1 > size2; break;\n" " case Py_GE: c = size1 >= size2; break;\n" " }\n" " result = c ? Py_True : Py_False;\n" " Py_INCREF(result);\n" " return result;\n" " }" #: ../../extending/newtypes.rst:408 msgid "Abstract Protocol Support" msgstr "抽象协议支持" #: ../../extending/newtypes.rst:410 msgid "" "Python supports a variety of *abstract* 'protocols;' the specific interfaces" " provided to use these interfaces are documented in :ref:`abstract`." msgstr "Python 支持多种 *抽象* '协议';被提供来使用这些接口的专门接口说明请在 :ref:`abstract` 中查看。" #: ../../extending/newtypes.rst:414 msgid "" "A number of these abstract interfaces were defined early in the development " "of the Python implementation. In particular, the number, mapping, and " "sequence protocols have been part of Python since the beginning. Other " "protocols have been added over time. For protocols which depend on several " "handler routines from the type implementation, the older protocols have been" " defined as optional blocks of handlers referenced by the type object. For " "newer protocols there are additional slots in the main type object, with a " "flag bit being set to indicate that the slots are present and should be " "checked by the interpreter. (The flag bit does not indicate that the slot " "values are non-``NULL``. The flag may be set to indicate the presence of a " "slot, but a slot may still be unfilled.) ::" msgstr "" "这些抽象接口很多都是在 Python 实现开发的早期被定义的。 特别地,数字、映射和序列协议从一开始就已经是 Python 的组成部分。 " "其他协议则是后来添加的。 对于依赖某些来自类型实现的处理器例程的协议来说,较旧的协议被定义为类型对象所引用的处理器的可选块。 " "对于较新的协议来说在主类型对象中还有额外的槽位,并带有一个预设旗标位来指明存在该槽位并应当由解释器来检查。 (此旗标位并不会指明槽位值非 " "``NULL`` 的情况,可以设置该旗标来指明一个槽位的存在,但此本位仍可能保持未填充的状态。) ::" #: ../../extending/newtypes.rst:425 msgid "" "PyNumberMethods *tp_as_number;\n" "PySequenceMethods *tp_as_sequence;\n" "PyMappingMethods *tp_as_mapping;" msgstr "" "PyNumberMethods *tp_as_number;\n" "PySequenceMethods *tp_as_sequence;\n" "PyMappingMethods *tp_as_mapping;" #: ../../extending/newtypes.rst:429 msgid "" "If you wish your object to be able to act like a number, a sequence, or a " "mapping object, then you place the address of a structure that implements " "the C type :c:type:`PyNumberMethods`, :c:type:`PySequenceMethods`, or " ":c:type:`PyMappingMethods`, respectively. It is up to you to fill in this " "structure with appropriate values. You can find examples of the use of each " "of these in the :file:`Objects` directory of the Python source distribution." " ::" msgstr "" "如果你希望你的对象的行为类似一个数字、序列或映射对象,那么你就要分别放置一个实现了 C 类型 :c:type:`PyNumberMethods`, " ":c:type:`PySequenceMethods` 或 :c:type:`PyMappingMethods`, 的结构体的地址。 " "你要负责将适当的值填入这些结构体。 你可以在 Python 源代码发布版的 :file:`Objects` 目录中找到这些对象各自的用法示例。 ::" #: ../../extending/newtypes.rst:436 msgid "hashfunc tp_hash;" msgstr "hashfunc tp_hash;" #: ../../extending/newtypes.rst:438 msgid "" "This function, if you choose to provide it, should return a hash number for " "an instance of your data type. Here is a simple example::" msgstr "如果你选择提供此函数,则它应当为你的数据类型的实例返回一个哈希数值。 下面是一个简单的示例::" #: ../../extending/newtypes.rst:441 msgid "" "static Py_hash_t\n" "newdatatype_hash(newdatatypeobject *obj)\n" "{\n" " Py_hash_t result;\n" " result = obj->some_size + 32767 * obj->some_number;\n" " if (result == -1)\n" " result = -2;\n" " return result;\n" "}" msgstr "" "static Py_hash_t\n" "newdatatype_hash(newdatatypeobject *obj)\n" "{\n" " Py_hash_t result;\n" " result = obj->some_size + 32767 * obj->some_number;\n" " if (result == -1)\n" " result = -2;\n" " return result;\n" "}" #: ../../extending/newtypes.rst:451 msgid "" ":c:type:`!Py_hash_t` is a signed integer type with a platform-varying width." " Returning ``-1`` from :c:member:`~PyTypeObject.tp_hash` indicates an error," " which is why you should be careful to avoid returning it when hash " "computation is successful, as seen above." msgstr "" ":c:type:`!Py_hash_t` 是一个宽度取决于具体平台的有符号整数类型。 从 " ":c:member:`~PyTypeObject.tp_hash` 返回 ``-1`` " "表示发生了错误,这就是为什么你应当注意避免在哈希运算成功时返回它,如上面所演示的那样。" #: ../../extending/newtypes.rst:458 msgid "ternaryfunc tp_call;" msgstr "ternaryfunc tp_call;" #: ../../extending/newtypes.rst:460 msgid "" "This function is called when an instance of your data type is \"called\", " "for example, if ``obj1`` is an instance of your data type and the Python " "script contains ``obj1('hello')``, the :c:member:`~PyTypeObject.tp_call` " "handler is invoked." msgstr "" "此函数会在“调用”你的数据类型实例时被调用,举例来说,如果 ``obj1`` 是你的数据类型的实例而 Python 脚本包含了 " "``obj1('hello')``,则将唤起 :c:member:`~PyTypeObject.tp_call` 处理器。" #: ../../extending/newtypes.rst:464 msgid "This function takes three arguments:" msgstr "此函数接受三个参数:" #: ../../extending/newtypes.rst:466 msgid "" "*self* is the instance of the data type which is the subject of the call. If" " the call is ``obj1('hello')``, then *self* is ``obj1``." msgstr "*self* 是作为调用目标的数据类型实例。 如果调用是 ``obj1('hello')``,则 *self* 为 ``obj1``。" #: ../../extending/newtypes.rst:469 msgid "" "*args* is a tuple containing the arguments to the call. You can use " ":c:func:`PyArg_ParseTuple` to extract the arguments." msgstr "*args* 是包含调用参数的元组。 你可以使用 :c:func:`PyArg_ParseTuple` 来提取参数。" #: ../../extending/newtypes.rst:472 msgid "" "*kwds* is a dictionary of keyword arguments that were passed. If this is " "non-``NULL`` and you support keyword arguments, use " ":c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you do " "not want to support keyword arguments and this is non-``NULL``, raise a " ":exc:`TypeError` with a message saying that keyword arguments are not " "supported." msgstr "" "*kwds* 是由传入的关键字参数组成的字典。 如果它不为 ``NULL`` 且你支持关键字参数,则可使用 " ":c:func:`PyArg_ParseTupleAndKeywords` 来提取参数。 如果你不想支持关键字参数而它为非 ``NULL`` " "值,则会引发 :exc:`TypeError` 并附带一个提示不支持关键字参数的消息。" #: ../../extending/newtypes.rst:478 msgid "Here is a toy ``tp_call`` implementation::" msgstr "下面是一个演示性的 ``tp_call`` 实现::" #: ../../extending/newtypes.rst:480 msgid "" "static PyObject *\n" "newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *kwds)\n" "{\n" " PyObject *result;\n" " const char *arg1;\n" " const char *arg2;\n" " const char *arg3;\n" "\n" " if (!PyArg_ParseTuple(args, \"sss:call\", &arg1, &arg2, &arg3)) {\n" " return NULL;\n" " }\n" " result = PyUnicode_FromFormat(\n" " \"Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]\\n\",\n" " obj->obj_UnderlyingDatatypePtr->size,\n" " arg1, arg2, arg3);\n" " return result;\n" "}" msgstr "" "static PyObject *\n" "newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *kwds)\n" "{\n" " PyObject *result;\n" " const char *arg1;\n" " const char *arg2;\n" " const char *arg3;\n" "\n" " if (!PyArg_ParseTuple(args, \"sss:call\", &arg1, &arg2, &arg3)) {\n" " return NULL;\n" " }\n" " result = PyUnicode_FromFormat(\n" " \"Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]\\n\",\n" " obj->obj_UnderlyingDatatypePtr->size,\n" " arg1, arg2, arg3);\n" " return result;\n" "}" #: ../../extending/newtypes.rst:500 msgid "" "/* Iterators */\n" "getiterfunc tp_iter;\n" "iternextfunc tp_iternext;" msgstr "" "/* Iterators */\n" "getiterfunc tp_iter;\n" "iternextfunc tp_iternext;" #: ../../extending/newtypes.rst:504 msgid "" "These functions provide support for the iterator protocol. Both handlers " "take exactly one parameter, the instance for which they are being called, " "and return a new reference. In the case of an error, they should set an " "exception and return ``NULL``. :c:member:`~PyTypeObject.tp_iter` " "corresponds to the Python :meth:`~object.__iter__` method, while " ":c:member:`~PyTypeObject.tp_iternext` corresponds to the Python " ":meth:`~iterator.__next__` method." msgstr "" "这些函数提供了对迭代器协议的支持。 这两个处理器都只接受一个形参,即它们被调用时所使用的实例,并返回一个新的引用。 " "当发生错误时,它们应设置一个异常并返回 ``NULL``。 :c:member:`~PyTypeObject.tp_iter` 对应于 Python " ":meth:`~object.__iter__` 方法,而 :c:member:`~PyTypeObject.tp_iternext` 对应于 " "Python :meth:`~iterator.__next__` 方法。" #: ../../extending/newtypes.rst:511 msgid "" "Any :term:`iterable` object must implement the " ":c:member:`~PyTypeObject.tp_iter` handler, which must return an " ":term:`iterator` object. Here the same guidelines apply as for Python " "classes:" msgstr "" "任何 :term:`iterable` 对象都必须实现 :c:member:`~PyTypeObject.tp_iter` 处理器,该处理器必须返回一个" " :term:`iterator` 对象。 下面是与 Python 类所应用的同一个指导原则:" #: ../../extending/newtypes.rst:515 msgid "" "For collections (such as lists and tuples) which can support multiple " "independent iterators, a new iterator should be created and returned by each" " call to :c:member:`~PyTypeObject.tp_iter`." msgstr "" "对于可以支持多个独立迭代器的多项集(如列表和元组),则应当在每次调用 :c:member:`~PyTypeObject.tp_iter` " "时创建并返回一个新的迭代器。" #: ../../extending/newtypes.rst:518 msgid "" "Objects which can only be iterated over once (usually due to side effects of" " iteration, such as file objects) can implement " ":c:member:`~PyTypeObject.tp_iter` by returning a new reference to themselves" " -- and should also therefore implement the " ":c:member:`~PyTypeObject.tp_iternext` handler." msgstr "" "只能被迭代一次的对象(通常是由于迭代操作的附带影响,例如文件对象)可以通过返回一个指向自身的新引用来实现 " ":c:member:`~PyTypeObject.tp_iter` -- 并且为此还应当实现 " ":c:member:`~PyTypeObject.tp_iternext` 处理器。" #: ../../extending/newtypes.rst:523 msgid "" "Any :term:`iterator` object should implement both " ":c:member:`~PyTypeObject.tp_iter` and :c:member:`~PyTypeObject.tp_iternext`." " An iterator's :c:member:`~PyTypeObject.tp_iter` handler should return a " "new reference to the iterator. Its :c:member:`~PyTypeObject.tp_iternext` " "handler should return a new reference to the next object in the iteration, " "if there is one. If the iteration has reached the end, " ":c:member:`~PyTypeObject.tp_iternext` may return ``NULL`` without setting an" " exception, or it may set :exc:`StopIteration` *in addition* to returning " "``NULL``; avoiding the exception can yield slightly better performance. If " "an actual error occurs, :c:member:`~PyTypeObject.tp_iternext` should always " "set an exception and return ``NULL``." msgstr "" "任何 :term:`iterator` 对象都应当同时实现 :c:member:`~PyTypeObject.tp_iter` 和 " ":c:member:`~PyTypeObject.tp_iternext`。 一个迭代器的 " ":c:member:`~PyTypeObject.tp_iter` 处理器应当返回一个指向该迭代器的新引用。 它的 " ":c:member:`~PyTypeObject.tp_iternext` 处理器应当返回一个指向迭代操作的下一个对象的新引用,如果还有下一个对象的话。" " 如果迭代已到达末尾,则 :c:member:`~PyTypeObject.tp_iternext` 可以返回 ``NULL`` " "而不设置异常,或者也可以在返回 ``NULL`` 的基础上 *额外* 设置 :exc:`StopIteration`;避免异常可以产生更好的性能。 " "如果发生了实际的错误,则 :c:member:`~PyTypeObject.tp_iternext` 应当总是设置一个异常并返回 ``NULL``。" #: ../../extending/newtypes.rst:539 msgid "Weak Reference Support" msgstr "弱引用支持" #: ../../extending/newtypes.rst:541 msgid "" "One of the goals of Python's weak reference implementation is to allow any " "type to participate in the weak reference mechanism without incurring the " "overhead on performance-critical objects (such as numbers)." msgstr "" "One of the goals of Python 弱引用实现的目标之一是允许任意类型参与弱引用机制而不会在重视性能的对象(例如数字)上产生额外开销。" #: ../../extending/newtypes.rst:546 msgid "Documentation for the :mod:`weakref` module." msgstr ":mod:`weakref` 模块的文档。" #: ../../extending/newtypes.rst:548 msgid "" "For an object to be weakly referenceable, the extension type must set the " "``Py_TPFLAGS_MANAGED_WEAKREF`` bit of the :c:member:`~PyTypeObject.tp_flags`" " field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should " "be left as zero." msgstr "" "对于可被弱引用的对象,扩展类型必须设置 :c:member:`~PyTypeObject.tp_flags` 字段的 " "``Py_TPFLAGS_MANAGED_WEAKREF`` 比特位。 旧式的 " ":c:member:`~PyTypeObject.tp_weaklistoffset` 字段应当保持为零。" #: ../../extending/newtypes.rst:553 msgid "" "Concretely, here is how the statically declared type object would look::" msgstr "具体地说,以下就是静态声明的类型对象的样子::" #: ../../extending/newtypes.rst:555 msgid "" "static PyTypeObject TrivialType = {\n" " PyVarObject_HEAD_INIT(NULL, 0)\n" " /* ... other members omitted for brevity ... */\n" " .tp_flags = Py_TPFLAGS_MANAGED_WEAKREF | ...,\n" "};" msgstr "" "static PyTypeObject TrivialType = {\n" " PyVarObject_HEAD_INIT(NULL, 0)\n" " /* ... 省略了其他成员以使代码简短 ... */\n" " .tp_flags = Py_TPFLAGS_MANAGED_WEAKREF | ...,\n" "};" #: ../../extending/newtypes.rst:562 msgid "" "The only further addition is that ``tp_dealloc`` needs to clear any weak " "references (by calling :c:func:`PyObject_ClearWeakRefs`)::" msgstr "" "唯一的额外补充是 ``tp_dealloc`` 需要清除任何弱引用 (通过调用 :c:func:`PyObject_ClearWeakRefs`)::" #: ../../extending/newtypes.rst:565 msgid "" "static void\n" "Trivial_dealloc(TrivialObject *self)\n" "{\n" " /* Clear weakrefs first before calling any destructors */\n" " PyObject_ClearWeakRefs((PyObject *) self);\n" " /* ... remainder of destruction code omitted for brevity ... */\n" " Py_TYPE(self)->tp_free((PyObject *) self);\n" "}" msgstr "" "static void\n" "Trivial_dealloc(TrivialObject *self)\n" "{\n" " /* 在调用任何析构器之前先清除弱引用 */\n" " PyObject_ClearWeakRefs((PyObject *) self);\n" " /* ... 省略了析构代码的其余部分以使代码简短 ... */\n" " Py_TYPE(self)->tp_free((PyObject *) self);\n" "}" #: ../../extending/newtypes.rst:576 msgid "More Suggestions" msgstr "更多建议" #: ../../extending/newtypes.rst:578 msgid "" "In order to learn how to implement any specific method for your new data " "type, get the :term:`CPython` source code. Go to the :file:`Objects` " "directory, then search the C source files for ``tp_`` plus the function you " "want (for example, ``tp_richcompare``). You will find examples of the " "function you want to implement." msgstr "" "为了学习如何为你的新数据类型实现任何特定方法,请获取 :term:`CPython` 源代码。 进入 :file:`Objects` 目录,然后在 C " "源文件中搜索 ``tp_`` 加上你想要的函数 (例如,``tp_richcompare``)。 你将找到你想要实现的函数的例子。" #: ../../extending/newtypes.rst:584 msgid "" "When you need to verify that an object is a concrete instance of the type " "you are implementing, use the :c:func:`PyObject_TypeCheck` function. A " "sample of its use might be something like the following::" msgstr "" "当你需要验证一个对象是否为你实现的类型的具体实例时,请使用 :c:func:`PyObject_TypeCheck` 函数。 它的一个用法示例如下::" #: ../../extending/newtypes.rst:588 msgid "" "if (!PyObject_TypeCheck(some_object, &MyType)) {\n" " PyErr_SetString(PyExc_TypeError, \"arg #1 not a mything\");\n" " return NULL;\n" "}" msgstr "" "if (!PyObject_TypeCheck(some_object, &MyType)) {\n" " PyErr_SetString(PyExc_TypeError, \"arg #1 not a mything\");\n" " return NULL;\n" "}" #: ../../extending/newtypes.rst:594 msgid "Download CPython source releases." msgstr "下载CPython源代码版本。" #: ../../extending/newtypes.rst:595 msgid "https://www.python.org/downloads/source/" msgstr "https://www.python.org/downloads/source/" #: ../../extending/newtypes.rst:597 msgid "" "The CPython project on GitHub, where the CPython source code is developed." msgstr "GitHub上开发CPython源代码的CPython项目。" #: ../../extending/newtypes.rst:598 msgid "https://github.com/python/cpython" msgstr "https://github.com/python/cpython" #: ../../extending/newtypes.rst:56 msgid "object" msgstr "object -- 对象" #: ../../extending/newtypes.rst:56 msgid "deallocation" msgstr "撤销分配" #: ../../extending/newtypes.rst:56 msgid "deallocation, object" msgstr "撤销分配,对象" #: ../../extending/newtypes.rst:56 msgid "finalization" msgstr "最终化" #: ../../extending/newtypes.rst:56 msgid "finalization, of objects" msgstr "最终化,对象" #: ../../extending/newtypes.rst:91 msgid "PyErr_Fetch (C function)" msgstr "PyErr_Fetch (C 函数)" #: ../../extending/newtypes.rst:91 msgid "PyErr_Restore (C function)" msgstr "PyErr_Restore (C 函数)" #: ../../extending/newtypes.rst:150 msgid "string" msgstr "string" #: ../../extending/newtypes.rst:150 msgid "object representation" msgstr "对象的表示" #: ../../extending/newtypes.rst:150 msgid "built-in function" msgstr "内置函数" #: ../../extending/newtypes.rst:150 msgid "repr" msgstr "repr"