回到PyLong_Type的定义,第一行 PyVarObject_HEAD_INIT(PyType_Type, 0),查看对应的宏定义
由以上关系可以知道,PyVarObject_HEAD_INIT(PyType_Type, 0)={ { _PyObject_EXTRA_INIT 1, PyType_Type } 0} , 将其代入 PyObject_VAR_HEAD,得到一个变长对象:
这样看就很明确了,PyLong_Type的类型就是PyType_Typ,同理可知,Python类型对象的类型就是PyType_Type ,而 PyType_Type对象的类型是它本身
从上述内容中,我们知道了对象和对象类型的定义,那么根据定义,对象可以有以下两种分类
Python对象定义有 PyObject 和 PyVarObject , 因此,根据对象大小是否可变的区别,Python对象可以划分为 可变对象(变长对象) 和 不可变对象(定长对象)
原本的对象a大小并没有改变,只是s引用的对象改变了 。这里的对象a、对象b就是定长对象
可以看到,变量l仍然指向对象a,只是对象a的内容发生了改变,数据量变大了 。这里的对象a就是变长对象
由于存在以上特性,所以使用这两种对象还会带来一种区别:
声明 s2 = s ,修改s的值: s = 'new string',s2的值不会一起改变 , 因为只是s指向了一个新的对象 , s2指向的旧对象的值并没有发生改变
声明 l2 = l,修改l的值: l.append(6),此时l2的值会一起改变,因为l和l2指向的是同一个对象,而该对象的内容被l修改了
此外,对于 字符串 对象,Python还有一套内存复用机制,如果两个字符串变量值相同,那它们将共用同一个对象:
对于 数值型 对象,Python会默认创建0~2 8以内的整数对象,也就是 0 ~ 256 之间的数值对象是共用的:
按照Python数据类型,对象可分为以下几类:
Python创建对象有两种方式 , 泛型API和和类型相关的API
这类API通常以 PyObject_xxx 的形式命名,可以应用在任意Python对象上,如:
使用 PyObjecg_New 创建一个数值型对象:
这类API通常只能作用于一种类型的对象上,如:
使用 PyLong_FromLong 创建一个数值型对象:
在我们使用Python声明变量的时候,并不需要为变量指派类型,在给变量赋值的时候,可以赋值任意类型数据 , 如:
从Python对象的定义我们已经可以知晓造成这个特点的原因了,Python创建对象时,会分配内存进行初始化 , 然后Python内部通过 PyObject* 变量来维护这个对象,所以在Python内部各函数直接传递的都是一种泛型指针 PyObject*,这个指针所指向的对象类型是不固定的,只能通过所指对象的 ob_type 属性动态进行判断 , 而Python正是通过 ob_type 实现了多态机制
Python在管理维护对象时 , 通过引用计数来判断内存中的对象是否需要被销毁,Python中所有事物都是对象,所有对象都有引用计数 ob_refcnt。
当一个对象的引用计数减少到0之后,Python将会释放该对象所占用的内存和系统资源 。
但这并不意味着最终一定会释放内存空间,因为频繁申请释放内存会大大降低Python的执行效率,因此Python中采用了内存对象池的技术,是的对象释放的空间会还给内存池,而不是直接释放,后续需要申请空间时 , 优先从内存对象池中获取 。
python实现泛型函数的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、python实现泛型函数的信息别忘了在本站进行查找喔 。
推荐阅读
- 谈恋爱应该怎样打游戏呢,怎么玩恋爱游戏
- 包含抖音视频号入口怎么开通的词条
- 电商平台开发如何收费,开电商平台需要多少资金
- 网站制作系统b超,bc网站制作
- c语言中的函数换行 c语言换行符是什么意思
- 什么路由器比腾达好一点,路由器腾达的好吗
- 怎么制作手机上的彩蛋,怎样制作彩蛋
- 直播话术坐垫,在直播中如何介绍椅子这款产品
- c语言产生非线性函数图像 c语言定义线性函数