如何使数据类实例属性非公共和 __init__ arg?

Int*_*rer 1 python python-dataclasses

如果我想要一个实例属性是:

  • 非公开(又名有一个前导下划线)
  • __init__作为签名中的参数

通常,我会这样做:

class Foo:
    def __init__(self, bar: str):
        self._bar = bar

foo = Foo(bar="bar")  # foo.bar would raise an AttributeError
Run Code Online (Sandbox Code Playgroud)

但是,在 中dataclasses,我不确定如何执行此操作。

from dataclasses import dataclass

@dataclass
class Foo:
    bar: str  # This leaves bar as a public instance attribute
Run Code Online (Sandbox Code Playgroud)

执行此操作的正确方法是什么dataclasses.dataclass

che*_*ner 7

InitVar对于and方法来说,这是一个相对简单的情况__post_init__。(尽管冗长的内容可能不是您想要的。)

from dataclasses import dataclass, InitVar


@dataclass
class Foo:
    bar: InitVar[str]

    def __post_init__(self, bar):
        self._bar = bar
Run Code Online (Sandbox Code Playgroud)

这就像你所描述的那样。bar(如所写)是 的必需参数__init__,但不会创建名为 的属性bar

>>> f = Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'bar'
>>> f = Foo(9)
>>> f._bar
9
>>> f.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'bar'
Run Code Online (Sandbox Code Playgroud)

需要明确的是,这是您将在现有数据类中使用的东西;您不会选择创建一个数据类来执行此操作。