如何修复 mypy 错误 "Expression has type Any [misc]",用于 python 类型提示 int __pow__ int?
How to fix mypy error, "Expression has type Any [misc]", for python type hinting of int __pow__ int?
我有一个 python 函数,它使用带有两个 int 的 python __pow__ (**) 运算符,Mypy 告诉我表达式 b ** e
的类型为“ Any”,其中 b 和 e 的类型为“int”。我试图用 int(b ** e)
将表达式转换为 int,但我仍然收到错误。如何正确键入提示此表达式?
此外,如果表达式 b ** e
确实 return 键入“Any”,您能解释一下原因吗?
错误:
temp.py:7: error: Expression has type "Any" [misc]
power: Callable[[int, int], int] = lambda b, e: b ** e
^
temp.py
from functools import reduce
from typing import Callable, Dict
def factorization_product(fact: Dict[int, int]) -> int:
'''returns the product which has the prime factorization of fact'''
power: Callable[[int, int], int] = lambda b, e: b ** e # error on expression "b ** e"
product: Callable[[int, int], int] = lambda x, y: x * y
return reduce(product, [power(b, e) for b, e in fact.items()], 1)
编辑:
我意识到我可以使用内置的 pow 和 operator.mul 而不是 lambda,但我仍然遇到错误。
错误:
temp.py:8: error: Expression has type "Any" [misc]
return reduce(mul, [pow(b, e) for b, e in fact.items()], 1)
^
已修订 temp.py
from functools import reduce
from operator import mul
from typing import Dict
def factorization_product(fact: Dict[int, int]) -> int:
'''returns the product which has the prime factorization of fact'''
return reduce(mul, [pow(b, e) for b, e in fact.items()], 1)
Also, if the expression b ** e really does return type "Any", can you explain why?
检查 typeshed 显示 int
仅针对数字平方的特殊情况(x
类型 Literal[2]
)返回。这是因为即使 b
和 e
是 int
,e
也可能是负数,在这种情况下结果是 float
。由于结果可以是 float
或 int
,因此一般情况下 typeshed
和 Any
是一致的。
我会说这是语言限制。理想情况下,我们可以对 x
的所有 non-negative 整数使用 @overload
,但 Literal
仅支持特定值。
要在使用 --disallow-any-expr
的同时解决这个问题,请像这样使用 typing.cast:
power: Callable[[int, int], int] = lambda b, e: typing.cast(int, b ** e)
运行 mypy --disallow-any-expr temp.py
现在 returns Success: no issues found in 1 source file
.
但在你盲目添加 cast
之前,请考虑我提出的 e
为负的场景,如果你这样做 int
会导致类型检查成功但运行时失败-特定操作,结果为 factorization_product
。您可能想在此处添加验证。例如,没有验证:
factorial_sized_lst = [0] * factorization_product({1: 2, 3: -4})
尽管 mypy
报告 type-check 成功,但 在 run-time 处失败且 can't multiply sequence by non-int of type 'float'
。
我有一个 python 函数,它使用带有两个 int 的 python __pow__ (**) 运算符,Mypy 告诉我表达式 b ** e
的类型为“ Any”,其中 b 和 e 的类型为“int”。我试图用 int(b ** e)
将表达式转换为 int,但我仍然收到错误。如何正确键入提示此表达式?
此外,如果表达式 b ** e
确实 return 键入“Any”,您能解释一下原因吗?
错误:
temp.py:7: error: Expression has type "Any" [misc]
power: Callable[[int, int], int] = lambda b, e: b ** e
^
temp.py
from functools import reduce
from typing import Callable, Dict
def factorization_product(fact: Dict[int, int]) -> int:
'''returns the product which has the prime factorization of fact'''
power: Callable[[int, int], int] = lambda b, e: b ** e # error on expression "b ** e"
product: Callable[[int, int], int] = lambda x, y: x * y
return reduce(product, [power(b, e) for b, e in fact.items()], 1)
编辑:
我意识到我可以使用内置的 pow 和 operator.mul 而不是 lambda,但我仍然遇到错误。
错误:
temp.py:8: error: Expression has type "Any" [misc]
return reduce(mul, [pow(b, e) for b, e in fact.items()], 1)
^
已修订 temp.py
from functools import reduce
from operator import mul
from typing import Dict
def factorization_product(fact: Dict[int, int]) -> int:
'''returns the product which has the prime factorization of fact'''
return reduce(mul, [pow(b, e) for b, e in fact.items()], 1)
Also, if the expression b ** e really does return type "Any", can you explain why?
检查 typeshed 显示 int
仅针对数字平方的特殊情况(x
类型 Literal[2]
)返回。这是因为即使 b
和 e
是 int
,e
也可能是负数,在这种情况下结果是 float
。由于结果可以是 float
或 int
,因此一般情况下 typeshed
和 Any
是一致的。
我会说这是语言限制。理想情况下,我们可以对 x
的所有 non-negative 整数使用 @overload
,但 Literal
仅支持特定值。
要在使用 --disallow-any-expr
的同时解决这个问题,请像这样使用 typing.cast:
power: Callable[[int, int], int] = lambda b, e: typing.cast(int, b ** e)
运行 mypy --disallow-any-expr temp.py
现在 returns Success: no issues found in 1 source file
.
但在你盲目添加 cast
之前,请考虑我提出的 e
为负的场景,如果你这样做 int
会导致类型检查成功但运行时失败-特定操作,结果为 factorization_product
。您可能想在此处添加验证。例如,没有验证:
factorial_sized_lst = [0] * factorization_product({1: 2, 3: -4})
尽管 mypy
报告 type-check 成功,但 在 run-time 处失败且 can't multiply sequence by non-int of type 'float'
。