如何让 mypy 抱怨将 Any 分配给 int
How to make mypy complain about assigning an Any to an int
mypy --strict
尽职尽责地抱怨以下代码:
from typing import Any, Dict
def main() -> None:
my_str: str = 'hello'
my_int: int = my_str
if __name__ == "__main__":
main()
通过输出:
error: Incompatible types in assignment (expression has type "str", variable has type "int")
然而,以下代码被接受且没有任何错误:
from typing import Any, Dict
def main() -> None:
my_str: Any = 'hello'
my_int: int = my_str
if __name__ == "__main__":
main()
mypy
是否有选项使其也拒绝第二个示例?
我希望它这样做,因为它也拒绝以下内容:
from typing import Any, Dict, Union
def main() -> None:
my_str: Union[int, str] = 'hello'
my_int: int = my_str
if __name__ == "__main__":
main()
与:
error: Incompatible types in assignment (expression has type "Union[int, str]", variable has type "int")
在我的理解中,Any
只是所有可能类型的 Union
。
And in my understanding an Any
is just the Union
of all possible types.
这是不正确的。 Any
是一个 escape hatch,一个你希望类型检查器忽略的变量注释。肯定不是工会
A value with the Any
type is dynamically typed. Mypy doesn’t know anything about the possible runtime types of such value. Any operations are permitted on the value, and the operations are only checked at runtime. You can use Any
as an “escape hatch” when you can’t use a more precise type for some reason.
(粗体强调我的)
它明确涵盖了您的案例:
Any
is compatible with every other type, and vice versa. You can freely assign a value of type Any to a variable with a more precise type:
a: Any = None
s: str = ''
a = 2 # OK (assign "int" to "Any")
s = a # OK (assign "Any" to "str")
Declared (and inferred) types are ignored (or erased) at runtime. They are basically treated as comments, and thus the above code does not generate a runtime error, even though s
gets an int
value when the program is run, while the declared type of s
is actually str
!
因此,如果您希望类型检查器继续跟踪值的使用方式,那么正确的做法是不使用Any
。使用 Union[]
,就像您在第三个示例中所做的那样,或者重新考虑您的数据结构以允许更好的类型提示。例如,与其使用具有联合值类型的字典,不如考虑使用具有显式字段和每个字段的特定类型的命名元组或数据类。
对于那些稍后阅读此内容的人,实际的解决方案是使用 "disallow any" 命令行标志系列,如 .
中所述
mypy --strict
尽职尽责地抱怨以下代码:
from typing import Any, Dict
def main() -> None:
my_str: str = 'hello'
my_int: int = my_str
if __name__ == "__main__":
main()
通过输出:
error: Incompatible types in assignment (expression has type "str", variable has type "int")
然而,以下代码被接受且没有任何错误:
from typing import Any, Dict
def main() -> None:
my_str: Any = 'hello'
my_int: int = my_str
if __name__ == "__main__":
main()
mypy
是否有选项使其也拒绝第二个示例?
我希望它这样做,因为它也拒绝以下内容:
from typing import Any, Dict, Union
def main() -> None:
my_str: Union[int, str] = 'hello'
my_int: int = my_str
if __name__ == "__main__":
main()
与:
error: Incompatible types in assignment (expression has type "Union[int, str]", variable has type "int")
在我的理解中,Any
只是所有可能类型的 Union
。
And in my understanding an
Any
is just theUnion
of all possible types.
这是不正确的。 Any
是一个 escape hatch,一个你希望类型检查器忽略的变量注释。肯定不是工会
A value with the
Any
type is dynamically typed. Mypy doesn’t know anything about the possible runtime types of such value. Any operations are permitted on the value, and the operations are only checked at runtime. You can useAny
as an “escape hatch” when you can’t use a more precise type for some reason.
(粗体强调我的)
它明确涵盖了您的案例:
Any
is compatible with every other type, and vice versa. You can freely assign a value of type Any to a variable with a more precise type:a: Any = None s: str = '' a = 2 # OK (assign "int" to "Any") s = a # OK (assign "Any" to "str")
Declared (and inferred) types are ignored (or erased) at runtime. They are basically treated as comments, and thus the above code does not generate a runtime error, even though
s
gets anint
value when the program is run, while the declared type ofs
is actuallystr
!
因此,如果您希望类型检查器继续跟踪值的使用方式,那么正确的做法是不使用Any
。使用 Union[]
,就像您在第三个示例中所做的那样,或者重新考虑您的数据结构以允许更好的类型提示。例如,与其使用具有联合值类型的字典,不如考虑使用具有显式字段和每个字段的特定类型的命名元组或数据类。
对于那些稍后阅读此内容的人,实际的解决方案是使用 "disallow any" 命令行标志系列,如