Jan*_*cki 4 python types typing typechecking mypy
请考虑以下代码示例:
from typing import Dict, Union
def count_chars(string) -> Dict[str, Union[str, bool, int]]:
result = {} # type: Dict[str, Union[str, bool, int]]
if isinstance(string, str) is False:
result["success"] = False
result["message"] = "Inavlid argument"
else:
result["success"] = True
result["result"] = len(string)
return result
def get_square(integer: int) -> int:
return integer * integer
def validate_str(string: str) -> bool:
check_count = count_chars(string)
if check_count["success"] is False:
print(check_count["message"])
return False
str_len_square = get_square(check_count["result"])
return bool(str_len_square > 42)
result = validate_str("Lorem ipsum")
Run Code Online (Sandbox Code Playgroud)
在针对此代码运行mypy时,将返回以下错误:
error: Argument 1 to "get_square" has incompatible type "Union[str, bool, int]"; expected "int"
Run Code Online (Sandbox Code Playgroud)
我不知道如果不在Dict[str, Any]第一个函数中使用返回类型或安装'TypedDict'mypy扩展名,我怎么能避免这个错误.mypy实际上是'正确',我的任何代码都不是类型安全的,或者这应该被视为mypy bug?
Mypy在这里是正确的 - 如果你的dict中的值可以是strs,int或bools,那么严格来说我们不能假设check_count["result"]总是会评估为int.
你有几种方法可以解决这个问题.第一种方法是实际上只检查它的类型,check_count["result"]看它是否为int.您可以使用断言执行此操作:
assert isinstance(check_count["result"], int)
str_len_square = get_square(check_count["result"])
Run Code Online (Sandbox Code Playgroud)
......或者也许是if语句:
if isinstance(check_count["result"], int):
str_len_square = get_square(check_count["result"])
else:
# Throw some kind of exception here?
Run Code Online (Sandbox Code Playgroud)
Mypy理解断言和if语句(在有限程度上)对此表单的类型检查.
但是,在整个代码中,这些检查可能会非常繁琐.因此,最好实际上放弃使用dicts并切换到使用类.
也就是说,定义一个类:
class Result:
def __init__(self, success: bool, message: str) -> None:
self.success = success
self.message = message
Run Code Online (Sandbox Code Playgroud)
...然后返回一个实例.
这是稍微更不方便,如果你的目标是最终返回/ JSON操作,你现在需要编写代码,该类自/至JSON的转换,但它确实让你避免类型相关的错误.
定义自定义类可能会稍微繁琐,因此您可以尝试使用NamedTuple类型:
from typing import NamedTuple
Result = NamedTuple('Result', [('success', bool), ('message', str)])
# Use Result as a regular class
Run Code Online (Sandbox Code Playgroud)
你仍然需要编写元组 - > json代码,而iirc namedtuples(collections模块中的常规版本和这种类型的变体)的性能都不如类,但也许这对你的用例无关紧要.
| 归档时间: |
|
| 查看次数: |
1000 次 |
| 最近记录: |