我有一个Interface类,它定义了对一个活动的“使用中”类的要求:
class Portfolio(ABC):
@abstractmethod
def update_portfolio(self):
raise NotImplementedError
@abstractmethod
def update_from_fill(self):
raise NotImplementedError
@abstractmethod
def check_signal(self, signal_event):
raise NotImplementedError
方法update_portfolio和update_from_fill都是99%的必需案例中相同的方法。只有check_signal方法会有所不同。因此,为了避免不得不一次又一次地编写相同的代码,我已经为update_portfolio和update_from_fill定义了一个带有默认方法的基类:
class BaseBacktestPortfolio(Portfolio):
def __init__(self, ...):
...
def update_portfolio(self, ...):
...
def update_from_fill(self, ...):
...
然后,最后,我有一个继承自BacktestPortfolio类的类,它指定了check_signal方法的正确实现:
class USBacktestPortfolio(BaseBacktestPortfolio):
def check_signal(self, ...):
...
现在,问题是我的编辑抱怨BacktestPortfolio分类没有所有必需的抽象方法。当然,我可以忽略这一点,但完美的情况是,如果我能确保不可能从BacktestPortfolio类中实例化一个对象。
这可能吗?和/或有没有更正确的方法来实现这样的结构?
您可以将BaseBacktestPortfolio
也作为抽象类。
from abc import ABC, abstractmethod
class Portfolio(ABC):
@abstractmethod
def update_portfolio(self):
pass
@abstractmethod
def update_from_fill(self):
pass
@abstractmethod
def check_signal(self, signal_event):
pass
class BaseBacktestPortfolio(Portfolio, ABC):
def update_portfolio(self):
print("updated portfolio")
def update_from_fill(self):
print("update from fill")
@abstractmethod
def check_signal(self):
pass
class USBacktestPortfolio(BaseBacktestPortfolio):
def check_signal(self):
print("checked signal")
另请注意,您在抽象方法中不需要raise NotImplementedError
。你可以只是pass
。它更Pythonic :)
当然,我可以忽略这一点,但完美的情况是,如果我能确保无法从BacktestPortfolio类中实例化对象。
你的例子就是这种情况:
>>> BaseBacktestPortfolio.mro()
[__main__.BaseBacktestPortfolio, __main__.Portfolio, abc.ABC, object]
>>> BaseBacktestPortfolio()
TypeError: Can't instantiate abstract class BaseBacktestPortfolio with abstract methods check_signal
由于ABC
和ABCMeta
只是常规类型,因此它们的特征是继承的。这包括他们防止实例化不完整的类。你的BaseBacktestPortfolio
已经是一个抽象类。
来自IDE / linter / ...的警告专门用于警告您无法实例化BaseBacktestPortfolio
。