شمارش ارجاع

توابع و ماکرو‌های این بخش برای مدیریت شمارش ارجاع اشیاء پایتون استفاده می‌شوند.

Py_ssize_t Py_REFCNT(PyObject *o)
قسمتی از ABI پایدار از نسخه‌ی 3.14.

شمارش ارجاع شیء پایتون o را دریافت کنید.

توجه داشته باشید که مقدار بازگشتی ممکن است در واقع تعداد ارجاع‌هایی را که واقعاً به شیء نگه‌داشته می‌شوند منعکس نکند. برای مثال، برخی از اشیاء immortal هستند و شمارش ارجاع بسیار بالایی دارند که تعداد واقعی ارجاع‌ها را منعکس نمی‌کند. در نتیجه، به‌جز در مورد مقدار ۰ یا ۱، بر دقت مقدار بازگشتی تکیه نکنید.

برای تنظیم شمارش ارجاع یک شیء، از تابع Py_SET_REFCNT() استفاده کنید.

توجه

در ساخت‌های نخ‌آزاد پایتون، بازگرداندن 1 برای تعیین اینکه آیا در نظر گرفتن o به‌عنوان شیئی که هیچ نخ دیگری به آن دسترسی ندارد، ایمن است، کافی نیست. برای این کار به‌جای آن از PyUnstable_Object_IsUniquelyReferenced() استفاده کنید.

همچنین تابع PyUnstable_Object_IsUniqueReferencedTemporary() را ببینید.

تغییر یافته در نسخه‌ی 3.10: Py_REFCNT() به تابع ایستای درون‌خطی تغییر یافته است.

تغییر یافته در نسخه‌ی 3.11: نوع پارامتر دیگر const PyObject* نیست.

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

شمارنده ارجاع شیء o را برابر refcnt قرار می‌دهد.

در ساخت پایتون با نخ‌بندی آزاد، اگر refcnt بزرگ‌تر از UINT32_MAX باشد، شیء نامیرا می‌شود.

این تابع هیچ تأثیری بر اشیاء نامیرا ندارد.

اضافه شده در نسخه‌ی 3.9.

تغییر یافته در نسخه‌ی 3.12: اشیاء نامیرا تغییر نمی‌یابند.

void Py_INCREF(PyObject *o)

نشان می‌دهد که یک strong reference جدید به شیء o گرفته می‌شود و بیانگر این است که آن در حال استفاده است و نباید نابود شود.

این تابع هیچ تأثیری بر اشیاء نامیرا ندارد.

این تابع معمولاً برای تبدیل یک ارجاع امانتی به یک ارجاع قوی به‌صورت درجا استفاده می‌شود. می‌توان از تابع Py_NewRef() برای ایجاد یک ارجاع قوی جدید استفاده کرد.

پس از پایان استفاده از شیء، آزادسازی آن با فراخوانی Py_DECREF() انجام می‌شود.

شیء نباید NULL باشد؛ اگر مطمئن نیستید که NULL نیست، از Py_XINCREF() استفاده کنید.

انتظار نداشته باشید که این تابع به هیچ وجه o را واقعاً تغییر دهد. دست‌کم برای برخی از اشیاء، این تابع هیچ تأثیری ندارد.

تغییر یافته در نسخه‌ی 3.12: اشیاء نامیرا تغییر نمی‌یابند.

void Py_XINCREF(PyObject *o)

مشابه Py_INCREF()، اما شیء o می‌تواند NULL باشد، که در این صورت هیچ اثری نخواهد داشت.

همچنین Py_XNewRef() را ببینید.

PyObject *Py_NewRef(PyObject *o)
قسمتی از ABI پایدار از نسخه‌ی 3.10.

یک ارجاع قوی جدید به یک شیء بسازید: Py_INCREF() را روی o فراخوانی کنید و شیء o را برگردانید.

هنگامی که strong reference دیگر مورد نیاز نیست، باید Py_DECREF() روی آن فراخوانی شود تا ارجاع آزاد شود.

شیء o نباید NULL باشد؛ اگر o می‌تواند NULL باشد، از Py_XNewRef() استفاده کنید.

برای مثال:

Py_INCREF(obj);
self->attr = obj;

می‌توان آن را به صورت زیر نوشت:

self->attr = Py_NewRef(obj);

همچنین ببینید Py_INCREF().

اضافه شده در نسخه‌ی 3.10.

PyObject *Py_XNewRef(PyObject *o)
قسمتی از ABI پایدار از نسخه‌ی 3.10.

مشابه Py_NewRef()، اما شیء o می‌تواند NULL باشد.

اگر شیء o برابر NULL باشد، تابع صرفاً NULL را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.10.

void Py_DECREF(PyObject *o)

یک ارجاع قوی به شیء o را آزاد کنید که نشان می‌دهد این ارجاع دیگر استفاده نمی‌شود.

این تابع هیچ تأثیری بر اشیاء نامیرا ندارد.

پس از آزاد شدن آخرین strong reference (یعنی زمانی که شمارش ارجاع شیء به ۰ برسد)، تابع تخصیص‌زدایی نوع شیء (که نباید NULL باشد) فراخوانی می‌شود.

