Kiểu cấu trúc đối tượng

Có lẽ một trong những cấu trúc quan trọng nhất của hệ thống đối tượng Python là cấu trúc xác định một kiểu mới: cấu trúc PyTypeObject. Các đối tượng loại có thể được xử lý bằng cách sử dụng bất kỳ hàm PyObject_* hoặc PyType_* nào, nhưng không mang lại nhiều điều thú vị cho hầu hết các ứng dụng Python. Các đối tượng này là nền tảng cho cách các đối tượng hoạt động, vì vậy chúng rất quan trọng đối với chính trình thông dịch và đối với bất kỳ mô-đun mở rộng nào triển khai các kiểu mới.

Đối tượng loại khá lớn so với hầu hết các loại tiêu chuẩn. Lý do cho kích thước là vì mỗi đối tượng kiểu lưu trữ một số lượng lớn các giá trị, chủ yếu là các con trỏ hàm C, mỗi đối tượng thực hiện một phần nhỏ chức năng của kiểu. Các trường của đối tượng loại được xem xét chi tiết trong phần này. Các trường sẽ được mô tả theo thứ tự xuất hiện trong cấu trúc.

Ngoài phần tham khảo nhanh sau đây, phần Ví dụ còn cung cấp cái nhìn tổng quan về ý nghĩa và cách sử dụng PyTypeObject.

Tham khảo nhanh

"khe tp"

Khe cắm PyTypeObject [1]

Type

phương pháp/attrs đặc biệt

Thông tin [2]

T

D

TÔI

<R> tp_name

const char *

__tên__

X

X

tp_basicsize

Py_ssize_t

X

X

X

tp_itemsize

Py_ssize_t

X

X

tp_dealloc

destructor

X

X

X

tp_vectorcall_offset

Py_ssize_t

X

X

(tp_getattr)

getattrfunc

__getattribute__, __getattr__

G

(tp_setattr)

setattrfunc

__setattr__, __delattr__

G

tp_as_async

PyAsyncMethods *

khe phụ

%

tp_repr

reprfunc

__repr__

X

X

X

tp_as_number

PyNumberMethods *

khe phụ

%

tp_as_sequence

PySequenceMethods *

khe phụ

%

tp_as_mapping

PyMappingMethods *

khe phụ

%

tp_hash

hashfunc

__băm__

X

G

tp_call

ternaryfunc

__gọi__

X

X

tp_str

reprfunc

__str__

X

X

tp_getattro

getattrofunc

__getattribute__, __getattr__

X

X

G

tp_setattro

setattrofunc

__setattr__, __delattr__

X

X

G

tp_as_buffer

PyBufferProcs *

khe phụ

%

tp_flags

dài không dấu

X

X

?

tp_doc

const char *

__doc__

X

X

tp_traverse

traverseproc

X

G

tp_clear

inquiry

X

G

tp_richcompare

richcmpfunc

__lt__, __le__, __eq__, __ne__, __gt__, __ge__

X

G

(tp_weaklistoffset)

Py_ssize_t

X

?

tp_iter

getiterfunc

__iter__

X

tp_iternext

iternextfunc

__Kế tiếp__

X

tp_methods

PyMethodDef []

X

X

tp_members

PyMemberDef []

X

tp_getset

PyGetSetDef []

X

X

tp_base

PyTypeObject *

__căn cứ__

X

tp_dict

PyObject *

__dict__

?

tp_descr_get

descrgetfunc

__lấy__

X

tp_descr_set

descrsetfunc

__đặt__, __xóa__

X

(tp_dictoffset)

Py_ssize_t

X

?

tp_init

initproc

__init__

X

X

X

tp_alloc

allocfunc

X

?

?

tp_new

newfunc

__mới__

X

X

?

?

tp_free

freefunc

X

X

?

?

tp_is_gc

inquiry

X

X

<tp_bases>

PyObject *

__bases__

~

<tp_mro>

PyObject *

__mro__

~

[tp_cache]

PyObject *

[tp_subclasses]

trống *

__lớp con__

[tp_weaklist]

PyObject *

(tp_del)

destructor

[tp_version_tag]

int không dấu

tp_finalize

destructor

__del__

X

tp_vectorcall

vectorcallfunc

[tp_watched]

ký tự không dấu

khe phụ

Chỗ

Type

phương pháp đặc biệt

am_await

unaryfunc

__chờ đợi__

am_aiter

unaryfunc

__aiter__

am_anext

unaryfunc

__tiếp theo__

am_send

sendfunc

nb_add

binaryfunc

__add__ __radd__

nb_inplace_add

binaryfunc

__iadd__

nb_subtract

binaryfunc

__phụ__ __rsub__

nb_inplace_subtract

binaryfunc

__isub__

nb_multiply

binaryfunc

__mul__ __rmul__

nb_inplace_multiply

binaryfunc

__imul__

nb_remainder

binaryfunc

__mod__ __rmod__

nb_inplace_remainder

binaryfunc

__imod__

nb_divmod

binaryfunc

__divmod__ __rdivmod__

nb_power

ternaryfunc

__pow__ __row__

nb_inplace_power

ternaryfunc

__iow__

nb_negative

unaryfunc

__tiêu cực__

nb_positive

unaryfunc

__vị trí__

nb_absolute

unaryfunc

__abs__

nb_bool

inquiry

__bool__

nb_invert

unaryfunc

__đảo ngược__

nb_lshift

binaryfunc

__lshift__ __rlshift__

nb_inplace_lshift

binaryfunc

__ilshift__

nb_rshift

binaryfunc

__rshift__ __rrshift__

nb_inplace_rshift

binaryfunc

__irshift__

nb_and

binaryfunc

__và__ __rand__

nb_inplace_and

binaryfunc

__và__

nb_xor

binaryfunc

__xor__ __rxor__

nb_inplace_xor

binaryfunc

__ixor__

nb_or

binaryfunc

__hoặc__ __ror__

nb_inplace_or

binaryfunc

__ior__

nb_int

unaryfunc

__int__

nb_reserved

trống *

nb_float

unaryfunc

__trôi nổi__

nb_floor_divide

binaryfunc

__sàndiv__

nb_inplace_floor_divide

binaryfunc

__ifloordiv__

nb_true_divide

binaryfunc

__truediv__

nb_inplace_true_divide

binaryfunc

__itruediv__

nb_index

unaryfunc

__chỉ mục__

nb_matrix_multiply

binaryfunc

__matmul__ __rmatmul__

nb_inplace_matrix_multiply

binaryfunc

__imatmul__

mp_length

lenfunc

__len__

mp_subscript

binaryfunc

__getitem__

mp_ass_subscript

objobjargproc

__setitem__, __delitem__

sq_length

lenfunc

__len__

sq_concat

binaryfunc

__thêm vào__

sq_repeat

ssizeargfunc

__mul__

sq_item

ssizeargfunc

__getitem__

sq_ass_item

ssizeobjargproc

__setitem__ __delitem__

sq_contains

objobjproc

__chứa__

sq_inplace_concat

binaryfunc

__iadd__

sq_inplace_repeat

ssizeargfunc

__imul__

bf_getbuffer

getbufferproc()

__bộ đệm__

bf_releasebuffer

releasebufferproc()

__release_bộ đệm__

khe typedefs

typedef

Các loại tham số

Kiểu trả về

allocfunc

PyObject *

destructor

PyObject *

trống rỗng

freefunc

trống *

trống rỗng

traverseproc

trống *

int

newfunc

PyObject *

initproc

int

reprfunc

PyObject *

PyObject *

getattrfunc

const char *

PyObject *

setattrfunc

const char *

int

getattrofunc

PyObject *

setattrofunc

int

descrgetfunc

PyObject *

descrsetfunc

int

hashfunc

PyObject *

Py_hash_t

richcmpfunc

int

PyObject *

getiterfunc

PyObject *

PyObject *

iternextfunc

PyObject *

PyObject *

lenfunc

PyObject *

Py_ssize_t

getbufferproc

int

releasebufferproc

trống rỗng

inquiry

PyObject *

int

unaryfunc

PyObject *

binaryfunc

PyObject *

ternaryfunc

PyObject *

ssizeargfunc

PyObject *

ssizeobjargproc

int

objobjproc

int

objobjargproc

int

Xem Loại vị trí typedefs bên dưới để biết thêm chi tiết.

Định nghĩa đối tượng PyType

Định nghĩa cấu trúc cho PyTypeObject có thể được tìm thấy trong Include/cpython/object.h. Để thuận tiện cho việc tham khảo, điều này lặp lại định nghĩa được tìm thấy ở đó:

typedef cấu trúc _typeobject {
    PyObject_VAR_HEAD
    const char *tp_name; /* Để in, ở định dạng "<module>.<name>" */
    Py_ssize_t tp_basicsize, tp_itemsize; /* Để phân bổ */

    /* Các phương thức thực hiện các thao tác chuẩn */

    hàm hủy tp_dealloc;
    Py_ssize_t tp_vectorcall_offset;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    PyAsyncMethods *tp_as_async; /* trước đây gọi là tp_compare (Python 2)
                                    hoặc tp_reserved (Python 3) */
    reprfunc tp_repr;

    /* Bộ phương thức cho các lớp tiêu chuẩn */

    Phương thức PyNumber *tp_as_number;
    Phương thức PySequence *tp_as_sequence;
    Phương thức PyMapping *tp_as_mapping;

    /* Các thao tác tiêu chuẩn khác (ở đây để tương thích nhị phân) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* Hàm truy cập đối tượng dưới dạng bộ đệm đầu vào/đầu ra */
    PyBufferProcs *tp_as_buffer;

    /* Cờ để xác định sự hiện diện của các tính năng tùy chọn/mở rộng */
    tp_flags dài không dấu;

    const char *tp_doc; /* Chuỗi tài liệu */

    /* Ý nghĩa được gán trong phiên bản 2.0 */
    /*gọi hàm cho tất cả các đối tượng có thể truy cập được */
    traverseproc tp_traverse;

    /*xóa tham chiếu đến các đối tượng được chứa */
    yêu cầu tp_clear;

    /* Ý nghĩa được gán trong phiên bản 2.1 */
    /* so sánh phong phú */
    richcmpfunc tp_richcompare;

    /* trình kích hoạt tham chiếu yếu */
    Py_ssize_t tp_weaklistoffset;

    /* Các vòng lặp */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* Bộ mô tả thuộc tính và nội dung phân lớp */
    PyMethodDef *tp_methods;
    PyMemberDef *tp_members;
    PyGetSetDef *tp_getset;
    // Tham chiếu mạnh trên kiểu heap, tham chiếu mượn trên kiểu tĩnh
    PyTypeObject *tp_base;
    PyObject *tp_dict;
    giải  tp_descr_get;
    giải  tp_descr_set;
    Py_ssize_t tp_dictoffset;
    initproc tp_init;
    phân bổ tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* Thủ tục bộ nhớ trống cấp độ thấp */
    yêu cầu tp_is_gc; /* Dành cho PyObject_IS_GC */
    PyObject *tp_base;
    Thứ tự phân giải phương thức PyObject *tp_mro; /* */
    PyObject *tp_cache; /* không còn được sử dụng */
    void *tp_subclasses;  /* đối với các kiểu dựng sẵn tĩnh, đây là một chỉ mục */
    PyObject *tp_weaklist; /* không được sử dụng cho các kiểu dựng sẵn tĩnh */
    hàm hủy tp_del;

    /* Nhập thẻ phiên bản bộ đệm thuộc tính. Đã thêm vào phiên bản 2.6.
     * Nếu bằng 0, bộ đệm không hợp lệ và phải được khởi tạo.
     */
    unsigned int tp_version_tag;

    hàm hủy tp_finalize;
    vectorcallfunc tp_vectorcall;

    /* bitset mà người theo dõi kiểu quan tâm đến kiểu này */
     tự không dấu tp_watched;

    /* Số lượng giá trị tp_version_tag được sử dụng.
     * Đặt thành _Py_ATTR_CACHE_UNUSED nếu bộ đệm thuộc tính là
     * bị vô hiệu hóa đối với loại này (ví dụ: do các mục MRO tùy chỉnh).
     * Mặt khác, giới hạn ở MAX_VERSIONS_PER_CLASS (được xác định ở nơi khác).
     */
    uint16_t tp_versions_used;
} PyTypeObject;

Khe cắm PyObject

Cấu trúc đối tượng kiểu mở rộng cấu trúc PyVarObject. Trường ob_size được sử dụng cho các loại động (được tạo bởi type_new(), thường được gọi từ một câu lệnh lớp). Lưu ý rằng PyType_Type (siêu kiểu) khởi tạo tp_itemsize, có nghĩa là các phiên bản của nó (tức là loại đối tượng) must có trường ob_size.

PyObject.ob_refcnt

Số tham chiếu của đối tượng loại được khởi tạo thành 1 bởi macro PyObject_HEAD_INIT. Lưu ý rằng đối với statically allocated type objects, các phiên bản của loại (các đối tượng có ob_type trỏ ngược lại loại) not được tính là tham chiếu. Nhưng đối với dynamically allocated type objects, các phiên bản do được tính là tham chiếu.

Inheritance:

Trường này không được kế thừa bởi các kiểu con.

PyObject.ob_type

Đây là loại của loại, nói cách khác là siêu loại của nó. Nó được khởi tạo bằng đối số của macro PyObject_HEAD_INIT và giá trị của nó thường là &PyType_Type. Tuy nhiên, đối với các mô-đun mở rộng có thể tải động và phải sử dụng được trên Windows (ít nhất), trình biên dịch sẽ phàn nàn rằng đây không phải là trình khởi tạo hợp lệ. Do đó, quy ước là chuyển NULL cho macro PyObject_HEAD_INIT và khởi tạo trường này một cách rõ ràng khi bắt đầu chức năng khởi tạo của mô-đun, trước khi thực hiện bất kỳ điều gì khác. Điều này thường được thực hiện như thế này:

Foo_Type.ob_type = &PyType_Type;

Điều này nên được thực hiện trước khi bất kỳ phiên bản nào của loại này được tạo. PyType_Ready() kiểm tra xem ob_type có phải là NULL hay không và nếu có, hãy khởi tạo nó ở trường ob_type của lớp cơ sở. PyType_Ready() sẽ không thay đổi trường này nếu nó khác 0.

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Khe cắm đối tượng PyVar

PyVarObject.ob_size

Đối với statically allocated type objects, giá trị này phải được khởi tạo bằng 0. Đối với dynamically allocated type objects, trường này có ý nghĩa nội tại đặc biệt.

Trường này phải được truy cập bằng macro Py_SIZE().

Inheritance:

Trường này không được kế thừa bởi các kiểu con.

Khe cắm đối tượng PyType

Mỗi slot có một phần mô tả tính kế thừa. Nếu PyType_Ready() có thể đặt giá trị khi trường được đặt thành NULL thì cũng sẽ có phần "Mặc định". (Lưu ý rằng nhiều trường được đặt trên PyBaseObject_TypePyType_Type hoạt động như mặc định một cách hiệu quả.)

const char *PyTypeObject.tp_name

Con trỏ tới chuỗi kết thúc bằng NUL chứa tên của loại. Đối với các loại có thể truy cập được dưới dạng toàn cục mô-đun, chuỗi phải là tên mô-đun đầy đủ, theo sau là dấu chấm, theo sau là tên loại; đối với các loại tích hợp, nó chỉ là tên loại. Nếu mô-đun là mô-đun con của gói thì tên gói đầy đủ là một phần của tên mô-đun đầy đủ. Ví dụ: loại có tên T được xác định trong mô-đun M trong gói con Q trong gói P phải có trình khởi tạo tp_name "P.Q.M.T".

