如何解决嵌套字典上的参数过多或参数过多
我正在尝试以dict
类型添加类型提示,该类型提示具有多个将功能绑定到它们的字段。
例如
from typing import Dict,Callable,Any,Union
def 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 arguments
test2.py:18: error: Too many arguments
很显然,从函数定义和类型提示可以看出,我已经传递了正确的参数。我显然丢失了一些东西,因为它会引发错误。
但是,以下方法可行,因此我怀疑它与类型提示中的Union
类型有关。
from typing import Dict,Union
def fn():
print("Hello World")
d = {"hello": {"world": fn}} # type: Dict[str,Callable[[],None]]]
d["hello"]["world"]()
解决方法
让我提醒您,使用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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。