购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1.1 PyLongObject对象

Python中对整数这个概念的实现是通过PyLongObject对象来完成的。

第0章讲解了定长对象和变长对象的区别,这是一种关于对象的二分法。实际上还存在另一种关于对象的二分法,即根据对象维护数据时的可变性将对象分为可变对象(Mutable)和不可变对象(Immutable)。

这里将要剖析的PyLongObject对象是一个不可变对象,这种不变性是针对PyLong-Object对象中所维护的真实的整数值而言的。也就是说,在创建了PyLongObject对象之后,就再也不能改变该对象的值了。在Python中,除PyLongObject之外,还有很多对象是不可变对象,比如字符串对象等。

在Python的应用程序中,整数的使用非常广泛,创建和删除操作非常频繁,并且结合了引用计数机制,这意味着系统堆将面临着整数对象大量的访问,这样的执行效率可以接受吗?因此设计一个高效的运行时机制,使得整数对象的使用不会成为Python的瓶颈,就成了一个至关重要的设计决策。

整数对象池是解决这个问题的一个非常好的办法。面向特定对象的缓冲池机制是Python语言实现时的核心设计策略之一。在Python中,几乎所有的内置对象都会有自己所特有的对象缓冲池机制。

PyLongObject对象的源码位置为Include/longobject.h及Include/longintrepr.h。

实际上,Python中的整数对象PyLongObject是对C中原生类型long的简单包装。Python中的对象与对象相关的元信息都保存在与对象对应的类型对象中。PyLongObject的类型对象是PyLong_Type。

PyLong_Type的源码位置为Objects/longobject.c,源码如下:


PyTypeObject PyLong_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "int",                                      /* tp_name */
    offsetof(PyLongObject, ob_digit),           /* tp_basicsize */
    sizeof(digit),                              /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    long_to_decimal_string,                     /* tp_repr */
    &long_as_number,                            /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc)long_hash,                        /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
        Py_TPFLAGS_LONG_SUBCLASS,               /* tp_flags */
    long_doc,                                   /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    long_richcompare,                           /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    long_methods,                               /* tp_methods */
    0,                                          /* tp_members */
    long_getset,                                /* 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 */
    long_new,                                   /* tp_new */
    PyObject_Del,                               /* tp_free */
};

PyLong_Type中保存了关于PyLongObject对象的丰富元信息,包括PyLongObject对象应该占用的内存大小,PyLongObject对象的文档信息,PyLongObject对象所支持的操作。

从PyLong_Type的源码中可以看到,创建整数对象的入口函数为long_new。该入口函数的源码位置为Objects/clinic/longobject.c.h。具体实现函数为long_new_impl,源码位置为Objects/longobject.c。 VhE6ct/J61PgrkG7+U17s7CXSlUcj6or1vYyZrHJi4CIfV4EWauxPMSA096aZOqF

点击中间区域
呼出菜单
上一章
目录
下一章
×