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

如何以内联方式断言值非None?解决Python类型检查报错

问题

我有如下代码:

if foo:
    bar = 1
else:
    bar = maybe_return_int(baz)

maybe_return_int的返回类型为Optional[int],因此mypy报错:

error: Incompatible types in assignment (expression has type "int | None", variable has type "int")  [assignment]

但在我的代码语境中,确定maybe_return_int(baz)绝不会返回None。为通过类型检查,我不得不写这样繁琐的代码:

if foo:
    bar = 1
else:
    bar_maybe_none = maybe_return_int(baz)
    assert bar_maybe_none is not None
    bar = bar_maybe_none

有没有更简洁的写法?我希望能有一个assert_not_none函数,像这样用:

if foo:
    bar = 1
else:
    bar = assert_not_none(maybe_return_int(baz))

我可以编写这样的assert_not_none函数吗?
我可以用cast,但更喜欢assert的实际检查功能(至少在断言未禁用时),而且用assert不用手动指定类型(我的实际代码中类型比int冗长得多)。

解决方案

当然可以实现这样的assert_not_none函数,利用Python的类型注解让mypy识别出返回值是非None类型,同时保留运行时的断言检查:

from typing import TypeVar, Optional

T = TypeVar('T')

def assert_not_none(value: Optional[T]) -> T:
    assert value is not None
    return value

说明

  • 用TypeVar实现泛型,函数可以适配任意类型的Optional输入,无需手动指定具体类型,正好满足你不想写冗长类型的需求。
  • 运行时会执行assert检查,默认Python不禁用断言(除非用-O参数运行),如果传入None会直接抛出AssertionError,保留了你想要的实际检查功能。
  • mypy能识别这个函数的类型注解,明确输入为Optional[T]时返回T,所以你的目标写法完全能通过类型检查:
if foo:
    bar = 1
else:
    bar = assert_not_none(maybe_return_int(baz))

这种写法既保持了代码简洁,又兼顾了类型检查和运行时断言的双重作用,比单独用cast更安全,比分步写assert更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:59:58