2012-10-21 14 views
7

Ho scritto la seguente classe wrapper. Voglio definire __setattr__ in modo tale da reindirizzare tutti gli attributi alla classe spostata. Tuttavia, questo mi impedisce di inizializzare la classe wrapper. Qualche modo elegante per risolvere questo problema?Modo pulito per disabilitare `__setattr__` fino a dopo l'inizializzazione

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

Cosa 'avvolgere Wrapper'? Perché non eredita 'object'? –

+0

@Tichodroma Si avvolge tutto. Lo sto usando in un'applicazione GUI; il wrapper avvisa i listener quando viene modificato l'oggetto incluso. Non eredita da 'object' perché voglio solo usare Python 3. –

risposta

8

si stanno recuperando tutte le assegnazioni, che impedisce il costruttore di assegnare self.value. È possibile utilizzare self.__dict__ per accedere al dizionario di istanza. Prova:

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

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

Un altro modo utilizzando 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

Nice. Una domanda però: perché dovrei usare 'self .__ dict __ ['value']' anche all'interno di '__setattr__'? –

+0

@Paul Spiacente, non è necessario. Pensavo che tu stessi ignorando anche '__getattr__'. – quantum

4

Un modo per disattivare il __setattr__ fino a dopo l'inizializzazione senza modificare la sintassi self.value = value nel metodo __init__ è coperto here. In breve, incorporare la conoscenza dell'inizializzazione nell'oggetto e utilizzarla nel metodo __setattr__. Per il vostro 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

Con __getattr__ sovrascritti così ::

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 
Problemi correlati