[英]How to incorporate type checking in an abstract base class in Python
When I define a class, I like to include type checking (using assert
) of the input variables. 当我定义一个类时,我喜欢包括输入变量的类型检查(使用
assert
)。 I am now defining a 'specialized' class Rule
which inherits from an abstract base class (ABC) BaseRule
, similar to the following: 我现在正在定义一个“特殊的”类
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)
The assert
statement in the __init__
function of the Rule
class ensures that the resources
input is a list (or other iterable) of Resource
objects. Rule
类的__init__
函数中的assert
语句可确保resources
输入是Resource
对象的列表(或其他可迭代的)。 However, this would also be the case for other classes which inherit from BaseRule
, so I would like to incorporate this assertion in the abstractproperty
somehow. 但是,对于其他继承自
BaseRule
类也是BaseRule
,因此我想以某种方式将此断言合并到abstractproperty
。 How might I go about this? 我该怎么办?
Make your base class have a non-abstract property that calls separate abstract getter and setter methods. 使您的基类具有非抽象属性,该属性调用单独的抽象getter和setter方法。 The property can do the validation you want before calling the setter.
该属性可以在调用设置器之前进行所需的验证。 Other code (such as the
__init__
method of a derived class) that wants to trigger the validation can do so by doing its assignment via the property: 想要触发验证的其他代码(例如派生类的
__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
You might even consider moving the __init__
method from Rule
into the BaseRule
class, since it doesn't need any knowledge about Rule
's concrete implementation. 您甚至可以考虑将
__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.