![](/img/trans.png)
[英]Python type annotations for instance of class derived from abstract base class
[英]How to incorporate type checking in an abstract base class in Python
當我定義一個類時,我喜歡包括輸入變量的類型檢查(使用assert
)。 我現在正在定義一個“特殊的”類Rule
,它從抽象基類(ABC) BaseRule
,類似於以下內容:
import abc
class BaseRule(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def resources(self):
pass
class Rule(BaseRule):
def __init__(self, resources):
assert all(isinstance(resource, Resource) for resource in resources) # type checking
self._resources = resources
@property
def resources(self):
return self._resources
class Resource(object):
def __init__(self, domain):
self.domain = domain
if __name__ == "__main__":
resources = [Resource("facebook.com")]
rule = Rule(resources)
Rule
類的__init__
函數中的assert
語句可確保resources
輸入是Resource
對象的列表(或其他可迭代的)。 但是,對於其他繼承自BaseRule
類也是BaseRule
,因此我想以某種方式將此斷言合並到abstractproperty
。 我該怎么辦?
使您的基類具有非抽象屬性,該屬性調用單獨的抽象getter和setter方法。 該屬性可以在調用設置器之前進行所需的驗證。 想要觸發驗證的其他代碼(例如派生類的__init__
方法)可以通過使用屬性進行分配來實現:
class BaseRule(object):
__metaclass__ = abc.ABCMeta
@property
def resources(self): # this property isn't abstract and shouldn't be overridden
return self._get_resources()
@resources.setter
def resources(self, value):
assert all(isinstance(resource, Resources) for resource in value)
self._set_resources(value)
@abstractmethod
def _get_resources(self): # these methods should be, instead
pass
@abstractmethod
def _set_resources(self, value):
pass
class Rule(BaseRule):
def __init__(self, resources):
self.resources = resources # assign via the property to get type-checking!
def _get_resources(self):
return self._resources
def _set_resources(self, value):
self._resources = value
您甚至可以考慮將__init__
方法從Rule
移到BaseRule
類中,因為它不需要任何有關Rule
的具體實現的知識。
請參閱帶有mypy-lang的abc類型注釋的此文檔https://mypy.readthedocs.io/en/latest/class_basics.html#abstract-base-classes-and-multiple-inheritance
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.