python 如何检查一个字符串是否是mypy的字符串常量?

jv4diomz  于 2023-01-08  发布在  Python
关注(0)|答案(2)|浏览(121)

有了这个代码

import os
from typing import Literal, get_args

Markets = Literal[
    "BE", "DE", "DK", "EE", "ES", "FI", "FR", "GB", "IT", "LT", "LV", "NL", "NO", "PL", "PT", "SE"
]
MARKETS: list[Markets] = list(get_args(Markets))

def foo(x: Markets) -> None:
    print(x)

market = os.environ.get("market")

if market not in MARKETS:
    raise ValueError

foo(market)

我得到以下错误。

Argument 1 to "foo" has incompatible type "str"; expected "Literal['BE', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'IT', 'LT', 'LV', 'NL', 'NO', 'PL', 'PT', 'SE']"  [arg-type]mypy(error)

我需要如何检查market变量,以便mypy知道它是正确的类型?

ntjbwcob

ntjbwcob1#

是的,cast是最简单的方法IMO:

import os
from typing import Literal, cast, get_args

Market = Literal[
    "BE", "DE", "DK", "EE", "ES", "FI", "FR", "GB", "IT", "LT", "LV", "NL", "NO", "PL", "PT", "SE"
]
MARKETS: list[Market] = list(get_args(Market))

def foo(x: Market) -> None:
    print(x)

market = cast(Market, os.environ.get("market"))
# reveal_type(market)

if market not in MARKETS:
    raise ValueError

foo(market)

取消注解reveal_type语句并运行mypy将给予以下结果:
note: Revealed type is "Union[Literal['BE'], Literal['DE'], Literal['DK'], Literal['EE'], Literal['ES'], Literal['FI'], Literal['FR'], Literal['GB'], Literal['IT'], Literal['LT'], Literal['LV'], Literal['NL'], Literal['NO'], Literal['PL'], Literal['PT'], Literal['SE']]"
因此,该类型被正确地推断为这些字符串常量的并集。
顺便说一句,从语义上讲,你的字面联合体的名字应该是Market,而不是Markets(甚至可能是MarketTypeMarketT),它指的是变量的类型,它毕竟代表了一个单一的市场,而不是多个市场,另一方面,list的名字是合适的,因为它指的是所有可能的市场的集合。

a9wyjsp7

a9wyjsp72#

不需要使用cast(..),只需键入变量即可:

def foo(x: Market) -> None:
    print(x)

market: Market = os.environ.get("market")

foo(market)

相关问题