我只想__setattr__
在对象的属性中找不到该属性时使用,例如__getattr__
.
我真的必须使用try-except吗?
def __setattr__(self, name, value):
try:
setattr(super(Clazz, self), name, value)
except AttributeError:
# implement *my* __setattr__
pass
您可以使用hasattr()
:
def __setattr__(self, name, value):
if hasattr(super(Clazz, self), name):
setattr(super(Clazz, self), name, value)
else:
# implement *my* __setattr__
pass
__setattr__
,如果存在,则为对象上设置的每个属性调用。
但是,您的示例代码对我来说相当混乱。你想对声明做什么:
setattr(super(Clazz, self), name, value)
??
在 self 上设置一个属性,将 self 视为其超类的一个实例?这是没有意义的,因为对象仍然是“自我”。
另一方面,尝试在调用“super”返回的对象上使用“setattr”总是会产生属性错误,无论该属性是否存在于超类中。那是因为 super 返回的不是超类本身,而是一个包装器对象,它会在需要时从那里获取属性 - 因此您可以在 super 返回的对象中使用“hasattr”,但不能使用 setattr。我以为它会这样,只是在控制台上尝试了一下:
>>> class A(object):pass
...
>>> class B(A): pass
...
>>> b = B()
>>> super(B,b)
<super: <class 'B'>, <B object>>
>>> setattr(super(B,b), "a", 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'a'
>>> A.a = 1
>>> setattr(super(B,b), "a", 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'a'
但是,您可以在对象本身中使用“hasattr”,然后像这样进行:
def __setattr__(self, attr, value):
if hasattr(self, value):
#this works because retrieving "__setattr__" from the
# result of the supercall gives the correct "__setattr__" of the superclass.
super(Clazz, self).__setattr__(self, attr, value)
else:
# transform value /or attribute as desired in your code
super(Clazz, self).__setattr__(self, attr, value)
很多时候调用hasattr
不会按您期望的方式工作(例如,您已被覆盖__getattr__
以始终返回一个值),因此在正确的位置设置正确属性的另一种方法是这样的:
def __setattr__(self, k, v):
if k in self.__dict__ or k in self.__class__.__dict__:
super(Clazz, self).__setattr__(k, v)
else:
# implement *my* __setattr__
pass