【问题标题】:Python Dynamic Inheritance and AttributesPython 动态继承和属性
【发布时间】:2020-06-05 21:15:49
【问题描述】:

我正在寻找一种解决方案,允许我根据满足的某些条件(Python 3.6)动态继承类。看起来很简单,但我无法让父类的属性在子类中可用。依赖于self 的所有内容要么产生缺少参数错误,要么属性不出现。我为动态继承实现了给定herehere 的问题的解决方案,但仍然遇到子类属性的相同问题。

示例:

class Parent:
    def __init__(self):
        self.some_value = 1

    def some_function(self):
        return self.some_value

def classFactory(parent):
    class child(parent):
        def __init__(self, parent):
            super(child, self).__init__()
            parent.__init__(self)
            self.some_other_value = 2

        def some_other_function(self):
            return self.some_value + self.some_other_value
    return child

child_class = classFactory(Parent)

child_class.some_value
AttributeError: type object 'child' has no attribute 'some_value'

child_class.some_other_value
AttributeError: type object 'child' has no attribute 'some_other_value'

child_class.some_other_function()
TypeError: some_other_function() missing 1 required positional argument: 'self'

但是,如果我采用相同的 child 构造并将其从函数定义中删除,它就可以工作。

class child(Parent):
    def __init__(self, parent):
        super(child, self).__init__()
        parent.__init__(self)
        self.some_other_value = 2

    def some_other_function(self):
        return self.some_value + self.some_other_value

child_class = child(Parent)
print(child_class.some_value)
# 1
print(child_class.some_other_value)
# 2
print(child_class.some_other_function())
# 3

为什么在第一种情况下属性没有被继承,而在第二种情况下却被继承了?如何编写动态继承来给我期望的行为(如第二种情况所示)?

【问题讨论】:

  • 您这样做是为了解决什么问题?可能有更好的方法来解决它。
  • 如果使用super 函数,我认为您不需要显式调用Parent 上的构造函数。
  • 错误是由于尝试使用该类而不是该类的实例而导致的。
  • 你为什么打电话给super.__init__parent.__init__
  • 无论如何,您会收到属性错误,因为这些是属于实例的实例属性,而不是它们的类。在第一个示例中,您永远不会实例化实例。

标签: python class oop


【解决方案1】:

如果我用return child(parent) 中的父参数实例化子类,它就可以工作。这保留了父子节点的属性和方法。

class Parent:
    def __init__(self):
        self.some_value = 1

    def some_function(self):
        return self.some_value

def classFactory(parent):
    class child(parent):
        def __init__(self, parent):
            parent.__init__(self)
            self.some_other_value = 2

        def some_other_function(self):
            return self.some_value + self.some_other_value
    return child(parent)

child_class = classFactory(Parent)

print(child_class.some_value)
# 1
print(child_class.some_other_value)
# 2    
print(child_class.some_other_function())
# 3
print(child_class.some_function())
# 1

【讨论】:

    【解决方案2】:

    动态继承最显式的实现可以用元类来实现:

    class A:pass
    
    class B:pass
    
    
    class Meta(type):
    
         def __new__(cls, name, bases, dct):
             bases = (A,) if Meta.condition() else (B,)
             return type(name, bases, dct)
    
         @staticmethod
         def condition():
             # implement condition.
             ...
    
    class C(metaclass=Meta):
        pass
    
    c_instance = C()
    print("is C instance of A:")
    print(isinstance(c_instance, A))
    print("is C instance of B:")
    print(isinstance(c_instance, B))
    
    

    或者,您可以定义条件函数,如下所示:

    
    condition = lambda: True
    class D(A if condition() else B):
        pass
    
    d_instance = D()
    print("is D instance of A:")
    print(isinstance(d_instance, A))
    print("is C instance of B:")
    print(isinstance(d_instance, B))
    

    使用元类的方法可以让您更好地控制类的创建,因此这取决于您的需求...

    【讨论】:

      猜你喜欢
      • 2010-09-19
      • 2011-04-16
      • 2016-10-10
      • 2015-03-27
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多