我有一些奇怪的行为造成的错误.我可能从根本上缺少一些关于函数属性语义的东西.或者它可能是一个错误.我上线了
$ 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是未绑定的方法.但是我不确定这是否是预期的副作用,如果我误解了某些东西,或者是否存在错误.
你应该做 :
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只有当传递的属性是对象命名空间的一部分(不是他的类既不是他的父类)时才会成功,因为安全原因(你不想(尝试)删除对象的属性不是你:-).
您的问题不是函数属性,而是实例方法和函数之间的区别.尝试:
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中消失了,你正在尝试的将在实例方法上正常工作.有关详细信息,请参阅此邮件列表主题.