执行此操作时......
class A:
def b(self, a):
print a
print dir(b)
print dir(A.b)
Run Code Online (Sandbox Code Playgroud)
它给出了结果:
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure',
'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self']
Run Code Online (Sandbox Code Playgroud)
为什么这个不同?
在Python 2中,第二种情况返回一个未绑定的方法,第一种情况是一个函数.从文档中,重点是我的:
用户定义的方法的对象可以被得到一个类的一个属性时创建(可能通过那个类的一个实例),如果该属性是一个用户定义的功能对象,未结合的用户定义的方法的对象,或一个类方法的对象.当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象; 否则,原始方法对象按原样使用.
所以你得到一个纯粹因为A.前缀的方法.原始函数仍然可以通过方法的im_func(或从2.6开始__func__)属性访问.另请注意,每次访问都会获得一个新方法对象,因此A.b is A.b返回False!
在Python 3中,未绑定的方法不再作为单独的类型存在,并且您将从两个打印调用获得相同的输出:
$ python3
Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... def b(self, a):
... print(a)
... print(dir(b))
...
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> print(dir(A.b))
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Run Code Online (Sandbox Code Playgroud)
如果你替换dir,id你会发现它在两种情况下都是完全相同的函数对象,在Python 3中.