2013-10-31 10 views
5

Natknąłem się na tę dodatkową, niezauważalną metodę, gdy korzystałem z __metaclass__ = abc.ABCMeta. Wygląda na to, że jest taki sam jak __mro__, z tym że zwraca listę zamiast krotki. Oto przykład losowy (ideone snippet):Jaka jest różnica między metodą mro a atrybutem __mro__ klasy?

import abc 
import copy 

class Life(object): 
    __metaclass__ = abc.ABCMeta 

    @abc.abstractmethod 
    def reproduce(self): 
     pass 

class Bacterium(Life): 
    def reproduce(self): 
     return copy.deepcopy(self) 

wiggly = Bacterium() 

print wiggly.__class__.__mro__ 
# (<class '__main__.Bacterium'>, <class '__main__.Life'>, <type 'object'>) 

print wiggly.__class__.mro() 
# [<class '__main__.Bacterium'>, <class '__main__.Life'>, <type 'object'>] 

znalazłem później, że to nie jest przypisany do ABCMeta ale jest dostępny we wszystkich klasach w nowym stylu.

Więc ... dlaczego? Co to takiego robi, nie jest?

Odpowiedz

7

Bezpośrednio z the documentation:

Ta metoda może być przesłonięta przez metaklasą dostosować metody rozwiązywania aby jego wystąpień. Jest wywoływana podczas tworzenia klasy, a jej wynik jest przechowywany w __mro__.

Dość oczywiste dla mnie ...

mro() nazywa na instanciation i przechowuje swój wynik w __mro__. Tak naprawdę nie mają tego samego celu.

+1

Kiedy zatem należy użyć? Czy standardowa implementacja 'mro()' używa '__mro__' jako pamięci podręcznej, ponieważ nie rekompute? Jeśli tak, to jest to powód "__mro__" i należy go traktować jako szczegół implementacji. W przeciwnym razie, jaki jest tego cel? – burnpanck

+0

@burnpanck. '__mro__' jest jawnie używane przez' super': https://docs.python.org/3/reference/datamodel.html#invoking- descriptors –

Powiązane problemy