【问题标题】:dynamic class inheritance using super使用 super 的动态类继承
【发布时间】:2016-03-12 14:32:52
【问题描述】:

我正在尝试使用type() 动态创建一个类并分配一个调用super().__init__(...)__init__ 构造函数;但是,当super() 被调用时,我收到以下错误:

TypeError: super(type, obj): obj must be an instance or subtype of type

这是我的代码:

class Item():    
    def __init__(self, name, description, cost, **kwargs):
        self.name           = name
        self.description    = description
        self.cost           = cost
        self.kwargs         = kwargs

class ItemBase(Item):
    def __init__(self, name, description, cost):
        super().__init__(name, description, cost)

def __constructor__(self, n, d, c):
    super().__init__(name=n, description=d, cost=c)

item = type('Item1', (ItemBase,), {'__init__':__constructor__})
item_instance = item('MyName', 'MyDescription', 'MyCost')

为什么__constructor__方法里面的super()不理解对象参数;以及如何解决?

【问题讨论】:

    标签: python-3.x object inheritance superclass


    【解决方案1】:

    这是我解决问题的方法。我引用了type() 方法来动态实例化一个带有变量引用的类:

    def __constructor__(self, n, d, c, h):
        # initialize super of class type
        super(self.__class__, self).__init__(name=n, description=d, cost=c, hp=h)
    
    # create the object class dynamically, utilizing __constructor__ for __init__ method
    item = type(item_name, (eval("{}.{}".format(name,row[1].value)),), {'__init__':__constructor__})
    # add new object to the global _objects object to be used throughout the world
    self._objects[ item_name ] = item(row[0].value, row[2].value, row[3].value, row[4].value)
    

    可能有更好的方法来实现这一点,但我需要一个修复,这就是我想出的......如果可以的话,使用它。

    【讨论】:

    • 下面提到的无限循环问题使得这个解决方案不可行。
    【解决方案2】:

    注意如果动态创建的类被继承,sadmicrowave 的解决方案会创建一个无限循环,因为self.__class__ 将对应于子类。

    不存在此问题的另一种方法是在创建类后分配__init__,例如可以通过闭包显式链接该类。示例:

    # Base class
    class A():
      def __init__(self):
        print('A')
    
    # Dynamically created class
    B = type('B', (A,), {})
    
    def __init__(self):
      print('B')
      super(B, self).__init__()
    
    B.__init__ = __init__
    
    # Child class
    class C(B):
      def __init__(self):
        print('C')
        super().__init__()
    
    
    C()  # print C, B, A
    

    【讨论】:

    • 很好的跟进 - 我正在更改已接受的答案,因为我总是对更好的解决方案持开放态度:)
    猜你喜欢
    • 2015-12-24
    • 1970-01-01
    • 2011-04-09
    • 2014-02-26
    • 2022-11-18
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 2019-04-07
    相关资源
    最近更新 更多