英文:
Python typing - TypeVar for something that inherits from multiple base classes
问题
T = TypeVar("T", bound=Union[X, Y])
def foo(x: T) -> None:
assert isinstance(x, X)
assert isinstance(x, Y)
英文:
Python's TypeVar
allows setting a bound
for a type, like so
from typing import TypeVar
class A:
pass
T = TypeVar("T", bound=A)
def foo(_: T) -> None:
pass
class B(A):
pass
class C:
pass
foo(B()) # OK
foo(C()) # error: Value of type variable "T" of "foo" cannot be "C"
My question is how can I express "any type T where T inherits from X and Y"?
This was my first naive attempt:
from typing import TypeVar
class X:
pass
class Y:
pass
class XY(X, Y):
pass
T = TypeVar("T", bound=XY)
def foo(_: T) -> None:
pass
class MyClass(X, Y):
pass
foo(MyClass()) # error: Value of type variable "T" of "foo" cannot be "MyClass"
This doesn't work, because MyClass
isn't a subclass of XY
, and mypy correctly rejects the code.
In this minimal example I could do class MyClass(XY)
, but this isn't a good solution for the actual code I'm working with. Consider what happens if there are classes X1
, X2
, ..., Xn
, and I have functions that expect types that inherit from some subset of these. Making a class for each combination would be infeasible, as MyClass
would need to inherit from each "combo-class".
Essentially I'm looking for something equivalent to this fictional code:
T = TypeVar("T", bound=(X, Y)) # Not allowed
def foo(x: T):
assert isinstance(x, X)
assert isinstance(x, Y)
Any thought's on how this could be done, or achieve something to this effect?
答案1
得分: 1
The only support the current Python typing system has for type hinting multiple inheritance is through a Protocol
, where all the bases also have to be Protocol
s, as documented in PEP-544:
from typing import TypeVar, Protocol
class X(Protocol):
pass
class Y(Protocol):
pass
class XY(X, Y, Protocol):
pass
T = TypeVar("T", bound=XY)
def foo(_: T) -> None:
pass
class MyClass(X, Y):
pass
foo(MyClass())
Demo: https://mypy-play.net/?mypy=latest&python=3.11&gist=f392ad6b46ff9b87c1f3e574bc7626c6
英文:
The only support the current Python typing system has for type hinting multiple inheritance is through a Protocol
, where all the bases also have be Protocol
s, as documented in PEP-544:
from typing import TypeVar, Protocol
class X(Protocol):
pass
class Y(Protocol):
pass
class XY(X, Y, Protocol):
pass
T = TypeVar("T", bound=XY)
def foo(_: T) -> None:
pass
class MyClass(X, Y):
pass
foo(MyClass())
Demo: https://mypy-play.net/?mypy=latest&python=3.11&gist=f392ad6b46ff9b87c1f3e574bc7626c6
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论