python 我如何缩小数据类注解的范围(例如,我如何在post_init中处理了default None之后更新类型提示)?

lsmepo6l  于 2023-02-07  发布在  Python
关注(0)|答案(1)|浏览(82)

我有一个数据类,它可以接受一个关键字值,或者,如果没有指定值,则可以从其他属性推断值。

import dataclasses

@dataclasses.dataclass
class RelatedValues:
    primary: float
    _: dataclasses.KW_ONLY
    secondary: float | None = None

def __post_init__(self):
    if self.secondary is None:
        self.secondary = self.primary

这段代码可以工作,但它让我坚持使用float | None作为.secondary的类型提示,即使.secondary * 不可能 * 在__post_init__之后是None
cast-在__post_init__中调用self.secondary不起作用。

NULL_FLOAT = float(int(uuid.uuid4())

@dataclasses.dataclass
class RelatedValues:
    primary: float
    _: dataclasses.KW_ONLY
    secondary: float = NULL_FLOAT

def __post_init__(self):
    if self.secondary == NULL_FLOAT:
        self.secondary = self.primary

但感觉明显不像Python。
这也适用于:

@dataclasses.dataclass
class RelatedValues:
    primary: float
    _: dataclasses.KW_ONLY
    _secondary: float | None = None

def __post_init__(self):
    if self._secondary is None:
        self.secondary = self.primary
    else:
        self.secondary = self._secondary

或者这个:

@dataclasses.dataclass
class RelatedValues:
    primary: float
    _: dataclasses.KW_ONLY
    _secondary: float | None = None

@property
def secondary(self) -> float:
    if self._secondary is None:
        self.secondary = self.primary
    else:
        self.secondary = self._secondary

但后两个只是为了类型缩小而损坏了我的kwargs,这感觉有点不对。
我错过了什么?

sycxhyv7

sycxhyv71#

如果secondary总是被赋值为非None值,那么它首先不应该被输入为float | None,只有__init__的 * 参数 *(用于初始化self.secondary)可能是None

from dataclasses import dataclass, field, InitVar

@dataclass
class RelatedValues:
    primary: float
    secondary: float = field(init=False)
    secondary_: InitVar[float|None] = None

    def __post_init__(self, secondary_):
        if secondary_ is None:
            secondary_ = self.primary
        self.secondary = secondary_

只有当您不想首先提供自己的__init__方法时,才有必要使用这些方法。

@dataclass(init=False)
class RelatedValues:
    primary: float
    secondary: float

    def __init__(self, primary: float, secondary: float = None):
        if secondary is None:
            secondary = primary
        self.primary = primary
        self.secondary = secondary

相关问题