Mig*_*ell 15 python python-3.x mypy python-typing
假设我们有一个简单的函数,它open()使用固定的参数进行调用:
def open_for_writing(*args, **kwargs):
kwargs['mode'] = 'w'
return open(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
如果我现在尝试调用open_for_writing(some_fake_arg = 123),没有类型检查器(例如 mypy)可以判断这是一个不正确的调用:它缺少所需的file参数,并且添加了另一个不属于open签名的参数。
我如何告诉类型检查器*args和**kwargs必须是open参数规范的子集?我意识到 Python 3.10 有新ParamSpec类型,但它似乎不适用于这里,因为你无法获得ParamSpec像open.
我认为开箱即用这是不可能的。但是,您可以编写一个装饰器,它将包含要检查的参数(在您的情况下为 open )的函数作为输入并返回装饰函数,即在您的情况下为 open_for_writing 。当然,这仅适用于 python 3.10 或使用 Typing_extensions,因为它使用 ParamSpec
from typing import TypeVar, ParamSpec, Callable, Optional
T = TypeVar('T')
P = ParamSpec('P')
def take_annotation_from(this: Callable[P, Optional[T]]) -> Callable[[Callable], Callable[P, Optional[T]]]:
def decorator(real_function: Callable) -> Callable[P, Optional[T]]:
def new_function(*args: P.args, **kwargs: P.kwargs) -> Optional[T]:
return real_function(*args, **kwargs)
return new_function
return decorator
@take_annotation_from(open)
def open_for_writing(*args, **kwargs):
kwargs['mode'] = 'w'
return open(*args, **kwargs)
open_for_writing(some_fake_arg=123)
open_for_writing(file='')
Run Code Online (Sandbox Code Playgroud)
如此处所示,mypy 现在抱怨得到一个未知的参数。
| 归档时间: |
|
| 查看次数: |
1659 次 |
| 最近记录: |