假设:
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)
请注意,这个目标(指定关键字和传递args + kwargs)掩盖了我对args的其他误解:在python中,参数不能在设置了带有默认值的参数(关键字arg)后传入,如下所述。
然后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)
3条答案
按热度按时间unftdfkk1#
尽管
foo
的调用顺序不同,但args
中的值在考虑关键字参数biz
之前被分配给位置参数。这意味着bar
,* 可以 * 用位置参数调用,* 可以 * 在ness
被分配给它之前将值分配给biz
。也就是说,
mypy
提前捕获了以下潜在的运行时错误:字符串
"1"
被赋值给ness
,字符串"2"
成为args
的第一个元素。当foo
被调用时,args
的元素被赋值给位置参数biz
和baz
;在这种情况下,只有biz
得到一个值,即"2"
。只有这样才考虑关键字参数biz=ness
,此时biz
已经被考虑。pgccezyw2#
根据你的回答,我假设你希望linter传递
bar
的定义,并且你愿意为此目的对bar
的实现/声明进行修改。对我来说,根本问题是
bar
的实现是错误的--如果*args
不为空,那么调用foo(biz=ness, *args, **kwargs)
将失败,并出现mypy报告的错误。对我来说,你有三个选择:
1.通过不再传递
args
来修复对foo
的调用。这样的更改不会导致功能损失,因为无论如何,bar
中的非空args
都会引发TypeError
。在这种情况下,您还可以从bar
的签名中删除args
(同样,在不丢失功能的情况下-您只需将调用foo
触发的TypeError
替换为调用bar
中的TypeError
)1.通过将
biz
作为位置参数而不是命名参数传递来修复对foo
的调用:1.对我隐瞒这个问题(我从你的回答中理解)
但是,如果目标只是简单地防止mypy报告错误,则有语法可以实现:
现在,如果我在运行时解释器中比较每个建议的结果:
您可以看到:
bar_from_question
返回结果的每种情况,每隔一个bar_...
实现返回相同的结果;bar_from_question
之外的每个实现都对mypy保持沉默,我的印象是这是你想要的;在你的情况下,我会去解决根本问题(也就是说,要么应用要点1,或2),而不仅仅是试图强迫我(要点3)。
uqcuzwp83#
这就是我一直在寻找的答案,最后: