【问题标题】:How do I initialize the parent class using a class method instead of calling the constructor?如何使用类方法而不是调用构造函数来初始化父类?
【发布时间】:2021-09-22 16:42:54
【问题描述】:

我有我想继承的类 A,这个类有一个类方法,可以从一些数据初始化一个新实例。我无权访问from_data 的代码,也无法更改 A 的实现。

我想使用传递给 A 的 from_data 方法的相同数据来初始化 B 类的新实例。在我想出的解决方案中,我在__new__(...) 中创建了一个新的A 实例,并将__class__ 更改为B。__init__(...) 然后可以像往常一样进一步初始化“B 的新实例”。它似乎有效,但我不确定这会产生某种副作用。

那么这会可靠地工作吗?有没有合适的方法来实现这一点?

class A:
    def __init__(self, alpha, beta):
        self.alpha = alpha
        self.beta = beta

    @classmethod
    def from_data(cls, data):
        obj = cls(*data)
        return obj


class B(A):
    def __new__(cls, data):
        a = A.from_data(data)
        a.__class__ = cls
        return a

    def __init__(self, data):
        pass


b = B((5, 3))
print(b.alpha, b.beta)
print(type(b))
print(isinstance(b, B))

输出:

5 3
<class '__main__.B'>
True

【问题讨论】:

  • 即使它确实可靠地工作,它也会让所有使用过你的代码的人感到困惑。你真的是说B 继承自A 吗?考虑让B 包含 一个A。然后你可以随心所欲地初始化它,没有人会质疑它。
  • a.__class__ = cls 只是 hacky。为什么要这样做?为什么要先实现__new__?为什么不直接使用B.from_data((5, 3))....?
  • 您是否尝试过简单地调用B.from_data(),然后摆脱您的__new__()?如果A.from_data() 的实现与您展示的完全一样,那应该可以正常工作。
  • 为什么需要重新实现它?你已经继承了它。
  • 不,它没有。它返回一个cls 的实例,其中cls 是您调用它的任何类。这就是 Python 中 classmethod 相对于 staticmethod 的优势。

标签: python python-3.x


【解决方案1】:

可能是您的用例比我理解的更抽象,但是在 REPL 中进行测试,似乎通过 super() 调用父级 class A 构造函数

class A:
    # ...


class B(A):
    def __init__(self, data):
        super().__init__(*data)


b = B((5, 3))
print(b.alpha, b.beta)
print(type(b))
print(isinstance(b, B))

也会导致

5 3
<class '__main__.B'>
True

您是否有不想调用super() 来实例化您的子类的新实例的原因?


编辑:

所以,如果您需要使用from_data 构造函数...您可以执行类似的操作

#... class A

class B(A):
    def __init__(self, data):
        a_obj = A.from_data(data)
        for attr in a_obj.__dict__:
            setattr(self, attr, getattr(a_obj, attr))

真的 hacky...并且不保证适用于A 类对象的所有属性,特别是如果__dict__ 函数已重载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 2022-01-17
    • 2013-02-28
    • 1970-01-01
    • 2021-12-21
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多