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

如何为带默认值的参数设置正确的Python类型提示

解决带默认参数的泛型函数类型提示不兼容问题

问题场景

你尝试为以下代码添加类型提示,使用bound=Foo的TypeVar后,mypy报类型不兼容错误:

from typing import TypeVar

class Foo:
    pass

class FooBar(Foo):
    pass

T = TypeVar("T", bound=Foo)

def baz(type_: type[T] = Foo) -> T:
    return type_()

报错信息:

Incompatible default for argument "type_" (default has type "type[Foo]", argument has type "type[T]")  [assignment]
    def baz(type_: type[T] = Foo) -> T:
                             ^~~

报错原因

带bound=Foo的TypeVar表示T可以是Foo或其子类,但默认值Foo的类型是type[Foo],mypy无法确认这个默认值能匹配所有可能的T(比如当T是FooBar时,type[T]是type[FooBar],和type[Foo]不兼容),因此抛出类型不兼容的错误。

解决方案

方案1:Python 3.12+ 用TypeVar的default参数

Python 3.12为TypeVar新增了default参数,直接指定T的默认类型为Foo,就能让mypy识别默认值的兼容性:

from typing import TypeVar

class Foo:
    pass

class FooBar(Foo):
    pass

# 指定T的默认类型为Foo
T = TypeVar("T", bound=Foo, default=Foo)

def baz(type_: type[T] = Foo) -> T:
    return type_()

方案2:兼容旧版本Python的函数重载

如果需要支持Python 3.11及以下版本,使用@overload定义两种调用场景:无参数时返回Foo,传入子类类型时返回对应子类实例:

from typing import TypeVar, overload

class Foo:
    pass

class FooBar(Foo):
    pass

T = TypeVar("T", bound=Foo)

# 无参数的重载情况
@overload
def baz() -> Foo:
    ...

# 传入类型参数的重载情况
@overload
def baz(type_: type[T]) -> T:
    ...

# 实际实现
def baz(type_: type[T] | type[Foo] = Foo) -> T | Foo:
    return type_()

这样mypy会正确推断:

  • 调用baz()时,返回类型为Foo
  • 调用baz(FooBar)时,返回类型为FooBar

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:25:13