有人可以解释方法属性上的Python hasattr/delattr吗?

Ian*_*Ian 3 python

我有一些奇怪的行为造成的错误.我可能从根本上缺少一些关于函数属性语义的东西.或者它可能是一个错误.我上线了

$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Run Code Online (Sandbox Code Playgroud)

首先,我定义一个类,并为其中一个方法添加一个属性.

>>> class Foo(object):
...    def bar(self):
...        pass
...    bar.xyzzy = 'magic'
...
Run Code Online (Sandbox Code Playgroud)

现在我可以看到它存在 Foo.bar

>>> hasattr(Foo.bar, 'xyzzy')
True
Run Code Online (Sandbox Code Playgroud)

我可以找回它.

>>> Foo.bar.xyzzy
'magic'

>>> getattr(Foo.bar, 'xyzzy')
'magic'
Run Code Online (Sandbox Code Playgroud)

但我不能删除它.

>>> del Foo.bar.xyzzy
Traceback (most recent call last):
   ...
AttributeError: 'instancemethod' object has no attribute 'xyzzy'

>>> delattr(Foo.bar, 'xyzzy')
Traceback (most recent call last):
   ...
AttributeError: 'instancemethod' object has no attribute 'xyzzy'
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?我认为这与在Foo.bar这里被报告为'instancemethod' 的事实有关,而不是如果你只是问什么Foo.bar是未绑定的方法.但是我不确定这是否是预期的副作用,如果我误解了某些东西,或者是否存在错误.

mou*_*uad 6

你应该做 :

del Foo.bar.im_func.xyzzy
Run Code Online (Sandbox Code Playgroud)

im_func需要访问真正的方法Foo.bar,将instancemethod是一种装饰的,与自动通过自我处理.......


正如我可能从你的问题了解你的同时,成功访问xyzzy的属性Foo.bar使用getattr和喜欢你碰到这样的事实delattr不采取行动,以同样的方式,而其原因是在内部getattr调用__getattribute__(和__getattr__)类和第一个参数中对象的所有父类,直到找到属性或引发一个属性AttributeError,相同的hasattr对应于:

def hasattr(obj, attr):
    try:
        getattr(obj, attr)
    except AttributeError:
        return False
    return True
Run Code Online (Sandbox Code Playgroud)

另一方面,delattr只有当传递的属性是对象命名空间的一部分(不是他的类既不是他的父类)时才会成功,因为安全原因(你不想(尝试)删除对象的属性不是你:-).


agf*_*agf 5

您的问题不是函数属性,而是实例方法和函数之间的区别.尝试:

class A(object):
    def foo(self):
        pass
    foo.bar = 'magic'

del A.__dict__['foo'].bar
Run Code Online (Sandbox Code Playgroud)

它会工作正常.这是因为在这里,您实际上是在获取函数对象foo,而不是实例方法foo.

这种区别在Python 3中消失了,你正在尝试的将在实例方法上正常工作.有关详细信息,请参阅此邮件列表主题.