繁体   English   中英

使用命名参数定义的函数的 MyPy 类型提示但可以采用 **kwargs?

[英]MyPy type hints for a function defined with named parameters but can take **kwargs?

为标题的混乱道歉:

假设我定义了一个带有多个参数的函数。

现在在我的代码中,我使用字典将所有关键字参数传递到test()

import argparse
from typing import Dict, Callable

def test(a: str, b: Dict[str, str], c: str, d: argparse.Namespace, e: Callable) -> None:
    if d.t:
        print(f"{a} to the {b['foo']} to the {c}!")
    else:
        print(f"{a} to the {b['foo']} to the {c} also, {e()}")

def hello() -> str:
    return "Hello"

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-t", action="store_true", default=False)
    args = parser.parse_args()

    b = {'foo': 'bar'}
    info = {'b': b, "c": "foobar", "d": args, "e": hello}
    test("foo", **info)

在我的代码上运行 MyPy 时,出现以下错误:

test.py:21: error: Argument 2 to "test" has incompatible type "**Dict[str, object]"; expected "Dict[str, str]"
test.py:21: error: Argument 2 to "test" has incompatible type "**Dict[str, object]"; expected "str"
test.py:21: error: Argument 2 to "test" has incompatible type "**Dict[str, object]"; expected "Namespace"
test.py:21: error: Argument 2 to "test" has incompatible type "**Dict[str, object]"; expected "Callable[..., Any]"
Found 4 errors in 1 file (checked 1 source file)

为什么我得到这个? 以及如何正确键入提示功能以允许此操作?

您在类型检查之前示例的原因是plot_info所有值都是str (同构的),并且所有传递给函数的关键字参数也是str 没有类型不匹配的可能性,所以mypy报告成功。

在您的新示例中,无法将异构类型的info单独编码到其类型中。 让我们看看当我们运行reveal_type (info)会发生什么:

note: Revealed type is 'builtins.dict[builtins.str*, builtins.object*]'

所以我们看到mypy必须为值选择一个同构类型,它与object搭配。 mypy能否保证对象字典满足您对bcde个人类型约束, mypy是您传递的object s 在其眼底下? 不,所以它错误。

为了保留bcde的粒度类型,我们可以使用TypedDict ,它被用来支持Dict s 中的异构类型值:

class Info(TypedDict):
    b: Dict[str, str]
    c: str
    d: argparse.Namespace
    e: Callable

并将info声明更改为:

info: Info = {'b': b, "c": "foobar", "d": args, "e": hello}

这会导致mypy报告成功。

我们必须复制参数名称和类型。 可悲的是, 从函数的关键字参数生成 TypedDict没有显示直接的解决方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM