gpt4 book ai didi

python - Python 中的受限泛型类型提示

转载 作者:行者123 更新时间:2023-12-02 16:23:52 27 4
gpt4 key购买 nike

我想像这里一样创建一个工厂方法。

class A:
...

class B(A):
def f(self):
...

class C:
...

def factory(cls):
return cls()

但我想添加一些具有两个要求的类型提示:

  • 只允许A 的子类作为factory 的参数。
  • 当传递B时,正确检测到factory(B)B的实例,即。允许使用 factory(B).f() 而不允许使用 factory(A).f()

尝试 1

使用 typing 模块中的 Type

from typing import Type

class A:
...

class B(A):
def f(self):
...

class C:
...

def factory(cls: Type[A]):
return cls()

factory(A) # Ok
factory(B) # Ok
factory(C) # Fail
factory(A).f() # Fail
factory(B).f() # Fail -- Wrong!

这个正确地检测到 C 不应该作为 factory 的参数传递。但是,类型检查器不允许 factory(B).f()

尝试 2

使用 TypeVar

from typing import TypeVar, Type
T = TypeVar('T')

class A:
...

class B(A):
def f(self):
...

class C:
...

def factory(cls: Type[T]) -> T:
return cls()

factory(A) # Ok
factory(B) # Ok
factory(C) # Ok -- Wrong!
factory(A).f() # Fail
factory(B).f() # Ok

可以很好地推断出 factory(B).f() 是好的,而 factory(A).f() 不是。但是,泛型没有限制,即。 factory(C) 也可以。

尝试 3

T 添加约束。

from typing import TypeVar, Type

class A:
...

class B(A):
def f(self):
...

class D(A):
...

class C:
...

T = TypeVar('T', A)
def factory(cls: Type[T]) -> T:
return cls()


factory(A) # Ok
factory(B) # Ok
factory(C) # Fail
factory(A).f() # Fail
factory(B).f() # Ok

这看起来很有希望,至少 PyCharm 可以正确处理所有情况。但对于实际使用来说,这个解决方案实际上是最糟糕的 - 不允许单个约束错误出现,但尚不清楚原因。在 PEP 484 中,只有简短的一行说“应该至少有两个约束,如果有的话;不允许指定单个约束。'

有什么好的解决办法吗?我只有一些东西,比如添加一个“虚拟”类 _A,一个 A 的空白子类,并将它作为另一个约束来拥有这样的东西。

_A = NewType('_A', A)
T = TypeVar('T', A, _A)
def factory(cls: Type[T]) -> T:
return cls()

但我真的不认为这是一个好的解决方案。

提前致谢!

最佳答案

TypeVarbound 一起使用似乎可行:

from typing import Type, TypeVar

class A:
...

class B(A):
def f(self):
...

class C:
...

AnyA = TypeVar("AnyA", bound=A)

def factory(cls: Type[AnyA]) -> AnyA:
return cls()


factory(A).f() # error: "A" has no attribute "f"
factory(B).f() # ok!
factory(C) # error: Value of type variable "AnyA" of "factory" cannot be "C"

关于python - Python 中的受限泛型类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64947638/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com