如何限制数据类属性中的值?

vt2*_*253 1 python python-dataclasses

我有以下数据类Gear,我想将 gear_level 的最大值限制为 0 到 5。但是正如您所看到的,当我增加 gear_level 时,它会高于 5,这不是我想要的。我尝试了方法以及postinit。我该如何解决这个问题?

from dataclasses import dataclass

@dataclass
class Gear:
    gear_level: int = 0
    direction: str = None
    # more codes ...

    def __postinit__(self):
        if self.gear_level <= 0:
            self.gear_level = 0
        elif 5 > self.gear_level > 0:
            self.gear_level = self.gear_level
        else:
            self.gear_level = 5

    def set_gear_level(self, level):
        if level <= 0:
            self.gear_level = 0
        elif 5 > level > 0:
            self.gear_level = level
        else:
            self.gear_level = 5


g = Gear()

g.set_gear_level(6)

print(g)

g.gear_level += 1

print(g)

g.set_gear_level(-1)

print(g)

g.gear_level -= 1
print(g)
Run Code Online (Sandbox Code Playgroud)

理想情况下,我更喜欢使用 g.gear_level += 1 表示法,因为我想增加 gear_level。它不应该从档位1跳到5。另外,当它递减时,它应该停在0。它应该既接受0的赋值又允许递减到0。这可以做到吗?

Gear(gear_level=5, direction=None)
Gear(gear_level=6, direction=None)
Gear(gear_level=0, direction=None)
Gear(gear_level=-1, direction=None)
Run Code Online (Sandbox Code Playgroud)

Jas*_*ijn 5

在这种情况下,我将简单地使用一个属性:

@dataclass
class Gear:
    gear_level: int

    # Rest of the class excluded for simplicity

    @property
    def gear_level(self) -> int:
        return self._gear_level

    @gear_level.setter
    def gear_level(self, value: int) -> None:
        self._gear_level = min(max(value, 0), 5)
Run Code Online (Sandbox Code Playgroud)

这样您就不需要编写__post_init__或必须记住调用特定方法:即使使用 ,分配给也gear_level将被保留。0 <= gear_level <= 5+=

  • 我同意,在更复杂的情况下,编写自定义描述符可能很有用(尽管在这种情况下,我实际上建议研究像 Pydantic 这样的库)。对于OP,我认为这就是YAGNI 的情况。 (2认同)