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

How to incorporate type checking in an abstract base class in Python

当我定义 class 时,我喜欢包括输入变量的类型检查(使用 assert)。我现在定义了一个'specialized' class Rule 继承自一个抽象基class (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 语句 class 确保 resources 输入是列表(或其他可迭代的) Resource 个对象。但是,对于从 BaseRule 继承的其他 classes 也是如此,所以我想以某种方式将此断言合并到 abstractproperty 中。我该怎么做?

让你的基础 class 有一个 non-abstract 属性 调用单独的抽象 getter 和 setter 方法。 属性 可以在调用 setter 之前进行您想要的验证。其他想要触发验证的代码(例如派生 class 的 __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 class,因为它不需要任何关于 Rule 的知识的具体实现。

请参阅此文档,了解带有 mypy-lang https://mypy.readthedocs.io/en/latest/class_basics.html#abstract-base-classes-and-multiple-inheritance

的 abc 类型注释