Clean way to disable `__setattr__` until after initialization
You are catching all assignments, which prevents the constructor from assigning self.value
. You can use self.__dict__
to access the instance dictionary. Try:
class Wrapper: def __init__(self, value): self.__dict__['value'] = value def __setattr__(self, name, value): setattr(self.value, name, value)
Another way using object.__setattr__
:
class Wrapper(object): def __init__(self, value): object.__setattr__(self, 'value', value) def __setattr__(self, name, value): setattr(self.value, name, value)
A way to disable the __setattr__
until after initialization without changing the self.value = value
syntax in the __init__
method is covered here. In short, embed knowledge of initialization in the object and use it in the __setattr__
method. For your 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)
With __getattr__
overridden as well::
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 = awa = Wrapper(A(3))#wa.a == wa.wrapped.a == 3