python - 限制类属性值的可能选项

标签 python python-3.x

如何在实例化类对象时限制可能选择的选项?假设我们有一个如下所示的类,我们希望将 value 值限制为仅在 valueOptions 列表中进行预定义。我的实现尝试如下。是否有更多 Pythonic 方式来实现相同的结果?

class TestClass:
    valueOptions = ['A value', 'The value', 'Another value']
    
    def __init__(self, value):
        self.value = value
    
    @property
    def value(self):
        return self._value
    
    @value.setter
    def value(self, val):
        if val not in self.valueOptions:
            raise ValueError('Value not in available options.')
        self._value = val
    
    def __str__(self):
        return f'Value: {self.value}'

v1 = TestClass('A value')  # line 20
v2 = TestClass('Value')  # line 21

运行后:

Traceback (most recent call last):
  File "<string>", line 21, in <module>
  File "<string>", line 5, in __init__
File "<string>", line 14, in value
ValueError: Value not in available options.

最佳答案

如果需要有限的值,请使用 Enum 而不是 str

核心问题是您(隐含地;您的代码未键入)将 value 定义为字符串类型。但是您不需要字符串:您需要一个有限的可能值列表。字符串不是编写该代码的正确变量类型。

enum模块允许您定义具有有限数量的选项/值的枚举类型(类)。

这实际上也解决了另一个问题:您的示例中的值是硬编码的,在您的代码中创建“魔数(Magic Number)”(或在本例中为:“魔数(Magic Number)”)。您的代码最终会在许多不同的地方导致“一个值”、“该值”和“另一个值”的分散实例。如果您(在将来某个时候)决定将“The value”替换为“The best value”,您就会遇到代码维护问题...

这是一个使用枚举(和类型提示)的代码示例:

from enum import Enum

class ValueOptions(Enum):
	A_VALUE = 'A value',
	THE_VALUE = 'The value',
	ANOTHER_VALUE = 'Another value'

class TestClass:    
    def __init__(self, value: ValueOptions) -> None:
        self.value = value


    def __str__(self) -> str:
        return f'Value: {self.value.name}'

v1 = TestClass(ValueOptions.A_VALUE)
print(v1)

v2 = TestClass(ValueOptions.ILLEGAL_VALUE)
print(v2)

Try it online!

这导致 v1 的代码有效,而 v2 的代码错误:

Traceback (most recent call last):
  File ".code.tio", line 19, in <module>
    v2 = TestClass(ValueOptions.ILLEGAL_VALUE)
  File "/usr/lib64/python3.7/enum.py", line 349, in __getattr__
    raise AttributeError(name) from None
AttributeError: ILLEGAL_VALUE

此错误不仅会在运行时显示,而且(甚至更好!)在编写代码时也会显示。任何 Python 代码检查器(例如 mypy)都会检测到我使用了非法属性:

❯ mypy ./enum_test.py
enum_test.py:21: error: "Type[ValueOptions]" has no attribute "ILLEGAL_VALUE"
Found 1 error in 1 file (checked 1 source file)

最重要的是:此代码比您的版本短一点! ;-)

关于python - 限制类属性值的可能选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74184600/

相关文章:

python - 如何执行 python 脚本并保持打开的 shell 以便在 VIM 中进行进一步测试

python - pytester - testdir 找不到 pytest 插件

python - 我怎样才能从 bs4 导入 BeautifulSoup?

python - 在 Python 中使用类根据用户输入打印出实例属性

python - 同时使用 Python 3.1 和 2.5

python - 如何在 Python 3.3 中更改 ttk.Treeview 列宽和粗细

Python 分解数字函数,接收数字以及分解方法

python Pandas 。使用 Series 创建 DataFrame 不会保留 dtype

python - 如何使用日期对 Python 列表进行排序

python - 如何根据特定列值从二维列表中删除行?