首页 > 解决方案 > 如何从父类实例化子类

问题描述

我想从父类创建一个子类。这是为了减少代码中的冗余。例如,

class Parent():
   def __init__(self, a, b, c, d, e, f, g):
       self.a = a
       self.b = b
       ...
       self.g = g

class Child1(Parent):
   def __init__(self, a, b, c, d, e, f, g, h, i, j, k):
          super().__init__(a, b, c d, e, f, g)
          self.i = i
          self.j = j
          self.k = k

class Child2(Parent):
   def __init__(self, a, b, c, d, e, f, g, h, x, y, z):
          super().__init__(a, b, c d, e, f, g)
          self.x = x
          self.y = y
          self.z = z

我不想一次又一次地为所有子类传递参数。有没有办法让 Child1 和 Child2 从 Parent 类?

我有 30 多个参数和许多子类。写出所有参数似乎非常多余。另外,它们都与父母共享相同的参数。

标签: pythonclassinheritance

解决方案


您在这里要做的与实例化无关。这个词的意思是创建一个类的实例。您不能“从父类实例化子类”,因为类对象不是(除非在非常不寻常的情况下)其基类的实例。

您要做的是消除一些样板。

__init__Python 非常灵活——实例可以在任何需要的地方定义属性,类可以为和等方法具有任何他们想要的签名__repr__。这非常强大,但这也意味着当你有一个非常重复的类层次结构时,你必须重复自己很多。但是——因为 Python 非常灵活——你可以编写工具来为你生成所有重复的东西,或者你可以只使用语言附带的工具,比如@dataclass1

from dataclasses import dataclass

@dataclass
class Parent:
    a: int
    b: int
    c: int
    d: int
    e: int
    f: int
    g: int
    h: int

@dataclass
class Child1(Parent):
    i: int
    j: int
    k: int

@dataclass
class Child2(Parent):
    x: int
    y: int
    z: int

这就是定义类所需的全部内容,包括自动生成__init__可以处理位置和关键字参数并将正确的东西转发给基类的方法,以及__repr__以某种有用的方式显示东西的方法,以及 Mypy 可以为你检查的静态类型提示,等等,没有任何重复:

>>> c1 = Child1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
>>> c1
Child1(a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9, j=10, k=11)
>>> c1b = Child1(1, 2, 3, 4, 5, 6, 7, k=11, j=10, h=8, i=9)
>>> c1 == c1b
True
>>> c2 = Child2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
>>> c1 == c2
False

如果您阅读文档,您会发现那里有更多的灵活性(在 中甚至更多attrs),但默认值在 80% 的情况下都能满足您的需求。


@dataclass在 Python 3.7 中添加。有一个 3.6 的 backport,您可以使用 just 安装pip install dataclasses,但如果您需要使用 3.5 或 2.7,则需要类似的第三方库attrs。还要查看namedtuple非常简单的情况,这些情况一直可以追溯到 2.6 和 3.1。


推荐阅读