[英]Creating value type that raises exception on reading
How do I create a value type that raises an exception when read?如何创建读取时引发异常的值类型?
For example:例如:
from dataclasses import dataclass, field
Missing = ...
@dataclass
class A:
a: int = field(default=None) # <- value can be None
b: int = field(default=Missing) # <- can be Missing until you try to access it
def print(self):
for i in [self.a, self.b]:
print(i) # <- raises ValueError if i is Missing
In Python, it seems there is always a way for anything :-)在 Python 中,似乎总有办法解决任何问题 :-)
It appears you can solve this by a clever use of a descriptor value as a dataclass field, as illustrated below.您可以通过巧妙地将描述符值用作数据类字段来解决此问题,如下图所示。 I would also read more on the section on Validators to understand a little bit more about how descriptors work.
我还将阅读有关验证器部分的更多信息,以了解更多关于描述符如何工作的信息。
from dataclasses import dataclass
# create `_MissingType` class
_MissingType = type('_MissingType', (), {'__bool__': lambda self: False})
# create a singleton for that class
Missing = _MissingType()
class MissingValidator:
__slots__ = ('default', 'private_name')
# You may or may not want a default value
def __init__(self, default=Missing):
self.default = default
def __set_name__(self, owner, name):
self.private_name = '_' + name
# override __get__() to return a default value if one is not passed in to __init__()
def __get__(self, obj, obj_type=None):
try:
value = getattr(obj, self.private_name)
if value is Missing:
cls_name = obj_type.__qualname__
public_name = self.private_name.lstrip('_')
raise ValueError(f'Missing value for field `{public_name}` in class `{cls_name}`')
return value
except AttributeError:
return self.default
def __set__(self, obj, value):
setattr(obj, self.private_name, value)
@dataclass
class A:
a: int = None # <- value can be None
b: int = MissingValidator() # <- can be Missing until you try to access it
def print(self):
for i in [self.a, self.b]:
print(i) # <- raises ValueError if i is Missing
A(b=3).print()
# None
# 3
A(a=42).print()
# raises:
# ValueError: Missing value for field `b` in class `A`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.