繁体   English   中英

如何在Python的抽象基类中合并类型检查

[英]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的具体实现的知识。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM