我正在尝试为类型之间的转换实现一个接口,但由于typing.Type
是协变的,因此我正在努力使其保持一致
U = TypeVar('U')
class Into(Protocol[U]):
@abstractmethod
def into(self, t: Type[U]) -> U:
pass
docs给出了一个相似的示例,但有一个关键的区别
class User: ...
class BasicUser(User): ...
class ProUser(User): ...
class TeamUser(User): ...
def make_new_user(user_class: Type[User]) -> User:
return user_class()
他们说类型检查器应检查User
的所有子类应实现带有有效签名的构造函数,以使其实例化。我的用例是不同的cos,我可能不会构造新的类型,而只是返回一个预先存在的类型。说我做
class X: pass
class Wrapper:
def __init__(self, x: X):
self._x = x
def into(self, t: Type[X]) -> X:
return self._x
一切正常,直到有人继承X
w = Wrapper(X)
...
class XX(X): pass
x: XX = w.into(XX)
mypy cos Type
是协变的,因此RHS很好,但是显然X
不是XX
的API已损坏cos。如果Type
不是协变的,则不必担心:在更新Wrapper
以支持XX
之前,RHS不会键入check。
我的问题是:鉴于Type
的协方差,是否有某种方法可以实现这一目标(或类似方法)?
上下文
我想用它来将一个类型转换为多种其他类型,显式地指定所需的类型,而不仅仅是into_X
,into_Y
等。我希望使用TypeVar
或overload
。我也遇到了问题there。
这受rust的Into
的启发,其中t: Type[U]
是类型参数,而不是函数参数。
答案 0 :(得分:-2)
eval
解决了这个问题。
class Wrapper:
def __init__(self, x: X):
self._x = x
def into(self, t: Type[X]) -> X:
return eval(f'{t}({self._x})')