为了账号安全,请及时绑定邮箱和手机立即绑定

嵌套字典上的参数太多或太少

嵌套字典上的参数太多或太少

弑天下 2023-07-11 17:11:00
dict我正在尝试在具有多个将函数绑定到它们的字段的类型中添加类型提示。例如from typing import Dict, Callable, Any, Uniondef fn():  print("Hello World")def fn2(name):   print("goodbye world", name)d = {  "hello" : {    "world": fn  },  "goodbye": {    "world": fn2  }} # type: Dict[str, Dict[str, Union[Callable[[], None], Callable[[str], None]]]]d["hello"]["world"]()d["goodbye"]["world"]("john")我遇到的问题是每当我尝试运行mypy(v0.782)时它都会抛出错误:test2.py:17: error: Too few argumentstest2.py:18: error: Too many arguments显然,从函数定义和类型提示中可以看出,我已经传递了正确的参数。我显然错过了一些东西,导致它抛出错误。Union但是,以下内容有效,所以我怀疑它与输入类型提示有关。from typing import Dict, Callable, Any, Uniondef fn():    print("Hello World")d = {"hello": {"world": fn}}  # type: Dict[str, Dict[str, Callable[[], None]]]d["hello"]["world"]()
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

让我提醒您,当使用 时未考虑以下约束时,就会出现问题中描述的问题Union

仅当操作对每个联合项都有效时,它们才对联合类型有效。这就是为什么通常需要使用isinstance()检查来首先将联合类型缩小为非联合类型。这也意味着建议避免使用union类型作为函数返回类型,因为调用者可能必须isinstance()在对值进行任何有趣的操作之前使用。[1]

作为解决方法,我建议使用带有可选参数的单个函数。我用来Protocol定义带有可选参数的回调类型,该参数无法使用Callable[...]

from typing import Protocol, Optional, Dict



class Fn(Protocol):

    def __call__(self, name: Optional[str] = None) -> None:

        ...



def fn(name: Optional[str] = None) -> None:

    if name is None:

        print("Hello World")

    else:

        print("goodbye world", name)



d: Dict[str, Dict[str, Fn]] = {

    "hello": {

        "world": fn

    },

    "goodbye": {

        "world": fn

    }

}


d["hello"]["world"]()

d["goodbye"]["world"]("john")

[1] https://mypy.readthedocs.io/en/stable/kinds_of_types.html#union-types


查看完整回答
反对 回复 2023-07-11
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信