求助:Python injector无法注入基于tuple[str, str]的NewType
问题原因分析
你的问题核心在于Python泛型擦除和injector对NewType及实例绑定的处理逻辑:
NewType的运行时本质:
NewType("Foo", tuple[str, str])创建的Foo只是一个包装函数,运行时调用Foo(("x", "y"))返回的仍然是普通tuple实例(泛型信息[str, str]在运行时被擦除),而非Foo类型的子类或专用实例。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错误。
- 对于基于
绑定参数的误解:你直接将实例作为
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
相关产品推荐
相关产品推荐

