执行此操作时......
class A:
def b(self, a):
print a
print dir(b)
print dir(A.b)
它给出了结果:
['__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']
为什么会有所不同?
答案 0 :(得分:7)
在 Python 2 中,第二种情况返回一个未绑定的方法,第一种情况是一个函数。来自the documentation,强调我的:
当获取类的属性时(可能通过该类的实例),如果该属性是用户定义的函数对象,未绑定的用户,则可以创建用户定义的方法对象 - 定义的方法对象或类方法对象。当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象;否则,原始方法对象按原样使用。
所以你得到的方法完全是因为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__']
如果将dir
替换为id
,您将在Python 3中看到它与两种情况下完全相同的函数对象。