2012-10-21 14 views
7

Ich habe die folgende Wrapper-Klasse geschrieben. Ich möchte __setattr__ so definieren, dass es alle Attribute an die umschlossene Klasse umleitet. Dies verhindert jedoch, dass ich die Wrapper-Klasse initialisieren kann. Irgendeine elegante Möglichkeit, das zu beheben?Saubere Möglichkeit, '__setattr__` bis nach der Initialisierung zu deaktivieren

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

überschrieben Was bedeutet 'Wrapper' wickeln? Warum erbt es nicht "Objekt"? –

+0

@Tichodroma Es wickelt alles ein. Ich benutze es in einer GUI-Anwendung; Der Wrapper benachrichtigt Listener, wenn das eingeschlossene Objekt geändert wird. Es erbt nicht von "Objekt", weil ich nur Python 3 verwenden möchte. –

Antwort

8

Sie fangen alle Zuordnungen ab, was verhindert, dass der Konstruktor self.value zuweist. Sie können self.__dict__ verwenden, um auf das Instanzwörterbuch zuzugreifen. Versuchen:

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

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

Ein anderer Weg object.__setattr__ Verwendung:

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

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

Schön. Eine Frage allerdings: Warum sollte ich 'self .__ dict __ ['value']' auch in '__setattr__' verwenden? –

+0

@Paul Tut mir leid, das brauchst du nicht. Ich dachte, du würdest auch '__getattr__' überschreiben. – quantum

4

Ein Weg, um die __setattr__, bis nach der Initialisierung zu deaktivieren, ohne die self.value = value Syntax in den __init__ Verfahren zu ändernden here bedeckt ist. Kurz gesagt, das Wissen über die Initialisierung in das Objekt einbetten und es in der __setattr__ Methode verwenden. Für Ihre 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

Mit __getattr__ auch ::

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