Đối với dynamically allocated type objects, đây chỉ là tên loại và tên mô-đun được lưu trữ rõ ràng trong lệnh loại làm giá trị cho khóa '__module__'.

Đối với statically allocated type objects, trường tp_name phải chứa dấu chấm. Mọi thứ trước dấu chấm cuối cùng đều có thể truy cập được dưới dạng thuộc tính __module__ và mọi thứ sau dấu chấm cuối cùng đều có thể truy cập được dưới dạng thuộc tính __name__.

Nếu không có dấu chấm, toàn bộ trường tp_name sẽ có thể truy cập được dưới dạng thuộc tính __name__ và thuộc tính __module__ không được xác định (trừ khi được đặt rõ ràng trong từ điển, như đã giải thích ở trên). Điều này có nghĩa là loại của bạn sẽ không thể ngâm được. Ngoài ra, nó sẽ không được liệt kê trong tài liệu mô-đun được tạo bằng pydoc.

Trường này không được là NULL. Đây là trường bắt buộc duy nhất trong PyTypeObject() (ngoài trường có khả năng là tp_itemsize).

Inheritance:

Trường này không được kế thừa bởi các kiểu con.

Py_ssize_t PyTypeObject.tp_basicsize
Py_ssize_t PyTypeObject.tp_itemsize

Các trường này cho phép tính toán kích thước tính bằng byte của các thể hiện của loại.

Có hai loại loại: loại có phiên bản có độ dài cố định có trường tp_itemsize bằng 0, loại có phiên bản có độ dài thay đổi có trường tp_itemsize khác 0. Đối với loại có phiên bản có độ dài cố định, tất cả phiên bản đều có cùng kích thước, được tính bằng tp_basicsize. (Các ngoại lệ cho quy tắc này có thể được thực hiện bằng PyUnstable_Object_GC_NewWithExtraData().)

Đối với loại có phiên bản có độ dài thay đổi, phiên bản phải có trường ob_size và kích thước phiên bản là tp_basicsize cộng với N lần tp_itemsize, trong đó N là "độ dài" của đối tượng.

Các hàm như PyObject_NewVar() sẽ lấy giá trị của N làm đối số và lưu trữ trong trường ob_size của phiên bản. Lưu ý rằng trường ob_size sau này có thể được sử dụng cho các mục đích khác. Ví dụ: các phiên bản int sử dụng các bit của ob_size theo cách được xác định khi triển khai; bộ nhớ cơ bản và kích thước của nó phải được truy cập bằng PyLong_Export().

Ghi chú

Trường ob_size phải được truy cập bằng macro Py_SIZE()Py_SET_SIZE().

Ngoài ra, sự hiện diện của trường ob_size trong bố cục phiên bản không có nghĩa là cấu trúc phiên bản có độ dài thay đổi. Ví dụ: loại list có các phiên bản có độ dài cố định, tuy nhiên các phiên bản đó có trường ob_size. (Giống như int, tránh đọc trực tiếp danh sách' ob_size. Thay vào đó hãy gọi PyList_Size().)

tp_basicsize bao gồm kích thước cần thiết cho dữ liệu thuộc loại tp_base, cộng với mọi dữ liệu bổ sung cần thiết cho mỗi phiên bản.

Cách chính xác để đặt tp_basicsize là sử dụng toán tử sizeof trên cấu trúc được sử dụng để khai báo bố cục cá thể. Cấu trúc này phải bao gồm cấu trúc được sử dụng để khai báo kiểu cơ sở. Nói cách khác, tp_basicsize phải lớn hơn hoặc bằng tp_basicsize của cơ số.

Vì mỗi loại là một kiểu con của object nên cấu trúc này phải bao gồm PyObject hoặc PyVarObject (tùy thuộc vào việc có nên đưa vào ob_size hay không). Chúng thường được xác định bởi macro PyObject_HEAD hoặc PyObject_VAR_HEAD tương ứng.

Kích thước cơ bản không bao gồm kích thước tiêu đề GC vì tiêu đề đó không phải là một phần của PyObject_HEAD.

Đối với trường hợp cấu trúc được sử dụng để khai báo loại cơ sở không xác định, hãy xem PyType_Spec.basicsizePyType_FromMetaclass().

Lưu ý về căn chỉnh:

  • tp_basicsize phải là bội số của _Alignof(PyObject). Khi sử dụng sizeof trên struct bao gồm PyObject_HEAD, như được khuyến nghị, trình biên dịch sẽ đảm bảo điều này. Khi không sử dụng C struct hoặc khi sử dụng các phần mở rộng của trình biên dịch như __attribute__((packed)), điều đó tùy thuộc vào bạn.

  • Nếu các mục biến yêu cầu một sự căn chỉnh cụ thể thì mỗi mục tp_basicsizetp_itemsize phải là bội số của sự căn chỉnh đó. Ví dụ: nếu phần biến của một loại lưu trữ double, thì trách nhiệm của bạn là cả hai trường đều là bội số của _Alignof(double).

Inheritance:

Các trường này được kế thừa riêng biệt theo kiểu con. (Nghĩa là, nếu trường được đặt thành 0, PyType_Ready() sẽ sao chép giá trị từ loại cơ sở, cho biết rằng các phiên bản không cần bộ nhớ bổ sung.)

Nếu loại cơ sở có tp_itemsize khác 0 thì việc đặt tp_itemsize thành một giá trị khác 0 trong một loại phụ thường không an toàn (mặc dù điều này phụ thuộc vào việc triển khai loại cơ sở).

destructor PyTypeObject.tp_dealloc

The corresponding slot ID Py_tp_dealloc is part of the ABI ổn định.

Một con trỏ tới hàm hủy phiên bản. Chữ ký hàm là:

void tp_dealloc(PyObject *self);

Hàm hủy sẽ xóa tất cả các tham chiếu mà phiên bản sở hữu (ví dụ: gọi Py_CLEAR()), giải phóng tất cả bộ đệm mà phiên bản đó sở hữu và gọi hàm tp_free của loại để giải phóng chính đối tượng đó.

Nếu bạn có thể gọi các hàm có thể đặt chỉ báo lỗi, bạn phải sử dụng PyErr_GetRaisedException()PyErr_SetRaisedException() để đảm bảo bạn không chặn chỉ báo lỗi có sẵn (việc xử lý có thể đã xảy ra trong khi xử lý một lỗi khác):

khoảng trống tĩnh
foo_dealloc(foo_object *self)
{
    PyObject *et, *ev, *etb;
    PyObject *exc = PyErr_GetRaisedException();
    ...
    PyErr_SetRaisedException(exc);
}

Bản thân trình xử lý dealloc không được đưa ra ngoại lệ; nếu gặp trường hợp lỗi, nó sẽ gọi PyErr_FormatUnraisable() để ghi lại (và xóa) một ngoại lệ không thể xử lý được.

Không có đảm bảo nào được đưa ra khi một đối tượng bị phá hủy, ngoại trừ:

  • Python sẽ hủy một đối tượng ngay lập tức hoặc một thời gian sau khi tham chiếu cuối cùng đến đối tượng bị xóa, trừ khi bộ hoàn thiện của nó (tp_finalize) sau đó phục hồi đối tượng.

  • Một đối tượng sẽ không bị hủy trong khi nó đang được tự động hoàn thiện (tp_finalize) hoặc tự động xóa (tp_clear).

CPython hiện phá hủy một đối tượng ngay lập tức khỏi Py_DECREF() khi số lượng tham chiếu mới bằng 0, nhưng điều này có thể thay đổi trong phiên bản tương lai.

Bạn nên gọi PyObject_CallFinalizerFromDealloc() khi bắt đầu tp_dealloc để đảm bảo rằng đối tượng luôn được hoàn thiện trước khi hủy.

Nếu loại hỗ trợ thu gom rác (cờ Py_TPFLAGS_HAVE_GC được đặt), hàm hủy sẽ gọi PyObject_GC_UnTrack() trước khi xóa bất kỳ trường thành viên nào.

Được phép gọi tp_clear từ tp_dealloc để giảm trùng lặp mã và đảm bảo rằng đối tượng luôn bị xóa trước khi hủy. Hãy lưu ý rằng tp_clear có thể đã được gọi.

Nếu loại được phân bổ heap (Py_TPFLAGS_HEAPTYPE), bộ giải phóng sẽ giải phóng tham chiếu được sở hữu cho đối tượng loại của nó (thông qua Py_DECREF()) sau khi gọi bộ giải phóng loại. Xem mã ví dụ bên dưới.:

khoảng trống tĩnh
foo_dealloc(PyObject *op)
{
   foo_object *self = (foo_object *) op;
   PyObject_GC_UnTrack(tự);
   Py_CLEAR(tự->ref);
   Py_TYPE(tự)->tp_free(tự);
}

tp_dealloc phải giữ nguyên trạng thái ngoại lệ. Nếu nó cần gọi một cái gì đó có thể tạo ra một ngoại lệ, thì trạng thái ngoại lệ phải được sao lưu trước và khôi phục sau (sau khi ghi lại bất kỳ ngoại lệ nào bằng PyErr_WriteUnraisable()).

Ví dụ:

khoảng trống tĩnh
foo_dealloc(PyObject *self)
{
    PyObject *exc = PyErr_GetRaisedException();

    if (PyObject_CallFinalizerFromDealloc(self) < 0) {
        // bản thân đã được hồi sinh.
        phải làm xong;
    }

    PyTypeObject *tp = Py_TYPE(self);

    if (tp->tp_flags & Py_TPFLAGS_HAVE_GC) {
        PyObject_GC_UnTrack(tự);
    }

    // Tùy chọn nhưng thuận tiện để tránh trùng lặp mã.
    if (tp->tp_clear && tp->tp_clear(self) < 0) {
        PyErr_WriteUnraiseable(self);
    }

    // Mọi sự phá hủy bổ sung sẽ được thực hiện tại đây.

    tp->tp_free(tự);
    tự = NULL;  // Trong trường hợp PyErr_WriteUnraisable() được gọi bên dưới.

    if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) {
        Py_CLEAR(tp);
    }

xong:
    // Tùy chọn, nếu một cái gì đó được gọi có thể gây ra
    // ngoại lệ.
    nếu (PyErr_Occurred()) {
        PyErr_WriteUnraiseable(self);
    }
    PyErr_SetRaisedException(exc);
}

tp_dealloc có thể được gọi từ bất kỳ luồng Python nào, không chỉ luồng đã tạo đối tượng (nếu đối tượng trở thành một phần của chu trình đếm lại, chu trình đó có thể được thu thập bởi bộ sưu tập rác trên bất kỳ luồng nào). Đây không phải là vấn đề đối với lệnh gọi API của Python, vì luồng mà tp_dealloc được gọi bằng attached thread state. Tuy nhiên, nếu đối tượng bị hủy lần lượt phá hủy các đối tượng từ một số thư viện C khác, cần cẩn thận để đảm bảo rằng việc hủy các đối tượng đó trên luồng có tên tp_dealloc sẽ không vi phạm bất kỳ giả định nào của thư viện.

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Xem thêm

Vòng đời của đối tượng để biết chi tiết về mối liên hệ giữa vị trí này với các vị trí khác.

Py_ssize_t PyTypeObject.tp_vectorcall_offset

Một phần bù tùy chọn cho hàm theo từng phiên bản triển khai việc gọi đối tượng bằng cách sử dụng vectorcall protocol, một giải pháp thay thế hiệu quả hơn cho tp_call đơn giản hơn.

Trường này chỉ được sử dụng nếu cờ Py_TPFLAGS_HAVE_VECTORCALL được đặt. Nếu vậy, đây phải là số nguyên dương chứa phần bù trong thể hiện của con trỏ vectorcallfunc.

Con trỏ vectorcallfunc có thể là NULL, trong trường hợp đó, phiên bản hoạt động như thể Py_TPFLAGS_HAVE_VECTORCALL chưa được đặt: việc gọi phiên bản sẽ quay lại tp_call.

Bất kỳ lớp nào đặt Py_TPFLAGS_HAVE_VECTORCALL cũng phải đặt tp_call và đảm bảo hành vi của nó nhất quán với hàm vectorcallfunc. Điều này có thể được thực hiện bằng cách đặt tp_call thành PyVectorcall_Call().

Thay đổi trong phiên bản 3.8: Trước phiên bản 3.8, slot này được đặt tên là tp_print. Trong Python 2.x, nó được sử dụng để in thành tệp. Trong Python 3.0 đến 3.7, nó không được sử dụng.

Thay đổi trong phiên bản 3.12: Trước phiên bản 3.12, mutable heap types không được khuyến nghị triển khai giao thức vectorcall. Khi người dùng đặt __call__ bằng mã Python, chỉ tp_call được cập nhật, điều này có thể khiến nó không nhất quán với hàm vectorcall. Kể từ phiên bản 3.12, cài đặt __call__ sẽ vô hiệu hóa tối ưu hóa vectorcall bằng cách xóa cờ Py_TPFLAGS_HAVE_VECTORCALL.

Inheritance:

Trường này luôn được kế thừa. Tuy nhiên, cờ Py_TPFLAGS_HAVE_VECTORCALL không phải lúc nào cũng được kế thừa. Nếu nó không được đặt thì lớp con sẽ không sử dụng vectorcall, ngoại trừ khi PyVectorcall_Call() được gọi rõ ràng.

getattrfunc PyTypeObject.tp_getattr

The corresponding slot ID Py_tp_getattr is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm chuỗi thuộc tính get.

Trường này không còn được dùng nữa. Khi được xác định, nó sẽ trỏ đến một hàm hoạt động giống như hàm tp_getattro nhưng lấy chuỗi C thay vì đối tượng chuỗi Python để đặt tên thuộc tính.

Inheritance:

Nhóm: tp_getattr, tp_getattro

Trường này được kế thừa bởi các kiểu con cùng với tp_getattro: một kiểu con kế thừa cả tp_getattrtp_getattro từ kiểu cơ sở của nó khi tp_getattrtp_getattro của kiểu con đều là NULL.

setattrfunc PyTypeObject.tp_setattr

The corresponding slot ID Py_tp_setattr is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm để thiết lập và xóa các thuộc tính.

Trường này không còn được dùng nữa. Khi được xác định, nó sẽ trỏ đến một hàm hoạt động giống như hàm tp_setattro nhưng lấy chuỗi C thay vì đối tượng chuỗi Python để đặt tên thuộc tính.

Inheritance:

Nhóm: tp_setattr, tp_setattro

Trường này được kế thừa bởi các kiểu con cùng với tp_setattro: một kiểu con kế thừa cả tp_setattrtp_setattro từ kiểu cơ sở của nó khi tp_setattrtp_setattro của kiểu con đều là NULL.

PyAsyncMethods *PyTypeObject.tp_as_async

Con trỏ tới một cấu trúc bổ sung chứa các trường chỉ liên quan đến các đối tượng triển khai giao thức awaitableasynchronous iterator ở cấp độ C. Xem Cấu trúc đối tượng không đồng bộ để biết chi tiết.

Added in version 3.5: Trước đây được gọi là tp_comparetp_reserved.

Inheritance:

Trường tp_as_async không được kế thừa nhưng các trường chứa trong đó được kế thừa riêng lẻ.

reprfunc PyTypeObject.tp_repr

The corresponding slot ID Py_tp_repr is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm thực hiện hàm tích hợp repr().

