PyObject, PyTypeObject - Python 中的 '对象' 们


1 PyObject, PyTypeObject - Python 中的 ‘对象‘ 们
  2
  3     ‘一切皆对象‘ - 这是 Python 的学习和使用者们最最常听到一句, 可谓 博大精深 - ‘勃大精深‘.
  4     ‘对象(Object)‘ 是 Python 最核心的一个概念, 在 Python 中 ‘一切皆是对象‘.
  5     整数,字符串,类型type(整数类型, 字符串类型)统统都是‘对象‘.
  6
  7     Python 已经预先定义了一些‘类型对象‘, 如 int 类型, dict 类型, string 类型等等,
  8     这些预先定义的类型对象被称为‘内建类型对象‘. ‘类型对象‘ 实现了面向对象理论中‘类‘的概念,
  9     通过对类型对象的 ‘实例化‘ 创建‘实例对象‘, 如 int 对象, dict 对象, string 对象等.
 10     ‘实例对象‘可以被视为面向对象理论中‘对象‘这个概念在 python 中的体现.
 11     另外, python 实现了通过 class A(object) 关键字实现自定义类型对象, 通过调用自定义的类型对象实例化类型对象 A().
 12         注: python ‘类型‘(type) -> ‘类‘(class) ; python ‘实例‘(instance) -> ‘对象‘(object)
 13
 14     怎样理解 ‘对象‘(object) 的概念
 15         ‘对象’ 这一概念对人的思维是一个比较形象的概念, 然后计算机不能像人的思维一样去‘理解‘对象这一概念.
 16         计算机并不能理解 3 是一个整数, 而 ‘3‘ 是一个字符串, 对于它来说这些都是‘字节‘(byte).
 17         通常, ‘对象‘ 是数据以及基于这些数据的操作的集合. 对于计算机来说, 一个 ‘对象‘ 实际上就是一片被分配的内存空间,
 18         这些内存可以是连续的, 也可以是离散的. 这片内存在更高的层面上被作为一个‘整体‘来考虑和处理, 这个整体就是一个‘对象‘(对计算机来说)
 19         而在这片内存中存储着一系列的数据以及可以对这些数据进行操作(修改,读取,运行等)的代码(字节码).
 20
 21     如大家所知道的那样, Python 是有 C 实现的, 那么‘对象‘ 在 C 层面是什么样子呢?
 22         PyObject 对象
 23             Python 中, ‘对象‘ 就是为 C 中的结构体(structure)在栈堆上申请的一块儿内存区域.
 24                 object.h (Python 3.6)
 25                     typedef struct _object {
 26                         _PyObject_HEAD_EXTRA
 27                         Py_ssize_t ob_refcnt;              # ob_refcnt 引用计数(垃圾回收机制)
 28                         struct _typeobject *ob_type;       # ob_type 是一个指向 _typeobject 结构体的指针
 29                     } PyObject;
 30             在 C 中定义 PyObject 结构体中 ob_refcnt 与 Python 内存管理机制有关, 它实现了基于 ‘引用计数‘ 的 ‘垃圾回收机制‘.
 31             对于某一特定对象 A, 当有另一个 PyObject ‘引用‘ 了该对象的时候, A 的‘引用计数‘( ob_refcnt ) 增加;
 32             相反地, 如果 当这个 PyObject 被销毁的时候, 对象 A 的‘引用计数‘( ob_refcnt ) 减少.
 33             当对象 A 的‘引用计数‘( ob_refcnt ) 减少到 0 的时候, Python 的垃圾回收机制将把对象 A 从栈堆中删除, 以便释放内存供其他对象使用.
 34             除 ‘引用计数‘( ob_refcnt ) 之外, ob_type 是一个指向 _typeobject 结构体的指针.
 35             这个结构体对应着 Python 内部的一种特殊对象, 用来指定一个‘对象‘ 类型的 ‘类型对象‘, 如 对象 5 的类型对象 是 int 类型对象.
 36             结论, 在 Python 中, 对象机制的核心, 一是 ‘引用计数‘( ob_refcnt ), 另一个是 ‘类型信息‘(ob_type).
 37             通过‘类型信息‘(ob_type) 进一步对应到 一个对象的‘内容‘,‘大小‘ 等信息.
 38
 39         PyTypeObject 类型信息
 40             PyObject 中包括了所有‘对象‘ 共有的信息的定义(ob_refcnt, ob_type).
 41             在结构体 _typeobject 中, 主要定义了 4 类信息,
 42                 1, 类型名(tp_name), 主要供 Python 内部, 以及调试使用.
 43                 2, 创建该类型‘对象‘ 时分配的内存空间相关信息, 即 tp_basicsize, tp_itemsize
 44                 3, 与该类型‘对象‘相关联的操作信息, 如 tp_print; tp_getattr; tp_setattr 这些函数指针
 45                 4, 该类型对象的‘类型信息‘ (通过 PyType_Type 来确定一个对象的 ‘类型对象‘)
 46
 47                 object.h (Python 3.6)
 48                     typedef struct _typeobject {
 49                         PyObject_VAR_HEAD
 50                         const char *tp_name; /* For printing, in format "<module>.<name>" */
 51                         Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
 52
 53                         /* Methods to implement standard operations */
 54                         destructor tp_dealloc;
 55                         printfunc tp_print;
 56                         getattrfunc tp_getattr;
 57                         setattrfunc tp_setattr;
 58                         PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
 59                                                         or tp_reserved (Python 3) */
 60                         reprfunc tp_repr;
 61
 62                         /* Method suites for standard classes */
 63                         PyNumberMethods *tp_as_number;
 64                         PySequenceMethods *tp_as_sequence;
 65                         PyMappingMethods *tp_as_mapping;
 66
 67                         /* More standard operations (here for binary compatibility) */
 68                         hashfunc tp_hash;
 69                         ternaryfunc tp_call;
 70                         reprfunc tp_str;
 71                         getattrofunc tp_getattro;
 72                         setattrofunc tp_setattro;
 73
 74                         /* Functions to access object as input/output buffer */
 75                         PyBufferProcs *tp_as_buffer;
 76
 77                         /* Flags to define presence of optional/expanded features */
 78                         unsigned long tp_flags;
 79
 80                         const char *tp_doc; /* Documentation string */
 81
 82                         /* Assigned meaning in release 2.0 */
 83                         /* call function for all accessible objects */
 84                         traverseproc tp_traverse;
 85
 86                         /* delete references to contained objects */
 87                         inquiry tp_clear;
 88
 89                         /* Assigned meaning in release 2.1 */
 90                         /* rich comparisons */
 91                         richcmpfunc tp_richcompare;
 92
 93                         /* weak reference enabler */
 94                         Py_ssize_t tp_weaklistoffset;
 95
 96                         /* Iterators */
 97                         getiterfunc tp_iter;
 98                         iternextfunc tp_iternext;
 99
100                         /* Attribute descriptor and subclassing stuff */
101                         struct PyMethodDef *tp_methods;
102                         struct PyMemberDef *tp_members;
103                         struct PyGetSetDef *tp_getset;
104                         struct _typeobject *tp_base;
105                         PyObject *tp_dict;
106                         descrgetfunc tp_descr_get;
107                         descrsetfunc tp_descr_set;
108                         Py_ssize_t tp_dictoffset;
109                         initproc tp_init;
110                         allocfunc tp_alloc;
111                         newfunc tp_new;
112                         freefunc tp_free; /* Low-level free-memory routine */
113                         inquiry tp_is_gc; /* For PyObject_IS_GC */
114                         PyObject *tp_bases;
115                         PyObject *tp_mro; /* method resolution order */
116                         PyObject *tp_cache;
117                         PyObject *tp_subclasses;
118                         PyObject *tp_weaklist;
119                         destructor tp_del;
120
121                         /* Type attribute cache version tag. Added in version 2.6 */
122                         unsigned int tp_version_tag;
123
124                         destructor tp_finalize;
125
126                     #ifdef COUNT_ALLOCS
127                         /* these must be last and never explicitly initialized */
128                         Py_ssize_t tp_allocs;
129                         Py_ssize_t tp_frees;
130                         Py_ssize_t tp_maxalloc;
131                         struct _typeobject *tp_prev;
132                         struct _typeobject *tp_next;
133                     #endif
134                     } PyTypeObject;

