قسمتی از ABI پایدار از نسخهی 3.14.مقدار عدد صحیح پایتون pylong را به یک buffer بومی با اندازهی n_bytes کپی کنید. flags را میتوان روی -1 تنظیم کرد تا مشابه تبدیل نوع در زبان C رفتار کند، یا برای کنترل رفتار، روی مقادیر مستندشده در ادامه تنظیم کرد.
در صورت خطا، -1 را همراه با ایجاد یک استثنا برمیگرداند. این ممکن است زمانی رخ دهد که pylong نتواند بهعنوان یک عدد صحیح تفسیر شود، یا اینکه pylong منفی بوده و پرچم Py_ASNATIVEBYTES_REJECT_NEGATIVE تنظیم شده باشد.
در غیر این صورت، تعداد بایتهای مورد نیاز برای ذخیره مقدار را برمیگرداند. اگر این عدد برابر یا کمتر از n_bytes باشد، کل مقدار کپی شده است. تمام n_bytes بافر نوشته میشوند: بایتهای باقیمانده با کپیهایی از بیت علامت پر میشوند.
اگر مقدار بازگشتی بزرگتر از n_bytes باشد، مقدار اسلایسشده است: هر تعداد از کمارزشترین بیتهای مقدار که جا داشتند نوشته میشوند و بیتهای پرارزش نادیده گرفته میشوند. این با رفتار معمول تبدیل نوع به پایین (downcast) به سبک C مطابقت دارد.
نکته
سرریز بهعنوان خطا در نظر گرفته نمیشود. اگر مقدار بازگشتی بزرگتر از n_bytes باشد، بیتهای پرارزش دور ریخته شدهاند.
0 هرگز بازگردانده نمیشود.
مقادیر همیشه بهصورت مکمل دو کپی میشوند.
مثال استفاده:
int32_t value;
Py_ssize_t bytes = PyLong_AsNativeBytes(pylong, &value, sizeof(value), -1);
if (bytes < 0) {
// Failed. A Python exception was set with the reason.
return NULL;
}
else if (bytes <= (Py_ssize_t)sizeof(value)) {
// Success!
}
else {
// Overflow occurred, but 'value' contains the truncated
// lowest bits of pylong.
}
ارسال صفر به n_bytes اندازهی بافری را برمیگرداند که برای نگهداشتن مقدار بهاندازهی کافی بزرگ باشد. این اندازه ممکن است از آنچه از نظر فنی لازم است بزرگتر باشد، اما نه بهطور نامعقول. اگر n_bytes=0 باشد، buffer میتواند NULL باشد.
نکته
ارسال n_bytes=0 به این تابع، راه دقیقی برای تعیین طول بیتی مقدار نیست.
برای دسترسی به کل مقدار پایتون با اندازهی نامشخص، میتوان تابع را دو بار فراخوانی کرد: ابتدا برای تعیین اندازهی بافر، سپس برای پر کردن آن:
// Ask how much space we need.
Py_ssize_t expected = PyLong_AsNativeBytes(pylong, NULL, 0, -1);
if (expected < 0) {
// Failed. A Python exception was set with the reason.
return NULL;
}
assert(expected != 0); // Impossible per the API definition.
uint8_t *bignum = malloc(expected);
if (!bignum) {
PyErr_SetString(PyExc_MemoryError, "bignum malloc failed.");
return NULL;
}
// Safely get the entire value.
Py_ssize_t bytes = PyLong_AsNativeBytes(pylong, bignum, expected, -1);
if (bytes < 0) { // Exception has been set.
free(bignum);
return NULL;
}
else if (bytes > expected) { // This should not be possible.
PyErr_SetString(PyExc_RuntimeError,
"Unexpected bignum truncation after a size check.");
free(bignum);
return NULL;
}
// The expected success given the above pre-check.
// ... use bignum ...
free(bignum);
flags یا -1 (Py_ASNATIVEBYTES_DEFAULTS) است تا پیشفرضهایی را انتخاب کند که رفتارشان بیشترین شباهت را به قالبریزی C دارد، یا ترکیبی از پرچمهای دیگر در جدول زیر است. توجه داشته باشید که -1 را نمیتوان با پرچمهای دیگر ترکیب کرد.
در حال حاضر، -1 معادل Py_ASNATIVEBYTES_NATIVE_ENDIAN | Py_ASNATIVEBYTES_UNSIGNED_BUFFER است.
These values are available when compiling for the
Stable ABI since version 3.14.
پرچم |
مقدار |
-
Py_ASNATIVEBYTES_DEFAULTS¶
|
-1
|
-
Py_ASNATIVEBYTES_BIG_ENDIAN¶
|
0
|
-
Py_ASNATIVEBYTES_LITTLE_ENDIAN¶
|
1
|
-
Py_ASNATIVEBYTES_NATIVE_ENDIAN¶
|
3
|
-
Py_ASNATIVEBYTES_UNSIGNED_BUFFER¶
|
4
|
-
Py_ASNATIVEBYTES_REJECT_NEGATIVE¶
|
8
|
-
Py_ASNATIVEBYTES_ALLOW_INDEX¶
|
16
|
مشخص کردن Py_ASNATIVEBYTES_NATIVE_ENDIAN هر پرچم اندیان دیگری را لغو میکند. ارسال 2 رزرو شده است.
بهطور پیشفرض، بافر کافی برای گنجاندن بیت علامت درخواست میشود. برای مثال، هنگام تبدیل ۱۲۸ با n_bytes=1، تابع ۲ (یا بیشتر) را برمیگرداند تا بیت علامت صفر ذخیره شود.
اگر Py_ASNATIVEBYTES_UNSIGNED_BUFFER مشخص شده باشد، بیت علامت صفر از محاسبات اندازه حذف میشود. این امکان را فراهم میکند که برای مثال عدد ۱۲۸ در یک بافر تکبایتی جا شود. اگر بافر مقصد بعداً علامتدار تلقی شود، ممکن است یک مقدار ورودی مثبت به مقداری منفی تبدیل شود. توجه داشته باشید که این پرچم بر مدیریت مقادیر منفی تأثیری ندارد: برای این مقادیر، همیشه فضایی برای بیت علامت درخواست میشود.
مشخص کردن Py_ASNATIVEBYTES_REJECT_NEGATIVE باعث میشود در صورت منفی بودن pylong، یک استثنا تنظیم شود. بدون این پرچم، مقادیر منفی کپی میشوند، به شرطی که فضای کافی برای حداقل یک بیت علامت وجود داشته باشد؛ صرفنظر از اینکه Py_ASNATIVEBYTES_UNSIGNED_BUFFER مشخص شده باشد یا خیر.
اگر Py_ASNATIVEBYTES_ALLOW_INDEX تعیین شده باشد و یک مقدار غیر عدد صحیح پاس داده شود، متد __index__() آن ابتدا فراخوانی خواهد شد. این ممکن است منجر به اجرای کد پایتون شود و به نخهای دیگر اجازه اجرا داده شود، که میتواند تغییراتی در اشیاء یا مقادیر دیگر در حال استفاده ایجاد کند. وقتی flags برابر -1 باشد، این گزینه تنظیم نشده است و مقادیر غیر عدد صحیح باعث ایجاد TypeError میشوند.
نکته
با flags پیشفرض (-1، یا UNSIGNED_BUFFER بدون REJECT_NEGATIVE)، چندین عدد صحیح پایتون میتوانند بدون سرریز به یک مقدار واحد نگاشت شوند. برای مثال، هر دو 255 و -1 در یک بافر تکبایتی جا میشوند و تمام بیتهای آن را تنظیم میکنند. این با رفتار تبدیل نوع معمول در C مطابقت دارد.
اضافه شده در نسخهی 3.13.