Chữ ký giống như đối với PyObject_Repr():

PyObject *tp_repr(PyObject *self);

Hàm phải trả về một chuỗi hoặc một đối tượng Unicode. Lý tưởng nhất là hàm này sẽ trả về một chuỗi mà khi được truyền tới eval(), trong một môi trường phù hợp, sẽ trả về một đối tượng có cùng giá trị. Nếu điều này không khả thi, nó sẽ trả về một chuỗi bắt đầu bằng '<' và kết thúc bằng '>' từ đó có thể suy ra cả loại và giá trị của đối tượng.

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Default:

Khi trường này không được đặt, một chuỗi có dạng <%s object at %p> được trả về, trong đó %s được thay thế bằng tên loại và %p bằng địa chỉ bộ nhớ của đối tượng.

PyNumberMethods *PyTypeObject.tp_as_number

Con trỏ tới một cấu trúc bổ sung chứa các trường chỉ liên quan đến các đối tượng thực hiện giao thức số. Các trường này được ghi lại trong Cấu trúc đối tượng số.

Inheritance:

Trường tp_as_number không được kế thừa nhưng các trường chứa trong đó được kế thừa riêng lẻ.

PySequenceMethods *PyTypeObject.tp_as_sequence

Con trỏ tới một cấu trúc bổ sung chứa các trường chỉ liên quan đến các đối tượng thực hiện giao thức tuần tự. Các trường này được ghi lại trong Cấu trúc đối tượng trình tự.

Inheritance:

Trường tp_as_sequence không được kế thừa nhưng các trường chứa trong đó được kế thừa riêng lẻ.

PyMappingMethods *PyTypeObject.tp_as_mapping

Con trỏ tới một cấu trúc bổ sung chứa các trường chỉ liên quan đến các đối tượng thực hiện giao thức ánh xạ. Các trường này được ghi lại trong Ánh xạ cấu trúc đối tượng.

Inheritance:

Trường tp_as_mapping không được kế thừa nhưng các trường chứa trong đó được kế thừa riêng lẻ.

hashfunc PyTypeObject.tp_hash

The corresponding slot ID Py_tp_hash is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm thực hiện hàm tích hợp hash().

Chữ ký giống như đối với PyObject_Hash():

Py_hash_t tp_hash(PyObject *);

Giá trị -1 không được trả về dưới dạng giá trị trả về thông thường; khi xảy ra lỗi trong quá trình tính toán giá trị băm, hàm sẽ đặt ngoại lệ và trả về -1.

Khi trường này không được đặt (and tp_richcompare không được đặt), nỗ lực lấy hàm băm của đối tượng sẽ tăng TypeError. Điều này cũng giống như cài đặt nó thành PyObject_HashNotImplemented().

Trường này có thể được đặt rõ ràng thành PyObject_HashNotImplemented() để chặn kế thừa phương thức băm từ kiểu cha. Điều này được hiểu là tương đương với __hash__ = None ở cấp Python, khiến isinstance(o, collections.Hashable) trả về chính xác False. Lưu ý rằng điều ngược lại cũng đúng - việc đặt __hash__ = None trên một lớp ở cấp độ Python sẽ dẫn đến vị trí tp_hash được đặt thành PyObject_HashNotImplemented().

Inheritance:

Nhóm: tp_hash, tp_richcompare

Trường này được kế thừa bởi các kiểu con cùng với tp_richcompare: một kiểu con kế thừa cả tp_richcomparetp_hash, khi tp_richcomparetp_hash của kiểu con đó đều là NULL.

Default:

PyBaseObject_Type sử dụng PyObject_GenericHash().

ternaryfunc PyTypeObject.tp_call

The corresponding slot ID Py_tp_call is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm thực hiện việc gọi đối tượng. Đây phải là NULL nếu đối tượng không thể gọi được. Chữ ký giống như đối với PyObject_Call():

PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);

Inheritance:

Trường này được kế thừa bởi các kiểu con.

reprfunc PyTypeObject.tp_str

The corresponding slot ID Py_tp_str is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm thực hiện thao tác tích hợp str(). (Lưu ý rằng str hiện là một loại và str() gọi hàm tạo cho loại đó. Hàm tạo này gọi PyObject_Str() để thực hiện công việc thực tế và PyObject_Str() sẽ gọi trình xử lý này.)

Chữ ký giống như đối với PyObject_Str():

PyObject *tp_str(PyObject *self);

Hàm phải trả về một chuỗi hoặc một đối tượng Unicode. Nó phải là một biểu diễn chuỗi "thân thiện" của đối tượng, vì đây là biểu diễn sẽ được sử dụng, cùng với những thứ khác, bởi hàm print().

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Default:

Khi trường này không được đặt, PyObject_Repr() được gọi để trả về biểu diễn chuỗi.

getattrofunc PyTypeObject.tp_getattro

The corresponding slot ID Py_tp_getattro is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm get-attribute.

Chữ ký giống như đối với PyObject_GetAttr():

PyObject *tp_getattro(PyObject *self, PyObject *attr);

Thông thường sẽ thuận tiện nếu đặt trường này thành PyObject_GenericGetAttr(), trường này thực hiện cách tìm kiếm thuộc tính đối tượng thông thường.

Inheritance:

Nhóm: tp_getattr, tp_getattro

Trường này được kế thừa bởi các kiểu con cùng với tp_getattr: một kiểu con kế thừa cả tp_getattrtp_getattro từ kiểu cơ sở của nó khi tp_getattrtp_getattro của kiểu con đều là NULL.

Default:

PyBaseObject_Type sử dụng PyObject_GenericGetAttr().

setattrofunc PyTypeObject.tp_setattro

The corresponding slot ID Py_tp_setattro is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm để thiết lập và xóa các thuộc tính.

Chữ ký giống như đối với PyObject_SetAttr():

int tp_setattro(PyObject *self, PyObject *attr, giá trị PyObject *);

Ngoài ra, cài đặt value thành NULL để xóa thuộc tính phải được hỗ trợ. Thông thường, sẽ thuận tiện hơn khi đặt trường này thành PyObject_GenericSetAttr(), cách này thực hiện cách thiết lập thuộc tính đối tượng thông thường.

Inheritance:

Nhóm: tp_setattr, tp_setattro

Trường này được kế thừa bởi các kiểu con cùng với tp_setattr: một kiểu con kế thừa cả tp_setattrtp_setattro từ kiểu cơ sở của nó khi tp_setattrtp_setattro của kiểu con đều là NULL.

Default:

PyBaseObject_Type sử dụng PyObject_GenericSetAttr().

PyBufferProcs *PyTypeObject.tp_as_buffer

Con trỏ tới một cấu trúc bổ sung chứa các trường chỉ liên quan đến các đối tượng triển khai giao diện bộ đệm. Các trường này được ghi lại trong Cấu trúc đối tượng đệm.

Inheritance:

Trường tp_as_buffer không được kế thừa nhưng các trường chứa trong đó được kế thừa riêng lẻ.

unsigned long PyTypeObject.tp_flags

Trường này là một mặt nạ bit của các cờ khác nhau. Một số cờ biểu thị ngữ nghĩa biến thể cho các tình huống nhất định; những trường khác được sử dụng để chỉ ra rằng các trường nhất định trong đối tượng loại (hoặc trong cấu trúc mở rộng được tham chiếu qua tp_as_number, tp_as_sequence, tp_as_mappingtp_as_buffer) trước đây không phải lúc nào cũng hợp lệ; nếu bit cờ đó rõ ràng thì các trường loại mà nó bảo vệ sẽ không được truy cập và thay vào đó phải được coi là có giá trị 0 hoặc NULL.

Inheritance:

Kế thừa của lĩnh vực này là phức tạp. Hầu hết các bit cờ được kế thừa riêng lẻ, tức là nếu loại cơ sở có tập hợp bit cờ thì kiểu con sẽ kế thừa bit cờ này. Các bit cờ liên quan đến cấu trúc mở rộng được kế thừa nghiêm ngặt nếu cấu trúc mở rộng được kế thừa, tức là giá trị của loại cơ sở của bit cờ được sao chép vào kiểu con cùng với một con trỏ tới cấu trúc mở rộng. Bit cờ Py_TPFLAGS_HAVE_GC được kế thừa cùng với các trường tp_traversetp_clear, tức là nếu bit cờ Py_TPFLAGS_HAVE_GC rõ ràng trong loại phụ và các trường tp_traversetp_clear trong loại phụ tồn tại và có các giá trị NULL.

Default:

PyBaseObject_Type sử dụng Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE.

Bit Masks:

Các mặt nạ bit sau đây hiện đã được xác định; những thứ này có thể được OR cùng nhau bằng cách sử dụng toán tử | để tạo thành giá trị của trường tp_flags. Macro PyType_HasFeature() nhận một loại và một giá trị cờ, tpf, đồng thời kiểm tra xem tp->tp_flags & f có khác 0 hay không.

Py_TPFLAGS_HEAPTYPE

Bit này được đặt khi chính đối tượng loại được phân bổ trên heap, ví dụ: các loại được tạo động bằng PyType_FromSpec(). Trong trường hợp này, trường ob_type của các phiên bản của nó được coi là tham chiếu đến loại và đối tượng loại được INCREF'ed khi một phiên bản mới được tạo và DECREF'ed khi một phiên bản bị hủy (điều này không áp dụng cho các phiên bản của kiểu con; chỉ loại được tham chiếu bởi ob_type của phiên bản mới nhận được INCREF'ed hoặc DECREF'ed). Các loại heap cũng nên support garbage collection vì chúng có thể tạo thành một chu trình tham chiếu với đối tượng mô-đun của riêng chúng.

Inheritance:

???

Py_TPFLAGS_BASETYPE
Một phần của ABI ổn định.

Bit này được đặt khi loại này có thể được sử dụng làm loại cơ sở của loại khác. Nếu bit này trống thì kiểu này không thể được phân kiểu phụ (tương tự như lớp "cuối cùng" trong Java).

Inheritance:

???

Py_TPFLAGS_READY

Bit này được thiết lập khi đối tượng loại đã được khởi tạo hoàn toàn bởi PyType_Ready().

Inheritance:

???

Py_TPFLAGS_READYING

Bit này được đặt trong khi PyType_Ready() đang trong quá trình khởi tạo đối tượng loại.

Inheritance:

???

Py_TPFLAGS_HAVE_GC
Một phần của ABI ổn định.

Bit này được thiết lập khi đối tượng hỗ trợ thu gom rác. Nếu bit này được đặt, bộ nhớ cho các phiên bản mới (xem tp_alloc) phải được phân bổ bằng PyObject_GC_New hoặc PyType_GenericAlloc() và được giải phóng (xem tp_free) bằng PyObject_GC_Del(). Thông tin thêm trong phần Hỗ trợ thu gom rác tuần hoàn.

Inheritance:

Nhóm: Py_TPFLAGS_HAVE_GC, tp_traverse, tp_clear

Bit cờ Py_TPFLAGS_HAVE_GC được kế thừa cùng với các trường tp_traversetp_clear, tức là nếu bit cờ Py_TPFLAGS_HAVE_GC rõ ràng trong loại phụ và các trường tp_traversetp_clear trong loại phụ tồn tại và có các giá trị NULL.

Py_TPFLAGS_DEFAULT
Một phần của ABI ổn định.

Đây là mặt nạ bit của tất cả các bit liên quan đến sự tồn tại của các trường nhất định trong đối tượng kiểu và cấu trúc mở rộng của nó. Hiện tại, nó bao gồm các bit sau: Py_TPFLAGS_HAVE_STACKLESS_EXTENSION.

Inheritance:

???

Py_TPFLAGS_METHOD_DESCRIPTOR
Một phần của ABI ổn định kể từ phiên bản 3.8.

Bit này chỉ ra rằng các đối tượng hoạt động giống như các phương thức không liên kết.

Nếu cờ này được đặt cho type(meth) thì:

  • meth.__get__(obj, cls)(*args, **kwds) (với obj chứ không phải None) phải tương đương với meth(obj, *args, **kwds).

  • meth.__get__(None, cls)(*args, **kwds) phải tương đương với meth(*args, **kwds).

Cờ này cho phép tối ưu hóa các lệnh gọi phương thức thông thường như obj.meth(): nó tránh tạo đối tượng "phương thức ràng buộc" tạm thời cho obj.meth.

Added in version 3.8.

Inheritance:

Cờ này không bao giờ được kế thừa bởi các loại không có cờ Py_TPFLAGS_IMMUTABLETYPE được đặt. Đối với các loại tiện ích mở rộng, nó được kế thừa bất cứ khi nào tp_descr_get được kế thừa.

Py_TPFLAGS_MANAGED_DICT

Bit này chỉ ra rằng các phiên bản của lớp có thuộc tính __dict__ và không gian dành cho từ điển được VM quản lý.

Nếu cờ này được đặt, Py_TPFLAGS_HAVE_GC cũng sẽ được đặt.

Hàm duyệt kiểu phải gọi PyObject_VisitManagedDict() và hàm rõ ràng của nó phải gọi PyObject_ClearManagedDict().

Added in version 3.12.

Inheritance:

Cờ này được kế thừa trừ khi trường tp_dictoffset được đặt trong siêu lớp.

Py_TPFLAGS_MANAGED_WEAKREF

Bit này chỉ ra rằng các thể hiện của lớp có thể được tham chiếu yếu.

Added in version 3.12.

Inheritance:

Cờ này được kế thừa trừ khi trường tp_weaklistoffset được đặt trong siêu lớp.

Py_TPFLAGS_ITEMS_AT_END
Một phần của ABI ổn định kể từ phiên bản 3.12.

Chỉ có thể sử dụng được với các loại có kích thước thay đổi, tức là các loại có tp_itemsize khác 0.

Cho biết rằng phần có kích thước thay đổi của một phiên bản thuộc loại này nằm ở cuối vùng bộ nhớ của phiên bản đó, ở độ lệch Py_TYPE(obj)->tp_basicsize (có thể khác nhau ở mỗi lớp con).

Khi đặt cờ này, hãy đảm bảo rằng tất cả các siêu lớp đều sử dụng bố cục bộ nhớ này hoặc không có kích thước thay đổi. Python không kiểm tra điều này.

Added in version 3.12.

Inheritance:

Cờ này được kế thừa.

Py_TPFLAGS_LONG_SUBCLASS
Py_TPFLAGS_LIST_SUBCLASS
Py_TPFLAGS_TUPLE_SUBCLASS
Py_TPFLAGS_BYTES_SUBCLASS
Py_TPFLAGS_UNICODE_SUBCLASS
Py_TPFLAGS_DICT_SUBCLASS
Py_TPFLAGS_BASE_EXC_SUBCLASS
Py_TPFLAGS_TYPE_SUBCLASS

Các hàm như PyLong_Check() sẽ gọi PyType_FastSubclass() bằng một trong các cờ này để nhanh chóng xác định xem một loại có phải là lớp con của loại tích hợp hay không; kiểm tra cụ thể như vậy nhanh hơn kiểm tra chung, như PyObject_IsInstance(). Các loại tùy chỉnh kế thừa từ các phần dựng sẵn phải được đặt tp_flags phù hợp hoặc mã tương tác với các loại đó sẽ hoạt động khác nhau tùy thuộc vào loại kiểm tra nào được sử dụng.

Py_TPFLAGS_HAVE_FINALIZE

Bit này được đặt khi có khe tp_finalize trong cấu trúc kiểu.

Added in version 3.4.

