这可能是一个艰难的.

假设我有一种类型

JSON = Union[Mapping[str, "JSON"], Sequence["JSON"], str, int, float, bool, None]

我有一个功能

def memoize[**P, T: JSON](fn: Callable[P,T]) -> Callable[P,T]:
    # ...make the function memoizable
    return wrapped_fn

如何约束FN的参数都是JSON的子类型?或者,如果这不能静态完成,我如何在创建包装器之前在Mememize中判断它?

我试着给ParamSpec变量 **P设置边界,但似乎还没有实现.我也试过issubclass,但这对typehints不好用.

推荐答案

如果fn有一个任意的签名,目前还没有办法做到这一点.我认为接下来最好的事情是在调用点生成错误(请参见 Pyright playground):

import collections.abc as cx
import typing as t

type JSON = cx.Mapping[str, JSON] | cx.Sequence[JSON] | str | int | float | bool | None

class _JSONOnlyCallable(t.Protocol):
    def __call__(self, /, *args: JSON, **kwargs: JSON) -> JSON: ...

def memoize[F: cx.Callable[..., t.Any]](fn: F, /) -> F | _JSONOnlyCallable:
    return fn

@memoize
def f(a: int, b: str, c: set[int]) -> str: ...
>>> f(1, "", {1, 2})
             ^^^^^^
pyright: Argument of type "set[int]" cannot be assigned to parameter "args" of type "JSON" in function "__call__"

Python相关问答推荐

如何使用Google Gemini API为单个提示生成多个响应?

如何使用LangChain和AzureOpenAI在Python中解决AttribeHelp和BadPressMessage错误?

如何使用数组的最小条目拆分数组

avxspan与pandas period_range

用砂箱开发Web统计分析

如何在Python中获取`Genericums`超级类型?

解决调用嵌入式函数的XSLT中表达式的语法移位/归约冲突

如何排除prefecture_related中查询集为空的实例?

Matplotlib中的字体权重

在方法中设置属性值时,如何处理语句不可达[Unreacable]";的问题?

如何在Gekko中使用分层条件约束

语法错误:文档. evaluate:表达式不是合法表达式

GPT python SDK引入了大量开销/错误超时

什么是一种快速而优雅的方式来转换一个包含一串重复的列,而不对同一个值多次运行转换,

如何在一组行中找到循环?

Polars时间戳同步延迟计算

以极轴表示的行数表达式?

FileNotFoundError:[WinError 2]系统找不到指定的文件:在os.listdir中查找扩展名

VSCode Pylance假阳性(?)对ImportError的react

某些值的数值幂和**之间的差异