__setattr__仅适用于在对象的属性中找不到的名称?

时间:2012-02-03 18:12:29

标签: python getattr setattr

我只想在对象的属性中找不到属性时使用__setattr__,例如__getattr__

我真的必须使用 try-except 吗?

def __setattr__(self, name, value):
    try:
        setattr(super(Clazz, self), name, value)
    except AttributeError:
        # implement *my* __setattr__
        pass

3 个答案:

答案 0 :(得分:3)

您可以使用hasattr()

def __setattr__(self, name, value):
    if hasattr(super(Clazz, self), name):
        setattr(super(Clazz, self), name, value)
    else:
        # implement *my* __setattr__
        pass

答案 1 :(得分:0)

__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)

答案 2 :(得分:0)

有很多次调用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