2012-02-07 11 views
6

Przegląd:zagnieżdżone obiekty i setattr & getattr (tak, to ten czas)

class Inner(object): 
    def __init__(self, x): 
     self.x = x 

class Outer(object): 
    def __init__(self, z): 
     self.inner = Inner(z) 

o = Outer(10) 

Teraz chcę zewnętrzna obiektu zachowywać się w sposób przejrzysty - żadnych atrybutów ustawionych na o powinien być ustawiony na o.inner, sam dla odczyt: o.something powinien powrócić, w rzeczywistości, wartość o.inner.sommething. Trochę jak proxy lub przekaźnik.

__getattr__ dla Outer wydaje się prosta & prace:

def __getattr__(self, item): 
    return getattr(self, item) 

Jak sobie radzić __setattr__? Nie mogłem wymyślić niczego, co nie powodowałoby błędu rekursji i sprawiało, że nienawidziłem siebie.

A może sama koncepcja jest wadliwa?

(Innym podejściem Próbowałem robił Outer podklasa Inner - to naprawdę nie grać estetycznie obecny @classmethods, nie wspominając IDE by zgubić wewnątrz tych. - nie jest w stanie rozwiązać pewne atrybuty Zostawmy że na razie, być może?)

+0

Czy chodziło Ci o 'self.inner = Inner (z)'? Czy twoja metoda getattr zwraca dane z Inner()? Sposób, w jaki jest napisany, wygląda na to, że odnosi się tylko do Outera. – gfortune

+0

Tak - wraca. Naprawiono oba, dzięki! – ntl0ve

Odpowiedz

7

Najtrudniejszą częścią jest prawidłowe ustawienie atrybutu inner klasy Outer. Co można zrobić, to wywołać metodę object__setattribute__ (klasa bazowa Outer):

class Inner(object): 
    def __init__(self, x): 
     self.x = x 

class Outer(object):  
    def __init__(self, z): 
     object.__setattr__(self, 'inner', Inner(z)) 

    def __getattr__(self, name): 
     return getattr(self.inner, name) 

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

Teraz to działa prawidłowo:

o = Outer(10) 
print o.x  # 10 
print o.inner.x # 10 
o.g = 3 
print o.g  # 3 
print o.inner.g # 3 

Jednak to nie jest jasne, mój, dlaczego nie zrobić w tym przypadku chcesz użyć dziedziczenia. Wydaje się bardziej naturalne i pythonic mieć Outer dziedziczy po Inner.

+0

Powód, dla którego działa print (o.inner), ponieważ o.inner już istnieje, więc nie wywołuje '__getattr__' i nie próbuje zwracać o.inner.inner, prawda? Nie jest oczywiste, że '__getattr__' nie zostanie wywołany w przypadkach, gdy żądany element już istnieje jako część danego obiektu. – gfortune

+0

@gfortune, tak; aby uzyskać więcej informacji, zobacz [to pytanie] (http://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute-in-python). – senderle

+0

tak, patrz [\ _ \ _ getattr \ _ \ _] (http://docs.python.org/reference/datamodel.html#object.__getattr__) dokumenty – jterrace

Powiązane problemy