Python 为(任何)键入提示 class

Python type hint for (any) class

我想键入提示以下函数:

def get_obj_class(self) -> CLASS_TYPE:
  return self.o.__class__

类似地,如果我有一个函数 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 可以是任何东西,但是没有办法暗示构造函数应该是什么样子,所以执行这个检查最终要么是不可能的,要么是非常困难的。)