Sắp loại bỏ từ phiên bản 3.8: Cờ này không cần thiết nữa vì trình thông dịch giả định rằng khe tp_finalize luôn hiện diện trong cấu trúc kiểu.

Py_TPFLAGS_HAVE_VECTORCALL
Một phần của ABI ổn định kể từ phiên bản 3.12.

Bit này được thiết lập khi lớp triển khai vectorcall protocol. Xem tp_vectorcall_offset để biết chi tiết.

Inheritance:

Bit này được kế thừa nếu tp_call cũng được kế thừa.

Added in version 3.8: như _Py_TPFLAGS_HAVE_VECTORCALL

Thay đổi trong phiên bản 3.9.

Đã đổi tên thành tên hiện tại, không có dấu gạch dưới ở đầu. Tên tạm thời cũ là soft deprecated.

Thay đổi trong phiên bản 3.12: Cờ này hiện đã bị xóa khỏi một lớp khi phương thức __call__() của lớp đó được gán lại.

Cờ này bây giờ có thể được kế thừa bởi các lớp có thể thay đổi.

Py_TPFLAGS_IMMUTABLETYPE

Bit này được đặt cho các đối tượng loại không thể thay đổi: thuộc tính loại không thể được đặt cũng như không thể xóa.

PyType_Ready() tự động áp dụng cờ này cho static types.

Inheritance:

Cờ này không được kế thừa.

Added in version 3.10.

Py_TPFLAGS_DISALLOW_INSTANTIATION

Không cho phép tạo các phiên bản của loại: đặt tp_new thành NULL và không tạo khóa __new__ trong từ điển loại.

Cờ phải được đặt trước khi tạo loại, không được đặt sau. Ví dụ: nó phải được đặt trước khi PyType_Ready() được gọi trên loại.

Cờ được đặt tự động trên static types nếu tp_base là NULL hoặc &PyBaseObject_Typetp_new là NULL.

Inheritance:

Cờ này không được kế thừa. Tuy nhiên, các lớp con sẽ không thể thực hiện được trừ khi chúng cung cấp một tp_new không phải NULL (điều này chỉ có thể thực hiện được thông qua C API).

Ghi chú

Để không cho phép khởi tạo trực tiếp một lớp nhưng cho phép khởi tạo các lớp con của nó (ví dụ: đối với abstract base class), không sử dụng cờ này. Thay vào đó, hãy tạo tp_new chỉ thành công cho các lớp con.

Added in version 3.10.

Py_TPFLAGS_MAPPING

Bit này chỉ ra rằng các thể hiện của lớp có thể khớp với các mẫu ánh xạ khi được sử dụng làm chủ đề của khối match. Nó được tự động đặt khi đăng ký hoặc phân lớp con collections.abc.Mapping và được hủy đặt khi đăng ký collections.abc.Sequence.

Ghi chú

Py_TPFLAGS_MAPPINGPy_TPFLAGS_SEQUENCE loại trừ lẫn nhau; đó là một lỗi khi bật cả hai cờ cùng một lúc.

Inheritance:

Cờ này được kế thừa bởi các loại chưa được đặt Py_TPFLAGS_SEQUENCE.

Xem thêm

PEP 634 -- Khớp mẫu cấu trúc: Đặc điểm kỹ thuật

Added in version 3.10.

Py_TPFLAGS_SEQUENCE

Bit này chỉ ra rằng các phiên bản của lớp có thể khớp với các mẫu trình tự khi được sử dụng làm chủ đề của khối match. Nó được tự động đặt khi đăng ký hoặc phân lớp collections.abc.Sequence và được hủy đặt khi đăng ký collections.abc.Mapping.

Ghi chú

Py_TPFLAGS_MAPPINGPy_TPFLAGS_SEQUENCE loại trừ lẫn nhau; đó là một lỗi khi bật cả hai cờ cùng một lúc.

Inheritance:

Cờ này được kế thừa bởi các loại chưa được đặt Py_TPFLAGS_MAPPING.

Xem thêm

PEP 634 -- Khớp mẫu cấu trúc: Đặc điểm kỹ thuật

Added in version 3.10.

Py_TPFLAGS_VALID_VERSION_TAG

Nội bộ. Không đặt hoặc hủy đặt cờ này. Để chỉ ra rằng một lớp đã thay đổi, hãy gọi PyType_Modified()

Cảnh báo

Cờ này hiện diện trong các tệp tiêu đề nhưng không được sử dụng. Nó sẽ bị xóa trong phiên bản CPython trong tương lai

Py_TPFLAGS_HAVE_VERSION_TAG

Đây là macro soft deprecated không làm gì cả. Về mặt lịch sử, điều này cho thấy trường tp_version_tag đã có sẵn và được khởi tạo.

Py_TPFLAGS_INLINE_VALUES

Bit này chỉ ra rằng các thể hiện thuộc loại này sẽ có một mảng "giá trị nội tuyến" (chứa các thuộc tính của đối tượng) được đặt ngay sau phần cuối của đối tượng.

Điều này yêu cầu Py_TPFLAGS_HAVE_GC được thiết lập.

Inheritance:

Cờ này không được kế thừa.

Added in version 3.13.

Py_TPFLAGS_IS_ABSTRACT

Bit này chỉ ra rằng đây là một loại trừu tượng và do đó không thể khởi tạo được.

Inheritance:

Cờ này không được kế thừa.

Xem thêm

abc

Py_TPFLAGS_HAVE_STACKLESS_EXTENSION

Nội bộ. Không đặt hoặc hủy đặt cờ này. Trong lịch sử, đây là cờ dành riêng để sử dụng trong Stackless Python.

Cảnh báo

Cờ này hiện diện trong các tệp tiêu đề nhưng không được sử dụng. Điều này có thể bị xóa trong phiên bản CPython trong tương lai.

const char *PyTypeObject.tp_doc

The corresponding slot ID Py_tp_doc is part of the ABI ổn định.

Một con trỏ tùy chọn tới chuỗi C kết thúc bằng NUL cung cấp chuỗi tài liệu cho đối tượng loại này. Điều này được hiển thị dưới dạng thuộc tính __doc__ trên loại và các phiên bản của loại.

Inheritance:

Trường này là not được kế thừa bởi các kiểu con.

traverseproc PyTypeObject.tp_traverse

The corresponding slot ID Py_tp_traverse is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm truyền tải dành cho trình thu gom rác. Điều này chỉ được sử dụng nếu bit cờ Py_TPFLAGS_HAVE_GC được đặt. Chữ ký là:

int tp_traverse(PyObject *self, visitproc visit, void *arg);

Bạn có thể tìm thêm thông tin về sơ đồ thu gom rác của Python trong phần Hỗ trợ thu gom rác tuần hoàn.

Con trỏ tp_traverse được trình thu gom rác sử dụng để phát hiện các chu kỳ tham chiếu. Cách triển khai điển hình của hàm tp_traverse chỉ cần gọi Py_VISIT() trên mỗi thành viên của phiên bản là các đối tượng Python mà phiên bản đó sở hữu. Ví dụ: đây là hàm local_traverse() từ mô-đun mở rộng _thread

int tĩnh
local_traverse(PyObject *op, visitproc visit, void *arg)
{
    localobject *self = (localobject *) op;
    Py_VISIT(tự->args);
    Py_VISIT(tự->kw);
    Py_VISIT(tự->dict);
    trả về 0;
}

Lưu ý rằng Py_VISIT() chỉ được gọi đối với những thành viên có thể tham gia vào chu trình tham chiếu. Mặc dù cũng có thành viên self->key nhưng nó chỉ có thể là NULL hoặc chuỗi Python và do đó không thể là một phần của chu trình tham chiếu.

Mặt khác, ngay cả khi bạn biết một thành viên không bao giờ có thể là một phần của một chu trình, thì với tư cách là một công cụ hỗ trợ gỡ lỗi, bạn vẫn có thể muốn truy cập nó chỉ để chức năng get_referents() của mô-đun gc sẽ bao gồm nó.

Các loại heap (Py_TPFLAGS_HEAPTYPE) phải truy cập loại của chúng bằng:

Py_VISIT(Py_TYPE(tự));

Nó chỉ cần thiết kể từ Python 3.9. Để hỗ trợ Python 3.8 trở lên, dòng này phải có điều kiện:

#if PY_VERSION_HEX >= 0x03090000
    Py_VISIT(Py_TYPE(tự));
#endif

Nếu bit Py_TPFLAGS_MANAGED_DICT được đặt trong trường tp_flags, hàm duyệt phải gọi PyObject_VisitManagedDict() như thế này:

PyObject_VisitQuản lýDict((PyObject*)self, truy cập, arg);

Cảnh báo

Khi triển khai tp_traverse, chỉ các thành viên có phiên bản owns (có strong references đối với họ) mới phải được truy cập. Ví dụ: nếu một đối tượng hỗ trợ các tham chiếu yếu thông qua khe tp_weaklist, con trỏ hỗ trợ danh sách được liên kết (cái mà tp_weaklist trỏ đến) phải được truy cập not vì phiên bản không sở hữu trực tiếp các tham chiếu yếu cho chính nó (danh sách tham chiếu yếu có ở đó để hỗ trợ bộ máy tham chiếu yếu, nhưng phiên bản không có tham chiếu mạnh đến các phần tử bên trong nó, vì chúng được phép xóa ngay cả khi phiên bản vẫn còn hoạt động).

Cảnh báo

Chức năng truyền tải không được có bất kỳ tác dụng phụ nào. Nó không được sửa đổi số lượng tham chiếu của bất kỳ đối tượng Python nào cũng như không được tạo hoặc hủy bất kỳ đối tượng Python nào.

Lưu ý rằng Py_VISIT() yêu cầu các tham số visitarg cho local_traverse() để có các tên cụ thể này; đừng đặt tên cho họ bất cứ điều gì.

Các phiên bản của heap-allocated types giữ một tham chiếu đến loại của chúng. Do đó, hàm truyền tải của chúng phải truy cập Py_TYPE(self) hoặc ủy thác trách nhiệm này bằng cách gọi tp_traverse thuộc loại được phân bổ heap khác (chẳng hạn như siêu lớp được phân bổ heap). Nếu không, đối tượng loại có thể không được thu gom rác.

Ghi chú

Hàm tp_traverse có thể được gọi từ bất kỳ luồng nào.

Thay đổi trong phiên bản 3.9: Các loại được phân bổ heap dự kiến ​​​​sẽ truy cập Py_TYPE(self) trong tp_traverse. Trong các phiên bản Python trước đó, do bug 40217, việc làm này có thể dẫn đến sự cố trong các lớp con.

Inheritance:

Nhóm: Py_TPFLAGS_HAVE_GC, tp_traverse, tp_clear

Trường này được kế thừa bởi các kiểu con cùng với tp_clear và bit cờ Py_TPFLAGS_HAVE_GC: bit cờ, tp_traversetp_clear đều được kế thừa từ kiểu cơ sở nếu chúng đều bằng 0 trong kiểu con.

inquiry PyTypeObject.tp_clear

The corresponding slot ID Py_tp_clear is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm rõ ràng. Chữ ký là:

int tp_clear(PyObject *);

Mục đích của chức năng này là phá vỡ các chu kỳ tham chiếu đang gây ra cyclic isolate để các đối tượng có thể bị phá hủy một cách an toàn. Đối tượng bị xóa là đối tượng bị phá hủy một phần; đối tượng không bắt buộc phải đáp ứng các bất biến thiết kế được giữ trong quá trình sử dụng bình thường.

tp_clear không cần xóa các tham chiếu đến các đối tượng không thể tham gia vào chu trình tham chiếu, chẳng hạn như chuỗi Python hoặc số nguyên Python. Tuy nhiên, có thể thuận tiện khi xóa tất cả các tham chiếu và viết hàm tp_dealloc của loại để gọi tp_clear nhằm tránh trùng lặp mã. (Lưu ý rằng tp_clear có thể đã được gọi. Thích gọi các hàm bình thường như Py_CLEAR().)

Bất kỳ việc dọn dẹp không tầm thường nào cũng phải được thực hiện trong tp_finalize thay vì tp_clear.

Ghi chú

Nếu tp_clear không phá vỡ được chu trình tham chiếu thì các đối tượng trong cyclic isolate có thể vẫn không thể thu thập được ("rò rỉ"). Xem gc.garbage.

Ghi chú

Người giới thiệu (trực tiếp và gián tiếp) có thể đã bị xóa; chúng không được đảm bảo ở trạng thái nhất quán.

Ghi chú

Hàm tp_clear có thể được gọi từ bất kỳ luồng nào.

Ghi chú

Một đối tượng không được đảm bảo sẽ tự động bị xóa trước khi hàm hủy của nó (tp_dealloc) được gọi.

Hàm này khác với hàm hủy (tp_dealloc) ở những điểm sau:

  • Mục đích của việc xóa một đối tượng là xóa các tham chiếu đến các đối tượng khác có thể tham gia vào chu trình tham chiếu. Mặt khác, mục đích của hàm hủy là một siêu tập hợp: nó phải giải phóng tài nguyên all mà nó sở hữu, bao gồm các tham chiếu đến các đối tượng không thể tham gia vào chu trình tham chiếu (ví dụ: số nguyên) cũng như bộ nhớ riêng của đối tượng (bằng cách gọi tp_free).

  • Khi tp_clear được gọi, các đối tượng khác vẫn có thể giữ các tham chiếu đến đối tượng đang bị xóa. Vì điều này, tp_clear không được giải phóng bộ nhớ riêng của đối tượng (tp_free). Mặt khác, hàm hủy chỉ được gọi khi không có tham chiếu (mạnh) nào tồn tại và do đó, phải phá hủy chính đối tượng đó một cách an toàn bằng cách giải phóng nó.

  • tp_clear có thể không bao giờ được gọi tự động. Mặt khác, hàm hủy của một đối tượng sẽ tự động được gọi một thời gian sau khi đối tượng không thể truy cập được (tức là không có tham chiếu đến đối tượng hoặc đối tượng là thành viên của cyclic isolate).

Không có đảm bảo nào được đưa ra về thời điểm, nếu hoặc tần suất Python tự động xóa một đối tượng, ngoại trừ:

  • Python sẽ không tự động xóa một đối tượng nếu nó có thể truy cập được, tức là có một tham chiếu đến nó và nó không phải là thành viên của cyclic isolate.

  • Python sẽ không tự động xóa một đối tượng nếu nó chưa được tự động hoàn thiện (xem tp_finalize). (Nếu bộ hoàn thiện phục hồi đối tượng, đối tượng có thể được tự động hoàn thiện lại hoặc không trước khi bị xóa.)

  • Nếu một đối tượng là thành viên của cyclic isolate, Python sẽ không tự động xóa nó nếu bất kỳ thành viên nào của vòng cách ly tuần hoàn chưa được tự động hoàn thiện (tp_finalize).

  • Python sẽ không hủy một đối tượng cho đến khi bất kỳ lệnh gọi tự động nào tới hàm tp_clear của nó quay trở lại. Điều này đảm bảo rằng hành động phá vỡ chu trình tham chiếu không làm mất hiệu lực con trỏ self trong khi tp_clear vẫn đang thực thi.

  • Python sẽ không tự động gọi tp_clear nhiều lần cùng một lúc.

CPython hiện chỉ tự động xóa các đối tượng khi cần thiết để phá vỡ chu kỳ tham chiếu trong cyclic isolate, nhưng các phiên bản trong tương lai có thể xóa các đối tượng thường xuyên trước khi chúng bị phá hủy.

