如何键入提示getter只允许dict键?

2024-09-27 19:19:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道如何使这个getter更安全:

VALUES = {
   '1': 'One',
   '2': 'Two',
   '3': 'Three'
}


def get(key : str) -> str:
    return VALUES[key]

我希望使用keyof VALUEStype(VALUES[key])类型,而不是str类型

get('4')应该抛出无效类型警告,因为该键不存在。我不确定这在Python中是否可行,因为我正生活在一个TypeScript仙境中:-)

TypeScript的正确外观如下所示:

get<K extends keyof VALUES>(key : K): typeof K
{
    return VALUES[key];
}

Tags: key警告类型getreturndeftypeone
2条回答

正如评论中所建议的那样,enum模块在这里提供了一个很好的解决方案。通过将strenum.Enum混合,我们可以创建一个与str完全向后兼容的Enum(即,可以在任何需要str类型的地方使用)

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'

如果将此定义输入交互式控制台,我们将看到此类具有以下行为:

>>> 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]

如您所见,我们定义了一种新类型:

  • 提供对成员的动态字典式访问,以及更多类型安全的访问形式
  • str完全向后兼容-它可以自由地与str对象进行比较,并且str方法可以在其成员上使用
  • 可以在类型提示中用作typing.Literal的替代方法。如果我有这样一个函数:
def do_something(some_string):
    if some_string not in ('One', 'Two', 'Three'):
        raise Exception('NO.')

然后我可以这样注释它:

from typing import Literal

def do_something(some_string: Literal['One', 'Two', 'Three']) -> None:
   ...

或者类似这样(在这种情况下,您必须传入Values枚举的成员,而不是普通字符串,否则类型检查器将引发错误):

# Values enum as defined above 
def do_something(some_string: Values) -> None:
   ...

还有一个更详细的指南,介绍pythonEnumshere的复杂性

一般来说,您不能这样做。但是,在这种特殊情况下,您可以使用^{}实现您想要的:

import typing
def get(key: typing.Literal['1','2','3']) -> str:
    return VALUES[key]

相关问题 更多 >

    热门问题