假设:
def foo(biz: str = 'biz',baz: str = 'baz', *args:Any, **kwargs:Any)-> str:
return biz + baz
我使用的方法如下:
def bar(ness: str = 'ness', *args, **kwargs):
return foo(biz=ness, *args, **kwargs)
Note that this goal (specifying keywords and passing args + kwargs) shadowed some other misunderstanding on my part related to args: args, in python, can't be passed in after an arg with a default value (a keyword arg) has been set, as correctly pointed out below..
然后mypy
版本0.812抛出如下错误:
$: mypy --ignore-missing-imports --disallow-untyped-defs --disallow-incomplete-defs
foo/foo.py:6: error: "foo" gets multiple values for keyword argument "biz"
是否有办法解决这个问题,尤其是,而不在下面的返回线以外的任何地方进行重大更改
return foo(biz=ness, *args, **kwargs)
这就是我最终想要的答案:
根据您的回答,我将假设您希望linter传递
bar
的定义,并且您愿意为此目的对bar
的实现/声明进行更改对我来说,根本的问题是
bar
的实现是错误的-如果*args
不是空的,那么调用foo(biz=ness, *args, **kwargs)
将失败,并出现mypy报告的错误对我来说,你有三个选择:
通过不再传递
args
修复对foo
的调用。这样的更改不会导致功能损失,因为在bar
中有一个非空的args
无论如何都会引发一个TypeError
。在这种情况下,您还可以从bar
的签名中删除args
(同样,在不丢失功能的情况下-您只需将对foo
的调用触发的TypeError
替换为对bar
的调用中的TypeError
)通过将
biz
作为位置参数而不是命名参数传递,修复对foo
的调用:向mypy隐瞒问题(我从您的回答中了解)
但是,如果目标只是防止mypy报告错误,则有以下语法:
现在,如果我在运行时解释器中比较每个建议的结果:
你可以看到:
bar_from_question
返回结果的每一种情况,其他每一个bar_...
实现都返回相同的结果李>bar_from_question
之外的每个实现都对mypy保持沉默,我认为mypy是您想要的李>在您的情况下,我会寻求根本问题的解决方案(即,应用要点1或2),而不仅仅是试图强制mypy(要点3)
尽管对
foo
的调用有顺序,但在考虑关键字参数biz
之前,args
中的值被分配给位置参数。这意味着bar
可以用位置参数调用,可以在ness
被赋值之前将一个值赋值给biz
也就是说,
mypy
正在提前捕获以下潜在的运行时错误:字符串
"1"
被分配给ness
,字符串"2"
成为args
的第一个元素。当调用foo
时,将args
的元素分配给位置参数biz
和baz
;在这种情况下,只有biz
获得一个值,即"2"
。只有这样,才会考虑关键字参数biz=ness
,此时biz
已被考虑相关问题 更多 >
编程相关推荐