"MRO方法"和类的"__mro__"属性有什么区别?

10

当我在使用__metaclass__ = abc.ABCMeta时,偶然发现了这个额外的、没有下划线的mro方法。它看起来与__mro__相同,只是返回一个列表而不是一个元组。以下是一个随机示例(ideone代码片段):

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'>]
我后来发现,这不仅适用于ABCMeta,而且在所有新式类中都可用。
那么,为什么?这样做有什么作用,__mro__不能完成吗?
1个回答

11
直接从文档中:

这个方法可以被元类重写,以定制其实例的方法解析顺序。它在类实例化时被调用,并将其结果存储在_mro_中。

所以,在实例化时调用mro()并将其结果缓存到__mro__中。它们实际上并不具有相同的目的。

4
那么我应该在什么情况下使用哪种方法?mro()的标准实现是否使用__mro__作为缓存,以便不重新计算?如果是的话,那就是使用__mro__的原因,并且应该被视为一种实现细节。否则,它的目的是什么? - burnpanck
1
@burnpanck。__mro__super显式使用:https://docs.python.org/3/reference/datamodel.html#invoking-descriptors - Mad Physicist
1
可以在Python CAPI中查看这个链接https://github.com/python/cpython/blob/main/Objects/typeobject.c#L2678,了解如何通过解释器调用.mro()方法。 - Jim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接