[英]How to instantiate a child class from parent class
我想從父類創建子類。 這是為了減少代碼中的冗余。 例如,
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
我不想為所有子類一次又一次地傳遞參數。 有什么方法可以使我從Parent類中獲得Child1和Child2嗎?
我有30多個參數和許多子類。 寫出所有參數似乎很多余。 另外,它們都與父母共享相同的參數。
您要在此處執行的操作與實例化無關。 這個詞的意思是創建一個類的實例。 您不能“實例化父類的子類”,因為類對象不是(除非在非常特殊的情況下)其基類的實例。
您正在嘗試做的是消除一些樣板。
Python非常靈活-實例可以在所需的任何地方定義屬性,類可以對__init__
和__repr__
等方法具有所需的任何簽名。這非常強大,但是這也意味着當您具有非常重復的類層次結構時,重復很多 但是,由於Python非常靈活,因此您可以編寫工具來為您生成所有重復的內容,也可以只使用該語言@dataclass
工具,例如@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版本的反向端口 ,您可以僅使用pip install dataclasses
,但是如果您需要使用3.5或2.7版本,則需要一個類似attrs
的第三方庫。 還可以查看namedtuple
中非常簡單的情況,該情況一直可以追溯到2.6和3.1。
您可以將所有參數作為列表傳遞給子類的__init__
,將盡可能多的參數傳遞給超類,並在子類本身中使用其余參數:
class Parent():
def __init__(self,a,b,c):
print(a,b,c)
class Child1(Parent):
def __init__(self, *args):
super().__init__(*args[:3]) # 3 for the parent
self.x, self.y = args[3:] # 2 for myself
print(self.x, self.y)
Child1(1,2,3,4,5)
#1 2 3
#4 5
#<__main__.Child1 object at 0x7f5d70c3c9e8>
從您的示例尚不清楚繼承在這里是否合適。 孩子是否滿足是一種關系,即是孩子真正的父母的一個子類? 如果不是,那么您應該考慮使用組合而不是繼承。
我建議使用組合,因為您在注釋中提到了實例化父類並在“子”類中使用該實例 。 因此,您可以創建父級實例並將其傳遞給“子級”類的__init__()
,從而使用組合。
class Parent():
def __init__(self, a, b, c, d, e, f, g):
self.a = a
self.b = b
...
self.g = g
class Child1:
def __init__(self, parent, h, i, j, k):
self.parent = parent
self.h = h
self.i = i
self.j = j
self.k = k
在子類中,您將通過例如self.parent.a
訪問父屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.