تجزیه آرگومانها و ساخت مقادیر¶
این توابع هنگام ایجاد توابع و متدهای توسعهای خودتان مفید هستند. اطلاعات و نمونههای بیشتر در توسعه و تعبیه مفسر پایتون در دسترس است.
سه تابع نخستِ توضیحدادهشده، PyArg_ParseTuple()، PyArg_ParseTupleAndKeywords() و PyArg_Parse()، همگی از رشتههای قالبی استفاده میکنند که برای اطلاعرسانی به تابع درباره آرگومانهای مورد انتظار به کار میروند. رشتههای قالبی برای هر یک از این توابع از سینتکس یکسانی استفاده میکنند.
پارس کردن آرگومانها¶
رشته قالب از صفر یا چند «واحد قالب» (format unit) تشکیل شده است. هر واحد قالب یک شیء پایتون را توصیف میکند؛ این واحد معمولاً یک نویسهی تنها یا یک دنبالهی پرانتزگذاریشده از واحدهای قالب است. با وجود چند استثنا، واحد قالبی که دنبالهی پرانتزگذاریشده نیست، معمولاً متناظر با تنها یک آرگومان آدرس برای این توابع است. در توضیح زیر، شکل نقلقولشده همان واحد قالب است؛ ورودی داخل پرانتز (گرد)، نوع شیء پایتون است که با واحد قالب تطابق دارد؛ و ورودی داخل کروشه [مربع]، نوع متغیر(های) C است که آدرس آن باید گذر داده شود.
رشتهها و بافرها¶
توجه
در پایتون 3.12 و قدیمیتر، باید ماکروی PY_SSIZE_T_CLEAN پیش از درج Python.h تعریف شود تا بتوان از همهی گونههای # قالبها (s#، y# و غیره) که در ادامه توضیح داده شدهاند استفاده کرد. در پایتون 3.13 و جدیدتر، این کار ضروری نیست.
این قالبها اجازه میدهند به یک شیء بهعنوان یک تکه پیوسته از حافظه دسترسی داشته باشید. لازم نیست فضای ذخیرهسازی خامی برای ناحیه یونیکد یا بایتهای برگرداندهشده فراهم کنید.
مگر آنکه خلاف آن ذکر شده باشد، بافرها با نویسه تهی (NUL) پایان نمییابند.
سه روش برای تبدیل رشتهها و بافرها به C وجود دارد:
قالبهایی مانند
y*وs*یک ساختارPy_bufferرا پر میکنند. این کار بافر زیرین را قفل میکند تا فراخواننده بتواند متعاقباً حتی درون یک بلوکPy_BEGIN_ALLOW_THREADSاز بافر استفاده کند، بدون خطر تغییر اندازه یا نابود شدن دادههای تغییرپذیر. در نتیجه، پس از اتمام پردازش دادهها (یا در هر حالت خاتمه زودهنگام)، بایدPyBuffer_Release()را فراخوانی کنید.قالبهای
es،es#،etوet#بافر نتیجه را تخصیص میدهند. باید پس از پایان پردازش دادهها (یا در هر مورد خاتمه زودهنگام)،PyMem_Free()را فراخوانی کنید.قالبهای دیگر یک
strیا یک شیء شبهبایت فقطخواندنی، مانندbytes، میگیرند و اشارهگری از نوعconst char *به بافر آن فراهم میکنند. در این حالت بافر «امانتی» است: توسط شیء پایتون متناظر مدیریت میشود و عمر آن با عمر این شیء مشترک است. شما نیازی نخواهید داشت که خودتان هیچ حافظهای را آزاد کنید.برای اطمینان از اینکه بافر زیرین بتواند بهطور ایمن به امانت گرفته شود، فیلد
PyBufferProcs.bf_releasebufferمربوط به شیء بایدNULLباشد. این امر نهتنها اشیاء تغییرپذیر رایج مانندbytearray، بلکه برخی اشیاء فقطخواندنی مانندmemoryviewازbytesرا نیز منع میکند.علاوه بر این الزام
bf_releasebuffer، هیچ بررسیای برای تأیید اینکه شیء ورودی تغییرناپذیر است یا خیر انجام نمیشود (مثلاً اینکه آیا شیء به درخواست بافر نوشتنی ترتیب اثر میدهد، یا اینکه آیا نخ دیگری میتواند دادهها را تغییر دهد).
s(str) [const char *]یک شیء یونیکد را به اشارهگر C به یک رشته نویسهای تبدیل میکند. اشارهگر به یک رشته موجود، در متغیر اشارهگر نویسه که نشانی آن را ارسال میکنید، ذخیره میشود. رشته C با NUL پایان مییابد. رشته پایتون نباید شامل نقطهکدهای تهی تعبیهشده باشد؛ در صورت وجود، استثنای
ValueErrorایجاد میشود. اشیاء یونیکد با استفاده از کدگذاری'utf-8'به رشتههای C تبدیل میشوند. اگر این تبدیل شکست بخورد، استثنایUnicodeErrorایجاد میشود.توجه
این قالب اشیاء شبهبایت را نمیپذیرد. اگر میخواهید مسیرهای سامانه فایلبندی را بپذیرید و آنها را به رشتههای نویسهای C تبدیل کنید، بهتر است از قالب
O&باPyUnicode_FSConverter()بهعنوان converter استفاده کنید.تغییر یافته در نسخهی 3.5: پیشتر، هنگام مواجهه با نقطهکدهای تهی تعبیهشده در رشته پایتون، استثنای
TypeErrorپرتاب میشد.s*(strیا bytes-like object) [Py_buffer]این قالب اشیاء یونیکد و همچنین اشیاء شبهبایت را میپذیرد. این قالب ساختار
Py_bufferفراهمشده توسط فراخواننده را پر میکند. در این حالت، رشته C حاصل ممکن است شامل بایتهای تهی تعبیهشده باشد. اشیاء یونیکد با استفاده از کدگذاری'utf-8'به رشتههای C تبدیل میشوند.s#(str، شیء شبهبایت فقطخواندنی) [const char *,Py_ssize_t]مانند
s*، با این تفاوت که یک بافر امانی فراهم میکند. نتیجه در دو متغیر C ذخیره میشود؛ اولی اشارهگری به یک رشته C و دومی طول آن است. رشته ممکن است حاوی بایتهای تهی تعبیهشده باشد. اشیاء یونیکد با استفاده از کدگذاری'utf-8'به رشتههای C تبدیل میشوند.z(strیاNone) [const char *]مانند
s، اما شیء پایتون میتواندNoneنیز باشد، که در این صورت اشارهگر C برابرNULLقرار میگیرد.z*(str، شیء شبهبایت یاNone) [Py_buffer]مانند
s*، اما شیء پایتون میتواندNoneنیز باشد، که در این صورت عضوbufاز ساختارPy_bufferبرابرNULLقرار میگیرد.z#(str، شیء شبهبایت فقطخواندنی یاNone) [const char *,Py_ssize_t]مانند
s#، اما شیء پایتون میتواندNoneنیز باشد، که در این حالت اشارهگر C برابرNULLقرار میگیرد.y(شیء شبهبایت فقطخواندنی) [const char *]این قالب یک شیء شبهبایت را به اشارهگر C به یک رشته نویسهی امانی تبدیل میکند؛ اشیاء یونیکد را نمیپذیرد. بافر بایتها نباید حاوی بایتهای تهی تعبیهشده باشد؛ در صورت وجود، استثنای
ValueErrorایجاد میشود.تغییر یافته در نسخهی 3.5: پیشتر، هنگامی که بایتهای تهی تعبیهشده در بافر بایتها مشاهده میشدند، استثنای
TypeErrorایجاد میشد.y*(شیء شبهبایت) [Py_buffer]این گونه از
s*اشیای یونیکد را نمیپذیرد، فقط اشیای شبهبایت را میپذیرد. این روش توصیهشده برای پذیرش دادههای دودویی است.y#(شیء شبهبایت فقطخواندنی) [const char *,Py_ssize_t]این گونه از
s#اشیاء یونیکد را نمیپذیرد، بلکه فقط اشیاء شبهبایت را میپذیرد.S(bytes) [PyBytesObject *]نیازمند است که شیء پایتون یک شیء
bytesباشد، بدون تلاش برای انجام هیچ تبدیلی. اگر شیء، یک شیء bytes نباشد، استثنایTypeErrorایجاد میشود. متغیر C همچنین میتواند به صورت PyObject* اعلان شود.Y(bytearray) [PyByteArrayObject *]الزام میکند که شیء پایتون یک شیء
bytearrayباشد، بدون تلاش برای انجام هیچ تبدیلی. اگر شیء یک شیءbytearrayنباشد، استثنایTypeErrorرا ایجاد میکند. متغیر C همچنین میتواند به صورت PyObject* اعلان شود.U(str) [PyObject *]الزام میکند که شیء پایتون یک شیء یونیکد باشد، بدون تلاش برای انجام هیچ تبدیلی. اگر شیء یک شیء یونیکد نباشد، استثنای
TypeErrorایجاد میشود. متغیر C همچنین میتواند بهصورت PyObject* اعلان شود.w*(شیء شبهبایت خواندن-نوشتن) [Py_buffer]این قالب هر شیءای را که رابط بافر خواندن-نوشتن را پیادهسازی کند، میپذیرد. این قالب ساختار
Py_bufferرا که توسط فراخواننده فراهم شده است، پر میکند. بافر ممکن است شامل بایتهای تهی تعبیهشده باشد. فراخواننده باید پس از پایان کار با بافر،PyBuffer_Release()را فراخوانی کند.es(str) [const char *encoding, char **buffer]این گونه از
sبرای کدگذاری یونیکد درون یک بافر نویسه استفاده میشود. این گونه تنها با دادههای کدگذاریشدهای که بایتهای تهی تعبیهشده ندارند کار میکند.این قالب به دو آرگومان نیاز دارد. آرگومان اول فقط به عنوان ورودی استفاده میشود و باید یک const char* باشد که به نام یک کدگذاری به صورت رشتهی پایانیافته با تهی (NUL-terminated) اشاره کند، یا
NULLباشد که در این صورت کدگذاری'utf-8'استفاده میشود. اگر کدگذاری نامبرده برای پایتون شناختهشده نباشد، استثنایی مطرح میشود. آرگومان دوم باید یک char** باشد؛ مقدار اشارهگری که این آرگومان به آن ارجاع میدهد، به بافری حاوی محتوای متن آرگومان تنظیم خواهد شد. متن در کدگذاری تعیینشده توسط آرگومان اول کدگذاری خواهد شد.PyArg_ParseTuple()یک بافر با اندازهی مورد نیاز تخصیص میدهد، دادههای کدگذاریشده را در این بافر کپی میکند و *buffer را طوری تنظیم میکند که به حافظهی تازه تخصیصیافته ارجاع دهد. فراخوانکننده مسئول فراخوانیPyMem_Free()برای آزاد کردن بافر تخصیصیافته پس از استفاده است.et(str،bytesیاbytearray) [const char *encoding, char **buffer]مانند
esاست، با این تفاوت که اشیاء رشته بایتی بدون بازکدگذاری عبور داده میشوند. در عوض، پیادهسازی فرض میکند که شیء رشته بایتی از کدگذاریای استفاده میکند که بهعنوان پارامتر به آن داده شده است.es#(str) [const char *encoding, char **buffer,Py_ssize_t*buffer_length]این واریانتِ
s#برای کدگذاری یونیکد به یک بافر نویسهای به کار میرود. برخلاف قالبes، این واریانت اجازهی دادههای ورودی حاوی نویسههای تهی را میدهد.این مورد به سه آرگومان نیاز دارد. آرگومان اول فقط به عنوان ورودی استفاده میشود و باید یک const char* باشد که به نام یک کدگذاری به صورت رشته خاتمهیافته با تهی (NUL) اشاره کند، یا
NULLباشد که در این صورت از کدگذاری'utf-8'استفاده میشود. اگر کدگذاری نامبرده برای پایتون شناخته نشده باشد، استثنایی مطرح میشود. آرگومان دوم باید یک char** باشد؛ مقدار اشارهگری که به آن ارجاع داده میشود، به بافری شامل محتوای متن آرگومان تنظیم خواهد شد. متن در کدگذاری مشخصشده توسط آرگومان اول کدگذاری خواهد شد. آرگومان سوم باید اشارهگری به یک عدد صحیح باشد؛ عدد صحیح ارجاعشده به تعداد بایتهای بافر خروجی تنظیم خواهد شد.دو حالت کارکرد وجود دارد:
اگر *buffer یک اشارهگر
NULLباشد، تابع بافری با اندازهی مورد نیاز تخصیص میدهد، دادههای کدگذاریشده را در این بافر کپی میکند و *buffer را برای ارجاع به فضای ذخیرهسازی تازه تخصیصیافته تنظیم میکند. فراخواننده مسئول فراخوانیPyMem_Free()برای آزاد کردن بافر تخصیصیافته پس از استفاده است.اگر *buffer به اشارهگری غیر
NULLاشاره کند (بافری که از قبل تخصیص داده شده است)،PyArg_ParseTuple()از این مکان به عنوان بافر استفاده میکند و مقدار اولیهی *buffer_length را به عنوان اندازهی بافر تفسیر میکند. سپس دادههای کدگذاریشده را در بافر کپی میکند و آن را با NUL پایان میدهد. اگر بافر به اندازهی کافی بزرگ نباشد، یکValueErrorتنظیم میشود.در هر دو حالت، *buffer_length به طول دادههای کدگذاریشده بدون بایت تهی انتهایی تنظیم میشود.
et#(str،bytesیاbytearray) [const char *encoding, char **buffer,Py_ssize_t*buffer_length]مانند
es#است، با این تفاوت که اشیاء رشته بایتی بدون بازکدگذاری، مستقیماً عبور داده میشوند. در عوض، پیادهسازی فرض میکند که شیء رشته بایتی از کدگذاریای استفاده میکند که بهعنوان پارامتر پاس داده شده است.
تغییر یافته در نسخهی 3.12: u، u#، Z و Z# حذف شدهاند زیرا از نمایش قدیمی Py_UNICODE* استفاده میکردند.
اعداد¶
این قالبها اجازه میدهند اعداد پایتون یا نویسههای تکی بهصورت اعداد C نمایش داده شوند. قالبهایی که به int، float یا complex نیاز دارند، میتوانند برای تبدیل شیء پایتون به نوع موردنیاز از متدهای ویژهی متناظر __index__()، __float__() یا __complex__() نیز استفاده کنند.
برای قالبهای عدد صحیح علامتدار، اگر مقدار خارج از محدوده نوع C باشد، OverflowError مطرح میشود. برای قالبهای عدد صحیح بدون علامت، هیچ بررسی محدودهای انجام نمیشود --- وقتی فیلد دریافتکننده برای دریافت مقدار بیش از حد کوچک باشد، بیتهای پرارزش بدون هیچ هشداری بریده میشوند.
b(int) [unsigned char]یک عدد صحیح نامنفی پایتون را به یک عدد صحیح بسیار کوچک بدون علامت تبدیل میکند که در یک unsigned char در زبان C ذخیره میشود.
B(int) [unsigned char]یک عدد صحیح پایتون را بدون بررسی سرریز به یک عدد صحیح کوچک تبدیل میکند که در یک unsigned char از C ذخیره میشود.
h(int) [short int]یک عدد صحیح پایتون را به short int در زبان C تبدیل میکند.
H(int) [unsigned short int]یک عدد صحیح پایتون را بدون بررسی سرریز به یک unsigned short int در C تبدیل میکند.
i(int) [int]یک عدد صحیح پایتون را به یک int سادهی C تبدیل میکند.
I(int) [unsigned int]یک عدد صحیح پایتون را به unsigned int در C تبدیل میکند، بدون بررسی سرریز.
l(int) [long int]یک عدد صحیح پایتون را به یک long int در C تبدیل میکند.
k(int) [unsigned long]یک عدد صحیح پایتون را بدون بررسی سرریز به یک unsigned long در C تبدیل میکند.
تغییر یافته در نسخهی 3.14: در صورت وجود، از
__index__()استفاده کنید.L(int) [long long]تبدیل یک عدد صحیح پایتون به یک long long در C.
K(int) [unsigned long long]یک عدد صحیح پایتون را بدون بررسی سرریز به یک unsigned long long در C تبدیل میکند.
تغییر یافته در نسخهی 3.14: در صورت وجود، از
__index__()استفاده کنید.n(int) [Py_ssize_t]یک عدد صحیح پایتون را به یک
Py_ssize_tدر C تبدیل میکند.c(bytesیاbytearrayبا طول ۱) [char]یک بایت پایتون را که به صورت شیء
bytesیاbytearrayبه طول ۱ نمایش داده میشود، به یک char در C تبدیل میکند.تغییر یافته در نسخهی 3.3: اجازهی استفاده از اشیاء
bytearray.C(strبه طول ۱) [int]یک نویسهی پایتون را، که بهصورت شیء
strبا طول ۱ نمایش داده میشود، به یک int در C تبدیل میکند.f(float) [float]تبدیل یک عدد ممیز شناور پایتون به یک float در C.
d(float) [double]یک عدد ممیز شناور پایتون را به یک double در C تبدیل میکند.
D(complex) [Py_complex]یک عدد مختلط پایتون را به ساختار
Py_complexزبان C تبدیل میکند.
سایر اشیاء¶
O(شیء) [PyObject *]یک شیء پایتون را (بدون هیچ تبدیلی) در یک اشارهگر شیء C ذخیره میکند. بدین ترتیب برنامهی C همان شیء واقعیای را که پاس دادهشده است دریافت میکند. ارجاع قوی جدیدی به این شیء ایجاد نمیشود (یعنی شمارش ارجاع آن افزایش نمییابد). اشارهگر ذخیرهشده
NULLنیست.O!(شیء) [typeobject, PyObject *]یک شیء پایتون را در یک اشارهگر شیء C ذخیره میکند. این مورد شبیه
Oاست، اما دو آرگومان C میگیرد: آرگومان اول نشانی یک شیء نوع پایتون است و آرگومان دوم نشانی متغیر C (از نوع PyObject*) است که اشارهگر شیء در آن ذخیره میشود. اگر شیء پایتون نوع مورد نیاز را نداشته باشد، استثنایTypeErrorمطرح میشود.
O&(شیء) [مبدل، آدرس]یک شیء پایتون را از طریق تابع مبدل به یک متغیر C تبدیل کنید. این تبدیل دو آرگومان میگیرد: اولی یک تابع است و دومی آدرس یک متغیر C (از نوع دلخواه) است که به void* تبدیل میشود. تابع مبدل به نوبه خود به شکل زیر فراخوانی میشود:
status = converter(object, address);
که در آن object شیء پایتونی است که باید تبدیل شود و address آرگومان void* است که به تابع
PyArg_Parse*ارسال شده است. status بازگرداندهشده باید در صورت تبدیل موفق1و در صورت شکست تبدیل0باشد. هنگامی که تبدیل شکست میخورد، تابع converter باید استثنایی را برانگیزد و محتوای address را بدون تغییر بگذارد.اگر مبدل مقدار
Py_CLEANUP_SUPPORTEDرا برگرداند، ممکن است در صورتی که تجزیهی آرگومانها در نهایت شکست بخورد، بار دوم فراخوانی شود، که این به مبدل فرصت میدهد تا هر حافظهای را که پیشتر تخصیص داده بود آزاد کند. در این فراخوانی دوم، پارامتر object برابرNULLخواهد بود؛ address همان مقداری را خواهد داشت که در فراخوانی اصلی داشت.نمونههایی از مبدلها:
PyUnicode_FSConverter()وPyUnicode_FSDecoder().تغییر یافته در نسخهی 3.1:
Py_CLEANUP_SUPPORTEDافزوده شد.p(bool) [int]مقدار پاسدادهشده را برای درستی آزمایش میکند (یک محمول بولی (predicate)) و نتیجه را به مقدار عدد صحیح true/false معادل آن در C تبدیل میکند. اگر عبارت درست باشد، int را روی
1و اگر نادرست باشد، روی0قرار میدهد. این، هر مقدار معتبر پایتون را میپذیرد. برای اطلاعات بیشتر دربارهی اینکه پایتون چگونه مقادیر را برای درستی آزمایش میکند، Truth Value Testing را ببینید.اضافه شده در نسخهی 3.3.
(items)(دنباله) [آیتمهای منطبق]شیء باید یک دنباله پایتونی باشد (به جز
str،bytesیاbytearray) که طول آن برابر با تعداد واحدهای قالب (format unit) در items است. آرگومانهای C باید با تکتک واحدهای قالب در items متناظر باشند. واحدهای قالب برای دنبالهها میتوانند تودرتو باشند.اگر items شامل واحدهای قالب (format unit) باشد که یک بافر امانتی (
s،s#،z،z#،yیاy#) یا یک ارجاع امانتی (S،Y،U،OیاO!) را ذخیره میکنند، شیء باید یک تاپل پایتون باشد. مبدل واحد قالبO&در items نباید بافر امانتی یا ارجاع امانتی ذخیره کند.منسوخ شده از نسخهی 3.14: اگر items شامل واحدهای قالب باشد که بافر امانتی یا ارجاع امانتی ذخیره میکنند، دنبالههای غیرتاپلی منسوخ شدهاند.
چند نویسهی دیگر نیز در رشتهی قالببندی معنا دارند. این نویسهها نمیتوانند درون پرانتزهای تودرتو به کار روند. آنها عبارتاند از:
|Indicates that the remaining arguments in the Python argument list are optional. The C variables corresponding to optional arguments should be initialized to their default value --- when an optional argument is not specified,
PyArg_ParseTuple()does not touch the contents of the corresponding C variable(s). For example, the format string"OO|OO"corresponds to the Python signaturef(a, b, c=None, d=None).$PyArg_ParseTupleAndKeywords()only: Indicates that the remaining arguments in the Python argument list are keyword-only. They are optional if|was specified before$, and required otherwise.|cannot be specified after$. For example, the format string"O|O$O"corresponds to the Python signaturef(a, b=None, *, c=None), and the format string"OO$OO"corresponds tof(a, b, *, c, d).اضافه شده در نسخهی 3.3.
:فهرست واحدهای قالب در اینجا به پایان میرسد؛ رشتهای که پس از دونقطه میآید بهعنوان نام تابع در پیامهای خطا استفاده میشود («مقدار مرتبط» استثنایی که
PyArg_ParseTuple()ایجاد میکند).;فهرست واحدهای قالب در اینجا به پایان میرسد؛ رشتهی پس از نقطهویرگول بهجای پیام خطای پیشفرض، بهعنوان پیام خطا استفاده میشود.
:و;با یکدیگر انحصار متقابل دارند.
توجه داشته باشید که هر ارجاع به شیء پایتون که به فراخوانکننده ارائه میشود، ارجاعی امانتی است؛ آنها را آزاد نکنید (یعنی شمارش ارجاع آنها را کاهش ندهید)!
آرگومانهای اضافی که به این توابع پاس داده میشوند باید آدرس متغیرهایی باشند که نوع آنها توسط رشتهی قالب تعیین میشود؛ از این آرگومانها برای ذخیرهی مقادیر تاپل ورودی استفاده میشود. چند مورد وجود دارد، همانطور که در فهرست واحدهای قالب در بالا توضیح داده شده، که در آنها این پارامترها بهعنوان مقادیر ورودی استفاده میشوند؛ در چنین مواردی، این پارامترها باید با آنچه برای واحد قالب متناظر مشخص شده است مطابقت داشته باشند.
برای آنکه تبدیل با موفقیت انجام شود، شیء arg باید با قالب مطابقت داشته باشد و قالب باید بهطور کامل مصرف شود. در صورت موفقیت، توابع PyArg_Parse* مقدار true را برمیگردانند، در غیر این صورت مقدار false را برمیگردانند و یک استثنای مناسب ایجاد میکنند. هنگامی که توابع PyArg_Parse* به دلیل شکست تبدیل در یکی از واحدهای قالب با شکست مواجه میشوند، متغیرهایی که در آدرسهای متناظر با آن واحد قالب و واحدهای قالب بعدی قرار دارند، دستنخورده باقی میمانند.
توابع API¶
-
int PyArg_ParseTuple(PyObject *args, const char *format, ...)¶
- قسمتی از ABI پایدار.
پارامترهای تابعی را که فقط پارامترهای جایگاهی میپذیرد، به متغیرهای محلی تجزیه میکند. در صورت موفقیت true برمیگرداند؛ در صورت شکست، false برمیگرداند و استثنای مناسب را برمیانگیزد.
-
int PyArg_VaParse(PyObject *args, const char *format, va_list vargs)¶
- قسمتی از ABI پایدار.
یکسان با
PyArg_ParseTuple()است، با این تفاوت که بهجای تعداد متغیری از آرگومانها، یک va_list را میپذیرد.
-
int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *const *keywords, ...)¶
- قسمتی از ABI پایدار.
پارامترهای تابعی را که هم پارامترهای جایگاهی و هم پارامترهای کلیدواژهای میپذیرد، به متغیرهای محلی تجزیه میکند. آرگومان keywords آرایهای خاتمهیافته با
NULLاز نامهای پارامترهای کلیدواژهای است که بهصورت رشتههای C خاتمهیافته با تهی و کدگذاریشده با اسکی یا UTF-8 مشخص شدهاند. نامهای خالی نشاندهندهی پارامترهای فقطجایگاهی هستند. در صورت موفقیت، true برمیگرداند؛ در صورت شکست، false برمیگرداند و استثنای مناسب را ایجاد میکند.توجه
اعلان پارامتر keywords در C به صورت char *const* و در C++ به صورت const char *const* است. این را میتوان با ماکروی
PY_CXX_CONSTبازنویسی کرد.تغییر یافته در نسخهی 3.6: پشتیبانی از پارامترهای فقطجایگاهی افزوده شد.
تغییر یافته در نسخهی 3.13: پارامتر keywords اکنون در C از نوع char *const* و در C++ از نوع const char *const* است، بهجای char**. پشتیبانی از نامهای غیراسکی برای پارامترهای کلیدواژهای افزوده شد.
-
int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *const *keywords, va_list vargs)¶
- قسمتی از ABI پایدار.
یکسان با
PyArg_ParseTupleAndKeywords()است، با این تفاوت که به جای تعداد متغیری از آرگومانها، یک va_list میپذیرد.
-
int PyArg_ValidateKeywordArguments(PyObject*)¶
- قسمتی از ABI پایدار.
مطمئن شوید که کلیدهای دیکشنری آرگومان keywords رشته باشند. این کار تنها در صورتی لازم است که از
PyArg_ParseTupleAndKeywords()استفاده نشده باشد، زیرا خودِ آن از پیش این بررسی را انجام میدهد.اضافه شده در نسخهی 3.2.
-
int PyArg_Parse(PyObject *args, const char *format, ...)¶
- قسمتی از ABI پایدار.
پارامتر تابعی را که یک پارامتر جایگاهی منفرد میگیرد، در یک متغیر محلی پارس میکند. در صورت موفقیت true را برمیگرداند؛ در صورت شکست، false برمیگرداند و استثنای مناسب را ایجاد میکند.
مثال:
// Function using METH_O calling convention static PyObject* my_function(PyObject *module, PyObject *arg) { int value; if (!PyArg_Parse(arg, "i:my_function", &value)) { return NULL; } // ... use value ... }
-
int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)¶
- قسمتی از ABI پایدار.
شکل سادهتری از بازیابی پارامتر که برای تعیین نوع آرگومانها از رشته قالب استفاده نمیکند. توابعی که از این روش برای بازیابی پارامترهای خود استفاده میکنند باید در جدولهای تابع یا متد بهصورت
METH_VARARGSاعلان شوند. تاپل حاوی پارامترهای واقعی باید بهعنوان args ارسال شود؛ واقعاً باید یک تاپل باشد. طول تاپل باید حداقل min و حداکثر max باشد؛ min و max میتوانند برابر باشند. آرگومانهای اضافی باید به تابع ارسال شوند که هر یک باید اشارهگری به متغیر PyObject* باشد؛ اینها با مقادیر args پر خواهند شد؛ آنها حاوی ارجاعهای امانتی خواهند بود. متغیرهای متناظر با پارامترهای اختیاری که توسط args داده نشدهاند، پر نخواهند شد؛ این متغیرها باید توسط فراخواننده مقداردهی اولیه شوند. این تابع در صورت موفقیت true برمیگرداند و اگر args یک تاپل نباشد یا تعداد عناصر نادرستی داشته باشد false برمیگرداند؛ در صورت شکست، یک استثنا تنظیم خواهد شد.این مثالی از استفاده از این تابع است که از کدهای منبع ماژول کمکی
_weakrefبرای ارجاعهای ضعیف برگرفته شده است:static PyObject * weakref_ref(PyObject *self, PyObject *args) { PyObject *object; PyObject *callback = NULL; PyObject *result = NULL; if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { result = PyWeakref_NewRef(object, callback); } return result; }
فراخوانی
PyArg_UnpackTuple()در این مثال کاملاً معادل این فراخوانیPyArg_ParseTuple()است:PyArg_ParseTuple(args, "O|O:ref", &object, &callback)
-
PY_CXX_CONST¶
مقداری که در صورت وجود، پیش از char *const* در اعلان پارامتر keywords در
PyArg_ParseTupleAndKeywords()وPyArg_VaParseTupleAndKeywords()درج میشود. مقدار پیشفرض برای C خالی و برای C++ مقدارconstاست (const char *const*). برای تغییر این مقدار، آن را پیش از گنجاندنPython.hبه مقدار دلخواه تعریف کنید.اضافه شده در نسخهی 3.13.
ساخت مقادیر¶
-
PyObject *Py_BuildValue(const char *format, ...)¶
- مقدار بازگشتی: مرجع جدید. قسمتی از ABI پایدار.
یک مقدار جدید بر اساس یک رشته قالببندی مشابه رشتههای پذیرفتهشده توسط خانوادهی توابع
PyArg_Parse*و یک دنباله از مقادیر ایجاد میکند. مقدار یاNULLرا در صورت وقوع خطا برمیگرداند؛ اگرNULLبرگردانده شود، استثنا ایجاد خواهد شد.Py_BuildValue()همیشه تاپل نمیسازد. این تابع تنها زمانی تاپل میسازد که رشته قالببندی آن شامل دو واحد قالببندی یا بیشتر باشد. اگر رشته قالببندی خالی باشد،Noneبرمیگرداند؛ و اگر دقیقاً یک واحد قالببندی داشته باشد، هر شیئی را که آن واحد قالببندی توصیف میکند برمیگرداند. برای وادار کردن آن به برگرداندن تاپلی با اندازه ۰ یا یک، رشته قالببندی را داخل پرانتز قرار دهید.هنگامی که بافرهای حافظه بهعنوان پارامتر برای تأمین دادههای ساخت اشیاء ارسال میشوند — مانند قالبهای
sوs#— دادههای مورد نیاز کپی میشوند. اشیایی کهPy_BuildValue()ایجاد میکند، هرگز به بافرهای فراهمشده توسط فراخوانکننده ارجاعی ندارند. به عبارت دیگر، اگر کد شماmalloc()را فراخوانی کند و حافظهی تخصیصیافته را بهPy_BuildValue()منتقل کند، کد شما مسئول است که بهمحض بازگشتPy_BuildValue()،free()را برای آن حافظه فراخوانی کند.در توضیح زیر، شکل داخل گیومه، واحد قالب (format unit) است؛ ورودی داخل پرانتز (گرد)، نوع شیء پایتونی است که واحد قالب بازمیگرداند؛ و ورودی داخل کروشه [مربع]، نوع مقدار(های) C است که باید گذر داده شود.
نویسههای فاصله، تب، دونقطه و ویرگول در رشتههای قالب نادیده گرفته میشوند (اما نه درون واحدهای قالب مانند
s#). از این میتوان برای کمی خواناتر کردن رشتههای قالب بلند استفاده کرد.s(strیاNone) [const char *]یک رشته C پایانیافته با نویسه تهی را با استفاده از کدگذاری
'utf-8'به شیءstrپایتون تبدیل میکند. اگر اشارهگر رشته C برابرNULLباشد، ازNoneاستفاده میشود.s#(strیاNone) [const char *,Py_ssize_t]یک رشتهی C و طول آن را با استفاده از کدگذاری
'utf-8'به یک شیءstrپایتون تبدیل میکند. اگر اشارهگر رشتهی C برابرNULLباشد، طول نادیده گرفته میشود وNoneبازگردانده میشود.y(bytes) [const char *]این، یک رشته C را به یک شیء
bytesپایتون تبدیل میکند. اگر اشارهگر رشته C برابرNULLباشد،Noneبازگردانده میشود.y#(bytes) [const char *,Py_ssize_t]این، یک رشتهی C و طول آن را به یک شیء پایتون تبدیل میکند. اگر اشارهگر رشتهی C برابر
NULLباشد،Noneبرگردانده میشود.z(strیاNone) [const char *]همانند
sاست.z#(strیاNone) [const char *,Py_ssize_t]همانند
s#است.u(str) [const wchar_t *]یک بافر پایانیافته با تهی از نوع
wchar_tحاوی دادههای یونیکد (UTF-16 یا UCS-4) را به یک شیء یونیکد پایتون تبدیل میکند. اگر اشارهگر بافر یونیکدNULLباشد،Noneبرگردانده میشود.u#(str) [const wchar_t *,Py_ssize_t]یک بافر داده یونیکد (UTF-16 یا UCS-4) و طول آن را به یک شیء یونیکد پایتون تبدیل میکند. اگر اشارهگر بافر یونیکد
NULLباشد، طول نادیده گرفته میشود وNoneبرگردانده میشود.U(strیاNone) [const char *]همانند
sاست.U#(strیاNone) [const char *,Py_ssize_t]همانند
s#است.i(int) [int]تبدیل یک int سادهی C به یک شیء عدد صحیح پایتون.
b(int) [char]تبدیل یک char سادهی C به یک شیء عدد صحیح پایتون.
h(int) [short int]یک short int سادهی C را به یک شیء عدد صحیح پایتون تبدیل میکند.
l(int) [long int]تبدیل یک long int از زبان C به یک شیء عدد صحیح پایتون.
B(int) [unsigned char]یک unsigned char از C را به یک شیء عدد صحیح پایتون تبدیل میکند.
H(int) [unsigned short int]تبدیل یک unsigned short int در زبان C به یک شیء عدد صحیح پایتون.
I(int) [unsigned int]تبدیل یک unsigned int از زبان C به یک شیء عدد صحیح پایتون.
k(int) [unsigned long]یک unsigned long در C را به یک شیء عدد صحیح پایتون تبدیل میکند.
L(int) [long long]یک long long از C را به یک شیء عدد صحیح پایتون تبدیل میکند.
K(int) [unsigned long long]یک unsigned long long در C را به یک شیء عدد صحیح پایتون تبدیل میکند.
n(int) [Py_ssize_t]یک
Py_ssize_tدر C را به یک عدد صحیح پایتون تبدیل میکند.p(bool) [int]تبدیل یک int در C به یک شیء
boolپایتون.آگاه باشید که این قالب به یک آرگومان
intنیاز دارد. برخلاف بیشتر زمینههای دیگر در C، آرگومانهای متغیر (variadic) بهطور خودکار به نوعی مناسب تبدیل ضمنی نمیشوند. میتوانید نوع دیگری (مثلاً یک اشارهگر یا یک عدد اعشاری) را با استفاده از(x) ? 1 : 0یا!!xبه مقدارintمناسب تبدیل کنید.اضافه شده در نسخهی 3.14.
c(bytesبه طول ۱) [char]یک int از زبان C که نمایانگر یک بایت است را به یک شیء
bytesپایتون به طول ۱ تبدیل میکند.C(strبه طول ۱) [int]یک int از C که نشاندهندهی یک نویسه است را به شیء
strپایتون با طول ۱ تبدیل میکند.d(float) [double]یک double در C را به یک عدد ممیز شناور پایتون تبدیل میکند.
f(float) [float]تبدیل یک float در C به یک عدد ممیز شناور پایتون.
D(complex) [Py_complex *]تبدیل ساختار C
Py_complexبه یک عدد مختلط پایتون.O(شیء) [PyObject *]شیء پایتون را بدون تغییر پاس میدهد، اما یک strong reference جدید به آن ایجاد میکند (یعنی شمارش ارجاع آن یک واحد افزایش مییابد). اگر شیء پاسدادهشده یک اشارهگر
NULLباشد، فرض میشود که این اتفاق به این دلیل رخ داده است که فراخوانیای که آرگومان را تولید کرده، خطایی یافته و استثنایی تنظیم کرده است. بنابراین،Py_BuildValue()مقدارNULLرا برمیگرداند اما استثنایی طرح نمیکند. اگر هنوز استثنایی طرح نشده باشد،SystemErrorتنظیم میشود.S(شیء) [PyObject *]مانند
Oاست.N(شیء) [PyObject *]مانند
Oاست، با این تفاوت که ارجاع قوی جدیدی ایجاد نمیکند. زمانی مفید است که شیء در فهرست آرگومانها با فراخوانی سازندهی شیء ایجاد شده باشد.O&(شیء) [مبدل، هر چیزی]تبدیل هرچیز به یک شیء پایتون از طریق یک تابع مبدل. این تابع با هرچیز (که باید با void* سازگار باشد) بهعنوان آرگومان خود فراخوانی میشود و باید یک شیء پایتون «جدید» برگرداند، یا در صورت وقوع خطا
NULL.(items)(tuple) [آیتمهای مطابق]یک دنباله از مقادیر C را به یک تاپل پایتون با همان تعداد آیتم تبدیل میکند.
[items](list) [آیتمهای مطابق]دنبالهای از مقادیر C را به یک فهرست پایتون با همان تعداد آیتم تبدیل میکند.
{items}(dict) [آیتمهای متناظر]یک دنباله از مقادیر C را به یک دیکشنری پایتون تبدیل میکند. هر جفت از مقادیر متوالی C یک آیتم به دیکشنری اضافه میکند که به ترتیب به عنوان کلید و مقدار عمل میکنند.
اگر خطایی در رشته قالببندی وجود داشته باشد، استثنای
SystemErrorتنظیم میشود وNULLبازگردانده میشود.
-
PyObject *Py_VaBuildValue(const char *format, va_list vargs)¶
- مقدار بازگشتی: مرجع جدید. قسمتی از ABI پایدار.
یکسان با
Py_BuildValue()است، با این تفاوت که به جای تعداد متغیری از آرگومانها، یک va_list میپذیرد.