PyObject, PyTypeObject - Python 中的 '对象' 们

时间: 2024-10-24 17:35:21

PyObject, PyTypeObject - Python 中的 '对象' 们的相关文章

zg手册 之 python2.7.7源码分析(1)-- python中的对象

源代码主要目录结构 Demo: python 的示例程序 Doc: 文档 Grammar: 用BNF的语法定义了Python的全部语法,提供给解析器使用 Include: 头文件,在用c/c++编写扩展模块时使用 Lib: Python自带的标准库,用python编写的 Modules: 用c编写的内建模块的实现,zlib,md5 等 Objects: 内建对象类型的实现 list,dict 等 PC:      windows 平台相关文件 PCbuild: Microsoft Visual

使用C语言为python编写动态模块(1)--从底层深度解析python中的对象以及变量

楔子 我们知道可以通过使用C语言编写动态链接库的方式来给python加速,但是方式是通过ctypes来加载,通过类CDLL将动态链接库加载进来得到一个对象之后,通过这个对象来调用动态链接库里面的函数.那么问题来了,我们可不可以使用C语言为python编写模块呢?然后在使用的时候不使用ctypes加载动态库的方式,而是通过python的关键字import进行加载. 答案是可以的,我们知道可以通过编写py文件的方式来得到一个模块,那么也可以使用C语言来编写C源文件,然后再通过python解释器进行编

