如何解决如何使用 MYPY 传递关键字参数?
假设:
Index
我这样使用:
def foo(biz: str = 'biz',baz: str = 'baz',*args:Any,**kwargs:Any)-> str:
return biz + baz
请注意,这个目标(指定关键字并传递 args + kwargs)掩盖了我对 args 的一些其他误解:在 python 中,不能在具有默认值的 arg 之后传入(关键字 arg)已设置,如下面正确指出的..
然后 def bar(ness: str = 'ness',*args,**kwargs):
return foo(biz=ness,**kwargs)
版本 0.812 抛出如下错误:
mypy
有没有办法解决这个问题,特别是除了下面的返回行之外的任何地方都没有进行重大更改?
$: mypy --ignore-missing-imports --disallow-untyped-defs --disallow-incomplete-defs
foo/foo.py:6: error: "foo" gets multiple values for keyword argument "biz"
解决方法
尽管对 foo
的调用进行了排序,但在考虑关键字参数 args
之前,biz
中的值已分配给位置参数。这意味着 bar
,可以 用位置参数调用,可以 在 biz
之前有一个赋值给 ness
分配给它。
也就是说,mypy
正在及早捕获以下潜在的运行时错误:
>>> bar("1","2")
Traceback (most recent call last):
File "<stdin>",line 1,in <module>
File "<stdin>",line 2,in bar
TypeError: foo() got multiple values for argument 'biz'
字符串"1"
被分配给ness
,字符串"2"
成为args
的第一个元素。当调用 foo
时,args
的元素被分配给位置参数 biz
和 baz
;在这种情况下,只有 biz
获得一个值,即 "2"
。只有到那时才考虑关键字参数 biz=ness
,此时 biz
已经被考虑在内。
这是我一直在寻找的答案,最后:
-----------------------------------------------------------------------------
PRES HGHT TEMP DWPT RELH MIXR DRCT SKNT THTA THTE THTV
hPa m C C % g/kg deg knot K K K
-----------------------------------------------------------------------------
1008.0 4 22.2 18.7 81 13.65 270 1 294.7 333.9 297.1
1004.0 40 21.6 16.6 73 11.97 268 2 294.4 328.9 296.5
1000.0 76 21.8 16.8 73 12.18 265 3 294.9 330.1 297.1
996.0 111 20.8 16.2 75 11.76 270 5 294.3 328.1 296.4
990.0 163 22.4 15.4 65 11.23 278 7 296.4 329.1 298.4
983.0 225 22.0 14.0 60 10.32 288 10 296.6 326.7 298.4
974.0 304 21.3 13.8 62 10.28 300 14 296.7 326.7 298.5
946.0 556 19.2 13.2 68 10.18 313 19 297.0 326.8 298.8
941.0 602 19.0 12.6 67 9.85 315 20 297.3 326.1 299.0
932.0 684 18.6 11.6 64 9.28 312 19 297.7 325.0 299.3
925.0 749 18.0 12.0 68 9.61 310 18 297.7 325.9 299.4
909.0 898 17.1 11.7 71 9.57 315 11 298.2 326.4 299.9
894.0 1039 16.1 11.3 73 9.52 355 5 298.7 326.8 300.4
884.0 1135 15.5 11.1 75 9.50 5 5 299.0 327.1 300.7
850.0 1469 13.4 10.4 82 9.40 100 5 300.2 328.1 301.9
829.0 1677 12.1 9.4 84 9.03 115 8 301.0 327.9 302.6
798.0 1995 10.2 8.0 86 8.49 180 8 302.2 327.7 303.8
788.0 2100 9.6 7.5 87 8.32 170 7 302.6 327.7 304.1
746.0 2556 6.8 5.4 91 7.59 252 4 304.4 327.5 305.8
719.0 2859 5.4 2.4 81 6.37 307 2 306.1 325.7 307.3
715.0 2905 5.5 2.0 78 6.22 315 2 306.7 325.9 307.9
712.0 2939 5.6 1.7 76 6.11 313 3 307.2 326.1 308.3
706.0 3008 5.2 1.1 75 5.90 309 4 307.5 325.8 308.6
700.0 3078 4.8 0.8 75 5.83 305 6 307.8 325.9 308.9
670.0 3433 1.8 -1.0 82 5.34 290 12 308.3 325.0 309.3
652.0 3652 1.0 -3.6 71 4.52 280 15 309.8 324.1 310.6
642.0 3776 0.0 -4.3 73 4.35 274 17 310.0 323.9 310.8
634.0 3876 -0.8 -4.5 76 4.34 270 19 310.3 324.1 311.1
622.0 4029 -1.9 -4.8 81 4.33 270 23 310.7 324.5 311.5
609.0 4195 -2.9 -7.0 73 3.74 270 28 311.4 323.5 312.1
568.0 4744 -6.1 -14.1 53 2.27 257 33 313.9 321.5 314.3
548.0 5022 -7.7 -14.3 59 2.31 250 35 315.2 322.9 315.6
518.0 5458 -10.3 -14.7 70 2.38 245 25 317.2 325.2 317.6
516.0 5488 -10.5 -14.7 71 2.38 244 25 317.3 325.4 317.8
500.0 5730 -11.7 -17.7 61 1.91 240 28 318.7 325.3 319.1
467.0 6252 -13.9 -23.9 43 1.19 243 30 322.3 326.5 322.5
413.0 7174 -21.5 -29.5 48 0.81 249 32 324.0 327.0 324.1
400.0 7410 -22.9 -31.9 44 0.66 250 33 325.1 327.6 325.3
313.0 9150 -36.3 -53.2 16 0.09 255 44 330.0 330.4 330.0
302.0 9404 -38.3 -56.3 13 0.06 251 50 330.6 330.9 330.7
300.0 9450 -38.3 -56.3 13 0.06 250 51 331.3 331.5 331.3
295.0 9566 -37.7 -55.7 13 0.07 250 55 333.7 334.0 333.7
289.0 9705 -38.4 -56.8 13 0.06 250 59 334.6 334.9 334.6
250.0 10690 -43.7 -64.7 8 0.03 240 78 341.0 341.1 341.0
249.0 10717 -43.8 -64.8 8 0.03 240 78 341.2 341.4 341.2
211.0 11822 -46.9 -67.9 7 0.02 250 94 352.9 353.0 352.9
205.0 12015 -47.4 -68.4 7 0.02 250 98 355.0 355.1 355.0
200.0 12180 -47.9 -68.9 7 0.02 250 93 356.8 356.8 356.8
184.0 12722 -49.9 -72.0 6 0.01 245 77 362.2 362.2 362.2
173.0 13123 -51.3 -74.3 5 0.01 235 86 366.2 366.2 366.2
163.0 13510 -52.7 -76.6 4 0.01 240 100 370.1 370.1 370.1
154.0 13879 -54.1 -78.7 3 0.01 250 90 373.9 373.9 373.9
150.0 14050 -54.7 -79.7 3 0.00 250 86 375.6 375.6 375.6
142.0 14399 -56.5 -81.5 3 0.00 255 76 378.4 378.4 378.4
141.0 14444 -56.5 -81.5 3 0.00 255 74 379.2 379.2 379.2
138.0 14581 -56.4 -82.0 3 0.00 255 66 381.7 381.7 381.7
136.0 14673 -56.3 -82.3 2 0.00 252 65 383.5 383.5 383.5
132.0 14862 -56.8 -82.8 2 0.00 245 62 385.9 385.9 385.9
128.0 15057 -57.3 -83.3 2 0.00 246 61 388.4 388.4 388.4
123.0 15310 -56.9 -82.9 2 0.00 248 60 393.5 393.6 393.5
106.0 16245 -59.9 -85.9 2 0.00 253 56 404.9 404.9 404.9
100.0 16610 -58.9 -86.9 2 0.00 255 54 413.6 413.7 413.6
93.7 17019 -58.1 -85.1 2 0.00 258 44 423.0 423.0 423.0
78.4 18130 -62.3 -88.3 2 0.00 265 17 436.4 436.4 436.4
70.0 18830 -61.5 -89.5 1 0.00 230 21 452.5 452.5 452.5
67.0 19101 -61.1 -89.1 1 0.00 252 18 459.0 459.1 459.0
62.1 19569 -61.7 -90.7 1 0.00 290 14 467.8 467.8 467.8
55.0 20326 -59.1 -88.7 1 0.00 350 7 490.2 490.2 490.2
50.0 20920 -57.1 -87.1 1 0.00 10 5 508.5 508.5 508.5
40.6 22241 -56.1 -86.1 1 0.01 56 15 542.2 542.2 542.2
39.0 22497 -56.5 -86.5 1 0.01 65 17 547.4 547.4 547.4
38.3 22612 -56.7 -86.7 1 0.01 68 16 549.7 549.8 549.7
30.0 24170 -54.1 -85.1 1 0.01 110 8 596.6 596.6 596.6
29.0 24391 -53.4 -84.6 1 0.01 130 11 604.4 604.5 604.4
25.0 25357 -50.1 -82.4 1 0.02 60 15 639.9 640.1 639.9
24.0 25622 -49.2 -81.8 1 0.02 95 18 650.0 650.2 650.0
22.6 26014 -47.9 -80.9 1 0.03 88 15 665.1 665.4 665.2
21.4 26374 -48.1 -80.1 1 0.03 82 12 675.0 675.3 675.0
20.0 26820 -47.9 -80.9 1 0.03 75 9 688.8 689.1 688.8
10.0 31460 -41.7 -75.7 1 0.13 95 30 862.8 864.4 862.8
4.4 37163 -30.1 -69.1 1 0.79 77 36 1145.5 1158.2 1146.0
4.3 37327 -29.9 -68.9 1 0.83 77 36 1154.0 1167.4 1154.6
4.2 37494 -31.5 -69.5 1 0.78 76 37 1154.1 1166.8 1154.7
4.0 75 37"
,
根据您的回答,我假设您希望 linter 传递 bar
的定义,并且您愿意为此目的对 bar
的实现/声明进行更改。
对我来说,根本问题是 bar
的实现是错误的 - 如果 *args
不为空,那么调用 foo(biz=ness,*args,**kwargs)
将失败,并准确报告由我的。
def foo(biz: str = 'biz',baz: str = 'baz',*args:Any,**kwargs:Any)-> str:
return biz + baz
def bar_from_question(ness: str = 'ness',**kwargs):
return foo(biz=ness,**kwargs)
>>> bar_from_question("1")
1baz
>>> bar_from_question("1",in <module>
File "/Users/jean/Projects/python/test-mypy/test.py",line 7,in bar_from_question
return foo(biz=ness,**kwargs)
TypeError: foo() got multiple values for argument 'biz'
对我来说,你有三个选择:
-
通过不再传递
foo
来修复对args
的调用。这样的更改不会导致功能损失,因为args
中的非空bar
无论如何都会引发TypeError
。在这种情况下,您还可以从args
的签名中删除bar
(同样,不会丢失功能 - 您只需将TypeError
调用触发的foo
替换为TypeError
在调用bar
)def bar_do_not_pass_args_to_foo(ness: str = 'ness',**kwargs) def bar_remove_args_from_signature(ness: str = 'ness',**kwargs)
-
通过将
foo
作为位置参数而不是命名参数传递来修复对biz
的调用:def bar_pass_biz_as_positional(ness: str = 'ness',**kwargs): return foo(ness,**kwargs)
-
对 mypy 隐藏问题(我从你的回答中了解到)
def bar_hide_from_mypy(ness: str = 'ness',**kwargs): kwargs['biz'] = ness return foo(*args,**kwargs)
但是,如果目标只是简单地防止 mypy 报告错误,则有相应的语法:
def bar_suppress_mypy(ness: str = 'ness',**kwargs) # type: ignore
现在,如果我在运行时解释器中比较每个提议的结果:
>>> bar_do_not_pass_args_to_foo("1")
'1baz'
>>> bar_do_not_pass_args_to_foo("1","2")
'1baz'
>>> bar_remove_args_from_signature("1")
'1baz'
>>> bar_remove_args_from_signature("1",in <module>
TypeError: bar_remove_args_from_signature() takes from 0 to 1 positional arguments but 2 were given
>>> bar_pass_biz_as_positional("1")
'1baz'
>>> bar_pass_biz_as_positional("1","2")
'12'
>>> bar_hide_from_mypy("1")
'1baz'
>>> bar_hide_from_mypy("1",line 20,in bar_hide_from_mypy
return foo(*args,**kwargs)
TypeError: foo() got multiple values for argument 'biz'
>>> bar_suppress_mypy("1")
'1baz'
>>> bar_suppress_mypy("1",line 23,in bar_suppress_mypy
return foo(biz=ness,**kwargs) # type: ignore
TypeError: foo() got multiple values for argument 'biz'
你可以看到:
- 对于
bar_from_question
返回结果的每种情况,其他所有bar_...
实现都会返回相同的结果; - 除了
bar_from_question
之外的所有实现都对 mypy 保持沉默,我的印象是你想要的;
在您的情况下,我会寻求解决潜在问题的方法(即应用第 1 点或第 2 点),而不仅仅是试图强制使用 mypy(第 3 点)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。