我们广泛使用静态类型检查,但我们也需要一些简单的运行时类型检查。我喜欢使用我们的静态类型进行运行时类型检查。我看过 typeguard 和其他库,但我更喜欢更简单的东西。
我已经在下面尝试过,但是
assert value in expected_type
没有意义。如何创建一个简单的函数来检查字符串是否在 Python 字符串文字中?
from typing_extensions import Literal
def check_str_in_literal(value: str, expected_type: Literal):
assert value in expected_type
Gender = Literal["Male", "Female", "Other"]
def print_gender(gender: Gender):
print(gender)
# Unknown string as it's been retrieved from elsewhere
strRetrievedFromDB = "Male" # type: ignore
check_str_in_literal(strRetrievedFromDB, Gender)
print_gender(strRetrievedFromDB)
看一个
Literal
的内容,我们可以看到值在私有属性里面__args__
>>> from typing_extensions import Literal
>>> literal = Literal["a", "b", "c"]
>>> literal.__dict__
{'_inst': True,
'_name': None,
'__origin__': typing.Literal,
'__slots__': None,
'__args__': ('a', 'b', 'c'),
'__parameters__': (),
'__module__': 'typing'}
因此,如果确实需要使用
Literal
,一种方法是这样做:
def check_str_in_literal(value: str, expected_type: Literal):
assert value in expected_type.__args__
但是,使用私有属性通常不是一个好主意。
如评论中所述,您还可以使用
Enum
(或来自 enum
模块的其他类型的枚举),例如:
import enum
from typing import Optional
class Gender(enum.Enum):
Male = enum.auto()
Female = enum.auto()
Other = enum.auto()
def get_gender(gender:str) -> Optional[Gender]:
"""Get an Enum Gender from its name (None if not valid)"""
try:
return Gender[gender]
except KeyError:
return None
def print_gender(gender:Gender) -> None:
"""Do something with a gender"""
print(gender.name)
gender_from_db = "Male"
gender = get_gender(gender_from_db)
if gender:
print_gender(gender)