2012-10-21 4 views
7

Pisałem następujące klasy otoki. Chcę zdefiniować __setattr__ w taki sposób, aby przekierowywało wszystkie atrybuty do zawiniętej klasy. Zapobiega to jednak inicjalizacji klasy opakowania. Jakiś elegancki sposób na rozwiązanie tego problemu?czysty sposób, aby wyłączyć `__setattr__` aż po inicjalizacji

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

Co 'Wrapper' owinąć? Dlaczego nie dziedziczy "obiektu"? –

+0

@Tichodroma Zawija wszystko. Używam go w aplikacji GUI; owijka powiadamia słuchaczy, gdy zamknięty obiekt jest modyfikowany. Nie dziedziczy po 'obiekcie', ponieważ chcę używać tylko Python 3. –

Odpowiedz

8

Łapie wszystkie przypisania, co uniemożliwia konstruktorowi przypisanie self.value. Możesz użyć self.__dict__, aby uzyskać dostęp do słownika instancji. Spróbuj:

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

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

Innym sposobem korzystania 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. Jedno pytanie jednak: dlaczego powinienem używać również 'self .__ dict __ ['value']' wewnątrz '_setztr__'? –

+0

@Paul Przepraszam, nie potrzebujesz tego. Myślałem też, że nadpisujesz również "__getattr__". – quantum

4

sposób wyłączyć __setattr__ dopiero po inicjalizacji bez zmiany składni self.value = value w metodzie __init__ jest pokryta here. W skrócie, osadzaj wiedzę o inicjalizacji w obiekcie i użyj go w metodzie __setattr__. Dla Państwa 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

Z __getattr__ nadpisane jak również ::

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 
Powiązane problemy