设为首页 收藏本站
查看: 556|回复: 0

[经验分享] [Python源码学习]之PyObject和PyTypeObject

[复制链接]

尚未签到

发表于 2017-4-29 14:28:56 | 显示全部楼层 |阅读模式
Python C api中的绝大多数函数其参数和返回值中包含PyObject*。这指针类型指向一个可以表示任何Python对象的不透明的数据结构。所有的Python对象在多数情况下以相同的方式对待。
所有的Python对象(甚至是Python的整数)都包含一个类型和引用计数。一个对象的类型决定了其是一个整数、列表、用户自定义函数还是其他。
引用计数对Python非常重要,引用计数必须显式地操作(通过Py_INCREF()、 Py_DECREF()等)。
本文:




  • PyObject



  • PyVarObject



  • PyTypeObject



PyObject



Include/object.h 提供了比较详细的注释。




  • PyObject 本身几乎没有声明任何东西,但是每一个Python对象的指针都可以cast为PyObject* 。类似地,每一个大小不固定的Python对象指针可以cast为 PyVarObject* 。



  • PyObject_HEAD 定义了每一个PyObject都有的起始片段。

  • Python2.7和Python3.2中,尽管内容一样,但源码的写法上有点小小的不同:

Python2.7


#define PyObject_HEAD                   \
    Py_ssize_t ob_refcnt;               \
    struct _typeobject *ob_type;
typedef struct _object {
    PyObject_HEAD
} PyObject;

Python3.2


typedef struct _object {
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;
#define PyObject_HEAD PyObject ob_base;

PyObject 是有两个成员的结构体,引用计数、对象类型:


  • ob_refcnt
  • ob_type

其类型分别为 Py_ssize_t 和 struct _typeobject


Py_ssize_t



Py_ssize_t 是一个所占字节数与 size_t 相同的有符号的整数类型(C99中没有定义ssize_t这种类型,某些编译器比如gcc扩展有该类型)。关于该类型的一个介绍见PEP
353。
源码位于:Include/pyport.h


#ifdef HAVE_SSIZE_T
typedef ssize_t         Py_ssize_t;
#elif SIZEOF_VOID_P == SIZEOF_SIZE_T
typedef Py_intptr_t     Py_ssize_t;
#else
#   error "Python needs a typedef for Py_ssize_t in pyport.h."
#endif

其中,Py_intptr_t 是可以存放指针的整数类型(C99中定义有 intptr_t),在不支持intptr_t的环境下,它是int、long或long long的别名。


PyVarObject



可变大小的容器对象
与PyObject相比,它多了一个成员:


  • ob_refcnt
  • ob_type
  • ob_size

其中:ob_size 是元素的数目,而不是所需的字节的数目。
Python2.7

#define PyObject_VAR_HEAD               \
    PyObject_HEAD                       \
    Py_ssize_t ob_size; /* Number of items in variable part */

typedef struct {
    PyObject_VAR_HEAD
} PyVarObject;

Python3.2

typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;
#define PyObject_VAR_HEAD      PyVarObject ob_base;

3个宏用来获取这3个成员的值

#define Py_REFCNT(ob)           (((PyObject*)(ob))->ob_refcnt)
#define Py_TYPE(ob)             (((PyObject*)(ob))->ob_type)
#define Py_SIZE(ob)             (((PyVarObject*)(ob))->ob_size)


PyTypeObject



每一个PyObject第二个成员是都是一个类型对象(PyTypeObject)。PyTypeObject本身是也一个PyVarObject
额,这个东西太复杂了,一堆堆的函数指针,看不懂。

typedef struct _typeobject {
    PyObject_VAR_HEAD
    const char *tp_name; /* For printing, in format "<module>.<name>" */
    Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */

    /* Methods to implement standard operations */

    destructor tp_dealloc;
    printfunc tp_print;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    void *tp_reserved; /* formerly known as tp_compare */
    reprfunc tp_repr;
...
} PyTypeObject;



tp_name



类型的字符串名,比如"str" "int" ...




tp_basicsize



tp_basesize + tp_tiemsize * ob_size




tp_itemsize




tp_doc



文档字符串





创建与析构?



tp_alloc




tp_new




tp_init




tp_del




tp_free




tp_dealloc





C API函数和这些函数指针的对应关系(调用关系):



C API函数



PyTypeObject

中的函数指针




Python表达式




PyObject_Print(PyObject*,FILE*,int)



tp_print

tp_str

tp_repr





PyObject_Repr(PyObject*)



tp_repr



repr(o)




PyObject_Str(PyObject*v)



tp_str



str(o)




PyObject_Hash(PyObject*)



tp_hash



hash(o)




PyObject_GetAttr(PyObject*,PyObject*)



tp_getattr

tp_getattro



o.attr_name




PyObject_CallMethod(PyObject*,char*,...)



tp_call



o.method(...)




...








参考






  • http://docs.python.org/py3k/c-api/object.html



  • http://docs.python.org/py3k/c-api/intro.html#objects-types-and-reference-counts



  • http://docs.python.org/py3k/c-api/structures.html



  • http://docs.python.org/py3k/c-api/typeobj.html


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-370881-1-1.html 上篇帖子: How to become a proficient Python Programmer 下篇帖子: 五Python对象和面向对象(二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表