在给定基数的情况下,如何恢复其MRO?

奥利维尔·梅兰松(OlivierMelançon)

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

class Meta(type):
    def __new__(cls, name, bases, namespace):
        mro = ...

是否有一种内置的方法来计算mro,这是重新实现C3算法以外的方法

布宜诺斯艾利斯

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

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个存根超类,其中N是您的类层次结构的深度(可以缓存的深度应为您选择此路线)。

无论如何,它的代码可能是这样的:

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)

(此方法适用于我在交互模式下尝试过的基本情况-但可能存在多个元类等未涵盖的复杂边缘情况)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在给定基数和指数的情况下计算能力时的变量包装

如何在给定FrameworkElement的情况下检索CompositionEffect?

如何在给定点的情况下绘制区域?

在给定唯一ID的情况下,仅选择其列之前已更改的行

使用版本作为部分主键,如何在给定其ID的情况下获取实体的最新版本?

如何在给定深度和后序遍历的情况下构造一棵树,然后打印其前序遍历

在给定条件的情况下,如何从递归层次结构返回节点的路径?

在给定目录结构的情况下如何导入python模块

在给定新名称列表的情况下,如何重命名一组目录?

在给定约束的情况下,如何查找数组中2个元素的最大差?

如何使用扫描仪在给定多个输入的情况下获得多个输出

在给定特定规则集的情况下如何拆分字符串?

在给定特定PID的情况下如何杀死Java中的进程

如何在给定元组列表的情况下创建倒排索引?

如何在给定特定公式的情况下添加用户输入的一些数字

如何在给定时间的情况下将时间转换为Json格式?

在给定均值、阈值和概率的情况下,如何找到正态分布的标准偏差?

Python 3.4:如何在给定完整路径的情况下导入模块?

条纹:如何在给定信用卡信息的情况下创建客户对象

在给定迭代器列表的情况下,如何从向量中删除元素?

如何在给定鼠标坐标的情况下检测重叠(旋转)的DOM元素?

如何在给定键数组的情况下创建嵌套对象

如何在给定成本中心的情况下读取头寸值

在给定半小时粒度的情况下,如何以小时粒度累计值?

如何在给定完整路径的情况下导入模块?

如何在给定SOAP WSDL操作的情况下创建WSDL文件

在给定APK文件的情况下,如何检测该应用是否使用React Native?

在给定转移概率矩阵的情况下,如何生成随机序列?

如何在给定AWS Cognito的情况下获取AWSCredentials access_token