pythonAssert前的可选类型

nbysray5  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(312)

我将python类型提示和mypy用于以下代码:

from typing import Optional

def compute(
    use_wcog: bool = False,
    Xt: Optional[float] = None,
    Xd: Optional[float] = None,
    Xw: Optional[float] = None,
    Xs: Optional[float] = None,
):

    if use_wcog:
        reqs = (Xt, Xd, Xw)
        assert all([_ is not None for _ in reqs])
        res = ((Xt**2 + Xw**2) / Xd)**2
    else:
        reqs = (Xs, Xd)
        assert all([_ is not None for _ in reqs])
        res = (Xs**2 / Xd)**2

    return res

我得到以下错误:**(float和none)的未移植操作数类型(mypy error)
正确的处理方法是什么?

9rygscc1

9rygscc11#

mypy不够聪明,无法根据 all 以及列表理解。简单点:

if use_wcog:
        assert Xt and Xd and Xw
        res = ((Xt**2 + Xw**2) / Xd)**2
    else:
        assert Xs and Xd
        res = (Xs**2 / Xd)**2

fwiw,在函数体中嵌入这些依赖项使得类型化在很大程度上是无用的imo——以一种在运行时会出错的方式调用这个函数是非常容易的,而静态类型化的全部目的就是使使用错误可以静态地检测到。考虑到函数的两个实现在预期的输入和返回的结果方面有完全不同的约定,我就把它设为两个函数。

def compute_wcog(Xt: float, Xd: float, Xw: float) -> float:
    return ((Xt**2 + Xw**2) / Xd)**2

def compute_no_wcog(Xd: float, Xs: float) -> float:
    return (Xs**2 / Xd)**2

如果你真的需要单身 compute 功能与有效的多个接口,您可以使用 @overload 装饰师:

from typing import Literal, Optional, overload

@overload
def compute(use_wcog: Literal[True], Xt: float, Xd: float, Xw: float, Xs: None) -> float: ...

@overload
def compute(use_wcog: Literal[False], Xt: None, Xd: float, Xw: None, Xs: float) -> float: ...

def compute(
    use_wcog: bool = False,
    Xt: Optional[float] = None,
    Xd: Optional[float] = None,
    Xw: Optional[float] = None,
    Xs: Optional[float] = None,
):
    assert Xd is not None

    if use_wcog:
        assert Xt is not None and Xw is not None
        res = ((Xt**2 + Xw**2) / Xd)**2
    else:
        assert Xs is not None
        res = (Xs**2 / Xd)**2

    return res

compute(True, 1.0, 1.0, 1.0, None)    # works
compute(False, None, 1.0, None, 1.0)  # works
compute(True, None, 1.0, None, 1.0)   # error: No overload variant of "compute" matches argument types...

但这显然是更多的代码,没有太多的收益

相关问题