2012-10-21 61 views
7

我寫了下面的包裝類。我想定義__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) 
+0

是什麼'Wrapper'包裝?爲什麼它不繼承'object'? – 2012-10-21 14:54:23

+0

@Tichodroma它包裝任何東西。我在一個GUI應用程序中使用它;包裝對象被修改時,包裝會通知偵聽器。它不會從'object'繼承,因爲我只想使用Python 3. –

回答

8

您捕獲所有的任務,這將阻止構造從分配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) 
+0

不錯。但有一個問題:爲什麼我應該在'__setattr__'裏面使用'self .__ dict __ ['value']'? –

+0

@Paul對不起,你不需要那個。我還以爲你重寫了'__getattr__'。 – quantum

4

一種方法來禁用__setattr__直到初始化後沒有在__init__方法改變self.value = value語法覆蓋here。簡而言之,在對象中嵌入初始化知識,並在__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) 
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 
相關問題