Tổng hợp lại, tất cả các chức năng tp_clear trong hệ thống phải kết hợp lại để phá vỡ mọi chu kỳ tham chiếu. Điều này thật tinh tế và nếu có nghi ngờ gì, hãy cung cấp chức năng tp_clear. Ví dụ: loại bộ dữ liệu không triển khai hàm tp_clear, vì có thể chứng minh rằng không có chu trình tham chiếu nào có thể bao gồm toàn bộ bộ dữ liệu. Do đó, các hàm tp_clear thuộc các loại khác chịu trách nhiệm phá vỡ bất kỳ chu trình nào chứa một bộ dữ liệu. Điều này không rõ ràng ngay lập tức và hiếm khi có lý do chính đáng để tránh triển khai tp_clear.

Việc triển khai tp_clear sẽ loại bỏ các tham chiếu của phiên bản tới các tham chiếu của các thành viên có thể là đối tượng Python và đặt con trỏ của nó tới các thành viên đó thành NULL, như trong ví dụ sau:

int tĩnh
local_clear(PyObject *op)
{
    localobject *self = (localobject *) op;
    Py_CLEAR(tự->khóa);
    Py_CLEAR(self->args);
    Py_CLEAR(tự->kw);
    Py_CLEAR(tự->dict);
    trả về 0;
}

Nên sử dụng macro Py_CLEAR() vì việc xóa tham chiếu rất tinh vi: tham chiếu đến đối tượng được chứa không được giải phóng (thông qua Py_DECREF()) cho đến khi con trỏ tới đối tượng được chứa được đặt thành NULL. Điều này là do việc giải phóng tham chiếu có thể khiến đối tượng được chứa trở thành thùng rác, kích hoạt một chuỗi hoạt động khôi phục có thể bao gồm việc gọi mã Python tùy ý (do các lệnh hoàn thiện hoặc lệnh gọi lại yếu, được liên kết với đối tượng được chứa). Nếu mã đó có thể tham chiếu lại self thì điều quan trọng là con trỏ tới đối tượng được chứa phải là NULL tại thời điểm đó, để self biết đối tượng được chứa không thể sử dụng được nữa. Macro Py_CLEAR() thực hiện các thao tác theo thứ tự an toàn.

Nếu bit Py_TPFLAGS_MANAGED_DICT được đặt trong trường tp_flags, hàm xóa phải gọi PyObject_ClearManagedDict() như thế này

PyObject_ClearQuản lýDict((PyObject*)self);

Bạn có thể tìm thêm thông tin về sơ đồ thu gom rác của Python trong phần Hỗ trợ thu gom rác tuần hoàn.

Inheritance:

Nhóm: Py_TPFLAGS_HAVE_GC, tp_traverse, tp_clear

Trường này được kế thừa bởi các kiểu con cùng với tp_traverse và bit cờ Py_TPFLAGS_HAVE_GC: bit cờ, tp_traversetp_clear đều được kế thừa từ kiểu cơ sở nếu chúng đều bằng 0 trong kiểu con.

Xem thêm

Vòng đời của đối tượng để biết chi tiết về mối liên hệ giữa vị trí này với các vị trí khác.

richcmpfunc PyTypeObject.tp_richcompare

The corresponding slot ID Py_tp_richcompare is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm so sánh phong phú, có chữ ký là:

PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);

Tham số đầu tiên được đảm bảo là một phiên bản của loại được xác định bởi PyTypeObject.

Hàm sẽ trả về kết quả so sánh (thường là Py_True hoặc Py_False). Nếu so sánh không được xác định, nó phải trả về Py_NotImplemented, nếu xảy ra lỗi khác, nó phải trả về NULL và đặt điều kiện ngoại lệ.

Các hằng số sau đây được xác định để sử dụng làm đối số thứ ba cho tp_richcompare và cho PyObject_RichCompare():

Không thay đổi

So sánh

Py_LT

<

Py_LE

<=

Py_EQ

==

Py_NE

!=

Py_GT

>

Py_GE

>=

Macro sau được xác định để dễ dàng viết các hàm so sánh phong phú:

Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)

Trả về Py_True hoặc Py_False từ hàm, tùy thuộc vào kết quả so sánh. VAL_A và VAL_B phải được toán tử so sánh C sắp xếp theo thứ tự (ví dụ: chúng có thể là C int hoặc float). Đối số thứ ba chỉ định thao tác được yêu cầu, như đối với PyObject_RichCompare().

Giá trị trả về là strong reference mới.

Nếu có lỗi, hãy đặt ngoại lệ và trả về NULL từ hàm.

Added in version 3.7.

Inheritance:

Nhóm: tp_hash, tp_richcompare

Trường này được kế thừa bởi các kiểu con cùng với tp_hash: một kiểu con kế thừa tp_richcomparetp_hash khi tp_richcomparetp_hash của kiểu con đó đều là NULL.

Default:

PyBaseObject_Type cung cấp triển khai tp_richcompare, có thể được kế thừa. Tuy nhiên, nếu chỉ xác định tp_hash thì ngay cả hàm kế thừa cũng không được sử dụng và các phiên bản của loại sẽ không thể tham gia vào bất kỳ so sánh nào.

Py_ssize_t PyTypeObject.tp_weaklistoffset

Mặc dù trường này vẫn được hỗ trợ nhưng thay vào đó, bạn nên sử dụng Py_TPFLAGS_MANAGED_WEAKREF nếu có thể.

Nếu các phiên bản thuộc loại này có khả năng tham chiếu yếu thì trường này lớn hơn 0 và chứa phần bù trong cấu trúc phiên bản của phần đầu danh sách tham chiếu yếu (bỏ qua tiêu đề GC, nếu có); phần bù này được sử dụng bởi các hàm PyObject_ClearWeakRefs()PyWeakref_*. Cấu trúc phiên bản cần bao gồm trường loại PyObject* được khởi tạo thành NULL.

Đừng nhầm lẫn trường này với tp_weaklist; đó là đầu danh sách dành cho các tham chiếu yếu đến chính đối tượng kiểu đó.

Sẽ có lỗi khi đặt cả bit Py_TPFLAGS_MANAGED_WEAKREFtp_weaklistoffset.

Inheritance:

Trường này được kế thừa bởi các kiểu con nhưng hãy xem các quy tắc được liệt kê bên dưới. Một kiểu con có thể ghi đè phần bù này; điều này có nghĩa là kiểu con sử dụng đầu danh sách tham chiếu yếu khác với kiểu cơ sở. Vì đầu danh sách luôn được tìm thấy qua tp_weaklistoffset nên đây không phải là vấn đề.

Default:

Nếu bit Py_TPFLAGS_MANAGED_WEAKREF được đặt trong trường tp_flags thì tp_weaklistoffset sẽ được đặt thành giá trị âm, để biểu thị rằng việc sử dụng trường này là không an toàn.

getiterfunc PyTypeObject.tp_iter

The corresponding slot ID Py_tp_iter is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm trả về iterator cho đối tượng. Sự hiện diện của nó thường báo hiệu rằng các phiên bản thuộc loại này là iterable (mặc dù các chuỗi có thể lặp lại được nếu không có chức năng này).

Hàm này có cùng chữ ký với PyObject_GetIter():

PyObject *tp_iter(PyObject *self);

Inheritance:

Trường này được kế thừa bởi các kiểu con.

iternextfunc PyTypeObject.tp_iternext

The corresponding slot ID Py_tp_iternext is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm trả về mục tiếp theo trong iterator. Chữ ký là:

PyObject *tp_iternext(PyObject *self);

Khi trình vòng lặp dùng hết, nó phải trả về NULL; ngoại lệ StopIteration có thể được đặt hoặc không. Khi xảy ra lỗi khác, nó cũng phải trả về NULL. Sự hiện diện của nó báo hiệu rằng các thể hiện của loại này là các trình vòng lặp.

Các kiểu iterator cũng phải xác định hàm tp_iter và hàm đó sẽ trả về chính phiên bản iterator (không phải một phiên bản iterator mới).

Hàm này có chữ ký giống như PyIter_Next().

Inheritance:

Trường này được kế thừa bởi các kiểu con.

struct PyMethodDef *PyTypeObject.tp_methods

The corresponding slot ID Py_tp_methods is part of the ABI ổn định.

Một con trỏ tùy chọn tới một mảng cấu trúc PyMethodDef kết thúc bằng NULL tĩnh, khai báo các phương thức thông thường thuộc loại này.

Đối với mỗi mục trong mảng, một mục được thêm vào từ điển của loại (xem tp_dict bên dưới) có chứa bộ mô tả phương thức.

Inheritance:

Trường này không được kế thừa bởi các kiểu con (các phương thức được kế thừa thông qua một cơ chế khác).

struct PyMemberDef *PyTypeObject.tp_members

The corresponding slot ID Py_tp_members is part of the ABI ổn định.

Một con trỏ tùy chọn tới một mảng cấu trúc PyMemberDef được kết thúc bằng NULL tĩnh, khai báo các thành viên dữ liệu thông thường (trường hoặc vị trí) của các phiên bản thuộc loại này.

Đối với mỗi mục trong mảng, một mục được thêm vào từ điển của loại (xem tp_dict bên dưới) có chứa bộ mô tả thành viên.

Inheritance:

Trường này không được kế thừa bởi các kiểu con (các thành viên được kế thừa thông qua một cơ chế khác).

struct PyGetSetDef *PyTypeObject.tp_getset

The corresponding slot ID Py_tp_getset is part of the ABI ổn định.

Một con trỏ tùy chọn tới một mảng cấu trúc PyGetSetDef được kết thúc bằng NULL tĩnh, khai báo các thuộc tính được tính toán của các phiên bản thuộc loại này.

Đối với mỗi mục trong mảng, một mục được thêm vào từ điển của loại (xem tp_dict bên dưới) có chứa bộ mô tả getset.

Inheritance:

Trường này không được kế thừa bởi các kiểu con (các thuộc tính được tính toán được kế thừa thông qua một cơ chế khác).

PyTypeObject *PyTypeObject.tp_base

The corresponding slot ID Py_tp_base is part of the ABI ổn định.

Một con trỏ tùy chọn tới một kiểu cơ sở mà từ đó các thuộc tính kiểu được kế thừa. Ở cấp độ này, chỉ hỗ trợ kế thừa duy nhất; đa kế thừa yêu cầu tạo động một đối tượng kiểu bằng cách gọi siêu kiểu.

Ghi chú

Việc khởi tạo vị trí phải tuân theo các quy tắc khởi tạo toàn cầu. C99 yêu cầu bộ khởi tạo phải là "hằng số địa chỉ". Các bộ chỉ định hàm như PyType_GenericNew(), với sự chuyển đổi ngầm định thành một con trỏ, là các hằng số địa chỉ C99 hợp lệ.

Tuy nhiên, toán tử '&' đơn phân áp dụng cho biến không tĩnh như PyBaseObject_Type không bắt buộc phải tạo ra hằng số địa chỉ. Trình biên dịch có thể hỗ trợ điều này (gcc có), MSVC thì không. Cả hai trình biên dịch đều tuân thủ tiêu chuẩn nghiêm ngặt trong hành vi cụ thể này.

Do đó, tp_base phải được đặt trong hàm init của mô-đun mở rộng.

Inheritance:

Trường này không được kế thừa bởi các kiểu con (rõ ràng).

Default:

Trường này mặc định là &PyBaseObject_Type (mà các lập trình viên Python gọi là loại object).

PyObject *PyTypeObject.tp_dict

Từ điển của loại được lưu trữ ở đây bởi PyType_Ready().

Trường này thường phải được khởi tạo thành NULL trước khi gọi PyType_Ready; nó cũng có thể được khởi tạo vào một từ điển chứa các thuộc tính ban đầu cho kiểu đó. Khi PyType_Ready() đã khởi tạo loại, các thuộc tính bổ sung cho loại đó chỉ có thể được thêm vào từ điển này nếu chúng không tương ứng với các hoạt động quá tải (như __add__()). Sau khi quá trình khởi tạo loại kết thúc, trường này sẽ được coi là chỉ đọc.

Một số loại có thể không lưu trữ từ điển của chúng trong khe này. Sử dụng PyType_GetDict() để truy xuất từ ​​điển cho một loại tùy ý.

Thay đổi trong phiên bản 3.12: Chi tiết bên trong: Đối với các kiểu dựng sẵn tĩnh, đây luôn là NULL. Thay vào đó, lệnh cho các loại như vậy được lưu trữ trên PyInterpreterState. Sử dụng PyType_GetDict() để lấy lệnh cho một loại tùy ý.

Inheritance:

Trường này không được kế thừa bởi các kiểu con (mặc dù các thuộc tính được xác định ở đây được kế thừa thông qua một cơ chế khác).

Default:

Nếu trường này là NULL, PyType_Ready() sẽ gán một từ điển mới cho nó.

Cảnh báo

Sẽ không an toàn khi sử dụng PyDict_SetItem() trên hoặc sửa đổi tp_dict bằng từ điển C-API.

descrgetfunc PyTypeObject.tp_descr_get

The corresponding slot ID Py_tp_descr_get is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm "mô tả get".

Chữ ký hàm là:

PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);

Inheritance:

Trường này được kế thừa bởi các kiểu con.

descrsetfunc PyTypeObject.tp_descr_set

The corresponding slot ID Py_tp_descr_set is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm để thiết lập và xóa giá trị của bộ mô tả.

Chữ ký hàm là:

int tp_descr_set(PyObject *self, PyObject *obj, PyObject *giá trị);

Đối số value được đặt thành NULL để xóa giá trị.

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Py_ssize_t PyTypeObject.tp_dictoffset

Mặc dù trường này vẫn được hỗ trợ nhưng thay vào đó, bạn nên sử dụng Py_TPFLAGS_MANAGED_DICT nếu có thể.

Nếu các thể hiện của loại này có một từ điển chứa các biến thể hiện, thì trường này khác 0 và chứa phần bù trong các thể hiện của loại từ điển biến thể hiện; phần bù này được sử dụng bởi PyObject_GenericGetAttr().

Đừng nhầm lẫn trường này với tp_dict; đó là từ điển cho các thuộc tính của chính đối tượng kiểu đó.

Giá trị chỉ định độ lệch của từ điển tính từ đầu cấu trúc cá thể.

Zz000zz nên được coi là chỉ ghi. Để đưa con trỏ tới từ điển, hãy gọi PyObject_GenericGetDict(). Việc gọi PyObject_GenericGetDict() có thể cần phân bổ bộ nhớ cho từ điển, do đó, việc gọi PyObject_GetAttr() có thể hiệu quả hơn khi truy cập một thuộc tính trên đối tượng.

Sẽ có lỗi khi đặt cả bit Py_TPFLAGS_MANAGED_DICTtp_dictoffset.

Inheritance:

Trường này được kế thừa bởi các kiểu con. Một kiểu con không được ghi đè phần bù này; làm như vậy có thể không an toàn nếu mã C cố gắng truy cập từ điển ở phần bù trước đó. Để hỗ trợ kế thừa đúng cách, hãy sử dụng Py_TPFLAGS_MANAGED_DICT.

Default:

Khe này không có mặc định. Đối với static types, nếu trường là NULL thì không có __dict__ nào được tạo cho các phiên bản.

Nếu bit Py_TPFLAGS_MANAGED_DICT được đặt trong trường tp_flags thì tp_dictoffset sẽ được đặt thành -1, để biểu thị rằng việc sử dụng trường này là không an toàn.

initproc PyTypeObject.tp_init

