清除方法以在初始化之后禁用`__setattr__`

时间:2012-10-21 14:52:41

标签: python python-3.x setattr

我写了以下包装类。我想定义__setattr__,以便将所有属性重定向到包装类。但是,这阻止我初始化包装类。有什么优雅的方法来解决这个问题吗?

class Wrapper:
    def __init__(self, value):
        # How to use the default '__setattr__' inside '__init__'?
        self.value = value

    def __setattr__(self, name, value):
        setattr(self.value, name, value)

4 个答案:

答案 0 :(得分:14)

您正在捕获所有分配,这会阻止构造函数分配self.value。您可以使用self.__dict__来访问实例字典。尝试:

class Wrapper:
    def __init__(self, value):
        self.__dict__['value'] = value

    def __setattr__(self, name, value):
        setattr(self.value, name, value)

使用object.__setattr__的另一种方式:

class Wrapper(object):
    def __init__(self, value):
        object.__setattr__(self, 'value', value)

    def __setattr__(self, name, value):
        setattr(self.value, name, value)

答案 1 :(得分:7)

在初始化之后禁用__setattr__而不更改self.value = value方法中的__init__语法的方法[{3}}。简而言之,在对象中嵌入初始化知识并在__setattr__方法中使用它。对于Wrapper

class Wrapper:
    __initialized = False
    def __init__(self, value):
        self.value = value
        self.__initialized = True

    def __setattr__(self, name, value):
        if self.__initialized:
            # your __setattr__ implementation here
        else:
            object.__setattr__(self, name, value)

答案 2 :(得分:0)

同时覆盖__getattr__ ::

class Wrapper:
    def __init__(self,wrapped):
        self.__dict__['wrapped'] = wrapped
    def __setattr__(self,name,value):
        setattr(self.__dict__['wrapped'],name,value)
    def __getattr__(self,name):
        return getattr(self.__dict__['wrapped'],name)


class A:
    def __init__(self,a):
        self.a = a

wa = Wrapper(A(3))
#wa.a == wa.wrapped.a == 3

答案 3 :(得分:0)

如其他答案中所建议,一个想法是直接访问对象字典以绕过setattr分辨率。

为便于阅读,我建议以下内容:

  def __init__(self,wrapped1, wrapped2):
       vars(self).update(dict(
          _wrapped1=wrapped1,
          _wrapped2=wrapped2,
        ))

使用vars是可选的,但我发现它比直接访问self.__dict__更好,并且内联dict()表示法可以用最小的模板代码将所有实例变量初始化分组在一个可见的块中高架。