این تابع معمولاً برای حذف یک ارجاع قوی پیش از خروج از محدوده‌ی آن استفاده می‌شود.

شیء نباید NULL باشد؛ اگر مطمئن نیستید که NULL نیست، از Py_XDECREF() استفاده کنید.

انتظار نداشته باشید که این تابع واقعاً o را به هیچ نحوی تغییر دهد. برای حداقل برخی اشیاء، این تابع هیچ اثری ندارد.

هشدار

تابع آزادسازی می‌تواند باعث فراخوانی کد دلخواه پایتون شود (مثلاً وقتی نمونه‌ای از کلاسی دارای متد __del__() آزادسازی می‌شود). اگرچه استثناهای چنین کدی منتشر نمی‌شوند، کد اجرا‌شده به تمام متغیرهای سراسری پایتون دسترسی آزاد دارد. این بدان معناست که هر شیئی که از یک متغیر سراسری قابل دسترسی باشد، باید پیش از فراخوانی Py_DECREF() در وضعیت سازگار قرار داشته باشد. برای مثال، کدی که شیئی را از یک فهرست حذف می‌کند، باید ارجاعی به شیء حذف‌شده را در یک متغیر موقت کپی کند، ساختار داده فهرست را به‌روزرسانی کند و سپس Py_DECREF() را برای متغیر موقت فراخوانی کند.

تغییر یافته در نسخه‌ی 3.12: اشیاء نامیرا تغییر نمی‌یابند.

void Py_XDECREF(PyObject *o)

مشابه Py_DECREF()، اما شیء o می‌تواند NULL باشد که در این صورت هیچ اثری ندارد. همان هشدارِ مربوط به Py_DECREF() در اینجا نیز صدق می‌کند.

void Py_CLEAR(PyObject *o)

یک ارجاع قوی برای شیء o را آزاد می‌کند. شیء ممکن است NULL باشد که در این صورت ماکرو هیچ اثری ندارد؛ در غیر این صورت، اثر آن همانند Py_DECREF() است، با این تفاوت که آرگومان نیز به NULL تنظیم می‌شود. هشدار مربوط به Py_DECREF() در مورد شیء ارسال‌شده اعمال نمی‌شود، زیرا ماکرو با دقت از یک متغیر موقت استفاده می‌کند و آرگومان را پیش از آزاد کردن ارجاع به NULL تنظیم می‌کند.

هر زمان که ارجاعی به شیئی را که ممکن است در حین زباله‌روبی پیمایش شود آزاد می‌کنید، استفاده از این ماکرو ایده‌ی خوبی است.

تغییر یافته در نسخه‌ی 3.12: آرگومان ماکرو اکنون فقط یک بار ارزیابی می‌شود. اگر آرگومان دارای اثرات جانبی باشد، این اثرات دیگر تکرار نمی‌شوند.

void Py_IncRef(PyObject *o)
قسمتی از ABI پایدار.

نشان دادن گرفتن یک ارجاع قوی جدید به شیء o. نسخه‌ی تابعی از Py_XINCREF(). می‌توان از آن برای تعبیه پویای پایتون در زمان اجرا استفاده کرد.

void Py_DecRef(PyObject *o)
قسمتی از ABI پایدار.

یک ارجاع قوی به شیء o را آزاد می‌کند. نسخه‌ی تابعی از Py_XDECREF(). می‌توان از آن برای تعبیه پویای پایتون در ران‌تایم استفاده کرد.

Py_SETREF(dst, src)

ماکرویی که ارجاع قوی به شیء dst را به‌صورت ایمن آزاد می‌کند و dst را برابر src قرار می‌دهد.

همانند مورد Py_CLEAR()، کد «بدیهی» می‌تواند مرگبار باشد:

Py_DECREF(dst);
dst = src;

روش امن این است:

Py_SETREF(dst, src);

این کار به‌گونه‌ای ترتیب می‌دهد که dst پیش از آزاد کردن ارجاع به مقدار قبلی dst برابر src قرار گیرد؛ به‌طوری که هر کدی که به‌عنوان اثر جانبیِ تخریب شدن dst اجرا می‌شود، دیگر باور نمی‌کند که dst به یک شیء معتبر اشاره می‌کند.

اضافه شده در نسخه‌ی 3.6.

تغییر یافته در نسخه‌ی 3.12: آرگومان‌های ماکرو اکنون تنها یک‌بار ارزیابی می‌شوند. اگر آرگومانی اثر جانبی داشته باشد، این اثرها دیگر دوبار رخ نمی‌دهند.

Py_XSETREF(dst, src)

گونه‌ای از ماکرو Py_SETREF که به‌جای Py_DECREF() از Py_XDECREF() استفاده می‌کند.

اضافه شده در نسخه‌ی 3.6.

تغییر یافته در نسخه‌ی 3.12: آرگومان‌های ماکرو اکنون تنها یک‌بار ارزیابی می‌شوند. اگر آرگومانی اثر جانبی داشته باشد، این اثرها دیگر دوبار رخ نمی‌دهند.