[英]How to type a function that takes either a class, or an instance of the class, and returns an instance of that class?
我想键入一个 function,它可以采用 class 类型或 class 的实例,然后返回相同 class 的实例。例如:
from typing import Type, TypeVar, Union
DT = TypeVar("DT")
def tmap(dest_type_or_obj: Union[DT, Type[DT]]) -> DT:
if isinstance(dest_type_or_obj, type):
dest_obj = dest_type_or_obj()
else:
dest_obj = dest_type_or_obj
return dest_obj
class Dest:
pass
instance_dest = tmap(Dest()) # Works fine
type_dest = tmap(Dest) # [arg-type] mypy(error)
# Argument 2 to "map" of "ObjectMapper" has incompatible type "Type[Dest]"; expected "Type[<nothing>]"
您应该将Dest
class 绑定到 TypeVar,以防止Type[<nothing>]
错误:
from typing import Type, TypeVar, Union
class Dest:
pass
DT = TypeVar("DT", bound=Dest)
def tmap(dest_type_or_obj: Union[DT, Type[DT]]) -> DT:
if isinstance(dest_type_or_obj, type):
dest_obj = dest_type_or_obj()
else:
dest_obj = dest_type_or_obj
return dest_obj
instance_dest = tmap(Dest())
print((type(instance_dest)))
type_dest = tmap(Dest)
print((type(type_dest)))
# output
<class '__main__.Dest'>
<class '__main__.Dest'>
虽然在技术上是等效的,但 MyPy 需要 使用overload
将两种情况分开:
@overload
def tmap(dest_type_or_obj: Type[DT]) -> DT:
...
@overload
def tmap(dest_type_or_obj: DT) -> DT:
...
这使 MyPy 能够在实例和类型情况下正确推断类型变量。
reveal_type(tmap(Dest())) # note: Revealed type is "__main__.Dest*"
reveal_type(tmap(Dest)) # note: Revealed type is "__main__.Dest*"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.