[英]in Python 3, can a superclass polymorphically call a subclass's constructor
我想在一個類( Parent
)中創建方法(例如copy
),該方法將返回該類或調用它的子類的對象。 我想要type(x) == type(x.copy())
。
我嘗試的所有方法均未令人滿意。
init_me
,但這樣做init_me
了繼承的目的。 __new__
和__init__
,但是很快決定Python必須有更好的方法。 樣例代碼
class Parent(object):
def __init__(self, p1=p1_default, p2=p2_default, p3=p3_default):
... # common stuff
self._special_suff()
def copy_works_if_subclass_does_extra(self):
return self.init_me()
def copy_only_does_superclass(self):
return Parent()
def copy_with_init(self):
return self.__init__()
def whoami(self):
print('I am just a parent')
class Dad(Parent):
def _special_stuff():
... # Dad special stuff
return
def whoami(self):
print('I am a dad')
def init_me(self):
return Dad()
class Mom(Parent):
def _special_stuff():
... # Mom special stuff
return
def whoami(self):
print('I am a mom')
如果我理解正確,您正在嘗試在基類中編寫一個copy
方法,該方法在派生類的實例上調用時仍然可以使用。 這可以使它起作用,但是只有當您的子類只期望與基類具有相同的參數集時,這才容易。 如果他們的__init__
方法期望使用不同的參數,則需要為每個派生類使用單獨的copy
方法。
這是一個如何工作的簡單示例。 訣竅是調用type(self)
以獲取正確的類,然后使用適當的構造函數參數調用該類以獲取新實例:
class Base(object):
def __init__(self, arg1, arg2, arg3):
self.attr1 = arg1
self.attr2 = arg2
self.attr3 = arg3
def copy(self):
cls = type(self)
return cls(self.attr1, self.attr2, self.attr3)
class Derived(Base):
def __init__(self, arg1, arg2, arg3):
super().__init__(arg1, arg2, arg3)
self.some_other_attr = "foo"
在實踐中,這往往效果不佳,因為Derived
類通常希望使用額外的參數來設置其額外屬性。 在這種情況下可能有效的選擇是使用copy
模塊,而不是編寫自己的copy
方法。 函數copy.copy
將能夠復制許多Python實例,而無需任何特殊支持。
您使事情復雜化了很多 。 在子類上實現了一個簡單構造函數的最小示例:
import copy
class Parent():
def whoami(self):
print('Just a parent')
def __init__(self, name):
self.name = name
def copy(self):
# Maybe copy.deepcopy instead
return copy.copy(self)
class Dad(Parent):
def whoami(self):
print('I am a dad')
def __init__(self, name):
super().__init__(name)
self.gender = 'Male'
如果不需要,甚至不需要使用Python中的構造函數。 或者,您可以在超類上擁有一個,而在子類上則沒有。
一些用法:
>>> dad = Dad("Clark Griswold")
>>> dad.name
'Clark Griswold'
>>> dad.whoami()
I am a dad
>>> isinstance(dad, Dad)
True
>>> isinstance(dad, Parent)
True
>>> type(dad.copy()) == type(dad)
True
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.