使用C语言为python编写动态模块(2)--解析python中的对象如何在C语言中传递并返回

楔子 编写扩展模块,需要有python源码层面的知识,我们之前介绍了python中的对象.但是对于编写扩展模块来讲还远远不够,因为里面还需要有python中模块的知识,比如:如何创建一个模块.如何初始化python环境等等.因此我们还需要了解一些前奏的知识,如果你的python基础比较好的话,那么我相信你一定能看懂,当然我们一开始只是介绍一个大概,至于细节方面我们会在真正编写扩展模块的时候会说. 关于使用C为python编写扩展模块,我前面还有一篇博客,强烈建议先去看那篇博客,对你了解Pytho

python中生成器对象和return 还有循环的区别

python中生成器对象和return 还有循环的区别 在python中存在这么一个关键字yield,这个关键字在项目中经常被用到,比如我写一个函数不想它只返回一次就结束那我们就不能用return,因为return后面就不能跟任何东西,意味着函数的结束.那么我们完全可以这么做: def main(): for i in range(1,100): yield i 这样就等于生成了一个循环返回对象,特别在爬虫scrapy中较为常见!yeild和return还有for 上本质有什么区别呢?其实很简单

python进阶四(类的继承)【4-5 python中获取对象信息】

python中获取对象信息 拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢? 例如,已有定义: 1 class Person(object): 2 def __init__(self, name, gender): 3 self.name = name 4 self.gender = gender 5 6 class Student(Person): 7 def __init__(self, name, gender, score

python中的对象拷贝

python中无论参数传递还是函数返回值,都是进行引用传递.那如何拷贝对象呢,标准库的copy模块提供了两个方法:copy和deepcopy方法. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 见下例: import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 e = a[:] #利用分片操作进行拷贝(浅拷贝) b = a <span style="white-

python中的对象

在python中一切都是对象,每个对象都有三个属性分别是,(id)身份,就是在内存中的地址,类型(type),是int.字符.字典(dic).列表(list)等,值, 例如: a = 12 就是用12这个类型为整数的,值为12,在内存空间中创建了一个空间(这个空间会用一个地址来表示,就是id),当对象被创建后,如果该对象的 值可以被更改,那么就称之为可变对象(mutable),如果值不可更改,就称之为不可变对象(inmutable),如果某个对象包含对其他的对象的引用的话,就称之 为容器或者集合

Python中的对象的拷贝赋值操作

Python中的赋值也分传值与传地址. 用=时,传的是地址,当两者绑定到一起,其中一个发生改变时,另一个也会改变. 如: x = [1, 2, 3, 4] y = x y[0] = 5 print(x) 这时候的结果显示的是 [5, 2, 3, 4] 若要仅仅传值,则要用copy函数. x = [1, 2, 3, 4] y = x.copy() y[0] = 5 print(x) 这时候的结果就显示的是 [1, 2, 3, 4],即x的值没有改变.

Python中的对象行为与特殊方法(一)对象的创建与销毁

Python中类调用__new__()类方法来创建实例,调用__init__()方法来初始化对象,对象的销毁则调用__del__()方法. __new__()方法第一个参数为类cls,通常返回cls的一个实例,然后新实例的__init__()方法将以类似于__init__(self[, ...])的方式被调用,self是创建的新的实例,其它的参数和传递给__new__()的参数一样. 如果__new__()方法不返回cls 的实例,那么__init__()将不会被调用. 对于一个类来说: cla