2013-10-31 29 views
5

Ich stolperte über diese zusätzliche, keine Unterstriche mro Methode, als ich __metaclass__ = abc.ABCMeta verwendet. Es scheint das gleiche wie __mro__ zu sein, außer dass es eine Liste anstelle eines Tupels zurückgibt. Hier ist ein willkürliches Beispiel (ideone snippet):Was ist der Unterschied zwischen der Methode "mro" und dem Attribut "__mro__" einer Klasse?

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'>] 

Später fand ich, dass dies zu ABCMeta nicht eindeutig zuzuordnen sind, sondern in allen neuen Stil Klassen zur Verfügung steht.

Also ... warum? Was macht das, __mro__ ist nicht?

Antwort

7

Direkt von the documentation:

Diese Methode kann durch eine Metaklasse außer Kraft gesetzt werden, um die Methode Auflösung, um für seine Instanzen anzupassen. Es wird bei der Klasseninstanziierung aufgerufen, und sein Ergebnis wird in __mro__ gespeichert.

ziemlich selbsterklärend zu mir ...

mro() auf Instanciation genannt und speichert das Ergebnis in __mro__. Sie haben nicht wirklich den gleichen Zweck.

+1

Also wann soll ich welche verwenden? Wird in der Standardimplementierung von 'mro()' '__mro__' als Cache verwendet, da es nicht neu berechnet wird? Wenn ja, dann ist das der Grund für "__mro__" und sollte als Implementierungsdetail betrachtet werden. Ansonsten, was ist der Zweck? – burnpanck

+0

@burnpanck. '__mro__' wird explizit von' super' verwendet: https://docs.python.org/3/reference/datamodel.html#invoking-descriptors –