# SOME DESCRIPTIVE TITLE. # Copyright (C) 2001 Python Software Foundation # This file is distributed under the same license as the Python package. # FIRST AUTHOR , YEAR. # # Translators: # Alireza Shabani (Revisto) , 2025 # Rafael Fontenelle , 2025 # Sepehr Rasouli , 2026 # msgid "" msgstr "" "Project-Id-Version: Python 3.14\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2026-09-21 11:59+0000\n" "PO-Revision-Date: 2021-06-28 00:51+0000\n" "Last-Translator: Sepehr Rasouli , 2026\n" "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" msgid "Extending Python with C or C++" msgstr "توسعه پایتون با C یا C++" 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 برنامه‌نویسی کنید، افزودن ماژول‌های توکار جدید به پایتون کاملاً آسان است. چنین :dfn:`ماژول‌های توسعه‌ای (extension modules)` می‌توانند دو کاری انجام دهند که مستقیماً در پایتون امکان‌پذیر نیست: می‌توانند نوع‌های شیء توکار جدید را پیاده‌سازی کنند و می‌توانند توابع کتابخانه C و فراخوان‌های سیستمی را فراخوانی کنند." 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 "برای پشتیبانی از توسعه‌ها، API پایتون (رابط برنامه‌نویسی کاربردی) مجموعه‌ای از توابع، ماکروها و متغیرها را تعریف می‌کند که دسترسی به بیشتر جنبه‌های سیستم زمان اجرای پایتون را فراهم می‌کنند. API پایتون با گنجاندن سرآیند ``\"Python.h\"`` در یک پرونده منبع C ادغام می‌شود." 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 "کامپایل یک ماژول توسعه‌ای به کاربرد موردنظر آن و همچنین به پیکربندی سیستم شما بستگی دارد؛ جزئیات در فصل‌های بعدی ارائه شده است." 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 `_ 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 مختص سی‌پایتون است و ماژول‌های توسعه‌ای روی پیاده‌سازی‌های دیگر پایتون کار نمی‌کنند. در بسیاری از موارد می‌توان از نوشتن توسعه‌های C پرهیز کرد و قابلیت حمل به پیاده‌سازی‌های دیگر را حفظ نمود. برای مثال، اگر مورد استفاده‌ی شما فراخوانی توابع کتابخانه C یا فراخوانی‌های سیستمی است، باید به جای نوشتن کد C سفارشی، استفاده از ماژول :mod:`ctypes` یا کتابخانه‌ی `cffi `_ را در نظر بگیرید. این ماژول‌ها به شما اجازه می‌دهند برای برقراری رابط با کد C، کد پایتون بنویسید و نسبت به نوشتن و کامپایل کردن یک ماژول توسعه‌ای C، بین پیاده‌سازی‌های پایتون قابلیت حمل بیشتری دارند." msgid "A Simple Example" msgstr "یک مثال ساده" 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`` بسازیم (غذای مورد علاقه‌ی طرفداران مونتی پایتون...) و فرض کنیم می‌خواهیم یک رابط پایتونی برای تابع کتابخانه‌ی C یعنی :c:func:`system` [#]_ بسازیم. این تابع یک رشته‌ی نویسه‌ای پایان‌یافته با نویسه‌ی تهی را به‌عنوان آرگومان می‌گیرد و یک عدد صحیح برمی‌گرداند. می‌خواهیم این تابع از پایتون به صورت زیر فراخوانی‌پذیر باشد:" msgid "" ">>> import spam\n" ">>> status = spam.system(\"ls -l\")" msgstr "" ">>> import spam\n" ">>> status = spam.system(\"ls -l\")" 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` باشد.)" msgid "The first two lines of our file can be::" msgstr "دو سطر نخست پرونده‌ی ما می‌تواند باشد::" msgid "" "#define PY_SSIZE_T_CLEAN\n" "#include " msgstr "" "#define PY_SSIZE_T_CLEAN\n" "#include " 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 "که API پایتون را وارد می‌کند (در صورت تمایل می‌توانید کامنتی که هدف ماژول را شرح می‌دهد و یک اعلان حق نشر اضافه کنید)." 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 "از آنجا که پایتون ممکن است برخی تعریف‌های پیش‌پردازنده را تعریف کند که در برخی سیستم‌ها بر سرآیندهای استاندارد تأثیر می‌گذارند، شما *باید* :file:`Python.h` را پیش از گنجاندن هر سرآیند استانداردی بگنجانید." 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`` برای نشان دادن اینکه ``Py_ssize_t`` باید در برخی API‌ها به‌جای ``int`` استفاده شود، به کار می‌رفت. از پایتون 3.13 به بعد دیگر ضروری نیست، اما ما آن را برای سازگاری با گذشته در اینجا نگه می‌داریم. برای توضیح این ماکرو به :ref:`arg-parsing-string-and-buffers` مراجعه کنید." 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`` دارند؛ به‌جز نمادهایی که در پرونده‌های سرآیند استاندارد تعریف شده‌اند." 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` چندین پرونده‌ی سرآیند استاندارد را include می‌کند. افزونه‌های C باید سرآیندهای استاندارد مورد استفاده‌ی خود را include کنند و نباید به این include‌های ضمنی تکیه کنند. اگر از C API محدود نسخه‌ی 3.13 یا جدیدتر استفاده می‌کنید، include‌های ضمنی عبارت‌اند از:" msgid "````" msgstr "````" msgid "```` (on Windows)" msgstr "```` (در ویندوز)" msgid "````" msgstr "````" msgid "````" msgstr "````" msgid "````" msgstr "````" msgid "````" msgstr "````" msgid "````" msgstr "````" msgid "```` (if present)" msgstr "```` (در صورت وجود)" 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 یا قدیمی‌تر تنظیم شده باشد، سرآیندهای زیر نیز گنجانده می‌شوند:" msgid "````" msgstr "````" msgid "```` (on POSIX)" msgstr "```` (در POSIX)" 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 یا قدیمی‌تر تنظیم شده باشد، سرآیندهای زیر نیز گنجانده می‌شوند:" msgid "````" msgstr "````" msgid "````" msgstr "````" msgid "````" msgstr "````" msgid "````" msgstr "````" 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 است که هنگام ارزیابی عبارت پایتون ``spam.system(string)`` فراخوانی خواهد شد (به‌زودی خواهیم دید که چگونه در نهایت فراخوانی می‌شود)::" 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" "}" 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 "ترجمه‌ای سرراست از فهرست آرگومان‌ها در پایتون (برای مثال، عبارت واحد ``\"ls -l\"``) به آرگومان‌های پاس‌داده‌شده به تابع C وجود دارد. تابع C همیشه دو آرگومان دارد که به‌طور قراردادی *self* و *args* نامیده می‌شوند." 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* برای توابع در سطح ماژول به شیء ماژول اشاره می‌کند؛ برای یک متد، به نمونه‌ی شیء اشاره خواهد کرد." 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* اشاره‌گری به یک شیء تاپل پایتون حاوی آرگومان‌ها خواهد بود. هر آیتم از تاپل با یک آرگومان در فهرست آرگومان‌های فراخوانی مطابقت دارد. آرگومان‌ها اشیاء پایتون هستند --- برای اینکه بتوانیم در تابع C خود کاری با آن‌ها انجام دهیم، باید آن‌ها را به مقادیر C تبدیل کنیم. تابع :c:func:`PyArg_ParseTuple` در API پایتون انواع آرگومان‌ها را بررسی می‌کند و آن‌ها را به مقادیر C تبدیل می‌کند. این تابع از یک رشته‌ی قالب برای تعیین انواع مورد نیاز آرگومان‌ها و همچنین انواع متغیرهای C که مقادیر تبدیل‌شده در آن‌ها ذخیره می‌شوند، استفاده می‌کند. در ادامه بیشتر درباره‌ی این موضوع توضیح داده خواهد شد." 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` در صورتی مقدار درست (غیرصفر) را برمی‌گرداند که همه‌ی آرگومان‌ها نوع درست را داشته باشند و اجزای آن در متغیرهایی که آدرس‌هایشان پاس داده شده، ذخیره شده باشند. اگر فهرست آرگومان نامعتبری پاس داده شده باشد، مقدار نادرست (صفر) را برمی‌گرداند. در حالت دوم، همچنین یک استثنای مناسب ایجاد می‌کند تا تابع فراخواننده بتواند بلافاصله ``NULL`` را برگرداند (همان‌طور که در مثال دیدیم)." msgid "Intermezzo: Errors and Exceptions" msgstr "میان‌پرده: خطاها و استثناها" 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 "یک قرارداد مهم در سراسر مفسر پایتون به شرح زیر است: هنگامی که تابعی شکست می‌خورد، باید وضعیت استثنا را تنظیم کند و یک مقدار خطا (معمولاً ``-1`` یا یک اشاره‌گر ``NULL``) برگرداند. اطلاعات استثنا در سه عضو از وضعیت نخ مفسر ذخیره می‌شود. در صورت نبود استثنا، این‌ها ``NULL`` هستند. در غیر این صورت، آن‌ها معادل‌های C اعضای تاپل پایتونی‌ای هستند که توسط :meth:`sys.exc_info` برگردانده می‌شود. این‌ها عبارت‌اند از نوع استثنا، نمونه استثنا، و یک شیء ردگیری. دانستن این موارد برای درک چگونگی انتقال خطاها اهمیت دارد." msgid "The Python API defines a number of functions to set various types of exceptions." msgstr "API پایتون تعدادی تابع برای تنظیم انواع مختلف استثناها تعریف می‌کند." 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 علت خطا را نشان می‌دهد، به یک شیء رشته پایتون تبدیل می‌شود و به عنوان «مقدار مرتبط» استثنا ذخیره می‌شود." 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` کنید." 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` ندارید، زیرا باید بتوانید از روی مقدار بازگشتی متوجه آن شوید." 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_*``، و به همین ترتیب --- دقیق‌ترین علت خطا قبلاً توسط تابعی که نخست آن را تشخیص داده است گزارش شده است. وقتی خطا به حلقه اصلی مفسر پایتون می‌رسد، این امر کد پایتون در حال اجرا را متوقف می‌کند و تلاش می‌کند هندلر استثنایی را که برنامه‌نویس پایتون تعیین کرده است بیابد." 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_*`` پیام خطای دقیق‌تری ارائه دهد، و در چنین مواردی انجام این کار اشکالی ندارد. با این حال، به‌عنوان یک قاعده کلی، این کار ضروری نیست و می‌تواند باعث از دست رفتن اطلاعاتی درباره علت خطا شود: بیشتر عملیات می‌توانند به دلایل مختلفی شکست بخورند.)" 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` را فراخوانی کند که نخواهد خطا را به مفسر منتقل کند، بلکه بخواهد خودش به‌طور کامل آن را مدیریت کند (احتمالاً با امتحان کردن چیز دیگری، یا وانمود کردن به اینکه هیچ مشکلی پیش نیامده است)." 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` را مستقیماً فراخوانی می‌کنند." 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` و امثال آن، توابعی که یک وضعیت عدد صحیح برمی‌گردانند معمولاً مانند فراخوانی‌های سیستمی یونیکس، برای موفقیت مقداری مثبت یا صفر و برای شکست ``-1`` برمی‌گردانند." 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` برای اشیایی که از قبل ایجاد کرده‌اید)!" 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 از پیش اعلان‌شده‌ای متناظر با تمام استثناهای توکار پایتون وجود دارند، مانند :c:data:`PyExc_ZeroDivisionError`، که می‌توانید مستقیماً از آن‌ها استفاده کنید. البته، باید استثناها را هوشمندانه انتخاب کنید --- از :c:data:`PyExc_TypeError` برای بیان اینکه پرونده‌ای نتوانست باز شود استفاده نکنید (آن مورد احتمالاً باید :c:data:`PyExc_OSError` باشد). اگر مشکلی در فهرست آرگومان‌ها وجود داشته باشد، تابع :c:func:`PyArg_ParseTuple` معمولاً استثنای :c:data:`PyExc_TypeError` را برمی‌افرازد. اگر آرگومانی داشته باشید که مقدار آن باید در محدوده‌ی خاصی باشد یا باید شرایط دیگری را برآورده کند، :c:data:`PyExc_ValueError` مناسب است." 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 "شما همچنین می‌توانید یک استثنای جدید تعریف کنید که مختص ماژول شما باشد. ساده‌ترین راه برای انجام این کار، اعلان یک متغیر شیء سراسری ایستا در ابتدای پرونده است::" msgid "static PyObject *SpamError = NULL;" msgstr "static PyObject *SpamError = NULL;" 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:func:`PyErr_NewException` در تابع :c:data:`Py_mod_exec` ماژول (:c:func:`!spam_module_exec`) مقداردهی اولیه کنید::" msgid "SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);" msgstr "SpamError = PyErr_NewException(\"spam.error\", NULL, NULL);" 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` فراخوانی می‌شود — بازنویسی خواهد شد." msgid "For now, let's avoid the issue: we will block repeated initialization by raising an :py:exc:`ImportError`::" msgstr "فعلاً، اجازه دهید از این مسئله اجتناب کنیم: راه‌اندازی مکرر را با پرتاب :py:exc:`ImportError` مسدود خواهیم کرد::" 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, // 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" "}" 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 "توجه داشته باشید که نام پایتونی شیء استثنا :exc:`!spam.error` است. تابع :c:func:`PyErr_NewException` می‌تواند کلاسی ایجاد کند که کلاس پایه‌ی آن :exc:`Exception` باشد (مگر اینکه کلاس دیگری به جای ``NULL`` ارسال شود)؛ این کلاس پایه در :ref:`bltin-exceptions` توصیف شده است." 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` ارجاعی به کلاس استثنای به‌تازگی ایجادشده را نگه می‌دارد؛ این کار عمدی است! از آنجا که ممکن است کد خارجی استثنا را از ماژول حذف کند، به یک ارجاع مالکانه (owned reference) به کلاس نیاز است تا اطمینان حاصل شود که کلاس دور انداخته نمی‌شود و در نتیجه :c:data:`!SpamError` به اشاره‌گر سرگردان (dangling pointer) تبدیل نمی‌شود. اگر این اشاره‌گر سرگردان شود، کد C که استثنا را برمی‌انگیزد ممکن است باعث برون‌ریزی هسته یا سایر اثرات جانبی ناخواسته شود." 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` برای حذف این ارجاع وجود ندارد. حتی هنگام خاموش شدن مفسر پایتون، متغیر سراسری :c:data:`!SpamError` زباله‌روبی نخواهد شد. این متغیر «نشت» خواهد کرد. با این حال، اطمینان حاصل کردیم که این اتفاق حداکثر یک بار به ازای هر فرایند رخ خواهد داد." msgid "We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type later in this sample." msgstr "استفاده از :c:macro:`PyMODINIT_FUNC` به‌عنوان نوع بازگشتی تابع را در ادامه‌ی این نمونه بحث می‌کنیم." 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 "می‌توانید استثنای :exc:`!spam.error` را در ماژول توسعه‌ای خود با فراخوانی :c:func:`PyErr_SetString` ایجاد کنید، همان‌طور که در ادامه نشان داده شده است::" 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" "}" msgid "Back to the Example" msgstr "بازگشت به مثال" msgid "Going back to our example function, you should now be able to understand this statement::" msgstr "با بازگشت به تابع مثال خودمان، اکنون باید بتوانید این دستور را درک کنید::" msgid "" "if (!PyArg_ParseTuple(args, \"s\", &command))\n" " return NULL;" msgstr "" "if (!PyArg_ParseTuple(args, \"s\", &command))\n" " return NULL;" 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`` اعلان شود)." 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 "دستور بعدی، تابع یونیکسی :c:func:`system` را فراخوانی می‌کند و رشته‌ای را که به‌تازگی از :c:func:`PyArg_ParseTuple` دریافت کرده‌ایم به آن پاس می‌دهد::" msgid "sts = system(command);" msgstr "sts = system(command);" 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` ما باید مقدار :c:data:`!sts` را به‌عنوان یک شیء پایتون بازگرداند. این کار با استفاده از تابع :c:func:`PyLong_FromLong` انجام می‌شود. ::" msgid "return PyLong_FromLong(sts);" msgstr "return PyLong_FromLong(sts);" msgid "In this case, it will return an integer object. (Yes, even integers are objects on the heap in Python!)" msgstr "در این حالت، یک شیء عدد صحیح را برمی‌گرداند. (بله، در پایتون حتی اعداد صحیح هم اشیایی روی هیپ هستند!)" 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` برمی‌گرداند)، تابع پایتونِ متناظر باید ``None`` را برگرداند. برای انجام این کار به این اصطلاح نیاز دارید (که توسط ماکروی :c:macro:`Py_RETURN_NONE` پیاده‌سازی شده است)::" msgid "" "Py_INCREF(Py_None);\n" "return Py_None;" msgstr "" "Py_INCREF(Py_None);\n" "return Py_None;" 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` نام C برای شیء ویژه‌ی پایتون ``None`` است. این یک شیء واقعی پایتون است، نه یک اشاره‌گر ``NULL`` که همان‌طور که دیدیم، در بیشتر زمینه‌ها به معنای «خطا» است." msgid "The Module's Method Table and Initialization Function" msgstr "جدول متدهای ماژول و تابع مقدار‌دهی اولیه" 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` چگونه از برنامه‌های پایتون فراخوانی می‌شود. ابتدا، باید نام و نشانی آن را در یک «جدول متد» فهرست کنیم::" 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" "};" 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` به کار می‌رود." 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``، تابع باید انتظار داشته باشد که پارامترهای سطح پایتون به‌صورت تاپلی مناسب برای پارس کردن توسط :c:func:`PyArg_ParseTuple` ارسال شوند؛ اطلاعات بیشتر درباره‌ی این تابع در ادامه ارائه شده است." 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` استفاده کنید." msgid "The method table must be referenced in the module definition structure::" msgstr "جدول متدها باید در ساختار تعریف ماژول ارجاع داده شود::" 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" "};" 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`` تعریف‌شده در پرونده‌ی ماژول باشد::" 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" "}" 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 *`` اعلام می‌کند، هرگونه اعلان پیوند (linkage) خاص مورد نیاز پلتفرم را اعلام می‌کند و برای C++ تابع را به‌صورت ``extern \"C\"`` اعلام می‌کند." 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 ":c:func:`!PyInit_spam` هنگامی فراخوانی می‌شود که هر مفسر، ماژول :mod:`!spam` خود را برای نخستین بار ایمپورت کند. (برای نکات مربوط به تعبیه پایتون، به ادامه مراجعه کنید.) اشاره‌گری به تعریف ماژول باید از طریق :c:func:`PyModuleDef_Init` بازگردانده شود تا سازوکار ایمپورت بتواند ماژول را ایجاد کرده و آن را در ``sys.modules`` ذخیره کند." 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 "هنگام تعبیه پایتون، تابع :c:func:`!PyInit_spam` به‌طور خودکار فراخوانی نمی‌شود، مگر آنکه ورودی‌ای در جدول :c:data:`PyImport_Inittab` وجود داشته باشد. برای افزودن ماژول به جدول مقداردهی اولیه، از :c:func:`PyImport_AppendInittab` استفاده کنید و در صورت تمایل، ماژول را ایمپورت کنید::" msgid "" "#define PY_SSIZE_T_CLEAN\n" "#include \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 \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" "}" msgid "If you declare a global variable or a local static one, the module may experience unintended side-effects on re-initialisation, for example when removing entries from ``sys.modules`` or importing compiled modules into multiple interpreters within a process (or following a :c:func:`fork` without an intervening :c:func:`exec`). If module state is not yet fully :ref:`isolated `, authors should consider marking the module as having no support for subinterpreters (via :c:macro:`Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED`)." msgstr "اگر یک متغیر سراسری یا یک متغیر ایستای محلی تعریف کنید، ماژول ممکن است هنگام مقداردهی مجدد دچار عوارض جانبی ناخواسته شود، برای مثال هنگام حذف ورودی‌ها از ``sys.modules`` یا ایمپورت کردن ماژول‌های کامپایل‌شده در چندین مفسر درون یک فرایند (یا پس از یک :c:func:`fork` بدون :c:func:`exec` در میان). اگر وضعیت ماژول هنوز به‌طور کامل :ref:`جداسازی‌شده ` نباشد، نویسندگان باید در نظر بگیرند که ماژول را به‌عنوان فاقد پشتیبانی از زیرمفسرها علامت‌گذاری کنند (از طریق :c:macro:`Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED`)." msgid "A more substantial example module is included in the Python source distribution as :file:`Modules/xxlimited.c`. This file may be used as a template or simply read as an example." msgstr "یک ماژول نمونه‌ی جامع‌تر در توزیع کد منبع پایتون به‌صورت :file:`Modules/xxlimited.c` گنجانده شده است. می‌توان از این پرونده به‌عنوان یک قالب استفاده کرد یا صرفاً آن را به‌عنوان مثال خواند." msgid "Compilation and Linkage" msgstr "کامپایل و پیونددهی (linkage)" msgid "There are two more things to do before you can use your new extension: compiling and linking it with the Python system. If you use dynamic loading, the details may depend on the style of dynamic loading your system uses; see the chapters about building extension modules (chapter :ref:`building`) and additional information that pertains only to building on Windows (chapter :ref:`building-on-windows`) for more information about this." msgstr "پیش از آنکه بتوانید از ماژول توسعه‌ای جدید خود استفاده کنید، باید دو کار دیگر انجام دهید: کامپایل کردن و پیوند دادن آن با سیستم پایتون. اگر از بارگذاری پویا استفاده کنید، جزئیات ممکن است به سبک بارگذاری پویایی که سیستم شما از آن استفاده می‌کند بستگی داشته باشد؛ برای اطلاعات بیشتر درباره‌ی این موضوع، به فصل‌های مربوط به ساخت ماژول‌های توسعه‌ای (فصل :ref:`building`) و اطلاعات تکمیلی‌ای که تنها به ساخت روی ویندوز مربوط می‌شود (فصل :ref:`building-on-windows`) مراجعه کنید." msgid "If you can't use dynamic loading, or if you want to make your module a permanent part of the Python interpreter, you will have to change the configuration setup and rebuild the interpreter. Luckily, this is very simple on Unix: just place your file (:file:`spammodule.c` for example) in the :file:`Modules/` directory of an unpacked source distribution, add a line to the file :file:`Modules/Setup.local` describing your file:" msgstr "اگر نتوانید از بارگذاری پویا استفاده کنید، یا اگر می‌خواهید ماژول خود را به بخشی دائمی از مفسر پایتون تبدیل کنید، باید تنظیمات پیکربندی را تغییر دهید و مفسر را بازسازی کنید. خوشبختانه، این کار در یونیکس بسیار ساده است: کافی است پرونده‌ی خود (برای مثال :file:`spammodule.c`) را در پوشه‌ی :file:`Modules/` یک توزیع کد منبعِ استخراج‌شده قرار دهید، و سطری به پرونده‌ی :file:`Modules/Setup.local` اضافه کنید که پرونده‌ی شما را توصیف کند:" msgid "spam spammodule.o" msgstr "spam spammodule.o" msgid "and rebuild the interpreter by running :program:`make` in the toplevel directory. You can also run :program:`make` in the :file:`Modules/` subdirectory, but then you must first rebuild :file:`Makefile` there by running ':program:`make` Makefile'. (This is necessary each time you change the :file:`Setup` file.)" msgstr "و مفسر را با اجرای :program:`make` در پوشه‌ی سطح بالا بازسازی کنید. همچنین می‌توانید :program:`make` را در زیرپوشه‌ی :file:`Modules/` اجرا کنید، اما در این صورت باید ابتدا :file:`Makefile` را در آنجا با اجرای ':program:`make` Makefile' بازسازی کنید. (این کار هر بار که پرونده‌ی :file:`Setup` را تغییر می‌دهید، ضروری است.)" msgid "If your module requires additional libraries to link with, these can be listed on the line in the configuration file as well, for instance:" msgstr "اگر ماژول شما به کتابخانه‌های اضافی برای پیوند دادن نیاز دارد، می‌توانید آن‌ها را نیز در همان سطر در پرونده پیکربندی فهرست کنید، برای مثال:" msgid "spam spammodule.o -lX11" msgstr "spam spammodule.o -lX11" msgid "Calling Python Functions from C" msgstr "فراخوانی توابع پایتون از زبان C" msgid "So far we have concentrated on making C functions callable from Python. The reverse is also useful: calling Python functions from C. This is especially the case for libraries that support so-called \"callback\" functions. If a C interface makes use of callbacks, the equivalent Python often needs to provide a callback mechanism to the Python programmer; the implementation will require calling the Python callback functions from a C callback. Other uses are also imaginable." msgstr "تا اینجا بر فراخوانی‌پذیر کردن توابع C از پایتون تمرکز کرده‌ایم. حالت معکوس نیز کاربردی است: فراخوانی توابع پایتون از C. این موضوع به‌ویژه در مورد کتابخانه‌هایی که از توابعی به اصطلاح «کال‌بک» پشتیبانی می‌کنند صادق است. اگر یک رابط C از کال‌بک‌ها استفاده کند، معادل پایتونی آن اغلب نیاز دارد که سازوکار کال‌بکی را در اختیار برنامه‌نویس پایتون قرار دهد؛ پیاده‌سازی این کار مستلزم فراخوانی توابع کال‌بک پایتون از یک کال‌بک C خواهد بود. کاربردهای دیگری نیز قابل تصور است." msgid "Fortunately, the Python interpreter is easily called recursively, and there is a standard interface to call a Python function. (If you're interested in how to call the Python parser with a particular string as input, see :ref:`veryhigh`.)" msgstr "خوشبختانه، مفسر پایتون به‌راحتی به‌صورت بازگشتی فراخوانی می‌شود و یک رابط استاندارد برای فراخوانی یک تابع پایتون وجود دارد. (اگر می‌خواهید بدانید چگونه می‌توان پارسر پایتون را با یک رشته خاص به‌عنوان ورودی فراخوانی کرد، به :ref:`veryhigh` مراجعه کنید.)" msgid "Calling a Python function is easy. First, the Python program must somehow pass you the Python function object. You should provide a function (or some other interface) to do this. When this function is called, save a pointer to the Python function object (be careful to :c:func:`Py_INCREF` it!) in a global variable --- or wherever you see fit. For example, the following function might be part of a module definition::" msgstr "فراخوانی یک تابع پایتون آسان است. نخست، برنامه پایتون باید به نحوی شیء تابع پایتون را به شما پاس دهد. شما باید تابعی (یا رابط دیگری) برای انجام این کار فراهم کنید. وقتی این تابع فراخوانی شد، اشاره‌گری به شیء تابع پایتون را (مراقب باشید که آن را :c:func:`Py_INCREF` کنید!) در یک متغیر سراسری --- یا هر جای دیگری که صلاح می‌دانید --- ذخیره کنید. برای مثال، تابع زیر ممکن است بخشی از تعریف یک ماژول باشد::" msgid "" "static PyObject *my_callback = NULL;\n" "\n" "static PyObject *\n" "my_set_callback(PyObject *dummy, PyObject *args)\n" "{\n" " PyObject *result = NULL;\n" " PyObject *temp;\n" "\n" " if (PyArg_ParseTuple(args, \"O:set_callback\", &temp)) {\n" " if (!PyCallable_Check(temp)) {\n" " PyErr_SetString(PyExc_TypeError, \"parameter must be callable\");\n" " return NULL;\n" " }\n" " Py_XINCREF(temp); /* Add a reference to new callback */\n" " Py_XDECREF(my_callback); /* Dispose of previous callback */\n" " my_callback = temp; /* Remember new callback */\n" " /* Boilerplate to return \"None\" */\n" " Py_INCREF(Py_None);\n" " result = Py_None;\n" " }\n" " return result;\n" "}" msgstr "" "static PyObject *my_callback = NULL;\n" "\n" "static PyObject *\n" "my_set_callback(PyObject *dummy, PyObject *args)\n" "{\n" " PyObject *result = NULL;\n" " PyObject *temp;\n" "\n" " if (PyArg_ParseTuple(args, \"O:set_callback\", &temp)) {\n" " if (!PyCallable_Check(temp)) {\n" " PyErr_SetString(PyExc_TypeError, \"parameter must be callable\");\n" " return NULL;\n" " }\n" " Py_XINCREF(temp); /* Add a reference to new callback */\n" " Py_XDECREF(my_callback); /* Dispose of previous callback */\n" " my_callback = temp; /* Remember new callback */\n" " /* Boilerplate to return \"None\" */\n" " Py_INCREF(Py_None);\n" " result = Py_None;\n" " }\n" " return result;\n" "}" msgid "This function must be registered with the interpreter using the :c:macro:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The :c:func:`PyArg_ParseTuple` function and its arguments are documented in section :ref:`parsetuple`." msgstr "این تابع باید با استفاده از پرچم :c:macro:`METH_VARARGS` در مفسر ثبت شود؛ این موضوع در بخش :ref:`methodtable` توضیح داده شده است. تابع :c:func:`PyArg_ParseTuple` و آرگومان‌های آن در بخش :ref:`parsetuple` مستندسازی شده‌اند." msgid "The macros :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF` increment/decrement the reference count of an object and are safe in the presence of ``NULL`` pointers (but note that *temp* will not be ``NULL`` in this context). More info on them in section :ref:`refcounts`." msgstr "ماکروهای :c:func:`Py_XINCREF` و :c:func:`Py_XDECREF` شمارش ارجاع یک شیء را افزایش/کاهش می‌دهند و در صورت وجود اشاره‌گرهای ``NULL`` ایمن هستند (اما توجه داشته باشید که *temp* در این زمینه ``NULL`` نخواهد بود). اطلاعات بیشتر درباره‌ی آن‌ها در بخش :ref:`refcounts` آمده است." msgid "Later, when it is time to call the function, you call the C function :c:func:`PyObject_CallObject`. This function has two arguments, both pointers to arbitrary Python objects: the Python function, and the argument list. The argument list must always be a tuple object, whose length is the number of arguments. To call the Python function with no arguments, pass in ``NULL``, or an empty tuple; to call it with one argument, pass a singleton tuple. :c:func:`Py_BuildValue` returns a tuple when its format string consists of zero or more format codes between parentheses. For example::" msgstr "بعداً، وقتی زمان فراخوانی تابع فرا می‌رسد، شما تابع Cِ :c:func:`PyObject_CallObject` را فراخوانی می‌کنید. این تابع دو آرگومان دارد که هر دو اشاره‌گر به اشیاء پایتونی دلخواه هستند: تابع پایتونی و فهرست آرگومان‌ها. فهرست آرگومان‌ها باید همیشه یک شیء تاپل باشد که طول آن برابر با تعداد آرگومان‌هاست. برای فراخوانی تابع پایتونی بدون هیچ آرگومانی، ``NULL`` یا یک تاپل خالی را ارسال کنید؛ برای فراخوانی آن با یک آرگومان، یک تاپل تک‌نمونه ارسال کنید. :c:func:`Py_BuildValue` زمانی که رشته قالب آن از صفر یا چند کد قالب درون پرانتز تشکیل شده باشد، یک تاپل برمی‌گرداند. برای مثال::" msgid "" "int arg;\n" "PyObject *arglist;\n" "PyObject *result;\n" "...\n" "arg = 123;\n" "...\n" "/* Time to call the callback */\n" "arglist = Py_BuildValue(\"(i)\", arg);\n" "result = PyObject_CallObject(my_callback, arglist);\n" "Py_DECREF(arglist);" msgstr "" "int arg;\n" "PyObject *arglist;\n" "PyObject *result;\n" "...\n" "arg = 123;\n" "...\n" "/* Time to call the callback */\n" "arglist = Py_BuildValue(\"(i)\", arg);\n" "result = PyObject_CallObject(my_callback, arglist);\n" "Py_DECREF(arglist);" msgid ":c:func:`PyObject_CallObject` returns a Python object pointer: this is the return value of the Python function. :c:func:`PyObject_CallObject` is \"reference-count-neutral\" with respect to its arguments. In the example a new tuple was created to serve as the argument list, which is :c:func:`Py_DECREF`\\ -ed immediately after the :c:func:`PyObject_CallObject` call." msgstr ":c:func:`PyObject_CallObject` یک اشاره‌گر به شیء پایتون برمی‌گرداند: این همان مقدار بازگشتی تابع پایتون است. :c:func:`PyObject_CallObject` نسبت به آرگومان‌های خود، از نظر شمارش ارجاع خنثی (reference-count-neutral) است. در این مثال، یک تاپل جدید برای استفاده به‌عنوان فهرست آرگومان‌ها ساخته می‌شود که بلافاصله پس از فراخوانی :c:func:`PyObject_CallObject`، :c:func:`Py_DECREF` روی آن اعمال می‌شود." msgid "The return value of :c:func:`PyObject_CallObject` is \"new\": either it is a brand new object, or it is an existing object whose reference count has been incremented. So, unless you want to save it in a global variable, you should somehow :c:func:`Py_DECREF` the result, even (especially!) if you are not interested in its value." msgstr "مقدار بازگشتی :c:func:`PyObject_CallObject` «جدید» است: یا شیئی کاملاً جدید است، یا شیئی موجود است که شمارش ارجاع آن افزایش یافته است. بنابراین، مگر آنکه بخواهید آن را در یک متغیر سراسری ذخیره کنید، باید به نحوی نتیجه را :c:func:`Py_DECREF` کنید، حتی (به‌ویژه!) اگر علاقه‌ای به مقدار آن نداشته باشید." msgid "Before you do this, however, it is important to check that the return value isn't ``NULL``. If it is, the Python function terminated by raising an exception. If the C code that called :c:func:`PyObject_CallObject` is called from Python, it should now return an error indication to its Python caller, so the interpreter can print a stack trace, or the calling Python code can handle the exception. If this is not possible or desirable, the exception should be cleared by calling :c:func:`PyErr_Clear`. For example::" msgstr "با این حال، پیش از انجام این کار، مهم است که بررسی کنید مقدار بازگشتی ``NULL`` نیست. اگر چنین باشد، تابع پایتونی با ایجاد یک استثنا خاتمه یافته است. اگر کد C که :c:func:`PyObject_CallObject` را فراخوانی کرده است از پایتون فراخوانی شده باشد، باید اکنون نشان خطایی را به فراخواننده پایتونی خود بازگرداند تا مفسر بتواند ردگیری پشته را چاپ کند، یا کد پایتونی فراخواننده بتواند استثنا را مدیریت کند. اگر این کار ممکن یا مطلوب نباشد، استثنا باید با فراخوانی :c:func:`PyErr_Clear` پاک شود. برای مثال::" msgid "" "if (result == NULL)\n" " return NULL; /* Pass error back */\n" "...use result...\n" "Py_DECREF(result);" msgstr "" "if (result == NULL)\n" " return NULL; /* Pass error back */\n" "...use result...\n" "Py_DECREF(result);" msgid "Depending on the desired interface to the Python callback function, you may also have to provide an argument list to :c:func:`PyObject_CallObject`. In some cases the argument list is also provided by the Python program, through the same interface that specified the callback function. It can then be saved and used in the same manner as the function object. In other cases, you may have to construct a new tuple to pass as the argument list. The simplest way to do this is to call :c:func:`Py_BuildValue`. For example, if you want to pass an integral event code, you might use the following code::" msgstr "بسته به رابط مورد نظر برای تابع کال‌بک پایتون، ممکن است لازم باشد فهرست آرگومان‌ها را نیز به :c:func:`PyObject_CallObject` ارائه کنید. در برخی موارد، فهرست آرگومان‌ها نیز توسط برنامه پایتون و از طریق همان رابطی که تابع کال‌بک را مشخص کرده بود، فراهم می‌شود. در این صورت می‌توان آن را ذخیره کرد و به همان شیوه‌ی شیء تابع از آن استفاده کرد. در موارد دیگر، ممکن است لازم باشد یک تاپل جدید ایجاد کنید تا آن را به‌عنوان فهرست آرگومان‌ها ارسال کنید. ساده‌ترین راه انجام این کار، فراخوانی :c:func:`Py_BuildValue` است. برای مثال، اگر بخواهید کد رویدادی از نوع عدد صحیح ارسال کنید، ممکن است از کد زیر استفاده کنید::" msgid "" "PyObject *arglist;\n" "...\n" "arglist = Py_BuildValue(\"(l)\", eventcode);\n" "result = PyObject_CallObject(my_callback, arglist);\n" "Py_DECREF(arglist);\n" "if (result == NULL)\n" " return NULL; /* Pass error back */\n" "/* Here maybe use the result */\n" "Py_DECREF(result);" msgstr "" "PyObject *arglist;\n" "...\n" "arglist = Py_BuildValue(\"(l)\", eventcode);\n" "result = PyObject_CallObject(my_callback, arglist);\n" "Py_DECREF(arglist);\n" "if (result == NULL)\n" " return NULL; /* بازگرداندن خطا */\n" "/* اینجا شاید از نتیجه استفاده شود */\n" "Py_DECREF(result);" msgid "Note the placement of ``Py_DECREF(arglist)`` immediately after the call, before the error check! Also note that strictly speaking this code is not complete: :c:func:`Py_BuildValue` may run out of memory, and this should be checked." msgstr "به قرارگیری ``Py_DECREF(arglist)`` بلافاصله پس از فراخوانی و پیش از بررسی خطا توجه کنید! همچنین توجه داشته باشید که به‌طور دقیق این کد کامل نیست: ممکن است :c:func:`Py_BuildValue` با کمبود حافظه مواجه شود و این موضوع باید بررسی شود." msgid "You may also call a function with keyword arguments by using :c:func:`PyObject_Call`, which supports arguments and keyword arguments. As in the above example, we use :c:func:`Py_BuildValue` to construct the dictionary. ::" msgstr "شما همچنین می‌توانید با استفاده از :c:func:`PyObject_Call` که از آرگومان‌ها و آرگومان‌های کلیدواژه‌ای پشتیبانی می‌کند، تابعی را با آرگومان‌های کلیدواژه‌ای فراخوانی کنید. مانند مثال بالا، از :c:func:`Py_BuildValue` برای ساخت دیکشنری استفاده می‌کنیم. ::" msgid "" "PyObject *dict;\n" "...\n" "dict = Py_BuildValue(\"{s:i}\", \"name\", val);\n" "result = PyObject_Call(my_callback, NULL, dict);\n" "Py_DECREF(dict);\n" "if (result == NULL)\n" " return NULL; /* Pass error back */\n" "/* Here maybe use the result */\n" "Py_DECREF(result);" msgstr "" "PyObject *dict;\n" "...\n" "dict = Py_BuildValue(\"{s:i}\", \"name\", val);\n" "result = PyObject_Call(my_callback, NULL, dict);\n" "Py_DECREF(dict);\n" "if (result == NULL)\n" " return NULL; /* بازگرداندن خطا */\n" "/* اینجا شاید از نتیجه استفاده کنید */\n" "Py_DECREF(result);" msgid "Extracting Parameters in Extension Functions" msgstr "استخراج پارامترها در توابع توسعه‌ای" msgid "The :c:func:`PyArg_ParseTuple` function is declared as follows::" msgstr "تابع :c:func:`PyArg_ParseTuple` به شرح زیر تعریف شده است::" msgid "int PyArg_ParseTuple(PyObject *arg, const char *format, ...);" msgstr "int PyArg_ParseTuple(PyObject *arg, const char *format, ...);" msgid "The *arg* argument must be a tuple object containing an argument list passed from Python to a C function. The *format* argument must be a format string, whose syntax is explained in :ref:`arg-parsing` in the Python/C API Reference Manual. The remaining arguments must be addresses of variables whose type is determined by the format string." msgstr "آرگومان *arg* باید یک شیء تاپل حاوی فهرست آرگومانی باشد که از پایتون به یک تابع C پاس داده می‌شود. آرگومان *format* باید یک رشته قالب باشد که سینتکس آن در :ref:`arg-parsing` در راهنمای مرجع Python/C API توضیح داده شده است. آرگومان‌های باقی‌مانده باید آدرس‌های متغیرهایی باشند که نوع آن‌ها توسط رشته قالب تعیین می‌شود." msgid "Note that while :c:func:`PyArg_ParseTuple` checks that the Python arguments have the required types, it cannot check the validity of the addresses of C variables passed to the call: if you make mistakes there, your code will probably crash or at least overwrite random bits in memory. So be careful!" msgstr "توجه داشته باشید که هرچند :c:func:`PyArg_ParseTuple` بررسی می‌کند که آرگومان‌های پایتون نوع‌های مورد نیاز را داشته باشند، نمی‌تواند اعتبار نشانی‌های متغیرهای C که به فراخوانی ارسال شده‌اند را بررسی کند: اگر در آنجا اشتباهی کنید، کد شما احتمالاً فروپاشی می‌کند یا دست‌کم بیت‌های تصادفی در حافظه را بازنویسی می‌کند. پس مراقب باشید!" msgid "Note that any Python object references which are provided to the caller are *borrowed* references; do not decrement their reference count!" msgstr "توجه داشته باشید که هر ارجاع به شیء پایتون که در اختیار فراخواننده قرار می‌گیرد، یک ارجاع *امانتی* است؛ شمارش ارجاع آن‌ها را کاهش ندهید!" msgid "Some example calls::" msgstr "چند نمونه فراخوانی::" msgid "" "int ok;\n" "int i, j;\n" "long k, l;\n" "const char *s;\n" "Py_ssize_t size;\n" "\n" "ok = PyArg_ParseTuple(args, \"\"); /* No arguments */\n" " /* Python call: f() */" msgstr "" "int ok;\n" "int i, j;\n" "long k, l;\n" "const char *s;\n" "Py_ssize_t size;\n" "\n" "ok = PyArg_ParseTuple(args, \"\"); /* No arguments */\n" " /* Python call: f() */" msgid "" "ok = PyArg_ParseTuple(args, \"s\", &s); /* A string */\n" " /* Possible Python call: f('whoops!') */" msgstr "" "ok = PyArg_ParseTuple(args, \"s\", &s); /* A string */\n" " /* Possible Python call: f('whoops!') */" msgid "" "ok = PyArg_ParseTuple(args, \"lls\", &k, &l, &s); /* Two longs and a string */\n" " /* Possible Python call: f(1, 2, 'three') */" msgstr "" "ok = PyArg_ParseTuple(args, \"lls\", &k, &l, &s); /* دو long و یک رشته */\n" " /* فراخوانی ممکن پایتون: f(1, 2, 'three') */" msgid "" "ok = PyArg_ParseTuple(args, \"(ii)s#\", &i, &j, &s, &size);\n" " /* A pair of ints and a string, whose size is also returned */\n" " /* Possible Python call: f((1, 2), 'three') */" msgstr "" "ok = PyArg_ParseTuple(args, \"(ii)s#\", &i, &j, &s, &size);\n" " /* یک جفت عدد صحیح و یک رشته، که اندازه‌ی آن نیز برگردانده می‌شود */\n" " /* فراخوانی ممکن پایتون: f((1, 2), 'three') */" msgid "" "{\n" " const char *file;\n" " const char *mode = \"r\";\n" " int bufsize = 0;\n" " ok = PyArg_ParseTuple(args, \"s|si\", &file, &mode, &bufsize);\n" " /* A string, and optionally another string and an integer */\n" " /* Possible Python calls:\n" " f('spam')\n" " f('spam', 'w')\n" " f('spam', 'wb', 100000) */\n" "}" msgstr "" "{\n" " const char *file;\n" " const char *mode = \"r\";\n" " int bufsize = 0;\n" " ok = PyArg_ParseTuple(args, \"s|si\", &file, &mode, &bufsize);\n" " /* A string, and optionally another string and an integer */\n" " /* Possible Python calls:\n" " f('spam')\n" " f('spam', 'w')\n" " f('spam', 'wb', 100000) */\n" "}" msgid "" "{\n" " int left, top, right, bottom, h, v;\n" " ok = PyArg_ParseTuple(args, \"((ii)(ii))(ii)\",\n" " &left, &top, &right, &bottom, &h, &v);\n" " /* A rectangle and a point */\n" " /* Possible Python call:\n" " f(((0, 0), (400, 300)), (10, 10)) */\n" "}" msgstr "" "{\n" " int left, top, right, bottom, h, v;\n" " ok = PyArg_ParseTuple(args, \"((ii)(ii))(ii)\",\n" " &left, &top, &right, &bottom, &h, &v);\n" " /* A rectangle and a point */\n" " /* Possible Python call:\n" " f(((0, 0), (400, 300)), (10, 10)) */\n" "}" msgid "" "{\n" " Py_complex c;\n" " ok = PyArg_ParseTuple(args, \"D:myfunction\", &c);\n" " /* a complex, also providing a function name for errors */\n" " /* Possible Python call: myfunction(1+2j) */\n" "}" msgstr "" "{\n" " Py_complex c;\n" " ok = PyArg_ParseTuple(args, \"D:myfunction\", &c);\n" " /* a complex, also providing a function name for errors */\n" " /* Possible Python call: myfunction(1+2j) */\n" "}" msgid "Keyword Parameters for Extension Functions" msgstr "پارامترهای کلیدواژه‌ای برای توابع توسعه‌ای" msgid "The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows::" msgstr "تابع :c:func:`PyArg_ParseTupleAndKeywords` به صورت زیر اعلان می‌شود::" msgid "" "int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,\n" " const char *format, char * const *kwlist, ...);" msgstr "" "int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,\n" " const char *format, char * const *kwlist, ...);" msgid "The *arg* and *format* parameters are identical to those of the :c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of keywords received as the third parameter from the Python runtime. The *kwlist* parameter is a ``NULL``-terminated list of strings which identify the parameters; the names are matched with the type information from *format* from left to right. On success, :c:func:`PyArg_ParseTupleAndKeywords` returns true, otherwise it returns false and raises an appropriate exception." msgstr "پارامتر‌های *arg* و *format* با پارامتر‌های تابع :c:func:`PyArg_ParseTuple` یکسان هستند. پارامتر *kwdict* دیکشنری کلیدواژه‌هایی است که به‌عنوان پارامتر سوم از ران‌تایم پایتون دریافت می‌شود. پارامتر *kwlist* فهرستی از رشته‌هاست که با ``NULL`` پایان می‌یابد و پارامترها را شناسایی می‌کند؛ نام‌ها از چپ به راست با اطلاعات نوع گرفته‌شده از *format* تطبیق داده می‌شوند. در صورت موفقیت، :c:func:`PyArg_ParseTupleAndKeywords` مقدار true را برمی‌گرداند؛ در غیر این صورت مقدار false را برمی‌گرداند و استثنای مناسبی ایجاد می‌کند." msgid "Nested tuples cannot be parsed when using keyword arguments! Keyword parameters passed in which are not present in the *kwlist* will cause :exc:`TypeError` to be raised." msgstr "تاپل‌های تودرتو هنگام استفاده از آرگومان‌های کلیدواژه‌ای قابل تجزیه نیستند! پارامترهای کلیدواژه‌ای که پاس داده می‌شوند و در *kwlist* وجود ندارند، باعث به‌وجود آمدن :exc:`TypeError` می‌شوند." msgid "Here is an example module which uses keywords, based on an example by Geoff Philbrick (philbrick@hks.com)::" msgstr "در اینجا یک ماژول نمونه که از کلیدواژه‌ها استفاده می‌کند، بر اساس نمونه‌ای از Geoff Philbrick (philbrick@hks.com) آمده است::" msgid "" "#define PY_SSIZE_T_CLEAN\n" "#include \n" "\n" "static PyObject *\n" "keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)\n" "{\n" " int voltage;\n" " const char *state = \"a stiff\";\n" " const char *action = \"voom\";\n" " const char *type = \"Norwegian Blue\";\n" "\n" " static char *kwlist[] = {\"voltage\", \"state\", \"action\", \"type\", NULL};\n" "\n" " if (!PyArg_ParseTupleAndKeywords(args, keywds, \"i|sss\", kwlist,\n" " &voltage, &state, &action, &type))\n" " return NULL;\n" "\n" " printf(\"-- This parrot wouldn't %s if you put %i Volts through it.\\n\",\n" " action, voltage);\n" " printf(\"-- Lovely plumage, the %s -- It's %s!\\n\", type, state);\n" "\n" " Py_RETURN_NONE;\n" "}\n" "\n" "static PyMethodDef keywdarg_methods[] = {\n" " /* The cast of the function is necessary since PyCFunction values\n" " * only take two PyObject* parameters, and keywdarg_parrot() takes\n" " * three.\n" " */\n" " {\"parrot\", (PyCFunction)(void(*)(void))keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,\n" " \"Print a lovely skit to standard output.\"},\n" " {NULL, NULL, 0, NULL} /* sentinel */\n" "};\n" "\n" "static struct PyModuleDef keywdarg_module = {\n" " .m_base = PyModuleDef_HEAD_INIT,\n" " .m_name = \"keywdarg\",\n" " .m_size = 0,\n" " .m_methods = keywdarg_methods,\n" "};\n" "\n" "PyMODINIT_FUNC\n" "PyInit_keywdarg(void)\n" "{\n" " return PyModuleDef_Init(&keywdarg_module);\n" "}" msgstr "" "#define PY_SSIZE_T_CLEAN\n" "#include \n" "\n" "static PyObject *\n" "keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)\n" "{\n" " int voltage;\n" " const char *state = \"a stiff\";\n" " const char *action = \"voom\";\n" " const char *type = \"Norwegian Blue\";\n" "\n" " static char *kwlist[] = {\"voltage\", \"state\", \"action\", \"type\", NULL};\n" "\n" " if (!PyArg_ParseTupleAndKeywords(args, keywds, \"i|sss\", kwlist,\n" " &voltage, &state, &action, &type))\n" " return NULL;\n" "\n" " printf(\"-- This parrot wouldn't %s if you put %i Volts through it.\\n\",\n" " action, voltage);\n" " printf(\"-- Lovely plumage, the %s -- It's %s!\\n\", type, state);\n" "\n" " Py_RETURN_NONE;\n" "}\n" "\n" "static PyMethodDef keywdarg_methods[] = {\n" " /* The cast of the function is necessary since PyCFunction values\n" " * only take two PyObject* parameters, and keywdarg_parrot() takes\n" " * three.\n" " */\n" " {\"parrot\", (PyCFunction)(void(*)(void))keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,\n" " \"Print a lovely skit to standard output.\"},\n" " {NULL, NULL, 0, NULL} /* sentinel */\n" "};\n" "\n" "static struct PyModuleDef keywdarg_module = {\n" " .m_base = PyModuleDef_HEAD_INIT,\n" " .m_name = \"keywdarg\",\n" " .m_size = 0,\n" " .m_methods = keywdarg_methods,\n" "};\n" "\n" "PyMODINIT_FUNC\n" "PyInit_keywdarg(void)\n" "{\n" " return PyModuleDef_Init(&keywdarg_module);\n" "}" msgid "Building Arbitrary Values" msgstr "ساخت مقادیر دلخواه" msgid "This function is the counterpart to :c:func:`PyArg_ParseTuple`. It is declared as follows::" msgstr "این تابع همتای :c:func:`PyArg_ParseTuple` است. این تابع به صورت زیر اعلان می‌شود::" msgid "PyObject *Py_BuildValue(const char *format, ...);" msgstr "PyObject *Py_BuildValue(const char *format, ...);" msgid "It recognizes a set of format units similar to the ones recognized by :c:func:`PyArg_ParseTuple`, but the arguments (which are input to the function, not output) must not be pointers, just values. It returns a new Python object, suitable for returning from a C function called from Python." msgstr "این تابع مجموعه‌ای از واحدهای قالب (format units) را تشخیص می‌دهد که مشابه واحدهای شناسایی‌شده توسط :c:func:`PyArg_ParseTuple` هستند، اما آرگومان‌ها (که ورودی تابع هستند، نه خروجی آن) نباید اشاره‌گر باشند، بلکه باید فقط مقدار باشند. این تابع یک شیء جدید پایتون برمی‌گرداند که برای بازگرداندن از یک تابع C فراخوانی‌شده از پایتون مناسب است." msgid "One difference with :c:func:`PyArg_ParseTuple`: while the latter requires its first argument to be a tuple (since Python argument lists are always represented as tuples internally), :c:func:`Py_BuildValue` does not always build a tuple. It builds a tuple only if its format string contains two or more format units. If the format string is empty, it returns ``None``; if it contains exactly one format unit, it returns whatever object is described by that format unit. To force it to return a tuple of size 0 or one, parenthesize the format string." msgstr "یک تفاوت با :c:func:`PyArg_ParseTuple` این است که در حالی که دومی نیازمند است آرگومان اولش یک تاپل باشد (چرا که فهرست‌های آرگومان پایتون همیشه به صورت داخلی به شکل تاپل نمایش داده می‌شوند)، :c:func:`Py_BuildValue` همیشه یک تاپل نمی‌سازد. این تابع تنها زمانی یک تاپل می‌سازد که رشته قالب‌بندی آن دو واحد قالب‌بندی یا بیشتر داشته باشد. اگر رشته قالب‌بندی خالی باشد، ``None`` برمی‌گرداند؛ اگر دقیقاً یک واحد قالب‌بندی داشته باشد، هر شیئی را که آن واحد قالب‌بندی توصیف می‌کند برمی‌گرداند. برای اینکه آن را وادار کنید یک تاپل با اندازه‌ی ۰ یا ۱ برگرداند، رشته قالب‌بندی را داخل پرانتز قرار دهید." msgid "Examples (to the left the call, to the right the resulting Python value):" msgstr "مثال‌ها (در سمت چپ فراخوانی، در سمت راست مقدار حاصل در پایتون):" msgid "" "Py_BuildValue(\"\") None\n" "Py_BuildValue(\"i\", 123) 123\n" "Py_BuildValue(\"iii\", 123, 456, 789) (123, 456, 789)\n" "Py_BuildValue(\"s\", \"hello\") 'hello'\n" "Py_BuildValue(\"y\", \"hello\") b'hello'\n" "Py_BuildValue(\"ss\", \"hello\", \"world\") ('hello', 'world')\n" "Py_BuildValue(\"s#\", \"hello\", 4) 'hell'\n" "Py_BuildValue(\"y#\", \"hello\", 4) b'hell'\n" "Py_BuildValue(\"()\") ()\n" "Py_BuildValue(\"(i)\", 123) (123,)\n" "Py_BuildValue(\"(ii)\", 123, 456) (123, 456)\n" "Py_BuildValue(\"(i,i)\", 123, 456) (123, 456)\n" "Py_BuildValue(\"[i,i]\", 123, 456) [123, 456]\n" "Py_BuildValue(\"{s:i,s:i}\",\n" " \"abc\", 123, \"def\", 456) {'abc': 123, 'def': 456}\n" "Py_BuildValue(\"((ii)(ii)) (ii)\",\n" " 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))" msgstr "" "Py_BuildValue(\"\") None\n" "Py_BuildValue(\"i\", 123) 123\n" "Py_BuildValue(\"iii\", 123, 456, 789) (123, 456, 789)\n" "Py_BuildValue(\"s\", \"hello\") 'hello'\n" "Py_BuildValue(\"y\", \"hello\") b'hello'\n" "Py_BuildValue(\"ss\", \"hello\", \"world\") ('hello', 'world')\n" "Py_BuildValue(\"s#\", \"hello\", 4) 'hell'\n" "Py_BuildValue(\"y#\", \"hello\", 4) b'hell'\n" "Py_BuildValue(\"()\") ()\n" "Py_BuildValue(\"(i)\", 123) (123,)\n" "Py_BuildValue(\"(ii)\", 123, 456) (123, 456)\n" "Py_BuildValue(\"(i,i)\", 123, 456) (123, 456)\n" "Py_BuildValue(\"[i,i]\", 123, 456) [123, 456]\n" "Py_BuildValue(\"{s:i,s:i}\",\n" " \"abc\", 123, \"def\", 456) {'abc': 123, 'def': 456}\n" "Py_BuildValue(\"((ii)(ii)) (ii)\",\n" " 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))" msgid "Reference Counts" msgstr "شمارش ارجاع" msgid "In languages like C or C++, the programmer is responsible for dynamic allocation and deallocation of memory on the heap. In C, this is done using the functions :c:func:`malloc` and :c:func:`free`. In C++, the operators ``new`` and ``delete`` are used with essentially the same meaning and we'll restrict the following discussion to the C case." msgstr "در زبان‌هایی مانند C یا C++، برنامه‌نویس مسئول تخصیص پویا و آزادسازی حافظه روی هیپ است. در C، این کار با استفاده از توابع :c:func:`malloc` و :c:func:`free` انجام می‌شود. در C++، عملگرهای ``new`` و ``delete`` با معنایی اساساً یکسان به کار می‌روند و بحث زیر را به مورد C محدود می‌کنیم." msgid "Every block of memory allocated with :c:func:`malloc` should eventually be returned to the pool of available memory by exactly one call to :c:func:`free`. It is important to call :c:func:`free` at the right time. If a block's address is forgotten but :c:func:`free` is not called for it, the memory it occupies cannot be reused until the program terminates. This is called a :dfn:`memory leak`. On the other hand, if a program calls :c:func:`free` for a block and then continues to use the block, it creates a conflict with reuse of the block through another :c:func:`malloc` call. This is called :dfn:`using freed memory`. It has the same bad consequences as referencing uninitialized data --- core dumps, wrong results, mysterious crashes." msgstr "هر بلوک حافظه‌ای که با :c:func:`malloc` تخصیص داده‌شده باشد، باید در نهایت از طریق دقیقاً یک فراخوانی :c:func:`free` به استخر حافظه‌ی در دسترس بازگردانده شود. مهم است که :c:func:`free` در زمان مناسب فراخوانی شود. اگر نشانی یک بلوک فراموش شود اما :c:func:`free` برای آن فراخوانی نشود، حافظه‌ای که آن بلوک اشغال کرده است، تا زمانی که برنامه خاتمه یابد، قابل استفاده‌ی مجدد نخواهد بود. این وضعیت :dfn:`نشت حافظه (memory leak)` نامیده می‌شود. از سوی دیگر، اگر برنامه‌ای :c:func:`free` را برای یک بلوک فراخوانی کند و سپس به استفاده از آن بلوک ادامه دهد، با استفاده‌ی مجدد از آن بلوک از طریق یک فراخوانی دیگر :c:func:`malloc` تداخل ایجاد می‌کند. این کار :dfn:`استفاده از حافظه‌ی آزادشده (using freed memory)` نامیده می‌شود. این همان پیامدهای بد ارجاع به داده‌های مقداردهی‌نشده را دارد --- برون‌ریزی هسته، نتایج نادرست، فروپاشی‌های مرموز." msgid "Common causes of memory leaks are unusual paths through the code. For instance, a function may allocate a block of memory, do some calculation, and then free the block again. Now a change in the requirements for the function may add a test to the calculation that detects an error condition and can return prematurely from the function. It's easy to forget to free the allocated memory block when taking this premature exit, especially when it is added later to the code. Such leaks, once introduced, often go undetected for a long time: the error exit is taken only in a small fraction of all calls, and most modern machines have plenty of virtual memory, so the leak only becomes apparent in a long-running process that uses the leaking function frequently. Therefore, it's important to prevent leaks from happening by having a coding convention or strategy that minimizes this kind of errors." msgstr "علت‌های رایج نشت حافظه، مسیرهای غیرمعمول در کد هستند. برای مثال، ممکن است یک تابع بلوکی از حافظه را تخصیص دهد، محاسبه‌ای انجام دهد و سپس بلوک را دوباره آزاد کند. اکنون تغییری در نیازمندی‌های تابع ممکن است آزمونی به محاسبه اضافه کند که شرط خطا را تشخیص می‌دهد و می‌تواند زودهنگام از تابع بازگردد. آسان است که آزاد کردن بلوک حافظه‌ی تخصیص‌یافته هنگام این خروج زودهنگام فراموش شود، به‌خصوص وقتی که این خروج بعداً به کد اضافه می‌شود. چنین نشت‌هایی، پس از ایجاد، اغلب مدت طولانی تشخیص داده نمی‌شوند: خروج خطا فقط در بخش کوچکی از همه‌ی فراخوانی‌ها رخ می‌دهد و بیشتر ماشین‌های مدرن حافظه‌ی مجازی فراوانی دارند، بنابراین نشت تنها در فرایند طولانی‌مدتی که مکرراً از تابع نشت‌کننده استفاده می‌کند آشکار می‌شود. از این رو، مهم است که با داشتن قرارداد یا راهبرد کدنویسی‌ای که این نوع خطاها را به حداقل می‌رساند، از وقوع نشت‌ها جلوگیری کنید." msgid "Since Python makes heavy use of :c:func:`malloc` and :c:func:`free`, it needs a strategy to avoid memory leaks as well as the use of freed memory. The chosen method is called :dfn:`reference counting`. The principle is simple: every object contains a counter, which is incremented when a reference to the object is stored somewhere, and which is decremented when a reference to it is deleted. When the counter reaches zero, the last reference to the object has been deleted and the object is freed." msgstr "از آنجا که پایتون به‌طور گسترده از :c:func:`malloc` و :c:func:`free` استفاده می‌کند، به راهبردی نیاز دارد تا از نشت حافظه و همچنین استفاده از حافظه‌ی آزادشده جلوگیری کند. روش انتخاب‌شده :dfn:`شمارش ارجاع (reference counting)` نام دارد. اصل کار ساده است: هر شیء شامل یک شمارنده است که وقتی ارجاعی به شیء در جایی ذخیره می‌شود، افزایش می‌یابد و وقتی ارجاعی به آن حذف می‌شود، کاهش می‌یابد. وقتی شمارنده به صفر برسد، آخرین ارجاع به شیء حذف شده و شیء آزاد می‌شود." msgid "An alternative strategy is called :dfn:`automatic garbage collection`. (Sometimes, reference counting is also referred to as a garbage collection strategy, hence the use of \"automatic\" to distinguish the two.) The big advantage of automatic garbage collection is that the user doesn't need to call :c:func:`free` explicitly. (Another claimed advantage is an improvement in speed or memory usage --- this is no hard fact however.) The disadvantage is that for C, there is no truly portable automatic garbage collector, while reference counting can be implemented portably (as long as the functions :c:func:`malloc` and :c:func:`free` are available --- which the C Standard guarantees). Maybe some day a sufficiently portable automatic garbage collector will be available for C. Until then, we'll have to live with reference counts." msgstr "راهبردی جایگزین، :dfn:`زباله‌روبی خودکار (automatic garbage collection)` نامیده می‌شود. (گاهی شمارش ارجاع نیز به‌عنوان یک راهبرد زباله‌روبی شناخته می‌شود، از این رو از واژه‌ی «خودکار» برای تمایز میان این دو استفاده می‌شود.) مزیت بزرگ زباله‌روبی خودکار این است که کاربر نیازی به فراخوانی صریح :c:func:`free` ندارد. (مزیت دیگری که ادعا می‌شود، بهبود سرعت یا مصرف حافظه است --- هرچند این موضوع واقعیتی قطعی نیست.) نقطه‌ضعف این است که برای C، هیچ زباله‌روب خودکاری که واقعاً قابل حمل باشد وجود ندارد، در حالی که شمارش ارجاع را می‌توان به‌صورت قابل حمل پیاده‌سازی کرد (تا زمانی که توابع :c:func:`malloc` و :c:func:`free` در دسترس باشند --- که استاندارد C آن را تضمین می‌کند). شاید روزی زباله‌روب خودکاری که به‌اندازه‌ی کافی قابل حمل باشد، برای C در دسترس قرار گیرد. تا آن زمان، چاره‌ای جز سازگاری با شمارش ارجاع نداریم." msgid "While Python uses the traditional reference counting implementation, it also offers a cycle detector that works to detect reference cycles. This allows applications to not worry about creating direct or indirect circular references; these are the weakness of garbage collection implemented using only reference counting. Reference cycles consist of objects which contain (possibly indirect) references to themselves, so that each object in the cycle has a reference count which is non-zero. Typical reference counting implementations are not able to reclaim the memory belonging to any objects in a reference cycle, or referenced from the objects in the cycle, even though there are no further references to the cycle itself." msgstr "در حالی که پایتون از پیاده‌سازی سنتی شمارش ارجاع استفاده می‌کند، همچنین آشکارساز چرخه‌ای ارائه می‌دهد که برای تشخیص چرخه‌های ارجاع کار می‌کند. این امر به برنامه‌ها اجازه می‌دهد که نگران ایجاد ارجاع‌های دایره‌ای مستقیم یا غیرمستقیم نباشند؛ این ارجاع‌ها نقطه‌ضعف زباله‌روبی‌ای هستند که تنها با استفاده از شمارش ارجاع پیاده‌سازی شده است. چرخه‌های ارجاع از اشیایی تشکیل شده‌اند که ارجاع‌هایی (احتمالاً غیرمستقیم) به خود دارند، به‌طوری که هر شیء در چرخه تعداد ارجاعی غیر از صفر دارد. پیاده‌سازی‌های متداول شمارش ارجاع نمی‌توانند حافظه‌ی متعلق به هیچ‌یک از اشیای درون یک چرخه ارجاع، یا اشیایی که از سوی اشیای درون چرخه به آن‌ها ارجاع شده است، را بازیابی کنند، هرچند هیچ ارجاع دیگری به خود چرخه وجود ندارد." msgid "The cycle detector is able to detect garbage cycles and can reclaim them. The :mod:`gc` module exposes a way to run the detector (the :func:`~gc.collect` function), as well as configuration interfaces and the ability to disable the detector at runtime." msgstr "آشکارساز چرخه می‌تواند چرخه‌های زباله را تشخیص دهد و آن‌ها را بازپس‌گیری کند. ماژول :mod:`gc` راهی برای اجرای آشکارساز (تابع :func:`~gc.collect`)، و همچنین رابط‌های پیکربندی و امکان غیرفعال‌سازی آشکارساز در زمان اجرا را فراهم می‌کند." msgid "Reference Counting in Python" msgstr "شمارش ارجاع در پایتون" msgid "There are two macros, ``Py_INCREF(x)`` and ``Py_DECREF(x)``, which handle the incrementing and decrementing of the reference count. :c:func:`Py_DECREF` also frees the object when the count reaches zero. For flexibility, it doesn't call :c:func:`free` directly --- rather, it makes a call through a function pointer in the object's :dfn:`type object`. For this purpose (and others), every object also contains a pointer to its type object." msgstr "دو ماکرو وجود دارد، ``Py_INCREF(x)`` و ``Py_DECREF(x)``، که افزایش و کاهش شمارش ارجاع را بر عهده دارند. :c:func:`Py_DECREF` همچنین هنگامی که شمارش به صفر برسد، شیء را آزاد می‌کند. برای انعطاف‌پذیری، این ماکرو :c:func:`free` را مستقیماً فراخوانی نمی‌کند --- بلکه فراخوانی را از طریق یک اشاره‌گر تابع در :dfn:`شیء نوع (type object)` مربوط به آن شیء انجام می‌دهد. برای این منظور (و منظورهای دیگر)، هر شیء همچنین حاوی اشاره‌گری به شیء نوع خود است." msgid "The big question now remains: when to use ``Py_INCREF(x)`` and ``Py_DECREF(x)``? Let's first introduce some terms. Nobody \"owns\" an object; however, you can :dfn:`own a reference` to an object. An object's reference count is now defined as the number of owned references to it. The owner of a reference is responsible for calling :c:func:`Py_DECREF` when the reference is no longer needed. Ownership of a reference can be transferred. There are three ways to dispose of an owned reference: pass it on, store it, or call :c:func:`Py_DECREF`. Forgetting to dispose of an owned reference creates a memory leak." msgstr "اکنون پرسش بزرگ این است: چه زمانی باید از ``Py_INCREF(x)`` و ``Py_DECREF(x)`` استفاده کرد؟ اجازه دهید ابتدا چند اصطلاح را معرفی کنیم. هیچ‌کس «مالک» یک شیء نیست؛ اما شما می‌توانید :dfn:`مالک یک ارجاع (own a reference)` به یک شیء باشید. اکنون شمارش ارجاع یک شیء به‌عنوان تعداد ارجاع‌های در مالکیت به آن تعریف می‌شود. مالک یک ارجاع مسئول است که وقتی دیگر به ارجاع نیازی نیست، :c:func:`Py_DECREF` را فراخوانی کند. مالکیت یک ارجاع می‌تواند منتقل شود. سه راه برای خلاص شدن از یک ارجاع در مالکیت وجود دارد: انتقال آن، ذخیره‌ی آن، یا فراخوانی :c:func:`Py_DECREF`. فراموش کردن خلاص شدن از یک ارجاع در مالکیت، باعث نشت حافظه می‌شود." msgid "It is also possible to :dfn:`borrow` [#]_ a reference to an object. The borrower of a reference should not call :c:func:`Py_DECREF`. The borrower must not hold on to the object longer than the owner from which it was borrowed. Using a borrowed reference after the owner has disposed of it risks using freed memory and should be avoided completely [#]_." msgstr "همچنین می‌توان ارجاعی به یک شیء را :dfn:`به امانت گرفت (borrow)` [#]_. امانت‌گیرنده‌ی ارجاع نباید :c:func:`Py_DECREF` را فراخوانی کند. امانت‌گیرنده نباید شیء را بیشتر از مالکی که ارجاع از او امانت گرفته‌شده است، نگه دارد. استفاده از ارجاع امانتی پس از آنکه مالک آن را دور انداخته باشد، خطر استفاده از حافظه‌ی آزادشده را در پی دارد و باید به‌طور کامل از آن پرهیز کرد [#]_." msgid "The advantage of borrowing over owning a reference is that you don't need to take care of disposing of the reference on all possible paths through the code --- in other words, with a borrowed reference you don't run the risk of leaking when a premature exit is taken. The disadvantage of borrowing over owning is that there are some subtle situations where in seemingly correct code a borrowed reference can be used after the owner from which it was borrowed has in fact disposed of it." msgstr "مزیت امانت گرفتن ارجاع نسبت به مالکیت آن این است که لازم نیست در تمام مسیرهای ممکن در کد، دفع ارجاع را مدیریت کنید --- به عبارت دیگر، با ارجاع امانتی، هنگام خروج زودهنگام در معرض خطر نشت قرار نمی‌گیرید. عیب امانت گرفتن نسبت به مالکیت این است که در برخی موقعیت‌های ظریف، ممکن است در کدی که به‌ظاهر درست است، از یک ارجاع امانتی پس از آنکه مالکی که ارجاع از او امانت گرفته شده، در واقع آن را دفع کرده باشد، استفاده شود." msgid "A borrowed reference can be changed into an owned reference by calling :c:func:`Py_INCREF`. This does not affect the status of the owner from which the reference was borrowed --- it creates a new owned reference, and gives full owner responsibilities (the new owner must dispose of the reference properly, as well as the previous owner)." msgstr "یک ارجاع امانتی را می‌توان با فراخوانی :c:func:`Py_INCREF` به یک ارجاع ملکی تبدیل کرد. این کار تأثیری بر وضعیت مالکی که ارجاع از او امانت گرفته‌شده بود نمی‌گذارد --- بلکه یک ارجاع ملکی جدید ایجاد می‌کند و مسئولیت‌های کامل مالکیت را به همراه دارد (مالک جدید باید ارجاع را به‌درستی دفع کند، همان‌طور که مالک قبلی نیز باید این کار را انجام دهد)." msgid "Ownership Rules" msgstr "قواعد مالکیت" msgid "Whenever an object reference is passed into or out of a function, it is part of the function's interface specification whether ownership is transferred with the reference or not." msgstr "هرگاه ارجاعی به یک شیء به داخل یا خارج از یک تابع پاس داده شود، اینکه آیا مالکیت به همراه ارجاع منتقل می‌شود یا خیر، بخشی از مشخصات رابط تابع است." msgid "Most functions that return a reference to an object pass on ownership with the reference. In particular, all functions whose function it is to create a new object, such as :c:func:`PyLong_FromLong` and :c:func:`Py_BuildValue`, pass ownership to the receiver. Even if the object is not actually new, you still receive ownership of a new reference to that object. For instance, :c:func:`PyLong_FromLong` maintains a cache of popular values and can return a reference to a cached item." msgstr "بیشتر توابعی که ارجاعی به یک شیء را برمی‌گردانند، مالکیت را همراه با ارجاع منتقل می‌کنند. به‌طور خاص، تمام توابعی که وظیفه‌شان ایجاد یک شیء جدید است، مانند :c:func:`PyLong_FromLong` و :c:func:`Py_BuildValue`، مالکیت را به گیرنده منتقل می‌کنند. حتی اگر شیء در واقع جدید نباشد، شما همچنان مالکیت یک ارجاع جدید به آن شیء را دریافت می‌کنید. برای نمونه، :c:func:`PyLong_FromLong` یک نهانگاه از مقادیر پرکاربرد را نگه می‌دارد و می‌تواند ارجاعی به یک آیتم نهانگاه‌شده را برگرداند." msgid "Many functions that extract objects from other objects also transfer ownership with the reference, for instance :c:func:`PyObject_GetAttrString`. The picture is less clear, here, however, since a few common routines are exceptions: :c:func:`PyTuple_GetItem`, :c:func:`PyList_GetItem`, :c:func:`PyDict_GetItem`, and :c:func:`PyDict_GetItemString` all return references that you borrow from the tuple, list or dictionary." msgstr "بسیاری از توابعی که اشیاء را از اشیاء دیگر استخراج می‌کنند، مالکیت را نیز همراه با ارجاع منتقل می‌کنند؛ برای مثال :c:func:`PyObject_GetAttrString`. با این حال، تصویر در اینجا کمتر روشن است، زیرا چند روال رایج استثنا هستند: :c:func:`PyTuple_GetItem`، :c:func:`PyList_GetItem`، :c:func:`PyDict_GetItem` و :c:func:`PyDict_GetItemString` همگی ارجاع‌هایی را برمی‌گردانند که شما آن‌ها را از تاپل، فهرست یا دیکشنری امانت می‌گیرید." msgid "The function :c:func:`PyImport_AddModule` also returns a borrowed reference, even though it may actually create the object it returns: this is possible because an owned reference to the object is stored in ``sys.modules``." msgstr "تابع :c:func:`PyImport_AddModule` نیز یک ارجاع امانتی برمی‌گرداند، هرچند ممکن است در واقع شیئی را که برمی‌گرداند ایجاد کند: این امر ممکن است زیرا یک ارجاع مالکانه به شیء در ``sys.modules`` ذخیره شده است." msgid "When you pass an object reference into another function, in general, the function borrows the reference from you --- if it needs to store it, it will use :c:func:`Py_INCREF` to become an independent owner. There are exactly two important exceptions to this rule: :c:func:`PyTuple_SetItem` and :c:func:`PyList_SetItem`. These functions take over ownership of the item passed to them --- even if they fail! (Note that :c:func:`PyDict_SetItem` and friends don't take over ownership --- they are \"normal.\")" msgstr "وقتی یک ارجاع به شیء را به تابع دیگری می‌دهید، به‌طور کلی، تابع ارجاع را به‌صورت امانتی از شما می‌گیرد --- اگر نیاز به ذخیره‌سازی آن داشته باشد، از :c:func:`Py_INCREF` استفاده می‌کند تا مالکی مستقل شود. دقیقاً دو استثنای مهم برای این قاعده وجود دارد: :c:func:`PyTuple_SetItem` و :c:func:`PyList_SetItem`. این توابع مالکیت آیتمی را که به آن‌ها داده می‌شود در اختیار می‌گیرند --- حتی اگر شکست بخورند! (توجه کنید که :c:func:`PyDict_SetItem` و توابع مشابه مالکیت را در اختیار نمی‌گیرند --- آن‌ها «معمولی» هستند.)" msgid "When a C function is called from Python, it borrows references to its arguments from the caller. The caller owns a reference to the object, so the borrowed reference's lifetime is guaranteed until the function returns. Only when such a borrowed reference must be stored or passed on, it must be turned into an owned reference by calling :c:func:`Py_INCREF`." msgstr "وقتی یک تابع C از پایتون فراخوانی می‌شود، ارجاع‌هایی به آرگومان‌های خود را از فراخوانی‌کننده به امانت می‌گیرد. فراخوانی‌کننده مالک ارجاعی به شیء است، بنابراین طول عمر ارجاع امانتی تا زمان بازگشت تابع تضمین‌شده است. تنها زمانی که چنین ارجاع امانتی‌ای باید ذخیره یا منتقل شود، باید با فراخوانی :c:func:`Py_INCREF` به یک ارجاع مالکانه (owned reference) تبدیل شود." msgid "The object reference returned from a C function that is called from Python must be an owned reference --- ownership is transferred from the function to its caller." msgstr "ارجاع شیئی که از یک تابع C فراخوانی‌شده از پایتون بازگردانده می‌شود، باید یک ارجاع مالکانه (owned reference) باشد --- مالکیت از تابع به فراخواننده‌ی آن منتقل می‌شود." msgid "Thin Ice" msgstr "یخ نازک" msgid "There are a few situations where seemingly harmless use of a borrowed reference can lead to problems. These all have to do with implicit invocations of the interpreter, which can cause the owner of a reference to dispose of it." msgstr "چند موقعیت وجود دارد که استفاده‌ی به‌ظاهر بی‌ضرر از یک ارجاع امانتی می‌تواند منجر به مشکلات شود. همه‌ی این موارد به فراخوانی‌های ضمنی مفسر مربوط‌اند که می‌توانند باعث شوند مالک یک ارجاع آن را رها کند." msgid "The first and most important case to know about is using :c:func:`Py_DECREF` on an unrelated object while borrowing a reference to a list item. For instance::" msgstr "نخستین و مهم‌ترین موردی که باید از آن آگاه باشید، استفاده از :c:func:`Py_DECREF` روی شیئی نامرتبط در حالی است که ارجاعی به یک آیتم فهرست را به امانت گرفته‌اید. برای نمونه::" msgid "" "void\n" "bug(PyObject *list)\n" "{\n" " PyObject *item = PyList_GetItem(list, 0);\n" "\n" " PyList_SetItem(list, 1, PyLong_FromLong(0L));\n" " PyObject_Print(item, stdout, 0); /* BUG! */\n" "}" msgstr "" "void\n" "bug(PyObject *list)\n" "{\n" " PyObject *item = PyList_GetItem(list, 0);\n" "\n" " PyList_SetItem(list, 1, PyLong_FromLong(0L));\n" " PyObject_Print(item, stdout, 0); /* BUG! */\n" "}" msgid "This function first borrows a reference to ``list[0]``, then replaces ``list[1]`` with the value ``0``, and finally prints the borrowed reference. Looks harmless, right? But it's not!" msgstr "این تابع ابتدا یک ارجاع امانتی به ``list[0]`` می‌گیرد، سپس ``list[1]`` را با مقدار ``0`` جایگزین می‌کند و در نهایت ارجاع امانتی را چاپ می‌کند. بی‌ضرر به نظر می‌رسد، نه؟ اما چنین نیست!" msgid "Let's follow the control flow into :c:func:`PyList_SetItem`. The list owns references to all its items, so when item 1 is replaced, it has to dispose of the original item 1. Now let's suppose the original item 1 was an instance of a user-defined class, and let's further suppose that the class defined a :meth:`!__del__` method. If this class instance has a reference count of 1, disposing of it will call its :meth:`!__del__` method. Internally, :c:func:`PyList_SetItem` calls :c:func:`Py_DECREF` on the replaced item, which invokes replaced item's corresponding :c:member:`~PyTypeObject.tp_dealloc` function. During deallocation, :c:member:`~PyTypeObject.tp_dealloc` calls :c:member:`~PyTypeObject.tp_finalize`, which is mapped to the :meth:`!__del__` method for class instances (see :pep:`442`). This entire sequence happens synchronously within the :c:func:`PyList_SetItem` call." msgstr "بیایید جریان کنترل را تا داخل :c:func:`PyList_SetItem` دنبال کنیم. فهرست مالک ارجاع‌هایی به همه‌ی آیتم‌های خود است، بنابراین وقتی آیتم ۱ جایگزین می‌شود، فهرست باید از آیتم اصلی ۱ خلاص شود. اکنون فرض کنید آیتم اصلی ۱ نمونه‌ای از یک کلاس تعریف‌شده توسط کاربر بوده است، و همچنین فرض کنید این کلاس متد :meth:`!__del__` را تعریف کرده است. اگر شمارش ارجاع این نمونه‌ی کلاس برابر با ۱ باشد، خلاص شدن از آن، متد :meth:`!__del__` آن را فراخوانی می‌کند. به‌طور داخلی، :c:func:`PyList_SetItem` :c:func:`Py_DECREF` را روی آیتم جایگزین‌شده فراخوانی می‌کند، که این امر موجب فراخوانی تابع :c:member:`~PyTypeObject.tp_dealloc` متناظر با آیتم جایگزین‌شده می‌شود. در حین تخصیص‌زدایی، :c:member:`~PyTypeObject.tp_dealloc` :c:member:`~PyTypeObject.tp_finalize` را فراخوانی می‌کند که برای نمونه‌های کلاس به متد :meth:`!__del__` نگاشت شده است (به :pep:`442` مراجعه کنید). کل این دنباله به‌صورت همگام درون فراخوانی :c:func:`PyList_SetItem` رخ می‌دهد." msgid "Since it is written in Python, the :meth:`!__del__` method can execute arbitrary Python code. Could it perhaps do something to invalidate the reference to ``item`` in :c:func:`!bug`? You bet! Assuming that the list passed into :c:func:`!bug` is accessible to the :meth:`!__del__` method, it could execute a statement to the effect of ``del list[0]``, and assuming this was the last reference to that object, it would free the memory associated with it, thereby invalidating ``item``." msgstr "از آنجا که به زبان پایتون نوشته شده است، متد :meth:`!__del__` می‌تواند کد پایتون دلخواهی را اجرا کند. آیا ممکن است کاری انجام دهد که ارجاع به ``item`` در :c:func:`!bug` را بی‌اعتبار کند؟ قطعاً! با فرض اینکه فهرست پاس‌داده‌شده به :c:func:`!bug` در دسترس متد :meth:`!__del__` باشد، می‌تواند دستوری مانند ``del list[0]`` اجرا کند، و با فرض اینکه این آخرین ارجاع به آن شیء باشد، حافظه‌ی مرتبط با آن را آزاد می‌کند و بدین ترتیب ``item`` را بی‌اعتبار می‌کند." msgid "The solution, once you know the source of the problem, is easy: temporarily increment the reference count. The correct version of the function reads::" msgstr "راه‌حل، وقتی منشأ مشکل را بدانید، آسان است: شمارش ارجاع را به‌طور موقت افزایش دهید. نسخه صحیح تابع چنین است::" msgid "" "void\n" "no_bug(PyObject *list)\n" "{\n" " PyObject *item = PyList_GetItem(list, 0);\n" "\n" " Py_INCREF(item);\n" " PyList_SetItem(list, 1, PyLong_FromLong(0L));\n" " PyObject_Print(item, stdout, 0);\n" " Py_DECREF(item);\n" "}" msgstr "" "void\n" "no_bug(PyObject *list)\n" "{\n" " PyObject *item = PyList_GetItem(list, 0);\n" "\n" " Py_INCREF(item);\n" " PyList_SetItem(list, 1, PyLong_FromLong(0L));\n" " PyObject_Print(item, stdout, 0);\n" " Py_DECREF(item);\n" "}" msgid "This is a true story. An older version of Python contained variants of this bug and someone spent a considerable amount of time in a C debugger to figure out why his :meth:`!__del__` methods would fail..." msgstr "این داستانی واقعی است. نسخه‌ای قدیمی‌تر از پایتون شامل گونه‌هایی از این باگ بود و کسی مدت زمان قابل توجهی را در دیباگر C صرف کرد تا بفهمد چرا متدهای :meth:`!__del__` او شکست می‌خوردند..." msgid "The second case of problems with a borrowed reference is a variant involving threads. Normally, multiple threads in the Python interpreter can't get in each other's way, because there is a :term:`global lock ` protecting Python's entire object space. However, it is possible to temporarily release this lock using the macro :c:macro:`Py_BEGIN_ALLOW_THREADS`, and to re-acquire it using :c:macro:`Py_END_ALLOW_THREADS`. This is common around blocking I/O calls, to let other threads use the processor while waiting for the I/O to complete. Obviously, the following function has the same problem as the previous one::" msgstr "دومین مورد از مشکلات مربوط به ارجاع امانتی، گونه‌ای است که به نخ‌ها مربوط می‌شود. به‌طور معمول، نخ‌های متعدد در مفسر پایتون نمی‌توانند مزاحم کار یکدیگر شوند، زیرا یک :term:`قفل سراسری ` از کل فضای اشیای پایتون محافظت می‌کند. با این حال، می‌توان این قفل را به‌طور موقت با استفاده از ماکروی :c:macro:`Py_BEGIN_ALLOW_THREADS` آزاد کرد و آن را با استفاده از :c:macro:`Py_END_ALLOW_THREADS` دوباره به دست آورد. این کار پیرامون فراخوانی‌های مسدودکننده‌ی ورودی/خروجی رایج است تا نخ‌های دیگر بتوانند در حین انتظار برای تکمیل ورودی/خروجی، از پردازنده استفاده کنند. بدیهی است که تابع زیر همان مشکلی را دارد که تابع قبلی داشت::" msgid "" "void\n" "bug(PyObject *list)\n" "{\n" " PyObject *item = PyList_GetItem(list, 0);\n" " Py_BEGIN_ALLOW_THREADS\n" " ...some blocking I/O call...\n" " Py_END_ALLOW_THREADS\n" " PyObject_Print(item, stdout, 0); /* BUG! */\n" "}" msgstr "" "void\n" "bug(PyObject *list)\n" "{\n" " PyObject *item = PyList_GetItem(list, 0);\n" " Py_BEGIN_ALLOW_THREADS\n" " ...some blocking I/O call...\n" " Py_END_ALLOW_THREADS\n" " PyObject_Print(item, stdout, 0); /* BUG! */\n" "}" msgid "NULL Pointers" msgstr "اشاره‌گرهای NULL" msgid "In general, functions that take object references as arguments do not expect you to pass them ``NULL`` pointers, and will dump core (or cause later core dumps) if you do so. Functions that return object references generally return ``NULL`` only to indicate that an exception occurred. The reason for not testing for ``NULL`` arguments is that functions often pass the objects they receive on to other function --- if each function were to test for ``NULL``, there would be a lot of redundant tests and the code would run more slowly." msgstr "به‌طور کلی، توابعی که ارجاع‌های شیء را به‌عنوان آرگومان می‌گیرند، انتظار ندارند که اشاره‌گرهای ``NULL`` را به آن‌ها پاس دهید، و اگر چنین کنید، برون‌ریزی هسته ایجاد می‌کنند (یا باعث برون‌ریزی‌های هسته‌ی بعدی می‌شوند). توابعی که ارجاع‌های شیء را برمی‌گردانند، معمولاً تنها برای نشان دادن اینکه استثنایی رخ داده است، ``NULL`` برمی‌گردانند. دلیل آزمایش نکردن ``NULL`` بودن آرگومان‌ها این است که توابع اغلب اشیایی را که دریافت می‌کنند به تابع دیگری پاس می‌دهند --- اگر هر تابعی ``NULL`` را آزمایش می‌کرد، آزمون‌های زائد زیادی صورت می‌گرفت و کد کندتر اجرا می‌شد." msgid "It is better to test for ``NULL`` only at the \"source:\" when a pointer that may be ``NULL`` is received, for example, from :c:func:`malloc` or from a function that may raise an exception." msgstr "بهتر است بررسی ``NULL`` تنها در \"source:\" انجام شود؛ زمانی که اشاره‌گری که ممکن است ``NULL`` باشد دریافت می‌شود، برای مثال از :c:func:`malloc` یا از تابعی که ممکن است استثنا برافراخواند." msgid "The macros :c:func:`Py_INCREF` and :c:func:`Py_DECREF` do not check for ``NULL`` pointers --- however, their variants :c:func:`Py_XINCREF` and :c:func:`Py_XDECREF` do." msgstr "ماکروهای :c:func:`Py_INCREF` و :c:func:`Py_DECREF` اشاره‌گرهای ``NULL`` را بررسی نمی‌کنند --- اما گونه‌های آن‌ها، :c:func:`Py_XINCREF` و :c:func:`Py_XDECREF`، این بررسی را انجام می‌دهند." msgid "The macros for checking for a particular object type (``Pytype_Check()``) don't check for ``NULL`` pointers --- again, there is much code that calls several of these in a row to test an object against various different expected types, and this would generate redundant tests. There are no variants with ``NULL`` checking." msgstr "ماکروهای بررسی یک نوع شیء خاص (``Pytype_Check()``) اشاره‌گرهای ``NULL`` را بررسی نمی‌کنند --- باز هم، کدهای زیادی وجود دارند که برای آزمودن یک شیء در برابر انواع مختلف مورد انتظار، چندین مورد از این ماکروها را پشت سر هم فراخوانی می‌کنند، و این کار آزمون‌های تکراری ایجاد می‌کرد. هیچ گونه‌ای با بررسی ``NULL`` وجود ندارد." msgid "The C function calling mechanism guarantees that the argument list passed to C functions (``args`` in the examples) is never ``NULL`` --- in fact it guarantees that it is always a tuple [#]_." msgstr "سازوکار فراخوانی تابع C تضمین می‌کند که فهرست آرگومان‌هایی که به توابع C ارسال می‌شود (``args`` در مثال‌ها) هرگز ``NULL`` نیست --- در واقع تضمین می‌کند که همیشه یک تاپل است [#]_." msgid "It is a severe error to ever let a ``NULL`` pointer \"escape\" to the Python user." msgstr "این خطایی بسیار جدی است که اشاره‌گر ``NULL`` به کاربر پایتون «گریز» کند." msgid "Writing Extensions in C++" msgstr "نوشتن توسعه‌ها با C++" msgid "It is possible to write extension modules in C++. Some restrictions apply. If the main program (the Python interpreter) is compiled and linked by the C compiler, global or static objects with constructors cannot be used. This is not a problem if the main program is linked by the C++ compiler. Functions that will be called by the Python interpreter (in particular, module initialization functions) have to be declared using ``extern \"C\"``. It is unnecessary to enclose the Python header files in ``extern \"C\" {...}`` --- they use this form already if the symbol ``__cplusplus`` is defined (all recent C++ compilers define this symbol)." msgstr "نوشتن ماژول‌های توسعه‌ای به زبان C++ ممکن است. برخی محدودیت‌ها اعمال می‌شوند. اگر برنامه اصلی (مفسر پایتون) توسط کامپایلر C کامپایل و پیوند داده شود، نمی‌توان از اشیاء سراسری یا ایستای دارای سازنده استفاده کرد. اگر برنامه اصلی توسط کامپایلر C++ پیوند داده شود، این مشکل وجود ندارد. توابعی که توسط مفسر پایتون فراخوانی خواهند شد (به‌ویژه توابع مقداردهی اولیه ماژول) باید با استفاده از ``extern \"C\"`` اعلام شوند. لازم نیست پرونده‌های سرآیند پایتون در ``extern \"C\" {...}`` محصور شوند --- این پرونده‌ها در صورتی که نماد ``__cplusplus`` تعریف شده باشد، از قبل به این شکل هستند (همه‌ی کامپایلرهای جدید C++ این نماد را تعریف می‌کنند)." msgid "Providing a C API for an Extension Module" msgstr "ارائه‌ی یک C API برای ماژول توسعه‌ای" msgid "Many extension modules just provide new functions and types to be used from Python, but sometimes the code in an extension module can be useful for other extension modules. For example, an extension module could implement a type \"collection\" which works like lists without order. Just like the standard Python list type has a C API which permits extension modules to create and manipulate lists, this new collection type should have a set of C functions for direct manipulation from other extension modules." msgstr "بسیاری از ماژول‌های توسعه‌ای صرفاً توابع و نوع‌های جدیدی فراهم می‌کنند که از پایتون مورد استفاده قرار می‌گیرند، اما گاهی کد موجود در یک ماژول توسعه‌ای می‌تواند برای ماژول‌های توسعه‌ای دیگر مفید باشد. برای مثال، یک ماژول توسعه‌ای می‌تواند نوعی به نام «مجموعه» پیاده‌سازی کند که مانند فهرست‌های بدون ترتیب کار می‌کند. درست همان‌طور که نوع فهرست استاندارد پایتون دارای یک C API است که به ماژول‌های توسعه‌ای اجازه می‌دهد فهرست‌ها را ایجاد و دستکاری کنند، این نوع مجموعه جدید نیز باید مجموعه‌ای از توابع C برای دستکاری مستقیم از سوی ماژول‌های توسعه‌ای دیگر داشته باشد." msgid "At first sight this seems easy: just write the functions (without declaring them ``static``, of course), provide an appropriate header file, and document the C API. And in fact this would work if all extension modules were always linked statically with the Python interpreter. When modules are used as shared libraries, however, the symbols defined in one module may not be visible to another module. The details of visibility depend on the operating system; some systems use one global namespace for the Python interpreter and all extension modules (Windows, for example), whereas others require an explicit list of imported symbols at module link time (AIX is one example), or offer a choice of different strategies (most Unices). And even if symbols are globally visible, the module whose functions one wishes to call might not have been loaded yet!" msgstr "در نگاه نخست این کار آسان به نظر می‌رسد: کافی است توابع را بنویسید (البته بدون اینکه آن‌ها را ``static`` اعلان کنید)، یک پرونده‌ی سرآیند مناسب فراهم کنید و API زبان C را مستند کنید. و در واقع اگر همه ماژول‌های توسعه‌ای همیشه به‌صورت ایستا با مفسر پایتون پیوند داده می‌شدند، همین روش کار می‌کرد. اما هنگامی که ماژول‌ها به‌صورت کتابخانه‌های اشتراکی استفاده می‌شوند، ممکن است نمادهای تعریف‌شده در یک ماژول برای ماژول دیگری نمایان نباشند. جزئیات نمایان بودن نمادها به سیستم‌عامل بستگی دارد؛ برخی سیستم‌ها برای مفسر پایتون و همه ماژول‌های توسعه‌ای از یک فضای نام سراسری واحد استفاده می‌کنند (مثلاً ویندوز)، در حالی که برخی دیگر در زمان پیوند ماژول به فهرست صریحی از نمادهای واردشده نیاز دارند (AIX یکی از این نمونه‌هاست)، یا امکان انتخاب میان راهبردهای مختلف را ارائه می‌دهند (بیشتر سیستم‌های یونیکس). و حتی اگر نمادها به‌صورت سراسری نمایان باشند، ممکن است ماژولی که می‌خواهید توابعش را فراخوانی کنید، هنوز بارگذاری‌نشده باشد!" msgid "Portability therefore requires not to make any assumptions about symbol visibility. This means that all symbols in extension modules should be declared ``static``, except for the module's initialization function, in order to avoid name clashes with other extension modules (as discussed in section :ref:`methodtable`). And it means that symbols that *should* be accessible from other extension modules must be exported in a different way." msgstr "بنابراین، قابلیت انتقال (portability) ایجاب می‌کند که هیچ فرضی درباره‌ی نمایانی نمادها صورت نگیرد. این بدان معناست که همه‌ی نمادها در ماژول‌های توسعه‌ای، به‌جز تابع مقداردهی اولیه‌ی ماژول، باید به‌صورت ``static`` اعلام شوند تا از تداخل نام با ماژول‌های توسعه‌ای دیگر پرهیز شود (همان‌طور که در بخش :ref:`methodtable` بحث شد). و این بدان معناست که نمادهایی که *باید* برای دیگر ماژول‌های توسعه‌ای دسترسی‌پذیر باشند، باید به شیوه‌ای متفاوت اکسپورت شوند." msgid "Python provides a special mechanism to pass C-level information (pointers) from one extension module to another one: Capsules. A Capsule is a Python data type which stores a pointer (:c:expr:`void \\*`). Capsules can only be created and accessed via their C API, but they can be passed around like any other Python object. In particular, they can be assigned to a name in an extension module's namespace. Other extension modules can then import this module, retrieve the value of this name, and then retrieve the pointer from the Capsule." msgstr "پایتون سازوکار ویژه‌ای برای انتقال اطلاعات در سطح C (اشاره‌گرها) از یک ماژول توسعه‌ای به ماژول توسعه‌ای دیگر فراهم می‌کند: کپسول‌ها (Capsules). کپسول یک نوع داده پایتونی است که یک اشاره‌گر (:c:expr:`void \\*`) را ذخیره می‌کند. ایجاد و دسترسی به کپسول‌ها تنها از طریق API زبان C آن‌ها ممکن است، اما می‌توان آن‌ها را مانند هر شیء پایتونی دیگری منتقل کرد. به‌طور خاص، می‌توان آن‌ها را به نامی در فضای نام یک ماژول توسعه‌ای منتسب کرد. سپس ماژول‌های توسعه‌ای دیگر می‌توانند این ماژول را ایمپورت کنند، مقدار این نام را بازیابی کنند و سپس اشاره‌گر را از کپسول بازیابی کنند." msgid "There are many ways in which Capsules can be used to export the C API of an extension module. Each function could get its own Capsule, or all C API pointers could be stored in an array whose address is published in a Capsule. And the various tasks of storing and retrieving the pointers can be distributed in different ways between the module providing the code and the client modules." msgstr "از کپسول‌ها می‌توان به روش‌های بسیاری برای اکسپورت کردن API زبان C یک ماژول توسعه‌ای استفاده کرد. هر تابع می‌تواند کپسول مخصوص خود را داشته باشد، یا تمام اشاره‌گرهای API زبان C می‌توانند در آرایه‌ای ذخیره شوند که آدرس آن در یک کپسول منتشر می‌شود. همچنین می‌توان وظایف گوناگون ذخیره و بازیابی اشاره‌گرها را به شیوه‌های مختلف بین ماژولی که کد را فراهم می‌کند و ماژول‌های مشتری توزیع کرد." msgid "Whichever method you choose, it's important to name your Capsules properly. The function :c:func:`PyCapsule_New` takes a name parameter (:c:expr:`const char \\*`); you're permitted to pass in a ``NULL`` name, but we strongly encourage you to specify a name. Properly named Capsules provide a degree of runtime type-safety; there is no feasible way to tell one unnamed Capsule from another." msgstr "هر روشی را که انتخاب کنید، مهم است که کپسول‌های خود را به‌درستی نام‌گذاری کنید. تابع :c:func:`PyCapsule_New` یک پارامتر نام می‌گیرد (:c:expr:`const char \\*`)؛ شما مجازید نام ``NULL`` ارسال کنید، اما ما به‌شدت توصیه می‌کنیم که نامی مشخص کنید. کپسول‌های به‌درستی نام‌گذاری‌شده درجه‌ای از ایمنی نوع در زمان اجرا فراهم می‌کنند؛ هیچ راه عملی‌ای برای تمایز یک کپسول بدون نام از کپسول دیگر وجود ندارد." msgid "In particular, Capsules used to expose C APIs should be given a name following this convention::" msgstr "به‌طور خاص، کپسول‌هایی که برای افشای APIهای C استفاده می‌شوند، باید مطابق این قرارداد نام‌گذاری شوند::" msgid "modulename.attributename" msgstr "modulename.attributename" msgid "The convenience function :c:func:`PyCapsule_Import` makes it easy to load a C API provided via a Capsule, but only if the Capsule's name matches this convention. This behavior gives C API users a high degree of certainty that the Capsule they load contains the correct C API." msgstr "تابع کمکی :c:func:`PyCapsule_Import` بارگذاری یک C API که از طریق یک کپسول ارائه شده را آسان می‌کند، اما تنها در صورتی که نام کپسول با این قرارداد مطابقت داشته باشد. این رفتار به کاربران C API درجه بالایی از اطمینان می‌دهد که کپسولی که بارگذاری می‌کنند، C API صحیح را در بر دارد." msgid "The following example demonstrates an approach that puts most of the burden on the writer of the exporting module, which is appropriate for commonly used library modules. It stores all C API pointers (just one in the example!) in an array of :c:expr:`void` pointers which becomes the value of a Capsule. The header file corresponding to the module provides a macro that takes care of importing the module and retrieving its C API pointers; client modules only have to call this macro before accessing the C API." msgstr "مثال زیر رویکردی را نشان می‌دهد که بیشتر بار را بر دوش نویسنده ماژول اکسپورتکننده قرار می‌دهد، که برای ماژول‌های کتابخانه‌ای پرکاربرد مناسب است. این رویکرد تمام اشاره‌گرهای C API (در مثال فقط یکی!) را در آرایه‌ای از اشاره‌گرهای :c:expr:`void` ذخیره می‌کند که مقدار یک کپسول می‌شود. پرونده‌ی سرآیند متناظر با ماژول، ماکرویی را فراهم می‌کند که کار ایمپورت کردن ماژول و بازیابی اشاره‌گرهای C API آن را انجام می‌دهد؛ ماژول‌های کلاینت تنها باید پیش از دسترسی به C API این ماکرو را فراخوانی کنند." msgid "The exporting module is a modification of the :mod:`!spam` module from section :ref:`extending-simpleexample`. The function :func:`!spam.system` does not call the C library function :c:func:`system` directly, but a function :c:func:`!PySpam_System`, which would of course do something more complicated in reality (such as adding \"spam\" to every command). This function :c:func:`!PySpam_System` is also exported to other extension modules." msgstr "ماژول اکسپورتکننده، نسخه‌ی تغییر‌یافته‌ای از ماژول :mod:`!spam` در بخش :ref:`extending-simpleexample` است. تابع :func:`!spam.system` مستقیماً تابع :c:func:`system` از کتابخانه‌ی C را فراخوانی نمی‌کند، بلکه تابع :c:func:`!PySpam_System` را فراخوانی می‌کند که البته در واقعیت کاری پیچیده‌تر انجام می‌دهد (مانند افزودن \"spam\" به هر دستور). این تابع :c:func:`!PySpam_System` همچنین به ماژول‌های توسعه‌ای دیگر اکسپورت می‌شود." msgid "The function :c:func:`!PySpam_System` is a plain C function, declared ``static`` like everything else::" msgstr "تابع :c:func:`!PySpam_System` یک تابع C ساده است که مانند بقیه موارد به‌صورت ``static`` اعلان شده است::" msgid "" "static int\n" "PySpam_System(const char *command)\n" "{\n" " return system(command);\n" "}" msgstr "" "static int\n" "PySpam_System(const char *command)\n" "{\n" " return system(command);\n" "}" msgid "The function :c:func:`!spam_system` is modified in a trivial way::" msgstr "تابع :c:func:`!spam_system` به شکلی ساده تغییر داده می‌شود::" 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 = PySpam_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 = PySpam_System(command);\n" " return PyLong_FromLong(sts);\n" "}" msgid "In the beginning of the module, right after the line ::" msgstr "در ابتدای ماژول، درست پس از سطر ::" msgid "#include " msgstr "#include " msgid "two more lines must be added::" msgstr "دو سطر دیگر باید افزوده شود::" msgid "" "#define SPAM_MODULE\n" "#include \"spammodule.h\"" msgstr "" "#define SPAM_MODULE\n" "#include \"spammodule.h\"" msgid "The ``#define`` is used to tell the header file that it is being included in the exporting module, not a client module. Finally, the module's :c:data:`mod_exec ` function must take care of initializing the C API pointer array::" msgstr "از ``#define`` استفاده می‌شود تا به پرونده‌ی سرآیند بگوید که در ماژول اکسپورتکننده گنجانده می‌شود، نه در یک ماژول کلاینت. در نهایت، تابع :c:data:`mod_exec ` ماژول باید مقداردهی اولیه‌ی آرایه اشاره‌گرهای C API را بر عهده بگیرد::" msgid "" "static int\n" "spam_module_exec(PyObject *m)\n" "{\n" " static void *PySpam_API[PySpam_API_pointers];\n" " PyObject *c_api_object;\n" "\n" " /* Initialize the C API pointer array */\n" " PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;\n" "\n" " /* Create a Capsule containing the API pointer array's address */\n" " c_api_object = PyCapsule_New((void *)PySpam_API, \"spam._C_API\", NULL);\n" "\n" " if (PyModule_Add(m, \"_C_API\", c_api_object) < 0) {\n" " return -1;\n" " }\n" "\n" " return 0;\n" "}" msgstr "" "static int\n" "spam_module_exec(PyObject *m)\n" "{\n" " static void *PySpam_API[PySpam_API_pointers];\n" " PyObject *c_api_object;\n" "\n" " /* Initialize the C API pointer array */\n" " PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;\n" "\n" " /* Create a Capsule containing the API pointer array's address */\n" " c_api_object = PyCapsule_New((void *)PySpam_API, \"spam._C_API\", NULL);\n" "\n" " if (PyModule_Add(m, \"_C_API\", c_api_object) < 0) {\n" " return -1;\n" " }\n" "\n" " return 0;\n" "}" msgid "Note that ``PySpam_API`` is declared ``static``; otherwise the pointer array would disappear when :c:func:`!PyInit_spam` terminates!" msgstr "توجه داشته باشید که ``PySpam_API`` به‌صورت ``static`` تعریف شده است؛ در غیر این صورت، آرایه اشاره‌گرها با خاتمه‌یافتن :c:func:`!PyInit_spam` ناپدید می‌شد!" msgid "The bulk of the work is in the header file :file:`spammodule.h`, which looks like this::" msgstr "بخش عمده‌ی کار در پرونده‌ی سرآیند :file:`spammodule.h` قرار دارد که به این شکل است::" msgid "" "#ifndef Py_SPAMMODULE_H\n" "#define Py_SPAMMODULE_H\n" "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n" "\n" "/* Header file for spammodule */\n" "\n" "/* C API functions */\n" "#define PySpam_System_NUM 0\n" "#define PySpam_System_RETURN int\n" "#define PySpam_System_PROTO (const char *command)\n" "\n" "/* Total number of C API pointers */\n" "#define PySpam_API_pointers 1\n" "\n" "\n" "#ifdef SPAM_MODULE\n" "/* This section is used when compiling spammodule.c */\n" "\n" "static PySpam_System_RETURN PySpam_System PySpam_System_PROTO;\n" "\n" "#else\n" "/* This section is used in modules that use spammodule's API */\n" "\n" "static void **PySpam_API;\n" "\n" "#define PySpam_System \\\n" " (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])\n" "\n" "/* Return -1 on error, 0 on success.\n" " * PyCapsule_Import will set an exception if there's an error.\n" " */\n" "static int\n" "import_spam(void)\n" "{\n" " PySpam_API = (void **)PyCapsule_Import(\"spam._C_API\", 0);\n" " return (PySpam_API != NULL) ? 0 : -1;\n" "}\n" "\n" "#endif\n" "\n" "#ifdef __cplusplus\n" "}\n" "#endif\n" "\n" "#endif /* !defined(Py_SPAMMODULE_H) */" msgstr "" "#ifndef Py_SPAMMODULE_H\n" "#define Py_SPAMMODULE_H\n" "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n" "\n" "/* Header file for spammodule */\n" "\n" "/* C API functions */\n" "#define PySpam_System_NUM 0\n" "#define PySpam_System_RETURN int\n" "#define PySpam_System_PROTO (const char *command)\n" "\n" "/* Total number of C API pointers */\n" "#define PySpam_API_pointers 1\n" "\n" "\n" "#ifdef SPAM_MODULE\n" "/* This section is used when compiling spammodule.c */\n" "\n" "static PySpam_System_RETURN PySpam_System PySpam_System_PROTO;\n" "\n" "#else\n" "/* This section is used in modules that use spammodule's API */\n" "\n" "static void **PySpam_API;\n" "\n" "#define PySpam_System \\\n" " (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])\n" "\n" "/* Return -1 on error, 0 on success.\n" " * PyCapsule_Import will set an exception if there's an error.\n" " */\n" "static int\n" "import_spam(void)\n" "{\n" " PySpam_API = (void **)PyCapsule_Import(\"spam._C_API\", 0);\n" " return (PySpam_API != NULL) ? 0 : -1;\n" "}\n" "\n" "#endif\n" "\n" "#ifdef __cplusplus\n" "}\n" "#endif\n" "\n" "#endif /* !defined(Py_SPAMMODULE_H) */" msgid "All that a client module must do in order to have access to the function :c:func:`!PySpam_System` is to call the function (or rather macro) :c:func:`!import_spam` in its :c:data:`mod_exec ` function::" msgstr "تنها کاری که یک ماژول کلاینت باید انجام دهد تا به تابع :c:func:`!PySpam_System` دسترسی داشته باشد، این است که تابع (یا بهتر بگوییم، ماکرو) :c:func:`!import_spam` را در تابع :c:data:`mod_exec ` خود فراخوانی کند::" msgid "" "static int\n" "client_module_exec(PyObject *m)\n" "{\n" " if (import_spam() < 0) {\n" " return -1;\n" " }\n" " /* additional initialization can happen here */\n" " return 0;\n" "}" msgstr "" "static int\n" "client_module_exec(PyObject *m)\n" "{\n" " if (import_spam() < 0) {\n" " return -1;\n" " }\n" " /* additional initialization can happen here */\n" " return 0;\n" "}" msgid "The main disadvantage of this approach is that the file :file:`spammodule.h` is rather complicated. However, the basic structure is the same for each function that is exported, so it has to be learned only once." msgstr "عیب اصلی این رویکرد این است که پرونده‌ی :file:`spammodule.h` نسبتاً پیچیده است. با این حال، ساختار پایه برای هر تابعی که اکسپورت می‌شود یکسان است، بنابراین تنها یک بار باید یاد گرفته شود." msgid "Finally it should be mentioned that Capsules offer additional functionality, which is especially useful for memory allocation and deallocation of the pointer stored in a Capsule. The details are described in the Python/C API Reference Manual in the section :ref:`capsules` and in the implementation of Capsules (files :file:`Include/pycapsule.h` and :file:`Objects/capsule.c` in the Python source code distribution)." msgstr "در نهایت باید ذکر شود که Capsule‌ها عملکردهای اضافی ارائه می‌دهند، که به‌ویژه برای تخصیص و آزادسازی حافظه اشاره‌گر ذخیره‌شده در یک Capsule مفید هستند. جزئیات در راهنمای ارجاع Python/C API در بخش :ref:`capsules` و در پیاده‌سازی Capsuleها (پرونده‌های :file:`Include/pycapsule.h` و :file:`Objects/capsule.c` در توزیع کد منبع پایتون) توصیف شده‌اند." msgid "Footnotes" msgstr "پانوشت‌ها" msgid "An interface for this function already exists in the standard module :mod:`os` --- it was chosen as a simple and straightforward example." msgstr "رابطی برای این تابع از پیش در ماژول استاندارد :mod:`os` وجود دارد --- این تابع به‌عنوان مثالی ساده و سرراست انتخاب شد." msgid "The metaphor of \"borrowing\" a reference is not completely correct: the owner still has a copy of the reference." msgstr "استعاره‌ی «امانت گرفتنِ» ارجاع کاملاً درست نیست: مالک همچنان نسخه‌ای از ارجاع را در اختیار دارد." msgid "Checking that the reference count is at least 1 **does not work** --- the reference count itself could be in freed memory and may thus be reused for another object!" msgstr "بررسی اینکه شمارش ارجاع دست‌کم ۱ باشد **کار نمی‌کند** --- خودِ شمارش ارجاع ممکن است در حافظه‌ی آزادشده باشد و بدین‌ترتیب برای شیء دیگری بازاستفاده شود!" msgid "These guarantees don't hold when you use the \"old\" style calling convention --- this is still found in much existing code." msgstr "این تضمین‌ها هنگامی که شما از قرارداد فراخوانی به سبک «قدیمی» استفاده می‌کنید، برقرار نیستند --- این سبک همچنان در بسیاری از کدهای موجود یافت می‌شود." msgid "PyObject_CallObject (C function)" msgstr "PyObject_CallObject (تابع C)" msgid "PyArg_ParseTuple (C function)" msgstr "PyArg_ParseTuple (تابع C)" msgid "PyArg_ParseTupleAndKeywords (C function)" msgstr "PyArg_ParseTupleAndKeywords (تابع C)" msgid "Philbrick, Geoff" msgstr "Philbrick, Geoff"