Python 3 super 和元编程

标签 python inheritance metaprogramming typeerror super

我正在尝试以编程方式复制然后修改一个类,但我遇到了 python 3 的 magic super 问题,例如以下

class Base():
    def __init__(self):
        print("Base init")

class Orginal(Base):
    def __init__(self):
        super().__init__()
        print("Orginal init")

Modified = type(Orginal.__name__, Orginal.__bases__, dict(Orginal.__dict__))
Modified.f = lambda self: print("f")

m = Modified()

加注

TypeError: super(type, obj): obj 必须是类型的实例或子类型

所以我想知道,有什么方法可以帮助 super() 在通过 type() 创建的类中找到正确的 __class__ 单元格?

最佳答案

注意:我更正了这个答案中Original的拼写


看来问题是,当您的 Modified 对象被实例化并调用 super 时,它的调用方式如下:super(Original, self) 因为它们是 super 的默认参数。由于 Original 不是 Modified 的父类(super class)(检查 isinstance(m, Original)),python 不允许您调用 super 这样。

以下代码与您的代码类似,但更好地说明了问题。

class Base():
    def __init__(self):
        print("Base init")

class Original(Base):
    def __init__(self):
        super().__init__()
        print("Orginal init")

class Modified(Base):
    def __init__(self):
        super(Original, self).__init__()  # illegal 

Modified.__name__ == Original.__name__

m = Modified()  # raises same Exception that your your code does

Original 添加到 Modifiedbases 将使其工作:

Modified = type(Original.__name__, (Original,) + Original.__bases__, dict(Original.__dict__))

编辑:

根据评论,上述建议可以简化,因为 Original 中包含的所有方法都将包含在 Modified 中,而无需传递 dicttype 调用中:

Modified = type(Original.__name__, (Original,), {})

更进一步,如果您不希望 Modified 成为 Original 的子类,您可以简单地制作 Modified Original 的副本,然后像在示例中一样添加属性:

from copy import deepcopy
Modified = deepcopy(Original)
Modified.f = lambda self: print("f")

m = Modified()

查看this answer ,看来您不能使用 deepcopy 来复制类,并且假设您在 Original.__init__ 方法中调用了 super()ModifiedOriginal 的子类(除非您还修改了 Modified 类中的 __init__ 方法)复制”)。

关于Python 3 super 和元编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40818991/

相关文章:

python 上下文管理器不传递异常

C++初始化常量和继承

Ruby动态对象属性,发送vs实例变量集

python - 由于组太多,Pandas 过滤器执行缓慢

python - __getattr__ 和 __getattribute__ 之间的区别

python - sklearn 中的 SVM 是否支持增量(在线)学习?

C++ 嵌套结构继承规则(访问 protected 成员)

java - 泛型问题java

c++ - 关联容器作为函数模板参数

R:创建自定义错误消息,为包中的函数提供参数值