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

迪兰姆

为标题混乱而道歉:

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

现在,在以后的代码中,我使用字典将test()所有关键字args传递给它

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)

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

马里奥(Mario Ishac)

您在进行类型检查之前示例的原因是因为的所有值plot_info都是str(同质的),并且传递到函数中的所有关键字参数也都是str类型不匹配的可能性mypy不大,因此报告成功。

在您的新示例中,info不能将异构类型的单独编码为其类型。让我们看看运行时会发生什么reveal_type(info)

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

因此,我们看到mypy必须为该值选择一个同质类型,并且与一起使用objectmypy保证对象满足您的个性化类型约束的字典bcde,因为你通过object在其眼睛S' 不,所以它出错。

为了保持颗粒类型bcde,我们可以使用TypedDict,这是为了支持在非均相类型的值DictS:

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对此没有直接的解决方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

可以使用命名参数火花提交吗?

在Go中可以使用命名参数调用函数吗?

我可以使用命名参数作为变量在python中调用函数吗?

Python3:可以使用命名函数定义进行列表理解吗?

我可以使用相同的URL,但可以使用不同的动态细分吗?

我可以使用一些参数引用命名子例程吗?

我可以在std :: function模板签名类型参数中使用命名参数吗?

python /我可以将定义的字典传递给** kwargs吗?

Typescript:可以使用enum作为函数参数类型吗?

DNS无法解析,但可以使用FQDN ping和使用nslookup吗?

Kotlin:可以为varargs使用命名参数吗?

ReSharper可以使用关键字进行声明,但可以输入名称作为成员访问权限吗?

在VS2015中使用目标.Net 4.5,但可以使用C#6功能吗?

OBJ-C,我可以使用协议作为函数参数的参数类型吗?

我可以使用类型作为值(或从构造函数参数正确推断通用类类型)吗?

修改两个单词的字符串函数以在Python中使用** kwargs吗?

我可以使用命令提示符来控制连接的设备吗?

我可以发送 **kwargs 代替 requests.post 中的设置参数吗?

用 C 编写的函数不能有 **kwargs 参数是真的吗?

您可以从函数,args和kwargs中确定如何分配变量吗?

类型构造函数可以使用与类型相同的别名吗?

无论如何,可以使剑道使用命名模板吗?

Thinking Sphinx延迟增量可以使用命名的delay_job队列吗?

编写可能最终传递任何类型的结构的函数时,可以使用接口作为参数吗?

可以使用自动占位符来推断非类型模板参数的函数结果吗?

我可以使用DataKinds编写一个返回参数编码类型的值的函数吗?

可以使用 std 容器为函数模板推导出类型参数吗?

休眠-我可以混合使用命名参数和位置参数吗?

可以在类函数中使用类的类型提示吗?