You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Typing中仅接受类方法作为关键字参数?

在Python中提取类方法类型用于kwargs类型注解

可以实现类似TypeScript中OnlyMethods的功能,在Python里通过类型系统的映射筛选或动态生成TypedDict来约束关键字参数仅接受目标类的方法名及对应可调用类型。

方案1:动态生成TypedDict(兼容Python 3.8+)

通过代码动态生成仅包含类方法的TypedDict,再用Unpack注解关键字参数:

from typing import TypeVar, Type, Callable, Any, TypedDict, Unpack

T = TypeVar('T')

def create_method_typed_dict(cls: Type[T]) -> type[TypedDict]:
    """生成仅包含类公开方法的TypedDict类型"""
    method_defs = {}
    for name, attr in cls.__dict__.items():
        # 过滤掉魔术方法和非可调用属性
        if callable(attr) and not name.startswith('__'):
            method_defs[name] = Callable[..., Any]
    return TypedDict(f"OnlyMethods_{cls.__name__}", method_defs)

class A:
    prop: int = 10
    def foo(self):
        pass
    def bar(self):
        pass

def fun[T](**kwargs: Unpack[create_method_typed_dict(T)]):
    pass

# 合法调用
fun[A](foo=lambda: 123)

# 以下调用会被类型检查器(如mypy、pyright)报错
fun[A](prop=200)       # 错误:prop不是方法
fun[A](smth=lambda:123) # 错误:smth不是A的方法

方案2:类型层面的映射筛选(Python 3.11+ + pyright支持)

利用typing_extensions的KeyOf实现纯类型层面的筛选,无需动态生成类:

from typing_extensions import TypeVar, KeyOf, Callable, Unpack, TypedDict

T = TypeVar('T')

# 定义仅保留方法的映射类型,total=False表示允许传部分方法
OnlyMethods = TypedDict(
    "OnlyMethods",
    {K: T[K] for K in KeyOf[T] if T[K] extends Callable[..., Any]},
    total=False
)

def fun[T](**kwargs: Unpack[OnlyMethods[T]]):
    pass

class A:
    prop: int = 10
    def foo(self):
        pass
    def bar(self):
        pass

fun[A](foo=lambda: 123)  # 合法
fun[A](prop=200)         # 类型错误
fun[A](smth=lambda:123)  # 类型错误

两种方案都能实现需求:限制fun的关键字参数只能是目标类的公开方法名,且值必须是可调用对象。其中方案2更贴近TypeScript的类型推导方式,依赖pyright等对高级类型语法的支持;方案1兼容性更好,适合低版本Python环境。

内容的提问来源于stack exchange,提问作者Malyutin Egor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:44:53