12. Bố cục đối tượng và loại vị trí
12. Bố cục đối tượng và loại slot
CPython đại diện cho mọi giá trị thời gian chạy dưới dạng một đối tượng. Mỗi đối tượng có một bố cục bộ nhớ và loại của mỗi đối tượng mô tả cách diễn giải bộ nhớ đó.
Bố cục đối tượng trả lời:text What fields exist inside this object? Where are the references to other Python objects? How large is one instance? Does the object have variable-sized trailing storage? Does the object participate in cyclic garbage collection? Các loại slot trả lời:```text
How is this object called?
How is it deallocated?
How does attribute lookup work?
How does indexing work?
How does addition work?
How does iteration work?
How is it represented as text?
## 12.1 Bộ nhớ đối tượng bắt đầu bằng tiêu đề
Mọi đối tượng CPython bình thường đều bắt đầu bằng tiêu đề đối tượng.
Về mặt khái niệm:```c
typedef struct {
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
} PyObject;
```Điều này mang lại cho mọi đối tượng hai trường cơ bản:
| Lĩnh vực | Ý nghĩa |
| ----------- | ---------------------------- |
|`ob_refcnt`| Số lượng tham khảo |
|`ob_type`| Con trỏ tới loại đối tượng |
Một đối tượng cụ thể đặt các trường riêng của nó sau tiêu đề này.
Hình dạng ví dụ:```text
PyLongObject
PyObject header
integer-specific fields
PyListObject
PyObject / PyVarObject header
list-specific fields
PyFunctionObject
PyObject header
function-specific fields
```Vì mọi đối tượng đều bắt đầu bằng cùng một tiêu đề nên mã CPython chung có thể thao tác với các đối tượng không xác định thông qua`PyObject *`.
## 12.2 Bố cục đối tượng có kích thước cố định
Một đối tượng có kích thước cố định có cùng kích thước cấu trúc C cho mọi phiên bản.
Ví dụ:```c
typedef struct {
PyObject_HEAD
double value;
} FloatLikeObject;
```Hình dạng bộ nhớ:```text
+--------------------+
| ob_refcnt |
+--------------------+
| ob_type |
+--------------------+
| value |
+--------------------+
```Tất cả các phiên bản thuộc loại này có cùng kích thước.
Ví dụ về các cấu trúc đối tượng có kích thước cố định:```text
float
function
module
cell
method
weakref
many iterator objects
many descriptor objects
```Kích thước cố định không có nghĩa là đối tượng không có tham chiếu đến bộ nhớ ngoài. Một đối tượng hàm có cấu trúc có kích thước cố định, nhưng nó trỏ đến một đối tượng mã, từ điển toàn cục, bộ dữ liệu mặc định, bộ dữ liệu đóng, chú thích và các đối tượng khác.
## 12.3 Bố cục đối tượng có kích thước thay đổi
Một đối tượng có kích thước thay đổi sẽ mở rộng tiêu đề chung bằng trường kích thước.
Về mặt khái niệm:```c
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size;
} PyVarObject;
```Các loại tiện ích mở rộng sử dụng:```c
typedef struct {
PyObject_VAR_HEAD
PyObject *items[1];
} ArrayLikeObject;
```Hình dạng bộ nhớ:```text
+--------------------+
| ob_refcnt |
+--------------------+
| ob_type |
+--------------------+
| ob_size |
+--------------------+
| variable payload |
+--------------------+
ob_sizecó ý nghĩa đặc trưng cho từng loại.
| Loại | Ý nghĩa của trường kích thước |
|---|---|
tuple |
Số phần tử |
bytes |
Số byte |
int |
Số và dấu của chữ số bên trong |
| loại biến tùy chỉnh | Được xác định bởi việc thực hiện kiểu |
12.4 Lưu trữ nội tuyến so với lưu trữ gián tiếp
Các giá trị Python có kích thước thay đổi có thể lưu trữ dữ liệu nội tuyến hoặc gián tiếp.
Một bộ lưu trữ các tham chiếu mục nội tuyến trong cùng một phân bổ:text tuple object header size = 3 item[0] ---> object A item[1] ---> object B item[2] ---> object C Một danh sách lưu trữ một con trỏ tới một mảng mục riêng biệt:```text
list object
header
size = 3
ob_item ----+
allocated |
v
[ptr A][ptr B][ptr C][spare...]
Một bộ dữ liệu không thể thay đổi kích thước sau khi phân bổ, do đó việc lưu trữ nội tuyến sẽ hiệu quả.
Một danh sách phải phát triển và thu nhỏ lại, do đó, nó giữ các phần tử trong một mảng riêng biệt có thể được phân bổ lại mà không cần di chuyển chính đối tượng danh sách.
## 12.5 Kiểu đối tượng Mô tả bố cục cá thể
Mỗi đối tượng trỏ đến một đối tượng kiểu.
Đối tượng loại lưu trữ siêu dữ liệu bố cục, chẳng hạn như:```text
tp_basicsize
tp_itemsize
tp_dictoffset
tp_weaklistoffset
tp_flags
```Các trường quan trọng:
| Lĩnh vực | Ý nghĩa |
| ------------------- | ------------------------------------- |
|`tp_basicsize`| Kích thước cố định của một phiên bản |
|`tp_itemsize`| Kích thước của mỗi mục ở cuối biến |
|`tp_dictoffset`| Ví dụ bù trừ`__dict__`, nếu có |
|`tp_weaklistoffset`| Bù trừ danh sách yếu, nếu được hỗ trợ |
|`tp_flags`| Gõ cờ mô tả khả năng |
Đối với loại có kích thước cố định:```text
tp_basicsize = sizeof(MyObject)
tp_itemsize = 0
```Đối với loại có kích thước thay đổi:```text
tp_basicsize = fixed header and fields
tp_itemsize = size of one trailing element
```Phân bổ sau đó tính toán:```text
total bytes = tp_basicsize + n * tp_itemsize
```Đây là cách CPython phân bổ một bộ độ dài`n`trong một khối bộ nhớ.
## 12.6 Kiểu đối tượng Mô tả hành vi
Một đối tượng kiểu cũng lưu trữ hành vi.
Một cái nhìn đơn giản hóa:```text
PyTypeObject
name
size fields
base type
method table
member table
getset table
deallocator
repr function
call function
attribute functions
numeric slots
sequence slots
mapping slots
iterator slots
```Khi Python đánh giá:```python
x + y
```CPython gửi qua các khe loại.
Khi Python đánh giá:```python
x[i]
```CPython sử dụng các khe trình tự hoặc ánh xạ.
Khi Python đánh giá:```python
x()
```CPython sử dụng khe cuộc gọi.
Đối tượng kiểu vừa là bộ mô tả bố cục vừa là bảng điều phối.
## 12.7 Các loại slot chính`PyTypeObject`chứa nhiều trường. Các loại quan trọng là:
| Thể loại slot | Mục đích |
| -------------------- | -------------------------------------------- |
| Vị trí vòng đời | phân bổ, khởi tạo, phân bổ |
| Khe đại diện |`repr`, `str`|
| Khe thuộc tính | nhận, thiết lập, hành vi mô tả |
| Khe gọi | cú pháp gọi hàm |
| Khe số | phép toán số học và bit |
| Khe trình tự | độ dài, lập chỉ mục, ngăn chặn, nối |
| Vị trí bản đồ | tra cứu và gán kiểu từ điển |
| Khe lặp | giao thức lặp |
| Khe đệm | tiếp xúc với bộ nhớ thô |
| Khe GC | truyền tải và thanh toán bù trừ |
| Vị trí phân lớp | kế thừa và hành vi MRO |
Mỗi danh mục ánh xạ cú pháp hoặc hành vi thời gian chạy của Python tới các con trỏ hàm C.
## 12.8 Vị trí vòng đời
Các khe vòng đời kiểm soát việc tạo và hủy.
Các slot quan trọng:```text
tp_new
tp_init
tp_alloc
tp_dealloc
tp_free
```Đường dẫn sáng tạo điển hình:```text
call class
tp_new allocates or returns object
tp_init initializes object
return object
```Ví dụ:```python
obj = MyClass(1, 2)
```Về mặt khái niệm:```text
MyClass.__call__
MyClass.__new__
MyClass.__init__
```Ở cấp độ C, điều này chảy qua các khe loại.
Đối với các đối tượng bất biến,`tp_new`thường xây dựng giá trị đầy đủ vì đối tượng không thể sửa đổi sau khi tạo.
Đối với các đối tượng có thể thay đổi,`tp_init`có thể điền hoặc đặt lại các trường sau khi phân bổ.
## 12.9 Khe phân bổ`tp_dealloc`phá hủy một đối tượng có số tham chiếu đạt tới 0.
Một công cụ giải quyết đơn giản:```c
static void
Box_dealloc(BoxObject *self)
{
Py_XDECREF(self->value);
Py_TYPE(self)->tp_free((PyObject *)self);
}
```Bộ giải phóng phải giải phóng mọi tham chiếu Python thuộc sở hữu của đối tượng.
Đối với các loại nhận biết GC, bộ giải phóng cũng phải hủy theo dõi đối tượng trước khi ngắt tham chiếu:```c
static void
Box_dealloc(BoxObject *self)
{
PyObject_GC_UnTrack(self);
Py_CLEAR(self->value);
Py_TYPE(self)->tp_free((PyObject *)self);
}
```Một người giải quyết phải được viết một cách phòng thủ.`Py_DECREF`Và`Py_CLEAR`có thể thực thi mã Python tùy ý một cách gián tiếp thông qua các bộ hoàn thiện.
## 12.10 Khe biểu diễn
Hỗ trợ khe biểu diễn`repr()`Và`str()`.
Các slot quan trọng:```text
tp_repr
tp_str
```Mã Python:```python
repr(obj)
str(obj)
```bản đồ để gõ hành vi.
Bản phác thảo triển khai kiểu ví dụ:```c
static PyObject *
Counter_repr(CounterObject *self)
{
return PyUnicode_FromFormat("Counter(%ld)", self->value);
}
```Sau đó:```python
repr(counter)
```có thể sản xuất:```text
Counter(10)
```Nếu như`tp_str`vắng mặt, CPython có thể rơi trở lại`tp_repr`hoặc hành vi định dạng đối tượng chung tùy thuộc vào loại.
## 12.11 Khe truy cập thuộc tính
Truy cập thuộc tính là một trong những đường dẫn quan trọng nhất của CPython.
Các vị trí liên quan:```text
tp_getattro
tp_setattro
tp_getattr
tp_setattr
```Các loại hiện đại thường sử dụng`tp_getattro`Và`tp_setattro`.
Mã Python:```python
obj.name
obj.name = value
del obj.name
```chảy qua máy móc thuộc tính.
Đối với các đối tượng thông thường, việc tra cứu thuộc tính chung sẽ xử lý:```text
data descriptors
instance dictionary
non-data descriptors
class attributes
base classes
__getattr__
```Loại tùy chỉnh có thể ghi đè hành vi này bằng cách cung cấp các vị trí thuộc tính tùy chỉnh.
## 12.12 Khe mô tả
Bộ mô tả thực hiện hành vi ràng buộc.
Một kiểu mô tả có thể định nghĩa:```text
tp_descr_get
tp_descr_set
```Tương đương cấp độ Python:```python
__get__
__set__
__delete__
```Chức năng là mô tả. Khi một hàm được lưu trữ trên một lớp và được truy cập thông qua một thể hiện, logic mô tả sẽ tạo ra một phương thức bị ràng buộc.```python
class Counter:
def inc(self):
return 1
c = Counter()
m = c.inc
```Về mặt khái niệm:```text
look up inc on Counter
find function object
function descriptor binds self = c
return bound method
```Bộ mô tả triển khai các phương thức, thuộc tính, phương thức lớp, phương thức tĩnh, vị trí và nhiều thuộc tính tích hợp.
## 12.13 Khe gọi
Khe cuộc gọi hỗ trợ cú pháp gọi hàm.
Vị trí có liên quan:```text
tp_call
```Mã Python:```python
obj(a, b, c)
```yêu cầu loại đối tượng có thể gọi được.
Hàm, lớp, phương thức, hàm dựng sẵn và đối tượng với`__call__`đều tham gia vào giao thức này.
Đối với lớp do người dùng định nghĩa:```python
class F:
def __call__(self, x):
return x + 1
f = F()
print(f(10))
```Ở cấp độ loại, máy móc lớp đảm bảo các phiên bản có`__call__`hoạt động như các đối tượng có thể gọi được.
## 12.14 Khe số
Các khe số xử lý các phép toán số học và bitwise.
Họ sống trong một`PyNumberMethods`bàn.
Các khe khái niệm phổ biến:```text
nb_add
nb_subtract
nb_multiply
nb_remainder
nb_power
nb_negative
nb_positive
nb_absolute
nb_bool
nb_invert
nb_lshift
nb_rshift
nb_and
nb_xor
nb_or
nb_int
nb_float
nb_index
```Cú pháp Python:```python
a + b
a - b
a * b
-a
bool(a)
a & b
a << b
```sử dụng máy móc giao thức số.
Đối với các lớp do người dùng định nghĩa, các phương thức đặc biệt như`__add__`, `__bool__`, Và`__index__`được kết nối với các khe này.
## 12.15 Công văn hoạt động nhị phân
Các phép toán nhị phân cần được gửi đi cẩn thận vì hai toán hạng có hai loại.
Vì:```python
a + b
```CPython có thể xem xét:```text
left operand type
right operand type
subclass relationships
left slot
right reflected slot
NotImplemented result
```Các phương thức cấp độ Python:```python
__add__
__radd__
__iadd__
```bản đồ tới máy móc hoạt động nhị phân nội bộ.
Một loại có thể trở lại`NotImplemented`để cho toán hạng khác tham gia.
Ví dụ:```python
class A:
def __add__(self, other):
return NotImplemented
class B:
def __radd__(self, other):
return "handled by B"
print(A() + B())
```Hành vi điều phối này là một phần của mô hình dữ liệu của Python và được triển khai thông qua các khe kiểu.
## 12.16 Khe trình tự
Các khe trình tự tồn tại trong một`PySequenceMethods`bàn.
Các khe khái niệm phổ biến:```text
sq_length
sq_concat
sq_repeat
sq_item
sq_ass_item
sq_contains
sq_inplace_concat
sq_inplace_repeat
```Cú pháp Python:```python
len(x)
x[i]
x[i] = value
item in x
x + y
x * n
```có thể sử dụng các khe trình tự.
Danh sách, bộ dữ liệu, chuỗi, byte và phạm vi đều thể hiện hành vi trình tự, mặc dù bố cục bên trong của chúng khác nhau.
## 12.17 Khe bản đồ
Các vị trí bản đồ tồn tại trong một`PyMappingMethods`bàn.
Các khe khái niệm phổ biến:```text
mp_length
mp_subscript
mp_ass_subscript
```Cú pháp Python:```python
len(x)
x[key]
x[key] = value
del x[key]
```có thể sử dụng các khe bản đồ.
Từ điển là loại ánh xạ chính.
Một đối tượng do người dùng định nghĩa thực hiện`__getitem__`, `__setitem__`, Và`__len__`có thể tham gia vào hành vi giống như lập bản đồ thông qua tích hợp khe loại.
## 12.18 Tra cứu trình tự và ánh xạ
Cú pháp tương tự có thể có nghĩa là truy cập trình tự hoặc ánh xạ:```python
x[i]
```Đối với một danh sách,`i`là một chỉ mục.
Đối với một lệnh,`i`là một chiếc chìa khóa.
Loại quyết định cách diễn giải hoạt động.
Về mặt khái niệm:```text
list.__getitem__(index)
index must be integer-like
dict.__getitem__(key)
key may be any hashable object
```Ở cấp độ C, CPython gửi đi dựa trên vị trí trình tự và ánh xạ của loại.
## 12.19 Khe lặp vòng lặp
Lặp lại sử dụng hỗ trợ giao thức cấp loại.
Các vị trí liên quan:```text
tp_iter
tp_iternext
```Mã Python:```python
for item in obj:
...
```đại khái có nghĩa là:```text
iterator = iter(obj)
while true:
try:
item = next(iterator)
except StopIteration:
break
```Ở cấp độ C:```text
tp_iter
returns iterator object
tp_iternext
returns next item or signals StopIteration
```Một iterator tự trả về chính nó từ`tp_iter`.
Một vùng chứa trả về một đối tượng lặp riêng biệt.
## 12.20 Khe đệm
Giao thức bộ đệm hiển thị bộ nhớ thô cho các đối tượng khác mà không cần sao chép.
Khu vực vị trí có liên quan:```text
tp_as_buffer
```Các đối tượng như`bytes`, `bytearray`, `memoryview`, mảng và các kiểu mở rộng số có thể tham gia.
Giao thức bộ đệm quan trọng đối với:```text
zero-copy I/O
binary parsing
NumPy interop
memoryview
file and socket operations
serialization
```Trình xuất bộ đệm phải giữ cho bộ nhớ hợp lệ trong khi người tiêu dùng giữ chế độ xem.
Điều này làm cho các khe đệm trở thành một phần của cả mô hình đối tượng và mô hình thời gian tồn tại của bộ nhớ.
## 12.21 Khe thu gom rác
Các loại vùng chứa nhận biết GC cần hỗ trợ truyền tải và xóa.
Các vị trí liên quan:```text
tp_traverse
tp_clear
tp_traversecác báo cáo chứa các tham chiếu Python tới bộ sưu tập.```c
static int
Box_traverse(BoxObject *self, visitproc visit, void *arg)
{
Py_VISIT(self->value);
return 0;
}
`tp_clear`ngắt chứa các tham chiếu trong quá trình thu thập theo chu kỳ.```c
static int
Box_clear(BoxObject *self)
{
Py_CLEAR(self->value);
return 0;
}
```Nếu một loại có thể tham gia vào các chu trình và không thực hiện đúng các chu trình này, nó có thể rò rỉ các chu trình không thể truy cập được.
## 12.22 Bảng thành viên
Một số trường mở rộng C có thể được hiển thị thông qua các định nghĩa thành viên.
Mẫu khái niệm:```c
static PyMemberDef Point_members[] = {
{"x", T_LONG, offsetof(PointObject, x), 0, "x coordinate"},
{"y", T_LONG, offsetof(PointObject, y), 0, "y coordinate"},
{NULL}
};
```Đối tượng loại trỏ đến bảng này.```c
.tp_members = Point_members
```Điều này cho phép CPython hiển thị các trường cấu trúc C dưới dạng thuộc tính Python.
Bảng thành viên rất hữu ích cho các trường C đơn giản. Các thuộc tính phức tạp hơn thường sử dụng bộ mô tả getset.
## 12.23 Bảng Getset
Bảng Getset hiển thị các thuộc tính được tính toán.
Mẫu khái niệm:```c
static PyObject *
Point_get_norm(PointObject *self, void *closure)
{
double norm = sqrt(self->x * self->x + self->y * self->y);
return PyFloat_FromDouble(norm);
}
static PyGetSetDef Point_getset[] = {
{"norm", (getter)Point_get_norm, NULL, "vector norm", NULL},
{NULL}
};
```Đối tượng loại trỏ đến bảng getset:```c
.tp_getset = Point_getset
```Mục getset hoạt động giống như một bộ mô tả.
Mã Python:```python
p.norm
```gọi getter.
## 12.24 Bảng phương thức
Các phương thức mở rộng C được hiển thị thông qua các bảng phương thức.
Mẫu khái niệm:```c
static PyObject *
Counter_inc(CounterObject *self, PyObject *Py_UNUSED(ignored))
{
self->value += 1;
return PyLong_FromLong(self->value);
}
static PyMethodDef Counter_methods[] = {
{"inc", (PyCFunction)Counter_inc, METH_NOARGS, "increment counter"},
{NULL}
};
```Đối tượng kiểu trỏ đến bảng phương thức:```c
.tp_methods = Counter_methods
```Mã Python:```python
counter.inc()
```sử dụng bộ mô tả và máy gọi phương thức để gọi hàm C.
## 12.25 Các loại heap và các loại tĩnh
CPython có loại tĩnh và loại heap.
Các kiểu tĩnh được định nghĩa là cấu trúc toàn cầu C. Nhiều kiểu tích hợp trong lịch sử sử dụng các đối tượng kiểu tĩnh.
Các loại heap được phân bổ động trong thời gian chạy. Các lớp Python do người dùng định nghĩa là các loại heap.
So sánh:
| Loại loại | Phân bổ | Sử dụng điển hình |
| ----------- | ------------------ | --------------------------------------------- |
| Loại tĩnh | Lưu trữ tĩnh C | Các loại tích hợp và được xác định bằng tiện ích mở rộng |
| Loại đống | Phân bổ thời gian chạy | Lớp Python, nhiều kiểu mở rộng hiện đại |
Các loại heap linh hoạt hơn. Chúng hỗ trợ hành vi lớp thông thường như thuộc tính động, siêu dữ liệu phân lớp và vòng đời được quản lý theo thời gian chạy.
Mã mở rộng hiện đại thường thích các loại heap thông qua các khe định nghĩa mô-đun và`PyType_FromSpec`.
## 12,26`PyType_FromSpec`
`PyType_FromSpec`tạo một đối tượng kiểu từ một đặc tả khai báo.
Khái niệm phác thảo:```c
static PyType_Slot Counter_slots[] = {
{Py_tp_dealloc, Counter_dealloc},
{Py_tp_methods, Counter_methods},
{0, NULL}
};
static PyType_Spec Counter_spec = {
.name = "example.Counter",
.basicsize = sizeof(CounterObject),
.itemsize = 0,
.flags = Py_TPFLAGS_DEFAULT,
.slots = Counter_slots,
};
```Sau đó:```c
PyObject *type = PyType_FromSpec(&Counter_spec);
```Phong cách này tránh việc khởi tạo trực tiếp một số lượng lớn`PyTypeObject`struct và hoạt động tốt hơn với nội bộ CPython đang phát triển.
## 12.27 Kế thừa vị trí
Các lớp con kế thừa hành vi từ các lớp cơ sở trừ khi chúng ghi đè lên nó.```python
class A:
def __len__(self):
return 10
class B(A):
pass
print(len(B()))
Bkế thừa hành vi độ dài từA.
Ở cấp độ C, tính sẵn sàng của loại sẽ lấp đầy các vị trí được kế thừa và tính toán siêu dữ liệu về bố cục loại và độ phân giải phương thức cuối cùng.
Kế thừa vị trí phải tôn trọng:```text base class layout method resolution order descriptor behavior special method lookup type flags GC support memory offsets
## 12.28 Tra cứu phương pháp đặc biệt
Tra cứu phương pháp đặc biệt thường bỏ qua việc tra cứu phiên bản thông thường.
Ví dụ:```python
class X:
pass
x = X()
x.__len__ = lambda: 3
len(x)
```Điều này vẫn làm tăng`TypeError`bởi vì`len(x)`tìm kiếm hành vi độ dài trên loại chứ không phải trong từ điển mẫu.
Chính xác:```python
class X:
def __len__(self):
return 3
x = X()
print(len(x))
```Quy tắc này cho phép CPython tối ưu hóa các hoạt động của giao thức và duy trì hành vi nhất quán cho cú pháp tích hợp.
## 12.29 Xung đột về bố cục
Nhiều kế thừa có thể tạo ra xung đột về bố cục.
Nếu hai lớp cơ sở yêu cầu bố cục phiên bản cấp C không tương thích thì CPython có thể từ chối lớp đó.
Hình dạng ví dụ:```text
BaseA requires C layout A
BaseB requires C layout B
Derived(BaseA, BaseB)
cannot combine both layouts safely
```Các lớp Python thuần túy thường linh hoạt vì trạng thái phiên bản của chúng dựa trên từ điển hoặc dựa trên vị trí.
Các loại tiện ích mở rộng C có yêu cầu bố cục chặt chẽ hơn.
Đây là một lý do khiến thiết kế kiểu mở rộng phải thận trọng về tính kế thừa trừ khi hành vi phân lớp con là cần thiết một cách rõ ràng.
## 12.30 Mô hình tinh thần
Sử dụng mô hình này khi đọc mã loại:```text
object memory stores state
type object describes layout and behavior
slots map Python operations to C functions
protocols are implemented through slot tables
attribute lookup uses descriptors and dictionaries
numeric, sequence, and mapping syntax dispatch through specialized slots
GC-aware objects must expose references through traversal slots
deallocation must release owned references and free memory
```Biểu thức Python thường là một đường dẫn xuyên qua các khe kiểu.```python
result = obj[key] + other
```Về mặt khái niệm:```text
load obj
dispatch subscription through mapping or sequence slot
load other
dispatch addition through number slots
store result
```## 12.31 Tóm tắt
Bố cục đối tượng xác định hình dạng bộ nhớ của đối tượng CPython. Các khe loại xác định những hoạt động mà đối tượng hỗ trợ.`PyObject`Và`PyVarObject`cung cấp các tiêu đề chung. Cấu trúc cụ thể thêm các trường dành riêng cho loại.`PyTypeObject`ghi lại kích thước, độ lệch, cờ, móc vòng đời, hành vi thuộc tính, vị trí giao thức, bảng phương thức, bảng thành viên, bảng getset và hỗ trợ thu gom rác.
Thiết kế này cho phép CPython kết hợp một biểu diễn đối tượng thống nhất với các triển khai có tính chuyên môn cao cho các loại tiện ích mở rộng và tích hợp sẵn.