【发布时间】:2021-08-09 05:45:08
【问题描述】:
我正在使用数据类和字段来传递默认值。 提供参数时,我想使用描述符类对其进行验证。
有什么方法可以利用字段(repr、default、init 等)的好处,同时获得描述符类的验证器好处?
from dataclasses import dataclass, field
class Descriptor:
def __init__(self, default):
self.default = default
def __set_name__(self, owner, name):
self.name = name
def __get__(self, obj, objtype=None):
if obj:
return vars(obj).get(self.name)
else:
return None
def __set__(self, obj, value):
if not value:
value = self.default
else:
value = field(default=int(value), repr=False)
vars(obj)[self.name] = value
@dataclass
class Person:
age: str = Descriptor(field(default=3, repr=False))
# Many additional attributes
# using same descriptor class
p = Person()
r = Person(2.37)
【问题讨论】:
-
为什么要将
field对象传递给描述符对象?老实说,我认为您正在尝试做的事情与dataclass不兼容。 -
描述符有效地取代了字段;我认为您想要
age = ClassVar(Descriptor(3))之类的东西,而Descriptor本身将处理将实际值存储在附加到其obj参数的属性中。 -
您可以考虑只使用
pydantic库,它有一个dataclass实现,具有验证功能。否则,标准库dataclass不会允许您尝试执行此操作。 -
顺便说一句,
vars(obj)[self.name] = value没有任何意义value = field(default=int(value), repr=False)... 将字段分配给实例属性对您没有任何作用。dataclass的全部意义在于,它自省类主体中的注释以生成各种样板方法当类本身被实例化时....当您创建实例以对该field对象执行任何操作时 -
基本上,人们需要了解数据类是针对特定用例的,即数据类,基本上充当记录类型的类。它们提供了一种避免样板文件的方法,但您必须坚持创建类定义的文档化方法。如果您想做其他更花哨的事情,那么最简单的解决方案就是不要使用
dataclasses.dataclass
标签: python python-3.x python-dataclasses