mypy:覆盖变量时赋值类型不兼容

问题描述 投票:0回答:1

在我无法理解的脚本上运行 mypy 版本 0.942 时出现

assignment
错误。

我有一个采用字符串形式的变量

price_point
,根据字符串是否包含“-”,将确定该变量在传递给另一个函数之前是否被操作到列表中
_other_func()
。变量也可以是
None
.

尝试 1:

代码:

def _other_func(
    price_points: Optional[Union[List[str], str]]
) -> float:
    return 1.0

def get_rate(price_point: Optional[str])->float:
    """
    Args:
        price_point: String representing single price or range of prices
        e.g. '100' or '100-200'. Can also be None.
    """

    if price_point and len(price_point_range := price_point.split("-")) > 1:

        print(f"Checking range {price_point_range[0]} to {price_point_range[1]}")
        price_point = price_point_range

    return _other_func(price_point)

返回错误:

error: Incompatible types in assignment (expression has type "List[str]", variable has type "Optional[str]")  [assignment]
            price_point = price_point_range
                          ^

有人可以解释为什么

mypy
关注这个变量,因为
List
类型在_other_func()输入的类型联合中被考虑了吗?我愿意听取其他建议。


尝试 2:

我认为这个问题可能与变量的名称有关,所以我尝试了这种替代方法来重命名变量,然后再将其传递给

_other_func()

def get_rate(price_point: Optional[str])->float:
    """
    Args:
        price_point: String representing single price or range of prices
        e.g. '100' or '100-200'. Can also be None.
    """

    if price_point and len(price_point_range := price_point.split("-")) > 1:

        print(f"Checking range {price_point_range[0]} to {price_point_range[1]}")
        price_point_input = price_point_range
    else:
        price_point_input = price_point

    return _other_func(price_point_input)

但同样的错误仍然存在:

error: Incompatible types in assignment (expression has type "Optional[str]", variable has type "List[str]")  [assignment]
            price_point_input = price_point
                                ^

我不确定我是否只是在那些盯着屏幕看太久的日子里……

python mypy typing
1个回答
1
投票

静态类型不能在运行时改变。

price_point
是一个
Optional[str]
,它必须在调用
get_rate
期间保持这种状态。如果你想将不同类型的值传递给
other_func
,你需要使用不同的变量来保存字符串或列表(或
None
):

def get_rate(price_point: Optional[str])->float:
    """
    Args:
        price_point: String representing single price or range of prices
        e.g. '100' or '100-200'. Can also be None.
    """
   
    arg: Optional[Union[list[str], str]] = price_point

    if price_point and len(price_point_range := price_point.split("-")) > 1:

        print(f"Checking range {price_point_range[0]} to {price_point_range[1]}")
        arg = price_point_range

    return _other_func(arg)

但是,我可能会跳过新变量,只调用两次

_other_func
,每个调用都有适当的参数。

def get_rate(price_point: Optional[str])->float:
    """
    Args:
        price_point: String representing single price or range of prices
        e.g. '100' or '100-200'. Can also be None.
    """

    
    if price_point and len(price_point_range := price_point.split("-")) > 1:

        print(f"Checking range {price_point_range[0]} to {price_point_range[1]}")
        return _other_func(price_point_range)

    return _other_func(price_point)

更好的是,考虑“统一”单一类型

list[str]
下的三种可能性,它应该包含0、1或2个字符串。

def _other_func(
    price_points: list[str]
) -> float:
    match len(price_points):
        case 0:
            ...  # Old None case
        case 1:
            ...  # Old str case
        case 2:
            ...  # Old list[str] case


def get_rate(price_point: Optional[str])->float:
    """
    arg: list[str]
    if not price_point:
        arg = []
    elif len(price_point_range := price_point.split("-")) > 1:
        arg = [price_point]
    else:
        print(f"Checking range {price_point_range[0]} to {price_point_range[1]}")
        arg = price_point_range

    return _other_func(arg)
© www.soinside.com 2019 - 2024. All rights reserved.