我写了以下包装类。我想定义__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)
答案 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()
表示法可以用最小的模板代码将所有实例变量初始化分组在一个可见的块中高架。