2024-06-01 19:40:04 发布
网友
我正在创建一个数据类,其中包含一个字段,我希望只有几个可能的值。我是这样想的:
@dataclass class Person: name: str = field(default='Eric', choices=['Eric', 'John', 'Graham', 'Terry'])
我知道一种解决方案是验证__post_init__方法中的参数,但是有没有更干净的方法使用类似于上面的语法
__post_init__
适用于Python3.8(typing.Literal):
from dataclasses import dataclass from typing import Literal from validated_dc import ValidatedDC @dataclass class Person(ValidatedDC): name: Literal['Eric', 'John', 'Graham', 'Terry'] = 'Eric' # Validation during instance creation eric = Person() assert eric.name == 'Eric' assert eric.get_errors() is None john = Person('John') assert john.get_errors() is None peter = Person('Peter') # < Invalid value! assert peter.get_errors() print(peter.get_errors()) # {'name': [ # LiteralValidationError( # literal_repr='Peter', literal_type=<class 'str'>, # annotation=typing.Literal['Eric', 'John', 'Graham', 'Terry'] # ) # ]} # You can check at any time assert john.is_valid() # Starts validation and returns True or False john.name = 'Ivan' # < Invalid value! assert not john.is_valid() print(john.get_errors()) # {'name': [ # LiteralValidationError( # literal_repr='Ivan', literal_type=<class 'str'>, # annotation=typing.Literal['Eric', 'John', 'Graham', 'Terry'] # ) # ]} john.name = 'John' # < Valid value assert john.is_valid() assert john.get_errors() is None
ValidatedDC:https://github.com/EvgeniyBurdin/validated_dc
python 3.8引入了一个名为Literal的新类型,可在此处使用:
Literal
from dataclasses import dataclass from typing import Literal @dataclass class Person: name: Literal['Eric', 'John', 'Graham', 'Terry'] = 'Eric'
像mypy这样的类型检查器在正确解释它时没有问题,Person('John')获得一个通过,并且Person('Marc')被标记为不兼容。请注意,这种提示需要类型检查器才能发挥作用,当您运行代码时,它本身不会做任何事情
mypy
Person('John')
Person('Marc')
如果您使用的是较旧的python版本,并且无法升级到3.8,那么还可以通过正式的pip可安装的backport包^{}访问Literal类型,并使用from typing_extensions import Literal导入它
from typing_extensions import Literal
如果您需要在运行时对传递的值进行实际检查,则应该考虑使用^{}来定义数据控件。它的主要目标是使用一个强大的验证引擎来扩展类似数据类的结构,该引擎将检查类型提示以强制执行它们,即您认为在__post_init__中手工编写的内容
适用于Python3.8(typing.Literal):
ValidatedDC:https://github.com/EvgeniyBurdin/validated_dc
python 3.8引入了一个名为
Literal
的新类型,可在此处使用:像
mypy
这样的类型检查器在正确解释它时没有问题,Person('John')
获得一个通过,并且Person('Marc')
被标记为不兼容。请注意,这种提示需要类型检查器才能发挥作用,当您运行代码时,它本身不会做任何事情如果您使用的是较旧的python版本,并且无法升级到3.8,那么还可以通过正式的pip可安装的backport包^{} 访问
Literal
类型,并使用from typing_extensions import Literal
导入它如果您需要在运行时对传递的值进行实际检查,则应该考虑使用^{} 来定义数据控件。它的主要目标是使用一个强大的验证引擎来扩展类似数据类的结构,该引擎将检查类型提示以强制执行它们,即您认为在
__post_init__
中手工编写的内容相关问题 更多 >
编程相关推荐