如何使python数据类字段不允许None值

How to make a python dataclass field not allow None values

提问人:Clay Casper 提问时间:10/25/2023 更新时间:10/26/2023 访问量:51

问:

在了解了数据类之后,似乎数据类将始终具有您定义的所有属性。添加 only 意味着您不必将参数传递到构造函数中。我想使一个字段成为必填字段,因为它不能是 .OptionalNone

所以如果我有

@dataclass
class SomeClass():
  a: int
  b: Optional[int] = None

test = SomeClass(a=None)

我希望这会引发错误,但不知道实现该结果的最佳方法。

我的两个想法是使用 运行验证逻辑或使用 pydantic。__post_init__

这个问题有没有普遍接受的解决方案?

蟒蛇 python-dataclasses

评论

0赞 Mad Physicist 10/25/2023
除非你使用强制类型的解释器/编译器,否则python不会为你做到这一点。
0赞 Clay Casper 10/25/2023
@MadPhysicist None 不就是一个值吗?这意味着您可以在运行时对其运行验证?
1赞 RomanPerekhrest 10/25/2023
@ClayCasper,是的,您可以通过以下方式确保它__post_init__

答:

1赞 RomanPerekhrest 10/26/2023 #1

您提到的两种方式都非常合适,但 pydantic.dataclasses 将为您进行自动验证:

from typing import Optional
from pydantic.dataclasses import dataclass as pdataclass

@pdataclass
class SomeClass():
  a: int
  b: Optional[int] = None

test = SomeClass(a=None) 

给出详细的输出/错误:

    test = SomeClass(a=None)
           ^^^^^^^^^^^^^^^^^
  File "/data/.virtualenvs/test/lib/python3.11/site-packages/pydantic/_internal/_dataclasses.py", line 132, in __init__
    s.__pydantic_validator__.validate_python(ArgsKwargs(args, kwargs), self_instance=s)
pydantic_core._pydantic_core.ValidationError: 1 validation error for SomeClass
a
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]

使用标准时,您需要在方法中提供自己的验证逻辑:dataclasses__post_init__

from dataclasses import dataclass
from typing import Optional

@dataclass
class SomeClass():
  a: int
  b: Optional[int] = None

  def __post_init__(self):
      if not isinstance(self.a, int):
          raise ValueError('Field `a` must be of integer type')

test = SomeClass(a=None) 

    test = SomeClass(a=None)
           ^^^^^^^^^^^^^^^^^
  File "<string>", line 5, in __init__
..., in __post_init__
    raise ValueError('Field `a` must be of integer type')
ValueError: Field `a` must be of integer type

评论

0赞 Clay Casper 10/26/2023
仅仅检查还不够吗?if a is None
0赞 RomanPerekhrest 10/26/2023
@ClayCasper,您可以这样做,但这并不能确保字段的真实类型检查。like 会被 承认,而传递的参数远非整数。a: intSomeClass(a=['a'])if a is None:
1赞 Clay Casper 10/26/2023
意义。谢谢!