我有一个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类中实例化一个对象。
这可能吗?和/或是否有更正确的方法来实现这样的结构?
答案 0 :(得分:1)
当然,我可以忽略这一点,但完美的情况是,如果我能确保无法从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
。
答案 1 :(得分:0)
您可以将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
。你可以require_once __DIR__ . '/vendor/autoload.php';
/**
* Minimal options
*/
$options = array(
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_URL => 'http://www.gls-group.eu/276-I-PORTAL-WEBSERVICE/services/ParcelShopSearch/wsdl/2010_01_ParcelShopSearch.wsdl',
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_TRACE => true,
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_CLASSMAP => ClassMap::get(),
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_LOGIN => 'mylog',
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_PASSWORD => 'mypass',
);
$id = "2500686161";
/**
* Samples for Get ServiceType
*/
$get = new \ServiceType\Get($options);
/**
* Sample call for GetParcelShopById operation/method
*/
if ($get->GetParcelShopById(new \StructType\GetParcelShopByIdRequestType($id)) !== false) {
print_r($get->getResult());
} else {
print_r($get->getLastError());
}
。它更Pythonic:)