首页 > 解决方案 > 使用 dataclasses.MISSING 作为 Python 数据类的可选参数值?

问题描述

我想让set参数成为可选参数,但仍然允许None它是一个有效值。根据文档,它建议dataclasses.MISSING可以使用默认值来帮助实现这一点。

如上图,MISSINGvalue是一个sentinel对象,用来检测某些参数是否是用户提供的。使用此标记是因为None它是某些具有不同含义的参数的有效值。任何代码都不应直接使用该MISSING值。

但是通过如下使用它:

import dataclasses
from dataclasses import dataclass, field

@dataclass
class Var:
    get: list
    set: list = dataclasses.MISSING

    def __post_init__(self):
        if self.set is dataclasses.MISSING:
            self.set = self.get

 print(Var(get=['Title']))  

我收到一个错误:

Traceback (most recent call last):
File "main.py", line 31, in <module>
print(Var(get=['Title']))
TypeError: __init__() missing 1 required positional argument: 'set'

标签: pythonpython-dataclasses

解决方案


任何代码都不应直接使用 MISSING 值。

上面的这部分在文档中注明是有原因的。因此,如果可能,我们应该避免MISSING在我们的应用程序代码中使用用法(和导入)。在这种情况下, usingMISSING根本不适用于我们的用例。

Assumed usage (by avoiding directly working with the MISSING sentinel value, and instead using dataclasses.field(...):

from dataclasses import dataclass, field
from typing import Optional


@dataclass
class Var:
    get: list[str]
    set: Optional[list[str]] = field(default=None)


print(Var(get=['Title']))
# Var(get=['Title'], set=None)

But where is MISSING actually used?

The MISSING is a sentinel object that the dataclasses module uses behind the scenes, for its magic.

You can inspect the source code for dataclasses.field and find a clear usage of it there:

def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
          hash=None, compare=True, metadata=None):

You'll see the declared default value for fields such as default is default=MISSING instead of default=None. This is done mainly to identify if the user actually passes in a value for default or default_factory to the factory function fields. For example, it's perfectly valid to pass field(default=None) as we did in example above; however, since the default value is actually MISSING instead, dataclasses is able to detect that a value has been passed for this parameter (a value of None).


推荐阅读