簡體   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