"Language-Team: Persian (https://github.com/python/python-docs-fa/)\n"
"Language: fa\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 3.6\n"
msgid"Defining Extension Types: Tutorial"
msgstr"تعریف نوعهای توسعهای: آموزش"
msgid"Python allows the writer of a C extension module to define new types that can be manipulated from Python code, much like the built-in :class:`str` and :class:`list` types. The code for all extension types follows a pattern, but there are some details that you need to understand before you can get started. This document is a gentle introduction to the topic."
msgstr"پایتون به نویسندهی یک ماژول توسعهای C اجازه میدهد نوعهای جدیدی تعریف کند که بتوان آنها را از طریق کد پایتون دستکاری کرد، بسیار شبیه به نوعهای توکار :class:`str` و :class:`list`. کد همهی نوعهای توسعهای از یک الگو پیروی میکند، اما جزئیاتی وجود دارند که پیش از شروع کار باید آنها را درک کنید. این سند مقدمهای ساده و روان بر این موضوع است."
msgid"The Basics"
msgstr"مبانی"
msgid"The :term:`CPython` runtime sees all Python objects as variables of type :c:expr:`PyObject*`, which serves as a \"base type\" for all Python objects. The :c:type:`PyObject` structure itself only contains the object's :term:`reference count` and a pointer to the object's \"type object\". This is where the action is; the type object determines which (C) functions get called by the interpreter when, for instance, an attribute gets looked up on an object, a method called, or it is multiplied by another object. These C functions are called \"type methods\"."
msgstr"رانتایم :term:`CPython` همهی اشیاء پایتون را بهصورت متغیرهایی از نوع :c:expr:`PyObject*` میبیند که بهعنوان یک «نوع پایه» برای همهی اشیاء پایتون عمل میکند. خودِ ساختار :c:type:`PyObject` تنها شامل :term:`reference count` شیء و اشارهگری به «شیء نوع» آن است. همینجاست که کار اصلی انجام میشود؛ شیء نوع تعیین میکند که مفسر در مواردی مانند جستجوی یک ویژگی روی یک شیء، فراخوانی یک متد یا ضرب آن در شیء دیگری، کدام توابع (C) را فراخوانی میکند. به این توابع C «متدهای نوع» گفته میشود."
msgid"So, if you want to define a new extension type, you need to create a new type object."
msgstr"بنابراین، اگر میخواهید یک نوع توسعهای جدید تعریف کنید، باید یک شیء نوع جدید ایجاد کنید."
msgid"This sort of thing can only be explained by example, so here's a minimal, but complete, module that defines a new type named :class:`!Custom` inside a C extension module :mod:`!custom`:"
msgstr"چنین چیزی را تنها میتوان با مثال توضیح داد، بنابراین در اینجا یک ماژول حداقلی اما کامل ارائه میشود که نوع جدیدی به نام :class:`!Custom` را درون یک ماژول توسعهای C به نام :mod:`!custom` تعریف میکند:"
msgid"What we're showing here is the traditional way of defining *static* extension types. It should be adequate for most uses. The C API also allows defining heap-allocated extension types using the :c:func:`PyType_FromSpec` function, which isn't covered in this tutorial."
msgstr"آنچه در اینجا نشان میدهیم، روش سنتی تعریف نوعهای توسعهای *ایستا* است. این روش باید برای بیشتر کاربردها کافی باشد. API زبان C همچنین اجازه میدهد نوعهای توسعهای تخصیصیافته در هیپ را با استفاده از تابع :c:func:`PyType_FromSpec` تعریف کنید؛ تابعی که در این آموزش پوشش داده نشده است."
msgid""
"#define PY_SSIZE_T_CLEAN\n"
"#include <Python.h>\n"
"\n"
"typedef struct {\n"
" PyObject_HEAD\n"
" /* Type-specific fields go here. */\n"
"} CustomObject;\n"
"\n"
"static PyTypeObject CustomType = {\n"
" .ob_base = PyVarObject_HEAD_INIT(NULL, 0)\n"
" .tp_name = \"custom.Custom\",\n"
" .tp_doc = PyDoc_STR(\"Custom objects\"),\n"
" .tp_basicsize = sizeof(CustomObject),\n"
" .tp_itemsize = 0,\n"
" .tp_flags = Py_TPFLAGS_DEFAULT,\n"
" .tp_new = PyType_GenericNew,\n"
"};\n"
"\n"
"static int\n"
"custom_module_exec(PyObject *m)\n"
"{\n"
" if (PyType_Ready(&CustomType) < 0) {\n"
" return -1;\n"
" }\n"
"\n"
" if (PyModule_AddObjectRef(m, \"Custom\", (PyObject *) &CustomType) < 0) {\n"
" .m_doc = \"Example module that creates an extension type.\",\n"
" .m_size = 0,\n"
" .m_slots = custom_module_slots,\n"
"};\n"
"\n"
"PyMODINIT_FUNC\n"
"PyInit_custom(void)\n"
"{\n"
" return PyModuleDef_Init(&custom_module);\n"
"}\n"
msgid"Now that's quite a bit to take in at once, but hopefully bits will seem familiar from the previous chapter. This file defines three things:"
msgstr"این واقعاً مقدار زیادی است که باید یکباره هضم کنید، اما امیدواریم بخشهایی از آن از فصل پیشین آشنا به نظر برسند. این پرونده سه چیز را تعریف میکند:"
msgid"What a :class:`!Custom` **object** contains: this is the ``CustomObject`` struct, which is allocated once for each :class:`!Custom` instance."
msgstr"آنچه یک **شیء** :class:`!Custom` در بر دارد: این ساختار ``CustomObject`` است که یکبار برای هر نمونهی :class:`!Custom` تخصیص داده میشود."
msgid"How the :class:`!Custom` **type** behaves: this is the ``CustomType`` struct, which defines a set of flags and function pointers that the interpreter inspects when specific operations are requested."
msgstr"نحوهی رفتار **نوع** :class:`!Custom`: این ساختار ``CustomType`` است که مجموعهای از پرچمها و اشارهگرهای تابع را تعریف میکند؛ مفسر آنها را زمانی که عملیاتهای خاصی درخواست میشوند بررسی میکند."
msgid"How to define and execute the :mod:`!custom` module: this is the ``PyInit_custom`` function and the associated ``custom_module`` struct for defining the module, and the ``custom_module_exec`` function to set up a fresh module object."
msgstr"نحوه تعریف و اجرای ماژول :mod:`!custom`: این، تابع ``PyInit_custom`` و ساختار مرتبط ``custom_module`` برای تعریف ماژول، و تابع ``custom_module_exec`` برای راهاندازی یک شیء ماژول تازه است."
msgid"The first bit is::"
msgstr"بخش اول این است::"
msgid""
"typedef struct {\n"
" PyObject_HEAD\n"
"} CustomObject;"
msgstr""
"typedef struct {\n"
" PyObject_HEAD\n"
"} CustomObject;"
msgid"This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory at the start of each object struct and defines a field called ``ob_base`` of type :c:type:`PyObject`, containing a pointer to a type object and a reference count (these can be accessed using the macros :c:macro:`Py_TYPE` and :c:macro:`Py_REFCNT` respectively). The reason for the macro is to abstract away the layout and to enable additional fields in :ref:`debug builds <debug-build>`."
msgstr"این همان چیزی است که یک شیء Custom در بر خواهد گرفت. ``PyObject_HEAD`` در ابتدای ساختار هر شیء الزامی است و فیلدی به نام ``ob_base`` از نوع :c:type:`PyObject` تعریف میکند که شامل یک اشارهگر به یک شیء نوع و یک شمارش ارجاع است (میتوان به اینها بهترتیب با استفاده از ماکروهای :c:macro:`Py_TYPE` و :c:macro:`Py_REFCNT` دسترسی داشت). دلیل وجود این ماکرو، انتزاعی کردن چیدمان و امکانپذیر کردن فیلدهای اضافی در :ref:`نسخههای اشکالزدایی <debug-build>` است."
msgid"There is no semicolon above after the :c:macro:`PyObject_HEAD` macro. Be wary of adding one by accident: some compilers will complain."
msgstr"در بالا، پس از ماکروی :c:macro:`PyObject_HEAD` هیچ نقطهویرگولی وجود ندارد. مراقب باشید که ناخواسته یکی اضافه نکنید: برخی کامپایلرها اعتراض خواهند کرد."
msgid"Of course, objects generally store additional data besides the standard ``PyObject_HEAD`` boilerplate; for example, here is the definition for standard Python floats::"
msgstr"البته، اشیاء بهطور کلی علاوه بر کد پیشساختهی استاندارد ``PyObject_HEAD`` دادههای اضافی نیز ذخیره میکنند؛ برای مثال، تعریف اعشاریهای استاندارد پایتون در ادامه آمده است::"
msgid""
"typedef struct {\n"
" PyObject_HEAD\n"
" double ob_fval;\n"
"} PyFloatObject;"
msgstr""
"typedef struct {\n"
" PyObject_HEAD\n"
" double ob_fval;\n"
"} PyFloatObject;"
msgid"The second bit is the definition of the type object. ::"
msgstr"بخش دوم، تعریف شیء نوع است. ::"
msgid""
"static PyTypeObject CustomType = {\n"
" .ob_base = PyVarObject_HEAD_INIT(NULL, 0)\n"
" .tp_name = \"custom.Custom\",\n"
" .tp_doc = PyDoc_STR(\"Custom objects\"),\n"
" .tp_basicsize = sizeof(CustomObject),\n"
" .tp_itemsize = 0,\n"
" .tp_flags = Py_TPFLAGS_DEFAULT,\n"
" .tp_new = PyType_GenericNew,\n"
"};"
msgstr""
"static PyTypeObject CustomType = {\n"
" .ob_base = PyVarObject_HEAD_INIT(NULL, 0)\n"
" .tp_name = \"custom.Custom\",\n"
" .tp_doc = PyDoc_STR(\"Custom objects\"),\n"
" .tp_basicsize = sizeof(CustomObject),\n"
" .tp_itemsize = 0,\n"
" .tp_flags = Py_TPFLAGS_DEFAULT,\n"
" .tp_new = PyType_GenericNew,\n"
"};"
msgid"We recommend using C99-style designated initializers as above, to avoid listing all the :c:type:`PyTypeObject` fields that you don't care about and also to avoid caring about the fields' declaration order."
msgstr"توصیه میکنیم مانند بالا از مقداردهندههای تعیینشده (designated initializers) به سبک C99 استفاده کنید تا از فهرستکردن تمام فیلدهای :c:type:`PyTypeObject` که به آنها اهمیت نمیدهید پرهیز کنید و همچنین از توجه به ترتیب اعلان فیلدها پرهیز کنید."
msgid"The actual definition of :c:type:`PyTypeObject` in :file:`object.h` has many more :ref:`fields <type-structs>` than the definition above. The remaining fields will be filled with zeros by the C compiler, and it's common practice to not specify them explicitly unless you need them."
msgstr"تعریف واقعی :c:type:`PyTypeObject` در :file:`object.h` نسبت به تعریف بالا :ref:`فیلدهای <type-structs>` بسیار بیشتری دارد. فیلدهای باقیمانده توسط کامپایلر C با صفر پر میشوند و رویه رایج این است که آنها را صریحاً مشخص نکنید، مگر اینکه به آنها نیاز داشته باشید."
msgid"We're going to pick it apart, one field at a time::"
msgstr"میخواهیم آن را کالبدشکافی کنیم، هر بار یک فیلد::"
msgid".ob_base = PyVarObject_HEAD_INIT(NULL, 0)"
msgstr".ob_base = PyVarObject_HEAD_INIT(NULL, 0)"
msgid"This line is mandatory boilerplate to initialize the ``ob_base`` field mentioned above. ::"
msgstr"این سطر یک کد پیشساخته الزامی برای مقداردهی اولیهی فیلد ``ob_base`` است که در بالا ذکر شد. ::"
msgid".tp_name = \"custom.Custom\","
msgstr".tp_name = \"custom.Custom\","
msgid"The name of our type. This will appear in the default textual representation of our objects and in some error messages, for example:"
msgstr"نام نوع ما. این نام در بازنمایی متنی پیشفرض اشیاء ما و در برخی پیامهای خطا ظاهر میشود، برای مثال:"
msgid""
">>> \"\" + custom.Custom()\n"
"Traceback (most recent call last):\n"
" File \"<stdin>\", line 1, in <module>\n"
"TypeError: can only concatenate str (not \"custom.Custom\") to str"
msgstr""
">>> \"\" + custom.Custom()\n"
"Traceback (most recent call last):\n"
" File \"<stdin>\", line 1, in <module>\n"
"TypeError: can only concatenate str (not \"custom.Custom\") to str"
msgid"Note that the name is a dotted name that includes both the module name and the name of the type within the module. The module in this case is :mod:`!custom` and the type is :class:`!Custom`, so we set the type name to :class:`!custom.Custom`. Using the real dotted import path is important to make your type compatible with the :mod:`pydoc` and :mod:`pickle` modules. ::"
msgstr"توجه داشته باشید که نام، یک نام نقطهگذاریشده است که هم نام ماژول و هم نام نوع درون ماژول را در بر میگیرد. ماژول در این مورد :mod:`!custom` است و نوع :class:`!Custom`، بنابراین نام نوع را برابر با :class:`!custom.Custom` قرار میدهیم. استفاده از مسیر ایمپورت نقطهگذاریشدهی واقعی برای سازگار کردن نوع شما با ماژولهای :mod:`pydoc` و :mod:`pickle` اهمیت دارد. ::"
msgid""
".tp_basicsize = sizeof(CustomObject),\n"
".tp_itemsize = 0,"
msgstr""
".tp_basicsize = sizeof(CustomObject),\n"
".tp_itemsize = 0,"
msgid"This is so that Python knows how much memory to allocate when creating new :class:`!Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is only used for variable-sized objects and should otherwise be zero."
msgstr"این کار برای آن است که پایتون بداند هنگام ایجاد نمونههای جدید :class:`!Custom` چه مقدار حافظه باید تخصیص دهد. :c:member:`~PyTypeObject.tp_itemsize` تنها برای شیءهای با اندازهی متغیر استفاده میشود و در غیر این صورت باید صفر باشد."
msgid"If you want your type to be subclassable from Python, and your type has the same :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple inheritance. A Python subclass of your type will have to list your type first in its :attr:`~type.__bases__`, or else it will not be able to call your type's :meth:`~object.__new__` method without getting an error. You can avoid this problem by ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its base type does. Most of the time, this will be true anyway, because either your base type will be :class:`object`, or else you will be adding data members to your base type, and therefore increasing its size."
msgstr "اگر میخواهید نوع شما از پایتون قابل زیرکلاسگیری باشد و نوع شما همان :c:member:`~PyTypeObject.tp_basicsize` نوع پایهاش را داشته باشد، ممکن است با وراثت چندگانه مشکلاتی داشته باشید. یک زیرکلاس پایتونی از نوع شما باید نوع شما را در ابتدای :attr:`~type.__bases__` خود فهرست کند، وگرنه نخواهد توانست متد :meth:`~object.__new__` نوع شما را بدون دریافت خطا فراخوانی کند. میتوانید با اطمینان از اینکه نوع شما مقدار بزرگتری برای :c:member:`~PyTypeObject.tp_basicsize` نسبت به نوع پایهاش دارد، از این مشکل اجتناب کنید. در بیشتر موارد، این موضوع به هر حال برقرار خواهد بود، زیرا یا نوع پایه شما :class:`object` خواهد بود، یا اعضای داده به نوع پایه خود اضافه خواهید کرد و بنابراین اندازهاش را افزایش میدهید."
msgid"We set the class flags to :c:macro:`Py_TPFLAGS_DEFAULT`. ::"
msgstr"پرچمهای کلاس را برابر :c:macro:`Py_TPFLAGS_DEFAULT` قرار میدهیم. ::"
msgid".tp_flags = Py_TPFLAGS_DEFAULT,"
msgstr".tp_flags = Py_TPFLAGS_DEFAULT,"
msgid"All types should include this constant in their flags. It enables all of the members defined until at least Python 3.3. If you need further members, you will need to OR the corresponding flags."
msgstr"همهی نوعها باید این ثابت را در پرچمهای خود بگنجانند. این ثابت همهی اعضای تعریفشده تا دستکم پایتون 3.3 را فعال میکند. اگر به اعضای بیشتری نیاز داشته باشید، باید پرچمهای مربوطه را OR کنید."
msgid"We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::"
msgstr"ما یک رشته مستند برای این نوع در :c:member:`~PyTypeObject.tp_doc` ارائه میکنیم. ::"
msgid".tp_doc = PyDoc_STR(\"Custom objects\"),"
msgstr".tp_doc = PyDoc_STR(\"Custom objects\"),"
msgid"To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` handler. This is the equivalent of the Python method :meth:`~object.__new__`, but has to be specified explicitly. In this case, we can just use the default implementation provided by the API function :c:func:`PyType_GenericNew`. ::"
msgstr"برای فعالسازی ایجاد شیء، باید هندلر :c:member:`~PyTypeObject.tp_new` را فراهم کنیم. این معادل متد پایتونی :meth:`~object.__new__` است، اما باید بهطور صریح مشخص شود. در این مورد، میتوانیم بهسادگی از پیادهسازی پیشفرض ارائهشده توسط تابع API یعنی :c:func:`PyType_GenericNew` استفاده کنیم. ::"
msgid".tp_new = PyType_GenericNew,"
msgstr".tp_new = PyType_GenericNew,"
msgid"Everything else in the file should be familiar, except for some code in :c:func:`!custom_module_exec`::"
msgstr"بقیهی محتوای پرونده باید برایتان آشنا باشد، بهجز بخشی از کد در :c:func:`!custom_module_exec`::"
msgid""
"if (PyType_Ready(&CustomType) < 0) {\n"
" return -1;\n"
"}"
msgstr""
"if (PyType_Ready(&CustomType) < 0) {\n"
" return -1;\n"
"}"
msgid"This initializes the :class:`!Custom` type, filling in a number of members to the appropriate default values, including :c:member:`~PyObject.ob_type` that we initially set to ``NULL``. ::"
msgstr"این کار نوع :class:`!Custom` را مقداردهی اولیه میکند و تعدادی از اعضا را با مقادیر پیشفرض مناسب پر میکند؛ از جمله :c:member:`~PyObject.ob_type` که در ابتدا آن را روی ``NULL`` قرار دادهایم. ::"
msgid"This adds the type to the module dictionary. This allows us to create :class:`!Custom` instances by calling the :class:`!Custom` class:"
msgstr"این کار، نوع را به دیکشنری ماژول اضافه میکند. این به ما امکان میدهد نمونههای :class:`!Custom` را با فراخوانی کلاس :class:`!Custom` ایجاد کنیم:"
msgid""
">>> import custom\n"
">>> mycustom = custom.Custom()"
msgstr""
">>> import custom\n"
">>> mycustom = custom.Custom()"
msgid"That's it! All that remains is to build it; put the above code in a file called :file:`custom.c`,"
msgstr"همین است! تنها کار باقیمانده، ساختن آن است؛ کد بالا را در پروندهای به نام :file:`custom.c` قرار دهید،"
msgid""
"[build-system]\n"
"requires = [\"setuptools\"]\n"
"build-backend = \"setuptools.build_meta\"\n"
"\n"
"[project]\n"
"name = \"custom\"\n"
"version = \"1\"\n"
msgstr""
"[build-system]\n"
"requires = [\"setuptools\"]\n"
"build-backend = \"setuptools.build_meta\"\n"
"\n"
"[project]\n"
"name = \"custom\"\n"
"version = \"1\"\n"
msgid"in a file called :file:`pyproject.toml`, and"
msgstr"در پروندهای به نام :file:`pyproject.toml`، و"
msgid"in a file called :file:`setup.py`; then typing"
msgstr"در پروندهای به نام :file:`setup.py`؛ سپس با تایپ کردن"
msgid"$ python -m pip install ."
msgstr"$ python -m pip install ."
msgid"in a shell should produce a file :file:`custom.so` in a subdirectory and install it; now fire up Python --- you should be able to ``import custom`` and play around with ``Custom`` objects."
msgstr"در یک پوسته باید پروندهی :file:`custom.so` را در یک زیرپوشه تولید کند و آن را نصب کند؛ اکنون پایتون را اجرا کنید --- باید بتوانید ``import custom`` را انجام دهید و با اشیای ``Custom`` آزمایش کنید."
msgid"That wasn't so hard, was it?"
msgstr"این کار چندان سخت نبود، نه؟"
msgid"Of course, the current Custom type is pretty uninteresting. It has no data and doesn't do anything. It can't even be subclassed."
msgstr"البته، نوع Custom فعلی کاملاً بیجالب است. هیچ دادهای ندارد و هیچ کاری انجام نمیدهد. حتی نمیتوان از آن زیرکلاس ساخت."
msgid"Adding data and methods to the Basic example"
msgstr"افزودن دادهها و متدها به مثال پایه"
msgid"Let's extend the basic example to add some data and methods. Let's also make the type usable as a base class. We'll create a new module, :mod:`!custom2` that adds these capabilities:"
msgstr"بیایید مثال پایه را گسترش دهیم تا برخی دادهها و متدها را اضافه کنیم. بیایید همچنین نوع را بهگونهای بسازیم که بهعنوان کلاس پایه قابل استفاده باشد. ماژول جدیدی میسازیم، :mod:`!custom2`، که این قابلیتها را اضافه میکند:"
" .m_doc = \"Example module that creates an extension type.\",\n"
" .m_size = 0,\n"
" .m_slots = custom_module_slots,\n"
"};\n"
"\n"
"PyMODINIT_FUNC\n"
"PyInit_custom2(void)\n"
"{\n"
" return PyModuleDef_Init(&custom_module);\n"
"}\n"
msgid"This version of the module has a number of changes."
msgstr"این نسخه از ماژول شامل تعدادی تغییر است."
msgid"The :class:`!Custom` type now has three data attributes in its C struct, *first*, *last*, and *number*. The *first* and *last* variables are Python strings containing first and last names. The *number* attribute is a C integer."
msgstr"نوع :class:`!Custom` اکنون سه ویژگی دادهای در ساختار C خود دارد: *first*، *last* و *number*. متغیرهای *first* و *last* رشتههای پایتونی حاوی نام و نام خانوادگی هستند. ویژگی *number* یک عدد صحیح C است."
msgid"The object structure is updated accordingly::"
msgstr"ساختار شیء متناسب با آن بهروزرسانی میشود::"
msgid""
"typedef struct {\n"
" PyObject_HEAD\n"
" PyObject *first; /* first name */\n"
" PyObject *last; /* last name */\n"
" int number;\n"
"} CustomObject;"
msgstr""
"typedef struct {\n"
" PyObject_HEAD\n"
" PyObject *first; /* first name */\n"
" PyObject *last; /* last name */\n"
" int number;\n"
"} CustomObject;"
msgid"Because we now have data to manage, we have to be more careful about object allocation and deallocation. At a minimum, we need a deallocation method::"
msgstr"از آنجا که اکنون دادههایی برای مدیریت داریم، باید در تخصیص و آزادسازی شیء دقت بیشتری به خرج دهیم. دستکم، به یک متد آزادسازی نیاز داریم::"
msgid""
"static void\n"
"Custom_dealloc(PyObject *op)\n"
"{\n"
" CustomObject *self = (CustomObject *) op;\n"
" Py_XDECREF(self->first);\n"
" Py_XDECREF(self->last);\n"
" Py_TYPE(self)->tp_free(self);\n"
"}"
msgstr""
"static void\n"
"Custom_dealloc(PyObject *op)\n"
"{\n"
" CustomObject *self = (CustomObject *) op;\n"
" Py_XDECREF(self->first);\n"
" Py_XDECREF(self->last);\n"
" Py_TYPE(self)->tp_free(self);\n"
"}"
msgid"which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::"
msgstr"که به عضو :c:member:`~PyTypeObject.tp_dealloc` انتساب داده میشود::"
msgid".tp_dealloc = Custom_dealloc,"
msgstr".tp_dealloc = Custom_dealloc,"
msgid"This method first clears the reference counts of the two Python attributes. :c:func:`Py_XDECREF` correctly handles the case where its argument is ``NULL`` (which might happen here if ``tp_new`` failed midway). It then calls the :c:member:`~PyTypeObject.tp_free` member of the object's type (computed by ``Py_TYPE(self)``) to free the object's memory. Note that the object's type might not be :class:`!CustomType`, because the object may be an instance of a subclass."
msgstr"این متد ابتدا شمارش ارجاع دو ویژگی پایتونی را پاک میکند. :c:func:`Py_XDECREF` بهدرستی حالتی را مدیریت میکند که آرگومان آن ``NULL`` باشد (که ممکن است در اینجا رخ دهد اگر ``tp_new`` در میانه کار شکست بخورد). سپس عضو :c:member:`~PyTypeObject.tp_free` از نوع شیء (که توسط ``Py_TYPE(self)`` محاسبه میشود) را فراخوانی میکند تا حافظه شیء را آزاد کند. توجه داشته باشید که نوع شیء ممکن است :class:`!CustomType` نباشد، زیرا شیء ممکن است نمونهای از یک زیرکلاس باشد."
msgid"The explicit cast to ``CustomObject *`` above is needed because we defined ``Custom_dealloc`` to take a ``PyObject *`` argument, as the ``tp_dealloc`` function pointer expects to receive a ``PyObject *`` argument. By assigning to the ``tp_dealloc`` slot of a type, we declare that it can only be called with instances of our ``CustomObject`` class, so the cast to ``(CustomObject *)`` is safe. This is object-oriented polymorphism, in C!"
msgstr"قالبریزی صریح به ``CustomObject *`` در بالا لازم است، زیرا ``Custom_dealloc`` را طوری تعریف کردیم که یک آرگومان ``PyObject *`` بگیرد، چرا که اشارهگر تابع ``tp_dealloc`` انتظار دارد یک آرگومان ``PyObject *`` دریافت کند. با انتساب به جایگاه ``tp_dealloc`` یک نوع، اعلام میکنیم که فقط میتوان آن را با نمونههای کلاس ``CustomObject`` ما فراخوانی کرد، بنابراین قالبریزی به ``(CustomObject *)`` ایمن است. این همان چندریختی شیءگرا است، در C!"
msgid"In existing code, or in previous versions of this tutorial, you might see similar functions take a pointer to the subtype object structure (``CustomObject*``) directly, like this::"
msgstr"در کدهای موجود، یا در نسخههای قبلی این آموزش، ممکن است ببینید که توابع مشابه، اشارهگر به ساختار شیء زیرنوع (``CustomObject*``) را مستقیماً میگیرند، به این شکل::"
msgid""
"Custom_dealloc(CustomObject *self)\n"
"{\n"
" Py_XDECREF(self->first);\n"
" Py_XDECREF(self->last);\n"
" Py_TYPE(self)->tp_free((PyObject *) self);\n"
"}\n"
"...\n"
".tp_dealloc = (destructor) Custom_dealloc,"
msgstr""
"Custom_dealloc(CustomObject *self)\n"
"{\n"
" Py_XDECREF(self->first);\n"
" Py_XDECREF(self->last);\n"
" Py_TYPE(self)->tp_free((PyObject *) self);\n"
"}\n"
"...\n"
".tp_dealloc = (destructor) Custom_dealloc,"
msgid"This does the same thing on all architectures that CPython supports, but according to the C standard, it invokes undefined behavior."
msgstr"این کار روی همهی معماریهایی که سیپایتون از آنها پشتیبانی میکند، یکسان انجام میشود، اما طبق استاندارد C، موجب رفتار تعریفنشده (undefined behavior) میشود."
msgid"We want to make sure that the first and last names are initialized to empty strings, so we provide a ``tp_new`` implementation::"
msgstr"میخواهیم مطمئن شویم که نام و نام خانوادگی با رشتههای خالی مقداردهی اولیه میشوند، بنابراین یک پیادهسازی ``tp_new`` ارائه میکنیم::"
msgid"and install it in the :c:member:`~PyTypeObject.tp_new` member::"
msgstr"و آن را در عضو :c:member:`~PyTypeObject.tp_new` نصب کنید::"
msgid".tp_new = Custom_new,"
msgstr".tp_new = Custom_new,"
msgid"The ``tp_new`` handler is responsible for creating (as opposed to initializing) objects of the type. It is exposed in Python as the :meth:`~object.__new__` method. It is not required to define a ``tp_new`` member, and indeed many extension types will simply reuse :c:func:`PyType_GenericNew` as done in the first version of the :class:`!Custom` type above. In this case, we use the ``tp_new`` handler to initialize the ``first`` and ``last`` attributes to non-``NULL`` default values."
msgstr"هندلر ``tp_new`` مسئول ایجاد (و نه مقداردهی اولیهی) اشیاء از این نوع است. این هندلر در پایتون بهصورت متد :meth:`~object.__new__` در دسترس قرار میگیرد. تعریف عضو ``tp_new`` الزامی نیست و در واقع بسیاری از نوعهای توسعهای صرفاً از :c:func:`PyType_GenericNew` بازاستفاده میکنند، همانطور که در نسخهی اول نوع :class:`!Custom` در بالا انجام شد. در این حالت، از هندلر ``tp_new`` برای مقداردهی اولیهی ویژگیهای ``first`` و ``last`` به مقادیر پیشفرض غیر ``NULL`` استفاده میکنیم."
msgid"``tp_new`` is passed the type being instantiated (not necessarily ``CustomType``, if a subclass is instantiated) and any arguments passed when the type was called, and is expected to return the instance created. ``tp_new`` handlers always accept positional and keyword arguments, but they often ignore the arguments, leaving the argument handling to initializer (a.k.a. ``tp_init`` in C or ``__init__`` in Python) methods."
msgstr"``tp_new`` نوعی را که از آن نمونهسازی میشود (اگر از یک زیرکلاس نمونهسازی شود، لزوماً ``CustomType`` نیست) و هر آرگومانی را که هنگام فراخوانی نوع پاس داده شده است، دریافت میکند و انتظار میرود که نمونهی ایجادشده را برگرداند. هندلرهای ``tp_new`` همیشه آرگومانهای جایگاهی و کلیدواژهای را میپذیرند، اما اغلب آرگومانها را نادیده میگیرند و مدیریت آرگومانها را به متدهای مقداردهندهی اولیه (معروف به ``tp_init`` در C یا ``__init__`` در پایتون) واگذار میکنند."
msgid"``tp_new`` shouldn't call ``tp_init`` explicitly, as the interpreter will do it itself."
msgstr"``tp_new`` نباید ``tp_init`` را بهطور صریح فراخوانی کند، زیرا مفسر خودش این کار را انجام میدهد."
msgid"The ``tp_new`` implementation calls the :c:member:`~PyTypeObject.tp_alloc` slot to allocate memory::"
msgstr"پیادهسازی ``tp_new`` جایگاه :c:member:`~PyTypeObject.tp_alloc` را برای تخصیص حافظه فراخوانی میکند::"
msgid"Since memory allocation may fail, we must check the :c:member:`~PyTypeObject.tp_alloc` result against ``NULL`` before proceeding."
msgstr"از آنجا که تخصیص حافظه ممکن است شکست بخورد، باید پیش از ادامه دادن، نتیجهی :c:member:`~PyTypeObject.tp_alloc` را در برابر ``NULL`` بررسی کنیم."
msgid"We didn't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. Rather :c:func:`PyType_Ready` fills it for us by inheriting it from our base class, which is :class:`object` by default. Most types use the default allocation strategy."
msgstr"ما خودمان جایگاه :c:member:`~PyTypeObject.tp_alloc` را پر نکردیم. بلکه :c:func:`PyType_Ready` آن را با ارثبری از کلاس پایهی ما — که بهطور پیشفرض :class:`object` است — برای ما پر میکند. بیشتر نوعها از راهبرد تخصیص پیشفرض استفاده میکنند."
msgid"If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`~object.__new__`), you must *not* try to determine what method to call using method resolution order at runtime. Always statically determine what type you are going to call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via ``type->tp_base->tp_new``. If you do not do this, Python subclasses of your type that also inherit from other Python-defined classes may not work correctly. (Specifically, you may not be able to create instances of such subclasses without getting a :exc:`TypeError`.)"
msgstr "اگر در حال ایجاد یک :c:member:`~PyTypeObject.tp_new` همکار هستید (یکی که :c:member:`~PyTypeObject.tp_new` نوع پایه یا :meth:`~object.__new__` را فراخوانی میکند)، *نباید* سعی کنید در زمان اجرا با استفاده از ترتیب حل متد تعیین کنید که کدام متد باید فراخوانی شود. همیشه بهصورت ایستا تعیین کنید که میخواهید کدام نوع را فراخوانی کنید و :c:member:`~PyTypeObject.tp_new` آن را مستقیماً یا از طریق ``type->tp_base->tp_new`` فراخوانی کنید. اگر این کار را نکنید، ممکن است زیرکلاسهای پایتونی از نوع شما که از کلاسهای دیگر تعریفشده در پایتون نیز ارثبری میکنند، بهدرستی کار نکنند. (بهطور خاص، ممکن است نتوانید بدون دریافت :exc:`TypeError` نمونههایی از چنین زیرکلاسهایی ایجاد کنید.)"
msgid"We also define an initialization function which accepts arguments to provide initial values for our instance::"
msgstr"ما همچنین یک تابع مقداردهی اولیه تعریف میکنیم که آرگومانهایی را میپذیرد تا مقادیر اولیه را برای نمونهی ما فراهم کند::"
" if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|OOi\", kwlist,\n"
" &first, &last,\n"
" &self->number))\n"
" return -1;\n"
"\n"
" if (first) {\n"
" tmp = self->first;\n"
" Py_INCREF(first);\n"
" self->first = first;\n"
" Py_XDECREF(tmp);\n"
" }\n"
" if (last) {\n"
" tmp = self->last;\n"
" Py_INCREF(last);\n"
" self->last = last;\n"
" Py_XDECREF(tmp);\n"
" }\n"
" return 0;\n"
"}"
msgid"by filling the :c:member:`~PyTypeObject.tp_init` slot. ::"
msgstr"با پر کردن جایگاه :c:member:`~PyTypeObject.tp_init`. ::"
msgid".tp_init = Custom_init,"
msgstr".tp_init = Custom_init,"
msgid"The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the :meth:`~object.__init__` method. It is used to initialize an object after it's created. Initializers always accept positional and keyword arguments, and they should return either ``0`` on success or ``-1`` on error."
msgstr"جایگاه :c:member:`~PyTypeObject.tp_init` در پایتون بهصورت متد :meth:`~object.__init__` در دسترس قرار میگیرد. از این متد برای مقداردهی اولیهی شیء پس از ایجاد آن استفاده میشود. مقداردهندههای اولیه همیشه آرگومانهای جایگاهی و کلیدواژهای را میپذیرند و باید در صورت موفقیت ``0`` و در صورت خطا ``-1`` را برگردانند."
msgid"Unlike the ``tp_new`` handler, there is no guarantee that ``tp_init`` is called at all (for example, the :mod:`pickle` module by default doesn't call :meth:`~object.__init__` on unpickled instances). It can also be called multiple times. Anyone can call the :meth:`!__init__` method on our objects. For this reason, we have to be extra careful when assigning the new attribute values. We might be tempted, for example to assign the ``first`` member like this::"
msgstr"برخلاف هندلر ``tp_new``، هیچ تضمینی وجود ندارد که ``tp_init`` اصلاً فراخوانی شود (برای مثال، ماژول :mod:`pickle` بهطور پیشفرض :meth:`~object.__init__` را روی نمونههای پیکلگشاییشده فراخوانی نمیکند). همچنین ممکن است چندین بار فراخوانی شود. هر کسی میتواند متد :meth:`!__init__` را روی اشیاء ما فراخوانی کند. به همین دلیل، باید هنگام انتساب مقادیر جدید به ویژگیها بسیار مراقب باشیم. ممکن است، برای مثال، وسوسه شویم که عضو ``first`` را به این صورت انتساب دهیم::"
msgid""
"if (first) {\n"
" Py_XDECREF(self->first);\n"
" Py_INCREF(first);\n"
" self->first = first;\n"
"}"
msgstr""
"if (first) {\n"
" Py_XDECREF(self->first);\n"
" Py_INCREF(first);\n"
" self->first = first;\n"
"}"
msgid"But this would be risky. Our type doesn't restrict the type of the ``first`` member, so it could be any kind of object. It could have a destructor that causes code to be executed that tries to access the ``first`` member; or that destructor could detach the :term:`thread state <attached thread state>` and let arbitrary code run in other threads that accesses and modifies our object."
msgstr"اما این کار پرخطر خواهد بود. نوع ما نوع عضو ``first`` را محدود نمیکند، بنابراین میتواند هر نوع شیء باشد. ممکن است مخربی داشته باشد که موجب اجرای کدی شود که تلاش میکند به عضو ``first`` دسترسی پیدا کند؛ یا همان مخرب میتواند :term:`وضعیت نخ <attached thread state>` را جدا کند و اجازه دهد کد دلخواهی در نخهای دیگر اجرا شود که به شیء ما دسترسی پیدا میکند و آن را تغییر میدهد."
msgid"To be paranoid and protect ourselves against this possibility, we almost always reassign members before decrementing their reference counts. When don't we have to do this?"
msgstr"برای احتیاط افراطی و محافظت از خود در برابر این احتمال، تقریباً همیشه اعضا را پیش از کاهش شمارش ارجاعشان مجدداً انتساب میکنیم. چه زمانی لازم نیست این کار را انجام دهیم؟"
msgid"when we absolutely know that the reference count is greater than 1;"
msgstr"وقتی بهطور قطع میدانیم که شمارش ارجاع بزرگتر از ۱ است؛"
msgid"when we know that deallocation of the object [#]_ will neither detach the :term:`thread state <attached thread state>` nor cause any calls back into our type's code;"
msgstr"زمانی که میدانیم آزادسازی شیء [#]_ نه :term:`وضعیت نخ <attached thread state>` را جدا میکند و نه هیچ فراخوانی مجددی به کد نوع ما ایجاد میکند؛"
msgid"when decrementing a reference count in a :c:member:`~PyTypeObject.tp_dealloc` handler on a type which doesn't support cyclic garbage collection [#]_."
msgstr"هنگام کاهش شمارش ارجاع در هندلر :c:member:`~PyTypeObject.tp_dealloc` روی نوعی که از زبالهروبی چرخهای پشتیبانی نمیکند [#]_."
msgid"We want to expose our instance variables as attributes. There are a number of ways to do that. The simplest way is to define member definitions::"
msgstr"ما میخواهیم متغیرهای نمونهی خود را بهعنوان ویژگیها در دسترس قرار دهیم. راههای مختلفی برای انجام این کار وجود دارد. سادهترین راه، تعریف تعریفهای عضو است::"
msgid"and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::"
msgstr"و تعاریف را در جایگاه :c:member:`~PyTypeObject.tp_members` قرار دهید::"
msgid".tp_members = Custom_members,"
msgstr".tp_members = Custom_members,"
msgid"Each member definition has a member name, type, offset, access flags and documentation string. See the :ref:`Generic-Attribute-Management` section below for details."
msgstr"هر تعریف عضو دارای نام عضو، نوع، آفست، پرچمهای دسترسی و رشته مستند است. برای جزئیات، بخش :ref:`Generic-Attribute-Management` را در ادامه ببینید."
msgid"A disadvantage of this approach is that it doesn't provide a way to restrict the types of objects that can be assigned to the Python attributes. We expect the first and last names to be strings, but any Python objects can be assigned. Further, the attributes can be deleted, setting the C pointers to ``NULL``. Even though we can make sure the members are initialized to non-``NULL`` values, the members can be set to ``NULL`` if the attributes are deleted."
msgstr"یکی از معایب این رویکرد این است که راهی برای محدود کردن نوع اشیایی که میتوان به ویژگیهای پایتون انتساب داد، فراهم نمیکند. انتظار داریم نام و نام خانوادگی رشته باشند، اما هر شیء پایتونی میتواند انتساب داده شود. علاوه بر این، ویژگیها را میتوان حذف کرد که این کار اشارهگرهای C را روی ``NULL`` قرار میدهد. حتی اگر بتوانیم اطمینان حاصل کنیم که اعضا با مقادیر غیر ``NULL`` مقداردهی اولیه شدهاند، در صورت حذف ویژگیها، اعضا میتوانند روی ``NULL`` قرار گیرند."
msgid"We define a single method, :meth:`!Custom.name`, that outputs the objects name as the concatenation of the first and last names. ::"
msgstr"ما یک متد واحد، :meth:`!Custom.name`، تعریف میکنیم که نام شیء را بهصورت الحاق نام کوچک و نام خانوادگی خروجی میدهد. ::"
msgid"The method is implemented as a C function that takes a :class:`!Custom` (or :class:`!Custom` subclass) instance as the first argument. Methods always take an instance as the first argument. Methods often take positional and keyword arguments as well, but in this case we don't take any and don't need to accept a positional argument tuple or keyword argument dictionary. This method is equivalent to the Python method:"
msgstr"این متد بهصورت یک تابع C پیادهسازی شده است که یک نمونهی :class:`!Custom` (یا زیرکلاس :class:`!Custom`) را بهعنوان نخستین آرگومان میگیرد. متدها همیشه یک نمونه را بهعنوان نخستین آرگومان میگیرند. متدها اغلب آرگومانهای جایگاهی و کلیدواژهای نیز میگیرند، اما در این مورد ما هیچ آرگومانی نمیگیریم و نیازی به پذیرفتن تاپل آرگومانهای جایگاهی یا دیکشنری آرگومانهای کلیدواژهای نداریم. این متد معادل متد پایتونی زیر است:"
msgid""
"def name(self):\n"
" return \"%s %s\" % (self.first, self.last)"
msgstr""
"def name(self):\n"
" return \"%s %s\" % (self.first, self.last)"
msgid"Note that we have to check for the possibility that our :attr:`!first` and :attr:`!last` members are ``NULL``. This is because they can be deleted, in which case they are set to ``NULL``. It would be better to prevent deletion of these attributes and to restrict the attribute values to be strings. We'll see how to do that in the next section."
msgstr"توجه داشته باشید که باید احتمال ``NULL`` بودن اعضای :attr:`!first` و :attr:`!last` خود را بررسی کنیم. دلیل این است که این اعضا ممکن است حذف شوند، که در این صورت برابر ``NULL`` قرار میگیرند. بهتر است که از حذف این ویژگیها جلوگیری کرده و مقادیر ویژگیها را به رشتهها محدود کنیم. در بخش بعدی خواهیم دید که چگونه این کار را انجام دهیم."