我正在尝试以编程方式复制然后修改一个类,但我遇到了 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
添加到 Modified
的 bases
将使其工作:
Modified = type(Original.__name__, (Original,) + Original.__bases__, dict(Original.__dict__))
编辑:
根据评论,上述建议可以简化,因为 Original
中包含的所有方法都将包含在 Modified
中,而无需传递 dict
在 type
调用中:
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()
, Modified
是 Original
的子类(除非您还修改了 Modified
类中的 __init__
方法)复制”)。
关于Python 3 super 和元编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40818991/