内置类型和用户定义的不一致

Aug*_*ack 5 python types

在阅读关于类型统一的内容时,我偶然发现内置类型有method_descriptors和builtin_function_or_methods而不是methods和functions,为什么呢?

>>> list.append
<method 'append' of 'list' objects>
>>> type(list.append)
<class 'method_descriptor'>
>>> [].append
<built-in method append of list object at 0x7f0c4214aef0>
>>> type([].append)
<class 'builtin_function_or_method'>
>>> class A(list):
...   def append(self): pass
... 
>>> A.append
<function A.append at 0x7f0c42168dd0>
>>> type(A.append)
<class 'function'>
>>> A().append
<bound method A.append of []>
>>> type(A().append)
<class 'method'>
Run Code Online (Sandbox Code Playgroud)

没有充分的理由class A将子列表子类化,我只是想表明类型不同.

alk*_*lko 4

区别在于,内置函数是 C 编译的代码描述符,而用户定义的函数表示解释的代码描述符。查看来源详情请

此外,虽然内置函数及其方法是静态分配的数据结构,但用户定义的数据结构的内存是动态分配的。甚至大小也不同:内置函数以及类似的用户定义函数之间的描述符大小是相等的,请参阅 C 源代码(上面的链接):

>>> sys.getsizeof(list.append)
72   # built-in
>>> sys.getsizeof(dir)
72   # built-in
>>> sys.getsizeof(A.__init__)
80   # class/instance method
>>> sys.getsizeof(lambda x: x)
120  # static function
Run Code Online (Sandbox Code Playgroud)

所以这些东西看起来不同,驻留在不同的地方,行为也不同。没有必要给它们起相同的名字。

我想添加错过编译的类似物classmethod, classmethod_descriptor,

>>> type(float.__dict__['fromhex'])
<type 'classmethod_descriptor'>
Run Code Online (Sandbox Code Playgroud)

以及其他一些有趣的类型:

>>> type(A.__init__)
<type 'wrapper_descriptor'>
>>> type(A.__dict__['__dict__'])
<type 'getset_descriptor'>
Run Code Online (Sandbox Code Playgroud)

看:

  1. 什么是wrapper_descriptor,为什么Foo.__init__在这种情况下是一个
  2. __dict__.__dict__Python 类的属性是什么?