1

当我定义一个类时,我喜欢包括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)

类函数中的语句assert确保输入是对象的列表(或其他可迭代的)。但是,对于其他继承自 的类也是如此,因此我想将这个断言合并到不知何故。我该怎么办?__init__RuleresourcesResourceBaseRuleabstractproperty

4

2 回答 2

2

使您的基类具有调用单独的抽象 getter 和 setter 方法的非抽象属性。该属性可以在调用 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__从类中移出,因为它不需要任何关于' 的具体实现的知识。RuleBaseRuleRule

于 2017-01-30T16:42:01.660 回答
2

请参阅有关使用 mypy-lang https://mypy.readthedocs.io/en/latest/class_basics.html#abstract-base-classes-and-multiple-inheritance的 abc 类型注释的文档

于 2017-01-30T16:49:39.887 回答