首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何恢复给定基础的类的mro?

如何恢复给定基础的类的mro?
EN

Stack Overflow用户
提问于 2018-09-15 03:06:35
回答 1查看 152关注 0票数 3

假设我们正在实现一个元类,它需要在类实例化之前知道方法的解析顺序。

代码语言:javascript
复制
class Meta(type):
    def __new__(cls, name, bases, namespace):
        mro = ...

除了重新实现C3算法之外,是否有一种计算mro的内置方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-20 14:13:40

更简单的方法是创建一个临时类,提取它的__mro__,计算您的东西,然后创建真实的元类:

代码语言:javascript
复制
class Meta(type):
    def __new__(metacls, name, bases, namespace):
        tmp_cls = super().__new__(metacls, name, bases, namespace)
        mro = tmp_cls.__mro__
        del tmp_cls  # Not actually needed, just to show you are done with it.
        ...
        # do stuff
        ...
        new_class = super().__new__(metacls, name, bases, namespace)
        ...
        return new_class

假设由于对层次结构上的一些超类的元类产生了疯狂的副作用,所以无法做到这一点,那么也有同样的想法,但是在实现之前,将基中的类克隆到“存根”类中--但可能的话,重新实现C3算法要比这更容易--当然也更高效,因为对于每个类来说,都会创建N*2个数的stub超类,其中N是类层次结构的深度(如果您选择这个路径,就可以缓存它)。

总之,这方面的代码可能是这样的:

代码语言:javascript
复制
stub_cache = {object: object}

def get_stub_class(cls):
    # yields an mro-equivalent with no metaclass side-effects.
    if cls is object:
        return object
    stub_bases = []
    for base in cls.__bases__:
        stub_bases.append(get_stub_class(base))
    if cls not in stub_cache:
        stub_cache[cls] = type(cls.__name__, tuple(stub_bases), {})
    return stub_cache[cls]

def get_future_mro(name, bases):
    stub_bases = tuple(get_stub_class(base) for base in bases)
    stub_cls = type(name, stub_bases, {})
    reversed_cache = {value:key for key, value in stub_cache.items()}
    return [reversed_cache[mro_base] for mro_base in  stub_cls.__mro__[1:]]

class Meta(type):
    def __new__(metacls, name, bases, namespace):
        mro = get_future_mro(name, bases)
        print(mro)
        return super().__new__(metacls, name, bases, namespace)

(这个东西适用于我在交互模式下尝试过的基本案例-但是可能有一些复杂的边缘案例没有涵盖,包括多个元类等等)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52341247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档