我一直在尝试验证用户可以在框架样式设置中创建的类。 我可以确保类属性以以下方式存在于子类中:
from abc import ABC, abstractmethod
class A(ABC):
@property
@classmethod
@abstractmethod
def s(self):
raise NotImplementedError
class ClassFromA(A):
pass
ClassFromA()
这导致以下Exception
:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class ClassFromA with abstract methods s
我还可以在类创建时使用装饰器检查类属性s
的类型,如下所示:
from abc import ABC, abstractmethod
def validate_class_s(cls):
if not isinstance(cls.s, int):
raise ValueError("S NOT INT!!!")
return cls
class A(ABC):
@property
@classmethod
@abstractmethod
def s(self):
raise NotImplementedError
@validate_class_s
class ClassFromA(A):
s = 'a string'
导致:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 3, in validate_class_s
ValueError: S NOT INT!!!
在类属性的最终检查中非常有用。 但这会导致冗长的类定义,其中每个子类都必须修饰。你知道吗
有没有一种方法可以验证基类中的class属性(s
在示例中)?最好不要太啰嗦?你知道吗
另一种方法是,用一个可配置的验证器作为装饰器,您可以在几个不同的子类和基类上使用,这样可以节省一些冗长的内容。 基类使用类型注释声明属性
如果类型不匹配,则引发
ValueError
;如果属性不存在,则引发AttributeError
。你知道吗当然,您可以收集错误(如前一个答案所示)并一次性地将它们全部呈现出来,而不是在第一个错误时停止
您可以使用新的in Python 3.6
__init_subclass__
功能。这是一个在基类上定义的classmethod,在创建时将为创建的每个子类调用一次。对于大多数断言用例来说,它可能比Python的ABC更有用,后者只会在类实例化时引发错误(相反,如果您想在进入具体类之前对其他AbstrateClass进行子类化,则必须在代码中检查这一点)。你知道吗
因此,例如,如果要通过在基类上做注释来指示子类上所需的方法和属性,可以执行以下操作:
您可以将
collections.abc.Callable
放在需要方法的注释上,或者将(type(None), int)
这样的元组放在可选整数上,但是isinstance
不幸的是,无法使用“typing”模块提供的多功能语义。如果您需要,我建议您看看pydantic项目并加以利用。你知道吗相关问题 更多 >
编程相关推荐