The corresponding slot ID Py_tp_init is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm khởi tạo cá thể.

Hàm này tương ứng với phương thức __init__() của các lớp. Giống như __init__(), có thể tạo một phiên bản mà không cần gọi __init__() và có thể khởi tạo lại một phiên bản bằng cách gọi lại phương thức __init__() của nó.

Chữ ký hàm là:

int tp_init(PyObject *self, PyObject *args, PyObject *kwds);

Đối số self là thể hiện được khởi tạo; các đối số argskwds đại diện cho các đối số từ khóa và vị trí của lệnh gọi tới __init__().

Hàm tp_init, nếu không phải là NULL, được gọi khi một phiên bản được tạo bình thường bằng cách gọi kiểu của nó, sau khi hàm tp_new của kiểu đó trả về một phiên bản của kiểu đó. Nếu hàm tp_new trả về một phiên bản của một số loại khác không phải là kiểu con của loại ban đầu thì không có hàm tp_init nào được gọi; nếu tp_new trả về một thể hiện của một kiểu con của kiểu ban đầu thì tp_init của kiểu con đó sẽ được gọi.

Trả về 0 nếu thành công, -1 và đặt ngoại lệ nếu có lỗi.

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Default:

Đối với static types trường này không có giá trị mặc định.

allocfunc PyTypeObject.tp_alloc

The corresponding slot ID Py_tp_alloc is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm phân bổ cá thể.

Chữ ký hàm là:

PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);

Inheritance:

Các kiểu con tĩnh kế thừa vị trí này, sẽ là PyType_GenericAlloc() nếu được kế thừa từ object.

Heap subtypes không kế thừa vị trí này.

Default:

Đối với các kiểu con heap, trường này luôn được đặt thành PyType_GenericAlloc().

Đối với các kiểu con tĩnh, vị trí này được kế thừa (xem ở trên).

newfunc PyTypeObject.tp_new

The corresponding slot ID Py_tp_new is part of the ABI ổn định.

Một con trỏ tùy chọn tới hàm tạo cá thể.

Chữ ký hàm là:

PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);

Đối số subtype là loại đối tượng được tạo; các đối số argskwds đại diện cho các đối số từ khóa và vị trí của lệnh gọi đến loại. Lưu ý rằng subtype không nhất thiết phải bằng loại có hàm tp_new được gọi; nó có thể là một kiểu con của loại đó (nhưng không phải là loại không liên quan).

Hàm tp_new sẽ gọi subtype->tp_alloc(subtype, nitems) để phân bổ không gian cho đối tượng, sau đó chỉ thực hiện khởi tạo thêm nếu thực sự cần thiết. Việc khởi tạo có thể được bỏ qua hoặc lặp lại một cách an toàn nên được đặt trong trình xử lý tp_init. Một nguyên tắc nhỏ là đối với các loại không thể thay đổi, tất cả quá trình khởi tạo phải diễn ra trong tp_new, trong khi đối với các loại có thể thay đổi, hầu hết quá trình khởi tạo phải được hoãn lại thành tp_init.

Đặt cờ Py_TPFLAGS_DISALLOW_INSTANTIATION để không cho phép tạo các phiên bản thuộc loại này trong Python.

Inheritance:

Trường này được kế thừa bởi các kiểu con, ngoại trừ trường này không được kế thừa bởi static typestp_baseNULL hoặc &PyBaseObject_Type.

Default:

Đối với static types trường này không có giá trị mặc định. Điều này có nghĩa là nếu vị trí được xác định là NULL thì loại này không thể được gọi để tạo phiên bản mới; có lẽ có một số cách khác để tạo phiên bản, như chức năng của nhà máy.

freefunc PyTypeObject.tp_free

The corresponding slot ID Py_tp_free is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm phân bổ cá thể. Chữ ký của nó là:

void tp_free(void *self);

Chức năng này phải giải phóng bộ nhớ được phân bổ bởi tp_alloc.

Inheritance:

Các kiểu con tĩnh kế thừa vị trí này, sẽ là PyObject_Free() nếu được kế thừa từ object. Ngoại lệ: Nếu loại hỗ trợ thu thập rác (tức là cờ Py_TPFLAGS_HAVE_GC được đặt trong tp_flags) và nó sẽ kế thừa PyObject_Free() thì vị trí này không được kế thừa mà thay vào đó được mặc định là PyObject_GC_Del().

Heap subtypes không kế thừa vị trí này.

Default:

Đối với heap subtypes, vị trí này mặc định là bộ phân bổ phù hợp để khớp với PyType_GenericAlloc() và giá trị của cờ Py_TPFLAGS_HAVE_GC.

Đối với các kiểu con tĩnh, vị trí này được kế thừa (xem ở trên).

inquiry PyTypeObject.tp_is_gc

The corresponding slot ID Py_tp_is_gc is part of the ABI ổn định.

Một con trỏ tùy chọn tới một hàm được gọi bởi trình thu gom rác.

Trình thu gom rác cần biết liệu một đối tượng cụ thể có thể được thu thập hay không. Thông thường, chỉ cần xem trường tp_flags của loại đối tượng và kiểm tra bit cờ Py_TPFLAGS_HAVE_GC là đủ. Nhưng một số loại có sự kết hợp giữa các phiên bản được phân bổ tĩnh và động và các phiên bản được phân bổ tĩnh không thể thu thập được. Những loại như vậy nên xác định chức năng này; nó sẽ trả về 1 cho phiên bản có thể sưu tập và 0 cho phiên bản không thể sưu tập. Chữ ký là:

int tp_is_gc(PyObject *self);

(Ví dụ duy nhất về điều này là chính các loại. Siêu dữ liệu, PyType_Type, xác định hàm này để phân biệt giữa tĩnh và dynamically allocated types.)

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Default:

Khe này không có mặc định. Nếu trường này là NULL thì Py_TPFLAGS_HAVE_GC được sử dụng làm chức năng tương đương.

PyObject *PyTypeObject.tp_bases

The corresponding slot ID Py_tp_bases is part of the ABI ổn định.

Tuple của các loại cơ sở.

Trường này phải được đặt thành NULL và được coi là chỉ đọc. Python sẽ điền nó khi loại là initialized.

Đối với các lớp được tạo động, Py_tp_bases slot có thể được sử dụng thay cho đối số bases của PyType_FromSpecWithBases(). Hình thức đối số được ưa thích.

Cảnh báo

Đa kế thừa không hoạt động tốt đối với các kiểu được xác định tĩnh. Nếu bạn đặt tp_bases thành một bộ dữ liệu, Python sẽ không phát sinh lỗi nhưng một số vị trí sẽ chỉ được kế thừa từ cơ sở đầu tiên.

Inheritance:

Trường này không được kế thừa.

PyObject *PyTypeObject.tp_mro

Bộ chứa tập hợp các loại cơ sở mở rộng, bắt đầu bằng chính loại đó và kết thúc bằng object, theo Thứ tự phân giải phương thức.

Trường này phải được đặt thành NULL và được coi là chỉ đọc. Python sẽ điền nó khi loại là initialized.

Inheritance:

Trường này không được kế thừa; nó được tính toán mới bởi PyType_Ready().

PyObject *PyTypeObject.tp_cache

Chưa sử dụng. Chỉ sử dụng nội bộ.

Inheritance:

Trường này không được kế thừa.

void *PyTypeObject.tp_subclasses

Một tập hợp các lớp con. Chỉ sử dụng nội bộ. Có thể là một con trỏ không hợp lệ.

Để có danh sách các lớp con, hãy gọi phương thức Python __subclasses__().

Thay đổi trong phiên bản 3.12: Đối với một số loại, trường này không chứa PyObject* hợp lệ. Loại đã được đổi thành void* để biểu thị điều này.

Inheritance:

Trường này không được kế thừa.

PyObject *PyTypeObject.tp_weaklist

Đầu danh sách tham chiếu yếu, dành cho các tham chiếu yếu đến đối tượng kiểu này. Không được thừa kế. Chỉ sử dụng nội bộ.

Thay đổi trong phiên bản 3.12: Chi tiết bên trong: Đối với các kiểu dựng sẵn tĩnh, đây luôn là NULL, ngay cả khi các điểm yếu được thêm vào. Thay vào đó, các điểm yếu cho mỗi điểm được lưu trữ trên PyInterpreterState. Sử dụng macro C-API công khai hoặc macro _PyObject_GET_WEAKREFS_LISTPTR() nội bộ để tránh sự phân biệt.

Inheritance:

Trường này không được kế thừa.

destructor PyTypeObject.tp_del

The corresponding slot ID Py_tp_del is part of the ABI ổn định.

Trường này không còn được dùng nữa. Thay vào đó hãy sử dụng tp_finalize.

unsigned int PyTypeObject.tp_version_tag

Được sử dụng để lập chỉ mục vào bộ đệm phương thức. Chỉ sử dụng nội bộ.

Inheritance:

Trường này không được kế thừa.

destructor PyTypeObject.tp_finalize

The corresponding slot ID Py_tp_finalize is part of the ABI ổn định kể từ phiên bản 3.5.

Một con trỏ tùy chọn tới một hàm hoàn thiện cá thể. Đây là cách triển khai C của phương thức đặc biệt __del__(). Chữ ký của nó là:

void tp_finalize(PyObject *self);

Mục đích chính của việc hoàn thiện là thực hiện bất kỳ hoạt động dọn dẹp không tầm thường nào phải được thực hiện trước khi đối tượng bị hủy, trong khi đối tượng và mọi đối tượng khác mà nó tham chiếu trực tiếp hoặc gián tiếp vẫn ở trạng thái nhất quán. Trình hoàn thiện được phép thực thi mã Python tùy ý.

Trước khi Python tự động hoàn thiện một đối tượng, một số tham chiếu trực tiếp hoặc gián tiếp của đối tượng có thể đã được tự động hoàn thiện. Tuy nhiên, chưa có người giới thiệu nào được tự động xóa (tp_clear).

Các đối tượng chưa được hoàn thiện khác có thể vẫn đang sử dụng một đối tượng đã được hoàn thiện, do đó, trình hoàn thiện phải để đối tượng ở trạng thái lành mạnh (ví dụ: các bất biến vẫn được đáp ứng).

Ghi chú

Sau khi Python tự động hoàn thiện một đối tượng, Python có thể bắt đầu tự động xóa (tp_clear) đối tượng đó và các tham chiếu của nó (trực tiếp và gián tiếp). Các đối tượng bị xóa không được đảm bảo ở trạng thái nhất quán; một đối tượng hoàn thiện phải có khả năng chấp nhận các tham chiếu đã được xóa.

Ghi chú

Một đối tượng không được đảm bảo sẽ được tự động hoàn thiện trước khi hàm hủy của nó (tp_dealloc) được gọi. Bạn nên gọi PyObject_CallFinalizerFromDealloc() khi bắt đầu tp_dealloc để đảm bảo rằng đối tượng luôn được hoàn thiện trước khi hủy.

Ghi chú

Hàm tp_finalize có thể được gọi từ bất kỳ luồng nào, mặc dù GIL sẽ được giữ.

Ghi chú

Hàm tp_finalize có thể được gọi trong khi tắt máy, sau khi một số biến toàn cục đã bị xóa. Xem tài liệu về phương pháp __del__() để biết chi tiết.

Khi Python hoàn thiện một đối tượng, nó hoạt động giống như thuật toán sau:

  1. Python có thể đánh dấu đối tượng là finalized. Hiện tại, Python luôn đánh dấu các đối tượng có loại hỗ trợ thu thập rác (tức là cờ Py_TPFLAGS_HAVE_GC được đặt trong tp_flags) và không bao giờ đánh dấu các loại đối tượng khác; điều này có thể thay đổi trong phiên bản tương lai.

  2. Nếu đối tượng không được đánh dấu là finalized và hàm hoàn thiện tp_finalize của nó không phải là NULL thì hàm hoàn thiện sẽ được gọi.

  3. Nếu hàm bộ hoàn thiện được gọi và bộ hoàn thiện làm cho đối tượng có thể truy cập được (tức là có một tham chiếu đến đối tượng và nó không phải là thành viên của cyclic isolate), thì bộ hoàn thiện được cho là có đối tượng resurrected. Không xác định được liệu trình hoàn thiện cũng có thể phục hồi đối tượng hay không bằng cách thêm một tham chiếu mới vào đối tượng mà không thể truy cập được, tức là đối tượng (vẫn) là thành viên của một cô lập tuần hoàn.

  4. Nếu trình hoàn thiện phục hồi đối tượng, quá trình hủy đối tượng đang chờ xử lý sẽ bị hủy và dấu finalized của đối tượng có thể bị xóa nếu có. Hiện tại, Python không bao giờ xóa dấu finalized; điều này có thể thay đổi trong phiên bản tương lai.

Automatic finalization đề cập đến bất kỳ quá trình hoàn thiện nào được thực hiện bởi Python ngoại trừ thông qua các lệnh gọi tới PyObject_CallFinalizer() hoặc PyObject_CallFinalizerFromDealloc(). Không có đảm bảo nào được đưa ra về thời điểm, nếu hoặc tần suất một đối tượng được tự động hoàn thiện, ngoại trừ:

  • Python sẽ không tự động hoàn thiện một đối tượng nếu nó có thể truy cập được, tức là có một tham chiếu đến nó và nó không phải là thành viên của cyclic isolate.

  • Python sẽ không tự động hoàn thiện một đối tượng nếu việc hoàn thiện nó không đánh dấu đối tượng là finalized. Hiện tại, điều này áp dụng cho các đối tượng có loại không hỗ trợ thu gom rác, tức là cờ Py_TPFLAGS_HAVE_GC không được đặt. Những đối tượng như vậy vẫn có thể được hoàn thiện thủ công bằng cách gọi PyObject_CallFinalizer() hoặc PyObject_CallFinalizerFromDealloc().

  • Python sẽ không tự động hoàn thiện đồng thời hai thành viên bất kỳ của cyclic isolate.

  • Python sẽ không tự động hoàn thiện một đối tượng sau khi nó đã tự động xóa (tp_clear) đối tượng đó.

  • Nếu một đối tượng là thành viên của cyclic isolate, Python sẽ không tự động hoàn thiện nó sau khi tự động xóa (xem tp_clear) bất kỳ thành viên nào khác.

  • Python sẽ tự động hoàn thiện mọi thành viên của cyclic isolate trước khi nó tự động xóa (xem tp_clear) bất kỳ thành viên nào trong số đó.

  • Nếu Python định tự động xóa một đối tượng (tp_clear), nó sẽ tự động hoàn thiện đối tượng đó trước tiên.

Python hiện chỉ tự động hoàn thiện các đối tượng là thành viên của cyclic isolate, nhưng các phiên bản trong tương lai có thể hoàn thiện các đối tượng thường xuyên trước khi chúng bị phá hủy.

Để hoàn thiện một đối tượng theo cách thủ công, không gọi trực tiếp hàm này; thay vào đó hãy gọi PyObject_CallFinalizer() hoặc PyObject_CallFinalizerFromDealloc().

tp_finalize nên giữ nguyên trạng thái ngoại lệ hiện tại. Cách được khuyến nghị để viết một trình hoàn thiện không tầm thường là sao lưu ngoại lệ ngay từ đầu bằng cách gọi PyErr_GetRaisedException() và khôi phục ngoại lệ ở cuối bằng cách gọi PyErr_SetRaisedException(). Nếu gặp phải ngoại lệ ở giữa trình hoàn thiện, hãy đăng nhập và xóa ngoại lệ đó bằng PyErr_WriteUnraisable() hoặc PyErr_FormatUnraisable(). Ví dụ:

