您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在运行时更改python mro

在运行时更改python mro

如果您不受问题中提到的约束的约束,则建议使用其他提供的答案。否则,我们需要踏入mro hack和Metaclass领域。

一番阅读之后,我发现您可以使用元类更改的mro

但是,这是在类创建时,而不是在对象创建时。轻微修改是必要的。

元类提供了mro我们重载的方法,该方法在类创建期间__new__调用元类调用)以产生__mro__属性

__mro__属性不是普通属性,因为:

但是,mro更改类的基数时,似乎重新计算了(使用该方法)。这构成了黑客的基础。

简单来说:

至于提到修改类的MRO,而在它__init__不是线程安全的。

以下内容可能会打扰一些观众。建议观看者谨慎。

hack:

class change_mro_Meta(type):
    def __new__(cls, cls_name, cls_bases, cls_dict):
        out_cls = super(change_mro_Meta, cls).__new__(cls, cls_name, cls_bases, cls_dict)
        out_cls.change_mro = False
        out_cls.hack_mro   = classmethod(cls.hack_mro)
        out_cls.fix_mro    = classmethod(cls.fix_mro)
        out_cls.recalc_mro = classmethod(cls.recalc_mro)
        return out_cls

    @staticmethod
    def hack_mro(cls):
        cls.change_mro = True
        cls.recalc_mro()

    @staticmethod
    def fix_mro(cls):
        cls.change_mro = False
        cls.recalc_mro()

    @staticmethod
    def recalc_mro(cls):
        # Changing a class' base causes __mro__ recalculation
        cls.__bases__  = cls.__bases__ + tuple()

    def mro(cls):
        default_mro = super(change_mro_Meta, cls).mro()
        if hasattr(cls, "change_mro") and cls.change_mro:
            return default_mro[1:2] + default_mro
        else:
            return default_mro

class A(object):
    def __init__(self):
        print "__init__ A"
        self.hello()

    def hello(self):
        print "A hello"

class B(A):
    __Metaclass__ = change_mro_Meta
    def __init__(self):
        self.hack_mro()
        super(B, self).__init__()
        self.fix_mro()
        print "__init__ B"
        self.msg_str = "B"
        self.hello()

    def hello(self):
        print "%s hello" % self.msg_str

a = A()
b = B()

一些注意事项:

hack_mrofix_mrorecalc_mro方法是staticmethods到元类,但classmethods到类。它做到了这一点,而不是多重继承,因为我想将mro代码分组在一起。

mro方法本身通常返回认值。在破解条件下,它将认mro的第二个元素(直接父类)附加到mro,从而使父类首先在子类之前看到自己的方法

我不确定此黑客的可移植性。它已在Windows 7 64bit上运行的64bit cpython 2.7.3上进行了测试。

不用担心,我敢肯定这不会在某个地方的生产代码中结束。

python 2022/1/1 18:28:07 有236人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