2 回答

TA貢獻1811條經(jīng)驗 獲得超6個贊
使用factory method方法怎么樣?當(dāng)應(yīng)該動態(tài)定義確切的實例類型時,這是一個不錯的選擇。好像:
class Monomial(Function):
@staticmethod
def create(coef: int, power: int, inner=Identity()):
if power == 0:
return Constant(coef)
else:
return Monomial(coef, power)
x = Monomial.create(...)

TA貢獻1847條經(jīng)驗 獲得超7個贊
調(diào)用類時返回不同類類型的__new__方法是覆蓋方法而不是__init__. 返回的值__new__是用作實例的值(與__init__它甚至不允許返回值不同)。您已經(jīng)正確開始,但是在內(nèi)部嘗試__new__通過調(diào)用它來實例化一個子類,只會重新輸入Monomial.__new__- 您可能會在那里遇到遞歸錯誤。
因此,即使 Python 確實允許更改 的返回類型__new__,也許您應(yīng)該考慮擁有一個工廠函數(shù)的想法 - 獨立于任何類 - 它將返回正確類的實例。有時“越簡單越好”。
無論如何,工廠方法的代碼是:
class Monomial(Function):
def __init__(self, coef: int, power: int, inner=Identity()):
super().__init__(inner)
self.pow = power
self.coef = coef
class Constant(Monomial):
def __init__(self, c: int):
super().__init__(self, coef=c, power=0)
...
def create_monomial(coef, power):
if power == 0:
return Constant(coef)
return Monomial(coef, power)
(create_monomial 也可以是靜態(tài)或類方法,你會發(fā)現(xiàn)更好)
而且,如果您真的認為它會更好,那么解開該__new__方法的一種方法是:
class Monomial(Function):
def __new__(cls, coef: int, power: int = 0, inner=Identity()):
if power == 0:
cls = Constant
return super().__new__(cls)
class Constant(Monomial):
def __init__(self, c: int, **kw):
super().__init__(c, 0)
Python 的實例化機制將調(diào)用__init__如果返回__new__的實例是self- 因此 Monomial 和 Constant__init__都將被正確調(diào)用。你只需要修復(fù) Constant's__init__不要破壞power = 0它會得到的 ocasional參數(shù)。
修復(fù)簽名將在那里花費更多的工作,并且可能涉及使用元類來實際吞咽,在其__call__方法中未使用powerConstant 的__init__;
另請注意,此處的“真正修復(fù)”是調(diào)用super().__new__需要顯式傳遞類 - 與super()Python 提供的“self”或“cls”的其他用法不同。這是因為__new__它實際上是一個靜態(tài)方法——Pythoncls在構(gòu)建類時向其中添加了,但是通過“classmethods”使用的其他機制。
添加回答
舉報