khoảng trống tĩnh
foo_finalize(PyObject *self)
{
    // Lưu ngoại lệ hiện tại, nếu có.
    PyObject *exc = PyErr_GetRaisedException();

    // ...

    if (do_something_that_might_raise() != thành công_indicator) {
        PyErr_WriteUnraiseable(self);
        phải làm xong;
    }

xong:
    // Khôi phục ngoại lệ đã lưu.  Điều này âm thầm loại bỏ mọi ngoại lệ
    // được nêu ở trên, vì vậy hãy nhớ gọi PyErr_WriteUnraisable trước nếu
    // cần thiết.
    PyErr_SetRaisedException(exc);
}

Inheritance:

Trường này được kế thừa bởi các kiểu con.

Added in version 3.4.

Thay đổi trong phiên bản 3.8: Trước phiên bản 3.8, cần phải đặt bit cờ Py_TPFLAGS_HAVE_FINALIZE để sử dụng trường này. Điều này không còn cần thiết nữa.

Xem thêm

vectorcallfunc PyTypeObject.tp_vectorcall

The corresponding slot ID Py_tp_vectorcall is part of the ABI ổn định kể từ phiên bản 3.14.

Một vectorcall function để sử dụng cho các cuộc gọi thuộc loại đối tượng này (chứ không phải các phiên bản). Nói cách khác, tp_vectorcall có thể được sử dụng để tối ưu hóa type.__call__, thường trả về một phiên bản mới của type.

Giống như bất kỳ hàm vectorcall nào, nếu tp_vectorcallNULL thì giao thức tp_call (Py_TYPE(type)->tp_call) sẽ được sử dụng thay thế.

Ghi chú

vectorcall protocol yêu cầu hàm vectorcall có hành vi tương tự như tp_call tương ứng. Điều này có nghĩa là type->tp_vectorcall phải phù hợp với hành vi của Py_TYPE(type)->tp_call.

Cụ thể, nếu type sử dụng siêu dữ liệu mặc định thì type->tp_vectorcall phải hoạt động giống như PyType_Type->tp_call, đó là:

  • gọi type->tp_new,

  • nếu kết quả là một lớp con của type, hãy gọi type->tp_init trên kết quả của tp_new

  • trả về kết quả của tp_new.

Thông thường, tp_vectorcall bị ghi đè để tối ưu hóa quy trình này cho tp_newtp_init cụ thể. Khi thực hiện việc này đối với các loại có thể phân lớp người dùng, hãy lưu ý rằng cả hai đều có thể bị ghi đè (sử dụng __new__()__init__() tương ứng).

Inheritance:

Trường này không bao giờ được kế thừa.

Added in version 3.9: (trường này tồn tại từ phiên bản 3.8 nhưng nó chỉ được sử dụng kể từ phiên bản 3.9)

unsigned char PyTypeObject.tp_watched

Nội bộ. Không sử dụng.

Added in version 3.12.

Các loại tĩnh

Theo truyền thống, các loại được xác định trong mã C là static, nghĩa là cấu trúc PyTypeObject tĩnh được xác định trực tiếp trong mã và được khởi tạo bằng PyType_Ready().

Điều này dẫn đến các loại bị giới hạn so với các loại được xác định trong Python:

  • Các kiểu tĩnh được giới hạn ở một cơ sở, tức là chúng không thể sử dụng nhiều kế thừa.

  • Các đối tượng loại tĩnh (nhưng không nhất thiết phải là phiên bản của chúng) là bất biến. Không thể thêm hoặc sửa đổi các thuộc tính của đối tượng loại từ Python.

  • Các đối tượng loại tĩnh được chia sẻ trên sub-interpreters, vì vậy chúng không được bao gồm bất kỳ trạng thái cụ thể nào của trình thông dịch phụ.

Ngoài ra, vì PyTypeObject chỉ là một phần của Limited API dưới dạng cấu trúc mờ, nên mọi mô-đun mở rộng sử dụng kiểu tĩnh phải được biên dịch cho một phiên bản phụ Python cụ thể.

Các loại đống

Một thay thế cho static typesheap-allocated types, hay gọi tắt là heap types, tương ứng chặt chẽ với các lớp được tạo bởi câu lệnh class của Python. Các loại heap có bộ cờ Py_TPFLAGS_HEAPTYPE.

Điều này được thực hiện bằng cách điền vào cấu trúc PyType_Spec và gọi PyType_FromSpec(), PyType_FromSpecWithBases(), PyType_FromModuleAndSpec() hoặc PyType_FromMetaclass().

Cấu trúc đối tượng số

type PyNumberMethods

Cấu trúc này chứa các con trỏ tới các hàm mà đối tượng sử dụng để thực hiện giao thức số. Mỗi hàm được sử dụng bởi hàm có tên tương tự được ghi trong phần Giao thức số.

Đây là định nghĩa cấu trúc:

cấu trúc typedef {
     nhị phân nb_add;
     nhị phân nb_subtract;
     nhị phân nb_multiply;
     nhị phân nb_remainder;
     nhị phân nb_divmod;
     ternaryfunc nb_power;
     unaryfunc nb_ Negative;
     unaryfunc nb_posid;
     unaryfunc nb_absolute;
     yêu cầu nb_bool;
     unaryfunc nb_invert;
     nhị phân nb_lshift;
     nhị phân nb_rshift;
     nhị phân nb_and;
     nhị phân nb_xor;
     nhị phân nb_or;
     unaryfunc nb_int;
     void *nb_reserved;
     unaryfunc nb_float;

     nhị phân nb_inplace_add;
     nhị phân nb_inplace_subtract;
     nhị phân nb_inplace_multiply;
     nhị phân nb_inplace_remainder;
     ternaryfunc nb_inplace_power;
     nhị phân nb_inplace_lshift;
     nhị phân nb_inplace_rshift;
     nhị phân nb_inplace_and;
     nhị phân nb_inplace_xor;
     nhị phân nb_inplace_or;

     nhị phân nb_floor_divide;
     nhị phân nb_true_divide;
     nhị phân nb_inplace_floor_divide;
     nhị phân nb_inplace_true_divide;

     unaryfunc nb_index;

     nhị phân nb_matrix_multiply;
     nhị phân nb_inplace_matrix_multiply;
} Phương thức PyNumber;

Ghi chú

Hàm nhị phân và hàm ba ngôi phải kiểm tra loại của tất cả toán hạng của chúng và thực hiện các chuyển đổi cần thiết (ít nhất một trong các toán hạng là một thể hiện của loại được xác định). Nếu thao tác không được xác định cho các toán hạng đã cho, các hàm nhị phân và bậc ba phải trả về Py_NotImplemented, nếu xảy ra lỗi khác thì chúng phải trả về NULL và đặt một ngoại lệ.

Ghi chú

Trường nb_reserved phải luôn là NULL. Trước đây nó được gọi là nb_long và được đổi tên trong Python 3.0.1.

binaryfunc PyNumberMethods.nb_add

The corresponding slot ID Py_nb_add is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_subtract

The corresponding slot ID Py_nb_subtract is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_multiply

The corresponding slot ID Py_nb_multiply is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_remainder

The corresponding slot ID Py_nb_remainder is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_divmod

The corresponding slot ID Py_nb_divmod is part of the ABI ổn định.

ternaryfunc PyNumberMethods.nb_power

The corresponding slot ID Py_nb_power is part of the ABI ổn định.

unaryfunc PyNumberMethods.nb_negative

The corresponding slot ID Py_nb_negative is part of the ABI ổn định.

unaryfunc PyNumberMethods.nb_positive

The corresponding slot ID Py_nb_positive is part of the ABI ổn định.

unaryfunc PyNumberMethods.nb_absolute

The corresponding slot ID Py_nb_absolute is part of the ABI ổn định.

inquiry PyNumberMethods.nb_bool

The corresponding slot ID Py_nb_bool is part of the ABI ổn định.

unaryfunc PyNumberMethods.nb_invert

The corresponding slot ID Py_nb_invert is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_lshift

The corresponding slot ID Py_nb_lshift is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_rshift

The corresponding slot ID Py_nb_rshift is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_and

The corresponding slot ID Py_nb_and is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_xor

The corresponding slot ID Py_nb_xor is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_or

The corresponding slot ID Py_nb_or is part of the ABI ổn định.

unaryfunc PyNumberMethods.nb_int

The corresponding slot ID Py_nb_int is part of the ABI ổn định.

void *PyNumberMethods.nb_reserved
unaryfunc PyNumberMethods.nb_float

The corresponding slot ID Py_nb_float is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_add

The corresponding slot ID Py_nb_inplace_add is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_subtract

The corresponding slot ID Py_nb_inplace_subtract is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_multiply

The corresponding slot ID Py_nb_inplace_multiply is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_remainder

The corresponding slot ID Py_nb_inplace_remainder is part of the ABI ổn định.

ternaryfunc PyNumberMethods.nb_inplace_power

The corresponding slot ID Py_nb_inplace_power is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_lshift

The corresponding slot ID Py_nb_inplace_lshift is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_rshift

The corresponding slot ID Py_nb_inplace_rshift is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_and

The corresponding slot ID Py_nb_inplace_and is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_xor

The corresponding slot ID Py_nb_inplace_xor is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_or

The corresponding slot ID Py_nb_inplace_or is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_floor_divide

The corresponding slot ID Py_nb_floor_divide is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_true_divide

The corresponding slot ID Py_nb_true_divide is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_floor_divide

The corresponding slot ID Py_nb_inplace_floor_divide is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_inplace_true_divide

The corresponding slot ID Py_nb_inplace_true_divide is part of the ABI ổn định.

unaryfunc PyNumberMethods.nb_index

The corresponding slot ID Py_nb_index is part of the ABI ổn định.

binaryfunc PyNumberMethods.nb_matrix_multiply

The corresponding slot ID Py_nb_matrix_multiply is part of the ABI ổn định kể từ phiên bản 3.5.

binaryfunc PyNumberMethods.nb_inplace_matrix_multiply

The corresponding slot ID Py_nb_inplace_matrix_multiply is part of the ABI ổn định kể từ phiên bản 3.5.

Ánh xạ cấu trúc đối tượng

type PyMappingMethods

Cấu trúc này chứa các con trỏ tới các hàm mà đối tượng sử dụng để thực hiện giao thức ánh xạ. Nó có ba thành viên:

lenfunc PyMappingMethods.mp_length

The corresponding slot ID Py_mp_length is part of the ABI ổn định.

Hàm này được PyMapping_Size()PyObject_Size() sử dụng và có cùng chữ ký. Khe này có thể được đặt thành NULL nếu đối tượng không có độ dài xác định.

binaryfunc PyMappingMethods.mp_subscript

The corresponding slot ID Py_mp_subscript is part of the ABI ổn định.

Hàm này được PyObject_GetItem()PySequence_GetSlice() sử dụng và có cùng chữ ký với PyObject_GetItem(). Khe này phải được lấp đầy để hàm PyMapping_Check() trả về 1, nếu không thì có thể là NULL.

objobjargproc PyMappingMethods.mp_ass_subscript

The corresponding slot ID Py_mp_ass_subscript is part of the ABI ổn định.

Chức năng này được sử dụng bởi PyObject_SetItem(), PyObject_DelItem(), PySequence_SetSlice()PySequence_DelSlice(). Nó có cùng chữ ký với PyObject_SetItem(), nhưng v cũng có thể được đặt thành NULL để xóa một mục. Nếu vị trí này là NULL, đối tượng không hỗ trợ gán và xóa mục.

Cấu trúc đối tượng trình tự

type PySequenceMethods

Cấu trúc này chứa các con trỏ tới các hàm mà đối tượng sử dụng để thực hiện giao thức tuần tự.

lenfunc PySequenceMethods.sq_length

The corresponding slot ID Py_sq_length is part of the ABI ổn định.

Hàm này được PySequence_Size()PyObject_Size() sử dụng và có cùng chữ ký. Nó cũng được sử dụng để xử lý các chỉ số âm thông qua các khe sq_itemsq_ass_item.

binaryfunc PySequenceMethods.sq_concat

The corresponding slot ID Py_sq_concat is part of the ABI ổn định.

Chức năng này được PySequence_Concat() sử dụng và có cùng chữ ký. Nó cũng được sử dụng bởi toán tử +, sau khi thử phép cộng số qua khe nb_add.

ssizeargfunc PySequenceMethods.sq_repeat

The corresponding slot ID Py_sq_repeat is part of the ABI ổn định.

Chức năng này được PySequence_Repeat() sử dụng và có cùng chữ ký. Nó cũng được sử dụng bởi toán tử *, sau khi thử nhân số qua khe nb_multiply.

ssizeargfunc PySequenceMethods.sq_item

The corresponding slot ID Py_sq_item is part of the ABI ổn định.

Chức năng này được PySequence_GetItem() sử dụng và có cùng chữ ký. Nó cũng được PyObject_GetItem() sử dụng sau khi thử đăng ký qua khe mp_subscript. Khe này phải được lấp đầy để hàm PySequence_Check() trả về 1, nếu không thì có thể là NULL.

Các chỉ mục âm được xử lý như sau: nếu khe sq_length được lấp đầy, nó sẽ được gọi và độ dài chuỗi được sử dụng để tính chỉ mục dương được chuyển đến sq_item. Nếu sq_lengthNULL, chỉ mục sẽ được truyền vào hàm.

ssizeobjargproc PySequenceMethods.sq_ass_item

The corresponding slot ID Py_sq_ass_item is part of the ABI ổn định.

Chức năng này được PySequence_SetItem() sử dụng và có cùng chữ ký. Nó cũng được PyObject_SetItem()PyObject_DelItem() sử dụng, sau khi thử gán và xóa vật phẩm qua khe mp_ass_subscript. Khe này có thể được để lại cho NULL nếu đối tượng không hỗ trợ gán và xóa vật phẩm.

objobjproc PySequenceMethods.sq_contains

The corresponding slot ID Py_sq_contains is part of the ABI ổn định.

Chức năng này có thể được PySequence_Contains() sử dụng và có cùng chữ ký. Vị trí này có thể được để lại cho NULL, trong trường hợp này, PySequence_Contains() chỉ đơn giản duyệt qua chuỗi cho đến khi tìm thấy kết quả khớp.

binaryfunc PySequenceMethods.sq_inplace_concat

The corresponding slot ID Py_sq_inplace_concat is part of the ABI ổn định.

Chức năng này được PySequence_InPlaceConcat() sử dụng và có cùng chữ ký. Nó sẽ sửa đổi toán hạng đầu tiên của nó và trả về nó. Khe này có thể để lại cho NULL, trong trường hợp này PySequence_InPlaceConcat() sẽ rơi về PySequence_Concat(). Nó cũng được sử dụng bởi phép gán tăng cường +=, sau khi thử phép cộng số tại chỗ thông qua khe nb_inplace_add.

ssizeargfunc PySequenceMethods.sq_inplace_repeat

The corresponding slot ID Py_sq_inplace_repeat is part of the ABI ổn định.

Chức năng này được PySequence_InPlaceRepeat() sử dụng và có cùng chữ ký. Nó sẽ sửa đổi toán hạng đầu tiên của nó và trả về nó. Khe này có thể để lại cho NULL, trong trường hợp này PySequence_InPlaceRepeat() sẽ rơi về PySequence_Repeat(). Nó cũng được sử dụng bởi phép gán tăng cường *=, sau khi thử phép nhân số tại chỗ thông qua khe nb_inplace_multiply.

