python - 使用 *args 时函数参数的类型安全 (mypy)
问题描述
使用 对以下代码进行类型检查mypy
:
def foo(a: str, b: float, c: int):
print(a, b, c + 1)
foo('ok', 2.2, 'bad')
也揭示了无效的呼叫foo
:
error: Argument 3 to "foo" has incompatible type "str"; expected "int"
现在假设我们有一个如下的包装函数:
from typing import Callable, Any
def say_hi_and_call(func: Callable[..., Any], *args):
print('Hi.')
func(*args)
并使用它进行无效调用
say_hi_and_call(foo, 'ok', 2.2, 'bad')
mypy
不会报告任何错误,相反我们只会在运行时了解此错误:
TypeError: must be str, not int
我想早点发现这个错误。是否有可能以mypy
能够报告问题的方式细化类型注释?
解决方案
好的,我想出的唯一解决方案是使函数的数量明确,即
from typing import Any, Callable, TypeVar
A = TypeVar('A')
B = TypeVar('B')
C = TypeVar('C')
def say_hi_and_call_ternary(func: Callable[[A, B, C], Any], a: A, b: B, c: C):
print('Hi.')
func(a, b, c)
def foo(a: str, b: float, c: int):
print(a, b, c + 1)
say_hi_and_call_ternary(foo, 'ok', 2.2, 'bad')
当然,也需要类似的say_hi_and_call_unary
等等say_hi_and_call_binary
。
但是由于我重视我的应用程序不会在 PROD 中爆炸而不是保存一些 LOC,所以我很高兴mypy
能够报告错误,现在肯定是这种情况:
error: Argument 1 to "say_hi_and_call_ternary" has incompatible type "Callable[[str, float, int], Any]"; expected "Callable[[str, float, str], Any]"
推荐阅读
- java - 关闭 JFrame 后清空 ArrayList
- go - 去测试错误 - 没有测试文件 - GOPATH 中的错误
- odoo-11 - Odoo11 用自定义模块替换 sale.report_invoice_layouted 中的字段
- vue.js - VueJs - 使用数组中的数据创建所有周的卡片
- graphql - 第三方 API 的 Gatsby 插件抛出错误
- python - AttributeError:“列表”对象没有属性“dist”
- wcf - 如何在不指定 FaultContractAttribute 的情况下使用带有详细信息的 FaultException
- macos - WebKitWebProcess 制作新的停靠图标
- python - 如何在 Python 中进行并行处理?
- node.js - 无法在 Nodejs 中连接本地 PostgreSQL 数据库