python - 如何从父类实例化子类
问题描述
我想从父类创建一个子类。这是为了减少代码中的冗余。例如,
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 多个参数和许多子类。写出所有参数似乎非常多余。另外,它们都与父母共享相同的参数。
解决方案
您在这里要做的与实例化无关。这个词的意思是创建一个类的实例。您不能“从父类实例化子类”,因为类对象不是(除非在非常不寻常的情况下)其基类的实例。
您要做的是消除一些样板。
__init__
Python 非常灵活——实例可以在任何需要的地方定义属性,类可以为和等方法具有任何他们想要的签名__repr__
。这非常强大,但这也意味着当你有一个非常重复的类层次结构时,你必须重复自己很多。但是——因为 Python 非常灵活——你可以编写工具来为你生成所有重复的东西,或者你可以只使用语言附带的工具,比如@dataclass
:1
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。
推荐阅读
- android - 使用 updateConfiguration Kotlin Android 更改语言
- windows - 如何在不生成 4703 事件的情况下从 Windows 事件日志中读取?
- reactjs - 为什么当我更改状态时我的 React 应用程序没有重新渲染?
- flutter - 如何在 Flutter 中将按钮图标更改为动画文本?
- ansible - Ansible 中的双重迭代
- excel - 基于其他两列组合单元格的代码或宏
- html - 如何将填充设置为延伸到父容器的顶部和底部边缘?
- google-sheets - 在 Google 表格中转置两个没有空白值的表格
- javascript - 用Javascript中的数组值替换字符串
- python-3.x - 如何将字符串中的列表变为 Python 中的真实列表?