Cấu trúc đối tượng đệm

type PyBufferProcs

Cấu trúc này chứa các con trỏ tới các hàm mà Buffer protocol yêu cầu. Giao thức xác định cách đối tượng nhà xuất khẩu có thể hiển thị dữ liệu nội bộ của nó cho đối tượng người tiêu dùng.

getbufferproc PyBufferProcs.bf_getbuffer

The corresponding slot ID Py_bf_getbuffer is part of the ABI ổn định kể từ phiên bản 3.11.

Chữ ký của hàm này là:

int (PyObject *exporter, Py_buffer *view, cờ int);

Xử lý yêu cầu tới exporter để điền vào view theo chỉ định của flags. Ngoại trừ điểm (3), việc triển khai chức năng này MUST thực hiện các bước sau:

  1. Kiểm tra xem yêu cầu có thể được đáp ứng hay không. Nếu không, hãy tăng BufferError, đặt view->obj thành NULL và trả về -1.

  2. Điền vào các trường được yêu cầu.

  3. Tăng bộ đếm nội bộ cho số lượng xuất khẩu.

  4. Đặt view->obj thành exporter và tăng view->obj.

  5. Trả về 0.

Thread safety:

Trong free-threaded build, việc triển khai phải đảm bảo:

  • Gia số bộ đếm xuất ở bước (3) là nguyên tử.

  • Dữ liệu bộ đệm cơ bản vẫn hợp lệ và ở vị trí bộ nhớ ổn định trong suốt thời gian xuất dữ liệu.

  • Đối với các đối tượng hỗ trợ thay đổi kích thước hoặc phân bổ lại (chẳng hạn như bytearray), bộ đếm xuất được kiểm tra nguyên tử trước các hoạt động đó và BufferError được tăng lên nếu tồn tại xuất.

  • Chức năng này an toàn khi gọi đồng thời từ nhiều luồng.

Xem thêm An toàn luồng cho các đối tượng MemoryView để biết các đảm bảo an toàn luồng ở cấp độ Python cho các đối tượng memoryview.

Nếu exporter là một phần của chuỗi hoặc cây các nhà cung cấp bộ đệm, có thể sử dụng hai sơ đồ chính:

  • Tái xuất: Mỗi thành viên của cây đóng vai trò là đối tượng xuất và đặt view->obj thành một tham chiếu mới cho chính nó.

  • Chuyển hướng: Yêu cầu bộ đệm được chuyển hướng đến đối tượng gốc của cây. Ở đây, view->obj sẽ là một tham chiếu mới cho đối tượng gốc.

Các trường riêng lẻ của view được mô tả trong phần Buffer structure, các quy tắc về cách nhà xuất khẩu phải phản ứng với các yêu cầu cụ thể có trong phần Buffer request types.

Tất cả bộ nhớ được trỏ đến trong cấu trúc Py_buffer thuộc về nhà xuất khẩu và phải duy trì hiệu lực cho đến khi không còn người tiêu dùng nào. format, shape, strides, suboffsetsinternal ở chế độ chỉ đọc cho người tiêu dùng.

PyBuffer_FillInfo() cung cấp một cách dễ dàng để hiển thị bộ đệm byte đơn giản trong khi xử lý chính xác tất cả các loại yêu cầu.

PyObject_GetBuffer() là giao diện dành cho người tiêu dùng bao bọc chức năng này.

releasebufferproc PyBufferProcs.bf_releasebuffer

The corresponding slot ID Py_bf_releasebuffer is part of the ABI ổn định kể từ phiên bản 3.11.

Chữ ký của hàm này là:

khoảng trống (PyObject *exporter, Py_buffer *view);

Xử lý yêu cầu giải phóng tài nguyên của bộ đệm. Nếu không cần giải phóng tài nguyên, PyBufferProcs.bf_releasebuffer có thể là NULL. Nếu không, việc triển khai tiêu chuẩn chức năng này sẽ thực hiện các bước tùy chọn sau:

  1. Giảm bộ đếm nội bộ cho số lượng xuất khẩu.

  2. Nếu bộ đếm là 0, hãy giải phóng tất cả bộ nhớ liên quan đến view.

Thread safety:

Trong free-threaded build:

  • Việc giảm bộ đếm xuất ở bước (1) phải là nguyên tử.

  • Việc dọn dẹp tài nguyên khi bộ đếm về 0 phải được thực hiện một cách nguyên tử, vì bản phát hành cuối cùng có thể chạy đua với các bản phát hành đồng thời từ các luồng khác và việc phân bổ chỉ phải xảy ra một lần.

Nhà xuất khẩu MUST sử dụng trường internal để theo dõi các tài nguyên dành riêng cho bộ đệm. Trường này được đảm bảo không đổi, trong khi MAY tiêu dùng chuyển một bản sao của bộ đệm gốc làm đối số view.

Hàm này MUST NOT giảm view->obj, vì việc đó được thực hiện tự động trong PyBuffer_Release() (sơ đồ này rất hữu ích để phá vỡ các chu kỳ tham chiếu).

PyBuffer_Release() là giao diện dành cho người tiêu dùng bao bọc chức năng này.

Cấu trúc đối tượng không đồng bộ

Added in version 3.5.

type PyAsyncMethods

Cấu trúc này chứa các con trỏ tới các hàm cần thiết để triển khai các đối tượng awaitableasynchronous iterator.

Đây là định nghĩa cấu trúc:

cấu trúc typedef {
    unaryfunc am_await;
    unaryfunc am_aiter;
    unaryfunc am_anext;
    sendfunc am_send;
} Phương thức PyAsync;
unaryfunc PyAsyncMethods.am_await

The corresponding slot ID Py_am_await is part of the ABI ổn định kể từ phiên bản 3.5.

Chữ ký của hàm này là:

PyObject *am_await(PyObject *self);

Đối tượng được trả về phải là iterator, tức là PyIter_Check() phải trả về 1 cho nó.

Khe này có thể được đặt thành NULL nếu đối tượng không phải là awaitable.

unaryfunc PyAsyncMethods.am_aiter

The corresponding slot ID Py_am_aiter is part of the ABI ổn định kể từ phiên bản 3.5.

Chữ ký của hàm này là:

PyObject *am_aiter(PyObject *self);

Phải trả về một đối tượng asynchronous iterator. Xem __anext__() để biết chi tiết.

Khe này có thể được đặt thành NULL nếu một đối tượng không triển khai giao thức lặp không đồng bộ.

unaryfunc PyAsyncMethods.am_anext

The corresponding slot ID Py_am_anext is part of the ABI ổn định kể từ phiên bản 3.5.

Chữ ký của hàm này là:

PyObject *am_anext(PyObject *self);

Phải trả về một đối tượng awaitable. Xem __anext__() để biết chi tiết. Khe này có thể được đặt thành NULL.

sendfunc PyAsyncMethods.am_send

The corresponding slot ID Py_am_send is part of the ABI ổn định kể từ phiên bản 3.10.

Chữ ký của hàm này là:

PySendResult am_send(PyObject *self, PyObject *arg, PyObject **kết quả);

Xem PyIter_Send() để biết chi tiết. Khe này có thể được đặt thành NULL.

Added in version 3.10.

Loại vị trí typedefs

typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)
Một phần của ABI ổn định.

Mục đích của chức năng này là tách việc cấp phát bộ nhớ khỏi việc khởi tạo bộ nhớ. Nó sẽ trả về một con trỏ tới một khối bộ nhớ có độ dài phù hợp cho phiên bản, được căn chỉnh phù hợp và được khởi tạo về số 0, nhưng với ob_refcnt được đặt thành 1ob_type được đặt thành đối số loại. Nếu tp_itemsize của loại khác 0 thì trường ob_size của đối tượng phải được khởi tạo thành nitems và độ dài của khối bộ nhớ được phân bổ phải là tp_basicsize + nitems*tp_itemsize, được làm tròn thành bội số của sizeof(void*); mặt khác, nitems không được sử dụng và độ dài của khối phải là tp_basicsize.

Hàm này không được thực hiện bất kỳ khởi tạo phiên bản nào khác, thậm chí không được phân bổ bộ nhớ bổ sung; việc đó nên được thực hiện bởi tp_new.

typedef void (*destructor)(PyObject*)
Một phần của ABI ổn định.
typedef void (*freefunc)(void*)

Xem tp_free.

typedef PyObject *(*newfunc)(PyTypeObject*, PyObject*, PyObject*)
Một phần của ABI ổn định.

Xem tp_new.

typedef int (*initproc)(PyObject*, PyObject*, PyObject*)
Một phần của ABI ổn định.

Xem tp_init.

typedef PyObject *(*reprfunc)(PyObject*)
Một phần của ABI ổn định.

Xem tp_repr.

typedef PyObject *(*getattrfunc)(PyObject *self, char *attr)
Một phần của ABI ổn định.

Trả về giá trị của thuộc tính được đặt tên cho đối tượng.

typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)
Một phần của ABI ổn định.

Đặt giá trị của thuộc tính được đặt tên cho đối tượng. Đối số giá trị được đặt thành NULL để xóa thuộc tính.

typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)
Một phần của ABI ổn định.

Trả về giá trị của thuộc tính được đặt tên cho đối tượng.

Xem tp_getattro.

typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)
Một phần của ABI ổn định.

Đặt giá trị của thuộc tính được đặt tên cho đối tượng. Đối số giá trị được đặt thành NULL để xóa thuộc tính.

Xem tp_setattro.

typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*)
Một phần của ABI ổn định.

Xem tp_descr_get.

typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*)
Một phần của ABI ổn định.

Xem tp_descr_set.

typedef Py_hash_t (*hashfunc)(PyObject*)
Một phần của ABI ổn định.

Xem tp_hash.

typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int)
Một phần của ABI ổn định.

Xem tp_richcompare.

typedef PyObject *(*getiterfunc)(PyObject*)
Một phần của ABI ổn định.

Xem tp_iter.

typedef PyObject *(*iternextfunc)(PyObject*)
Một phần của ABI ổn định.

Xem tp_iternext.

typedef Py_ssize_t (*lenfunc)(PyObject*)
Một phần của ABI ổn định.
typedef int (*getbufferproc)(PyObject*, Py_buffer*, int)
Một phần của ABI ổn định kể từ phiên bản 3.12.
typedef void (*releasebufferproc)(PyObject*, Py_buffer*)
Một phần của ABI ổn định kể từ phiên bản 3.12.
typedef PyObject *(*unaryfunc)(PyObject*)
Một phần của ABI ổn định.
typedef PyObject *(*binaryfunc)(PyObject*, PyObject*)
Một phần của ABI ổn định.
typedef PySendResult (*sendfunc)(PyObject*, PyObject*, PyObject**)

Xem am_send.

typedef PyObject *(*ternaryfunc)(PyObject*, PyObject*, PyObject*)
Một phần của ABI ổn định.
typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t)
Một phần của ABI ổn định.
typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*)
Một phần của ABI ổn định.
typedef int (*objobjproc)(PyObject*, PyObject*)
Một phần của ABI ổn định.
typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*)
Một phần của ABI ổn định.

Ví dụ

Sau đây là những ví dụ đơn giản về định nghĩa kiểu Python. Chúng bao gồm cách sử dụng phổ biến mà bạn có thể gặp phải. Một số chứng minh các trường hợp góc khó. Để biết thêm ví dụ, thông tin thực tế và hướng dẫn, hãy xem Xác định các loại tiện ích mở rộng: Hướng dẫnXác định các loại tiện ích mở rộng: Các chủ đề khác nhau.

Một static type cơ bản:

cấu trúc typedef {
    PyObject_HEAD
    const char *dữ liệu;
} MyObject;

PyTypeObject tĩnh MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject),
    .tp_doc = PyDoc_STR("Đối tượng của tôi"),
    .tp_new = myobj_new,
    .tp_dealloc = (hàm hủy)myobj_dealloc,
    .tp_repr = (reprfunc)myobj_repr,
};

Bạn cũng có thể tìm thấy mã cũ hơn (đặc biệt là trong cơ sở mã CPython) với trình khởi tạo chi tiết hơn

PyTypeObject tĩnh MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "mymod.MyObject", /* tp_name */
    sizeof(MyObject), /* tp_basicsize */
    0, /* tp_itemsize */
    (hàm hủy)myobj_dealloc, /* tp_dealloc */
    0, /* tp_vectorcall_offset */
    0, /*tp_getattr */
    0, /*tp_setattr */
    0, /* tp_as_async */
    (reprfunc)myobj_repr, /* tp_repr */
    0, /* tp_as_number */
    0, /* tp_as_sequence */
    0, /* tp_as_mapping */
    0, /* tp_hash */
    0, /* tp_call */
    0, /*tp_str */
    0, /*tp_getattro */
    0, /*tp_setattro */
    0, /* tp_as_buffer */
    0, /* tp_flags */
    PyDoc_STR("Đối tượng của tôi"), /* tp_doc */
    0, /* tp_traverse */
    0, /* tp_clear */
    0, /* tp_richcompare */
    0, /* tp_weaklistoffset */
    0, /*tp_iter */
    0, /* tp_iternext */
    0, /* tp_methods */
    0, /* tp_members */
    0, /*tp_getset */
    0, /*tp_base */
    0, /*tp_dict */
    0, /* tp_descr_get */
    0, /* tp_descr_set */
    0, /* tp_dictoffset */
    0, /*tp_init */
    0, /* tp_alloc */
    myobj_new, /* tp_new */
};

Một loại hỗ trợ các điểm yếu, ký tự phiên bản và hàm băm

cấu trúc typedef {
    PyObject_HEAD
    const char *dữ liệu;
} MyObject;

PyTypeObject tĩnh MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject),
    .tp_doc = PyDoc_STR("Đối tượng của tôi"),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
         Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT |
         Py_TPFLAGS_MANAGED_WEAKREF,
    .tp_new = myobj_new,
    .tp_traverse = (traverseproc)myobj_traverse,
    .tp_clear = (truy vấn)myobj_clear,
    .tp_alloc = PyType_GenericNew,
    .tp_dealloc = (hàm hủy)myobj_dealloc,
    .tp_repr = (reprfunc)myobj_repr,
    .tp_hash = (hashfunc)myobj_hash,
    .tp_richcompare = PyBaseObject_Type.tp_richcompare,
};

Một lớp con str không thể được phân lớp và không thể gọi để tạo các phiên bản (ví dụ: sử dụng một func xuất xưởng riêng) bằng cờ Py_TPFLAGS_DISALLOW_INSTANTIATION:

cấu trúc typedef {
    PyUnicodeObject thô;
    char *thêm;
} MyStr;

PyTypeObject tĩnh MyStr_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyStr",
    .tp_basicsize = sizeof(MyStr),
    .tp_base = NULL, // đặt thành &PyUnicode_Type trong mô-đun init
    .tp_doc = PyDoc_STR("str tùy chỉnh của tôi"),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
    .tp_repr = (reprfunc)myobj_repr,
};

Zz000zz đơn giản nhất với các phiên bản có độ dài cố định

cấu trúc typedef {
    PyObject_HEAD
} MyObject;

PyTypeObject tĩnh MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
};

Zz000zz đơn giản nhất với các phiên bản có độ dài thay đổi

cấu trúc typedef {
    PyObject_VAR_HEAD
    const char *data[1];
} MyObject;

PyTypeObject tĩnh MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject) - sizeof(char *),
    .tp_itemsize = sizeof(char *),
};