Python 如何使格式不引起类型提示错误?

Python 如何使格式不引起类型提示错误?,python,python-3.x,list-comprehension,typing,mypy,Python,Python 3.x,List Comprehension,Typing,Mypy,我有以下Python中的列表理解: 从键入import cast #一切都很好 打印([1,2,3,4]]中的值对应的值) #在第一个“值”上:表达式类型包含“Any”(具有类型“List[Any]”) 打印(“{}.”格式([1,2,3,4]]中的值对应的值) #在“cast”上:表达式类型包含“Any”(具有类型“List[Any]”) 打印(“{}”.format([1,2,3,4]]中的值的[cast(int,value)]) 为什么使用格式会导致Mypy返回错误?正如你所看到的,我试

我有以下Python中的列表理解:

从键入import cast
#一切都很好
打印([1,2,3,4]]中的值对应的值)
#在第一个“值”上:表达式类型包含“Any”(具有类型“List[Any]”)
打印(“{}.”格式([1,2,3,4]]中的值对应的值)
#在“cast”上:表达式类型包含“Any”(具有类型“List[Any]”)
打印(“{}”.format([1,2,3,4]]中的值的[cast(int,value)])
为什么使用
格式
会导致Mypy返回错误?正如你所看到的,我试图使用铸造,但还是失败了

看起来很相似,但我的特殊情况很奇怪,因为只要我不使用
格式
函数,Mypy似乎就可以了(但是
打印
函数总是可以的)

我能做些什么,不让格式化的行给我错误?(或者我应该只
#键入:忽略它们吗?)

编辑: 请注意,这似乎不仅仅是我的Atom linter的问题。 我使用的是Mypy版本
0.701
,我在该文件上运行了Mypy,结果如下:

$ python3 -m mypy testing_list_iter.py --disallow-any-expr
testing_list_iter.py:7: error: Expression type contains "Any" (has type "List[Any]")
testing_list_iter.py:10: error: Expression type contains "Any" (has type "List[Any]")

这实际上与列表理解无关:这实际上是
str.format(…)
的类型签名、mypy执行类型推断的方式以及
--不允许任何expr
标志之间的不良交互

这是str.format(…)
的类型签名:

当mypy对函数调用执行类型推断时,它将尝试使用声明的参数类型来帮助为传入的表达式提供上下文

因此,在本例中,由于参数都是这里的
Any
,mypy将认识到它可以简化它通常需要执行的许多类型推断。因此,如果我们将任何列表文本传递到
str.format(…)
,mypy将决定“嘿,推断的类型可以是
list[any]

下面是一个示例程序,演示了这种行为(当使用
--disallow any expr
标志进行检查时):

通过键入import cast,任何
def test1(x:Any)->无:
通过
def test2(x:对象)->无:
通过
#显示类型为“内置。列出[任何]”
#表达式类型包含“Any”(具有类型“List[Any]”)
测试1(显示类型([1,2,3,4]))
#显示类型为“builtins.list[builtins.int*]”
测试2(显示类型([1,2,3,4]))
请注意,当我们尝试使用接受
对象
而不是
任何
的函数时,mypy将推断完整类型,而不是执行此快捷方式。(从技术上讲,Mypy可以做同样的快捷方式,因为所有类型也都是
对象
的子类,但我怀疑,与
任何
不同的是,
对象
只是一个普通的旧类型,因此与它的特殊大小写交互有点奇怪。)

通常情况下,mypy处理这种情况的准确程度并不重要:无论哪种方式,都可以得到准确的结果

然而,
--disallow any expr
标志仍然是非常新的,并且相对未经测试(它对很多人来说太激进了,尤其是那些试图在现有代码库上使用mypy的人),因此我们不时会遇到这些糟糕的交互


那么,解决办法是什么

最好的修复方法是,您提供一个pull请求来修改文件中的
str.format(…)
unicode.format(…)
,以便它们接受对象,而不是
任何

这一变化将符合Typeshed的任何方式——特别是,在“约定”部分中的这个片段:

添加类型提示时,尽可能避免使用
Any
类型。在以下情况下保留使用
Any

  • 当前类型系统无法表示正确的类型;及
  • 避免联合退货(见上文)
请注意,如果您想表明某些函数可以接受任何内容,则使用
Any
不是正确的类型:在这些情况下,请使用
object

然后,等待mypy的下一个版本,理论上应该很快发布

同时,您可以做的只是将列表理解的结果分配给一个新变量,然后将其传递到
str.format(…)

results=[值对应于[1,2,3,4]中的值]
打印(“{}”。格式(结果))

这将导致mypy在没有
Any
上下文的情况下推断列表理解的类型,从而推断出完整的类型。这避免了与
——disallow any expr
标志的不良交互。

@AmartyaGaur是的,这三条语句在Python中都能正确运行。是Mypy给出了错误。(Mypy不应给出任何
[1,2,3,4]
输出)已生成!(感谢您不仅亲自动手,还向我和其他人展示了这些问题是如何解决的,我真的很感激!)
def format(self, *args: Any, **kwargs: Any) -> str: ...