关于非内置型。types.FunctionType
和 types.MethodType
表现为预期。
>>> isinstance(MyClass.func, FunctionType)
True
>>> isinstance(MyClass.func, MethodType)
False
>>> isinstance(MyClass().func, FunctionType)
False
>>> isinstance(MyClass().func, MethodType)
True
然而,在一个内置类型上, BuiltinFunctionType
和 BuiltinMethodType
不要有相应的行为。
>>> isinstance(list.append, (FunctionType, MethodType,
... BuiltinFunctionType, BuiltinMethodType))
False <- Why??
>>> isinstance([].append, (FunctionType, MethodType))
False
>>> isinstance([].append, BuiltinFunctionType)
True <- Why??
>>> isinstance([].append, BuiltinMethodType)
True
现在,这没有意义,对吧?谁能解释一下?
EDIT: isinstance(list.append, MethodDescriptorType) == True
. 谁能解释一下 MethodDescriptorType
不同于 BuiltinMethodType
为什么我们需要它?我们为什么需要它?公文 并不能说明什么。
BuiltinFunctionType
和 BuiltinMethodType
只是指向同一个对象的不同名称。
>>> BuiltinFunctionType is BuiltinMethodType
True
isinstance(list.append, BuiltinMethodType)
是假的,因为它不是一个方法(即一个绑定到某个对象的实例方法)。方法绑定是通过 object.__getattribute__
,所以用类定义的函数只是普通函数。
>>> def func(x): pass
...
>>> class MyClass: func = func
...
>>> MyClass.func is func
True
因此 isinstance(MyClass.func, FunctionType)
. 这样做的原因是所有的功能都是 非数据描述符:
>>> func.__get__
<method-wrapper '__get__' of function object at 0x7f80abe57400>
对于内建类型,这些对象(如 list.append
)也是专门的描述符,用来处理与其对象的绑定。所以 x = []; x.append
返回一个由描述符 list.append
并绑定到对象上 x
:
>>> type(list.append)
<class 'method_descriptor'>