2011-10-09 21 views
5

Przebacz mi, jeśli nie mam pojęcia o tym, co tutaj jest oczywiste, ale co by się stało, gdybyś zapisał połączenie do super w zmiennej i użył go później.Co stanie się, jeśli zapiszesz połączenie do super w zmiennej do wykorzystania w przyszłości?

Oto część definicji klasy, która pokazuje, co mam na myśli.

class CaselessDict(dict): 

    def __init__(self, *args, **kwargs): 
     self.super = super(CaselessDict, self) # save super 
     self.update(*args, **kwargs) 

    def __getitem__(self, key): 
     key = self.parsekey(key) 
     return self.super.__getitem__(key) # use saved super 

Ten pomysł pojawił się podczas wdrażania tej klasy CaselessDict i prawie każda metoda miała w sobie super.

Odpowiedz

4

Oczekiwana rzecz: self.super po prostu przytrzyma obiekt super, który działa tak jak super(CaselessDict, self).

Problem z tym podejściem polega na tym, że każda instancja ma tylko jeden atrybut super, więc jeśli miałbyś więcej klas, które używały tej techniki, tylko ta, która przypisała ostatnie super, działałaby poprawnie. Oooo! Dlatego generalnie nie jest to dobry pomysł. Możesz może nazwa atrybutu __super, więc jest zmanipulowany, ale polecam po prostu wywołanie super(CaselessDict, self), jak każdy inny robi.

Oczywiście trawa jest bardziej zielona w Pythonie 3, gdzie wystarczy zwykła rozmowa super().

0

Wszechświat wybuchnie. Nie, nic złego nie powinno się stać, nawet jeśli nie jest to zwyczajne użycie. Dla przypomnienia, w Pythonie 3, możesz po prostu użyć super().foo(...), więc jest to w zasadzie bezużyteczne.

0

Miałem uzasadniony przypadek, w którym I miał zrobić coś takiego, obejmując klasy, które zostały załadowane dynamicznie i ponownie załadowane. Oto fragment, który ładuje moduł „a” zawierający klasa A, a także tworzy i wystąpienie go:

>>> import imp 
>>> m = imp.find_module("a") 
>>> a = imp.load_module("a", *m) 
>>> a.A 
<class 'a.A'> 
>>> aobj = a.A() 
>>> aobj.__class__ 
<class 'a.A'> 

Teraz gdybym ponownie importować „A”, zobaczymy co się stanie jeśli zadzwonię isinstance z wcześniej utworzonego aobj:

>>> a = imp.load_module("a", *m) 
>>> print a.A 
<class 'a.A'> 
>>> isinstance(aobj, a.A) 
False 

jak to dotyczy Super jest to, że jak Pythona 2.6, super(AClass,self) dodał upewnij się, że odniesienie samo było rzeczywiście instancją AClass. W moim przypadku użyłem super w metodzie "A", ale kiedy ponownie zaimportowano moduł "a" i zmieniono klasę "A", moje super referencje przestały działać! Klasa a.A zmieniła się na coś, czego moje istniejące wystąpienia a.A nie były już instancjami, i tak super(a.A, self) zacząłby podnosić TypeErrors. Aby rozwiązać ten problem, w zasadzie zrobiłem to, co OP zrobił: w __init__ zapisuję odniesienie do super w zmiennej instancji, która następnie zostaje użyta w innych metodach, by podnieść się do metod bazowych.

Oto moja pełna (i może nieco nieokiełznana) blog post.

Powiązane problemy