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

求助:Python injector无法注入基于tuple[str, str]的NewType

问题原因分析

你的问题核心在于Python泛型擦除和injector对NewType及实例绑定的处理逻辑:

  1. NewType的运行时本质:NewType("Foo", tuple[str, str])创建的Foo只是一个包装函数,运行时调用Foo(("x", "y"))返回的仍然是普通tuple实例(泛型信息[str, str]在运行时被擦除),而非Foo类型的子类或专用实例。

  2. injector的绑定逻辑差异:

    • 对于基于str的NewType:Bar("test")返回的是str实例,而Bar的__supertype__是str,injector能识别到该实例与Bar的父类型匹配,因此可以成功绑定。
    • 对于基于tuple[str, str]的NewType:Foo(("x", "y"))返回的是tuple实例,但Foo的__supertype__是泛型类型tuple[str, str]——而运行时不存在这个具体类型,只有原始tuple类型。injector无法将普通tuple实例与泛型父类型关联,因此抛出UnknownProvider错误。
  3. 绑定参数的误解:你直接将实例作为bind的第二个参数传入,injector会默认把它当作“要绑定到的目标类型”而非实例。对于基础类型(如str)这种逻辑碰巧能工作,但对于泛型类型则失效。

解决方法

有两种可靠的修复方式:

方式一:明确使用to_instance参数

直接告诉injector你要绑定的是一个实例:

import injector
from typing import NewType

Foo = NewType("Foo", tuple[str, str])

class MyModule(injector.Module):
    def configure(self, binder: injector.Binder) -> None:
        # 使用to_instance参数指定实例
        binder.bind(Foo, to_instance=Foo(("x", "y")))

injector.Injector(modules=[MyModule]).get(Foo)

方式二:使用提供者函数

通过定义提供者函数,明确返回Foo实例:

import injector
from typing import NewType

Foo = NewType("Foo", tuple[str, str])

class MyModule(injector.Module):
    def configure(self, binder: injector.Binder) -> None:
        # 定义提供者函数
        def provide_foo() -> Foo:
            return Foo(("x", "y"))
        binder.bind(Foo, to=provide_foo)

injector.Injector(modules=[MyModule]).get(Foo)

这两种方式都能让injector明确知道如何获取Foo类型的实例,绕过泛型擦除带来的识别问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 11:13:11