自定义模块级别常量的Python类型提示

我试图在类中添加类型提示,但是我在模块级常量这一特殊问题上苦苦挣扎。在下面的示例中,我用BLUECAR,REDCAR,YELLOWCAR,WHITECAR替换了我的常量-仅仅假设我的整个程序都是围绕这4个常量演化的,这就是为什么我要明确定义它们的原因。

from collections import namedtuple
from typing import List,Union,TypeVar

# I define CarTypeRef from id and name
CarTypeRef = namedtuple("CarType","id name")


# I define possible car types by id and name
BLUECAR: CarTypeRef = CarTypeRef (1,'Blue Car')
REDCAR: CarTypeRef = CarTypeRef (2,'Red Car')
YELLOWCAR: CarTypeRef = CarTypeRef (3,'Yellow Car')
WHITECAR: CarTypeRef = CarTypeRef (4,'White Car')
"""Car type init with id-name"""

# 1. try: this does not work:
CarType = TypeVar("CarType",BLUECAR,REDCAR,YELLOWCAR,WHITECAR)
"""Type alias for possible car types"""

# 2. try: this (type alias) does also not work:
CarType = Union[BLUECAR,WHITECAR]

# I later use the following list
# e.g. to loop through available car types
CARTYPES: List[CarType] = [
    BLUECAR,WHITECAR]
"""Available car types"""

对于这两种类型定义,我都会在运行时得到以下输出:

> 1.try: TypeError: Union[arg,...]: each arg must be a type. Got CarType(id=1,name='Blue Car').
> 2. try: TypeError: TypeVar(name,constraint,...): constraints must be types. Got CarType(id=1,name='Blue Car').

我在做什么错?如何为这4个常量创建自定义类型检查?

注意:当然,我可以简单地使用字符串(例如:“ bluecar”,“ redcar”,..),但是由于这4个常量在我的代码中出现的频率很高,所以我想更明确一些-出于代码易读性和静态类型测试的目的。

yymbaya 回答:自定义模块级别常量的Python类型提示

感谢@ Aran-Fey向我指出正确的方向。我还没有在python中听说过枚举。我能够大大减少代码,现在只有:

class CarType(Enum):
    """Available car types"""
    BLUECAR = 1
    REDCAR = 2
    YELLOWCAR = 3
    WHITECAR = 4

我什至可以得到人类可读的文本,而无需指定str作为名称,例如:

>>>> print(Car.REDCAR.name.lower().capitalize())
Redcar

..尽管有点复杂。

此外,我无法直接导入BLUECAR,REDCAR,YELLOWCAR或WHITECAR,这意味着我必须始终引用具有完整Enum类的对象,例如

from .typedef import CarType
if car_type in [CarType.BLUECAR,CarType.REDCAR,CarType.WHITECAR]:
    paint_yellow(car)

..远远超过:

from .typedef import BLUECAR,REDCAR,WHITECAR

if car_type in [BLUECAR,WHITECAR]:
    paint_yellow(car)

[更新]

虽然枚举方法很好,但我最终还是使用了更适合自己目的的简单字符串常量,例如:

BLUECAR: str = "Blue Car"
REDCAR: str = "Red Car"
YELLOWCAR: str = "Yellow Car"
WHITECAR: str = "White Car"

CARTYPES: List[str] = [BLUECAR,YELLOWCAR,WHITECAR]

..因为我可以做到:

from .typedef import BLUECAR,WHITECAR,CARTYPES

for car_type in CARTYPES:
    ...
..
if car_type in [BLUECAR,REDCAR]:
    ...

我了解这特定于这些变量的使用方式,也许汽车类型的示例不太适合描述我的实际实现方案。

本文链接:https://www.f2er.com/3045876.html

大家都在问