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

如何基于构造函数签名指定Python泛型类型?

解决类型转换泛型函数的类型标注问题

你想要实现一个泛型类型转换函数,接受任何仅需单个参数即可实例化的类型(比如str、int或自定义类),但现有标注方式无法同时兼容类型对象传入和mypy类型检查。

你的初始尝试代码:

from typing import TypeVar

T = TypeVar("T")  # Annotation here

def some_func(x: Type[T]) -> T:
    return x(do_something_else())

遇到的问题:

  • 用Callable[[Any], T]标注x时,无法传入str、int这类类型对象;
  • 用Type[T]标注时,mypy会提示参数过多的错误。

解决方案:使用Protocol定义构造协议

通过typing.Protocol定义一个描述“可接受单个参数实例化”的类型协议,让类型变量绑定该协议,既能兼容内置类型和自定义类,又能让mypy正确识别构造函数的参数要求。

示例代码:

from typing import TypeVar, Protocol, Any

# 定义协议:要求类型的__init__接受一个任意类型参数
class OneArgConstructible(Protocol):
    def __init__(self, arg: Any) -> None: ...

# 绑定协议,限制T必须符合该构造规则
T = TypeVar("T", bound=OneArgConstructible)

def do_something_else() -> Any:
    # 示例实现,返回任意类型值
    return "sample_data"

def some_func(x: type[T]) -> T:
    return x(do_something_else())

# 测试验证
result_str: str = some_func(str)
result_int: int = some_func(int)

class CustomClass:
    def __init__(self, arg: Any) -> None:
        self.value = arg

result_custom: CustomClass = some_func(CustomClass)

说明

  • 协议OneArgConstructible明确了类型必须具备接受单个参数的构造方法;
  • TypeVar通过bound参数限定T的范围,确保传入的类型符合构造规则;
  • 若需要更严格的参数类型(比如要求构造参数是str),只需修改协议中arg的类型标注即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:32:47