__setattr__
, если он существует, вызывается для каждого атрибута, установленного на объекте.
Ваш пример кода довольно смущает меня. Что вы пытаетесь сделать с заявлением:
setattr(super(Clazz, self), name, value)
??
Установить атрибут для себя, при этом self рассматривается как экземпляр его суперкласса? Это не имеет смысла, потому что объект все еще "я".
С другой стороны, попытка использовать setattr для объекта, возвращаемого вызовом super, всегда приведет к ошибке атрибута, независимо от того, существует атрибут в суперклассе или нет. Это связано с тем, что super возвращает не сам суперкласс, а объект-обертку, который будет извлекать туда атрибуты, когда они необходимы - так что вы можете использовать hasattr в объекте, возвращаемом super, но не 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)