size_t PyObject PyVarObject PyTypeObject

size_t 类型定义在cstddef头文件中,该文件是C标准库的头文件stddef.h的C++版。它是一个与机器相关的unsigned类型,其大小足以保证存储内存中对象的大小。   例如:bitset的size操作返回bitset对象中二进制位中的个数,返回值类型是size_t。   例如:在用下标访问元素时,vector使用vector::size_type作为下标类型,而数组下标的正确类型则是size_t。

 

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(...)

...

   

参考

原文链接: https://www.cnblogs.com/vicsmb/archive/2012/02/01/2334792.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    size_t PyObject PyVarObject PyTypeObject

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/40778

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 下午5:37
下一篇 2023年2月8日 下午5:38

相关推荐