<p>正如评论中所建议的那样,<code>enum</code>模块在这里提供了一个很好的解决方案。通过将<code>str</code>与<code>enum.Enum</code>混合,我们可以创建一个与<code>str</code>完全向后兼容的<code>Enum</code>(即,可以在任何需要<code>str</code>类型的地方使用)</p>
<pre><code>from enum import Enum
# The mixin type has to come first if you're combining
# enum.Enum with other types
class Values(str, Enum):
N1 = 'One'
N2 = 'Two'
N3 = 'Three'
</code></pre>
<p>如果将此定义输入交互式控制台,我们将看到此类具有以下行为:</p>
<pre><code>>>> Values['N1']
<Values.N1: 'One'>
>>> Values('One')
<Values.N1: 'One'>
>>> Values.N1
<Values.N1: 'One'>
>>> Values('One') is Values.N1 is Values['N1']
True
>>> Values.N1.name
'N1'
>>> Values.N1.value
'One'
>>> Values.N1 == 'One'
True
>>> Values.N1 is 'One'
False
>>> Values.N1.startswith('On')
True
>>> type(Values.N1)
<enum 'Values'>
>>> for key in Values:
... print(key)
...
Values.N1
Values.N2
Values.N3
>>> list(Values)
[Values.N1, Values.N2, Values.N3]
</code></pre>
<p>如您所见,我们定义了一种新类型:</p>
<ul>
<li>提供对成员的动态字典式访问,以及更多类型安全的访问形式</li>
<li>与<code>str</code>完全向后兼容-它可以自由地与<code>str</code>对象进行比较,并且<code>str</code>方法可以在其成员上使用</li>
<li>可以在类型提示中用作<code>typing.Literal</code>的替代方法。如果我有这样一个函数:</li>
</ul>
<pre><code>def do_something(some_string):
if some_string not in ('One', 'Two', 'Three'):
raise Exception('NO.')
</code></pre>
<p>然后我可以这样注释它:</p>
<pre><code>from typing import Literal
def do_something(some_string: Literal['One', 'Two', 'Three']) -> None:
...
</code></pre>
<p>或者类似这样(在这种情况下,您必须传入<code>Values</code>枚举的成员,而不是普通字符串,否则类型检查器将引发错误):</p>
<pre><code># Values enum as defined above
def do_something(some_string: Values) -> None:
...
</code></pre>
<p>还有一个更详细的指南,介绍python<code>Enum</code>s<a href="https://docs.python.org/3.11/howto/enum.html" rel="nofollow noreferrer">here</a>的复杂性</p>