IT@程序员猿媛程序员

Python类型对象举例

2019-04-01  本文已影响0人  ringawho

查看之前的PyObject以及PyVarObject结构,我们会发觉它十分简单,甚至简单的不像话,可能我们会想明明在Python中学的是基类是object,有着各种各样的属性

['__class__', '__delattr__', '__dir__', ...... ,'__setattr__', '__sizeof__', '__str__']

但是在PyObject中却什么都看不到,其实是有的,只不过是放在了ob_type里面,它是struct _typeobject指针,也就是PyTypeObject指针,我们来看一下Python中的object所对应的ob_type

Objects/typeobject.c
// 只列出一部分,剩余部分还涉及其它东西,没有看呢
PyTypeObject PyBaseObject_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "object",                                   /* tp_name */
    object_repr,                                /* tp_repr */
    object_str,                                 /* tp_str */
    PyDoc_STR("object()\n--\n\nThe most base type"),  /* tp_doc */
    ......
};

它的里面包含了各种各样的信息,比如类的名字,对象占用空间的大小,转换为string的方法,都在它里面,

>>> type(object())
<class 'oo'>
static PyObject *  object_str(PyObject *self)
{
    unaryfunc f;

    f = Py_TYPE(self)->tp_repr;
    if (f == NULL)
        f = object_repr;
    return f(self);
}
static PyObject *  object_repr(PyObject *self)
{
    PyTypeObject *type;
    PyObject *mod, *name, *rtn;
    // ......
    if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins))
        rtn = PyUnicode_FromFormat("<%U.%U object at %p>", mod, name, self);
    else
        rtn = PyUnicode_FromFormat("<%s object at %p>",
                                  type->tp_name, self);
    // ......
    return rtn;
}

此时对比一下使用str()时的结果,就可以看出它算是怎么做出rtn

>>> str(object())
'<object object at 0x00000239682FB0D0>'

人为的在return语句之前自己写一条,就可以出现自己想要的输出了,例如:

//else语句修改为
rtn = PyUnicode_FromFormat("<%s object at ???>", "MyObject");
// 输出
>>> str(object())
'<MyObject object at ???>'
const char *old_doc = _PyType_DocWithoutSignature(type->tp_name,
                type->tp_doc);

小小的修改一下,虽然改的东西是最浅显的,但是至少可以知道自己读对了,同时也减少Python解释器源码的神秘感,给自己点信心喽!

上一篇下一篇

猜你喜欢

热点阅读