Python 为(任何)键入提示 class
Python type hint for (any) class
我想键入提示以下函数:
def get_obj_class(self) -> CLASS_TYPE:
return self.o.__class__
CLASS_TYPE
应表示 class
es.
self.o
可以是运行时确定的任何类型。
类似地,如果我有一个函数 f(cls: CLASS_TYPE)
,其中 return 是 cls
的一个实例,有没有办法键入提示 return 值合适吗?
对于Python >=3.7,使用type
(see also PEP 585):
def get_obj_class(self) -> type:
return self.o.__class__
对于Python <3.7,使用typing.Type
:
def get_obj_class(self) -> typing.Type:
return self.o.__class__
那typing.Type
呢?
这似乎很合适,因为 __class__
应该总是 return 一种类型。
import typing
def test(t: object) -> typing.Type:
return t.__class__
class Dummy(object):
pass
test(Dummy())
关于你的第二个问题:那应该是 generic.
我建议使用 TypeVar
, to indicate that your self.o
value could be any arbitrary type, and Type
的组合,如下所示:
from typing import TypeVar, Type
T = TypeVar('T')
class MyObj:
def __init__(self, o: T) -> None:
self.o = o
def get_obj_class(self) -> Type[T]:
return type(self.o)
def accept_int_class(x: Type[int]) -> None:
pass
i = MyObj(3)
foo = i.get_obj_class()
accept_int_class(foo) # Passes
s = MyObj("foo")
bar = s.get_obj_class()
accept_int_class(bar) # Fails
如果你想让 o
的类型更加动态,你可以显式或隐式地给它一个类型 Any
.
关于你的后一个问题,你会做:
def f(cls: Type[T]) -> T:
return cls()
请注意,在实例化 class 时需要小心——我不记得 Pycharm 在这里做了什么,但我知道 mypy 目前不会检查以确保你正在调用您的 __init__
函数 correctly/with 正确数量的参数。
(这是因为 T 可以是任何东西,但是没有办法暗示构造函数应该是什么样子,所以执行这个检查最终要么是不可能的,要么是非常困难的。)
我想键入提示以下函数:
def get_obj_class(self) -> CLASS_TYPE:
return self.o.__class__
CLASS_TYPE
应表示class
es.self.o
可以是运行时确定的任何类型。
类似地,如果我有一个函数 f(cls: CLASS_TYPE)
,其中 return 是 cls
的一个实例,有没有办法键入提示 return 值合适吗?
对于Python >=3.7,使用type
(see also PEP 585):
def get_obj_class(self) -> type:
return self.o.__class__
对于Python <3.7,使用typing.Type
:
def get_obj_class(self) -> typing.Type:
return self.o.__class__
那typing.Type
呢?
这似乎很合适,因为 __class__
应该总是 return 一种类型。
import typing
def test(t: object) -> typing.Type:
return t.__class__
class Dummy(object):
pass
test(Dummy())
关于你的第二个问题:那应该是 generic.
我建议使用 TypeVar
, to indicate that your self.o
value could be any arbitrary type, and Type
的组合,如下所示:
from typing import TypeVar, Type
T = TypeVar('T')
class MyObj:
def __init__(self, o: T) -> None:
self.o = o
def get_obj_class(self) -> Type[T]:
return type(self.o)
def accept_int_class(x: Type[int]) -> None:
pass
i = MyObj(3)
foo = i.get_obj_class()
accept_int_class(foo) # Passes
s = MyObj("foo")
bar = s.get_obj_class()
accept_int_class(bar) # Fails
如果你想让 o
的类型更加动态,你可以显式或隐式地给它一个类型 Any
.
关于你的后一个问题,你会做:
def f(cls: Type[T]) -> T:
return cls()
请注意,在实例化 class 时需要小心——我不记得 Pycharm 在这里做了什么,但我知道 mypy 目前不会检查以确保你正在调用您的 __init__
函数 correctly/with 正确数量的参数。
(这是因为 T 可以是任何东西,但是没有办法暗示构造函数应该是什么样子,所以执行这个检查最终要么是不可能的,要么是非常困难的。)