(任何)类的Python类型提示

y-s*_*een 7 python types type-hinting python-3.x

我想输入提示以下函数:

def get_obj_class(self) -> *class*:
  return self.o.__class__
Run Code Online (Sandbox Code Playgroud)

self.o 可以是任何类型,它是在运行时确定的.

*class*显然不是这里的答案,因为它是无效的语法.但是,什么正确的答案?我找不到任何关于此的文档,任何帮助表示赞赏.


在类似的说明中,如果我有一个f(cls: *class*)返回实例的函数cls,有没有办法键入提示返回值?

VMR*_*uiz 16

对于 Python >=3.7,请使用type(另请参阅PEP 585):

def get_obj_class(self) -> type:
    return self.o.__class__
Run Code Online (Sandbox Code Playgroud)

对于 Python <3.7,请使用typing.Type

def get_obj_class(self) -> typing.Type:
    return self.o.__class__
Run Code Online (Sandbox Code Playgroud)

  • + 为了简单起见,尽管“typing.TypeVar”似乎是正确的解决方案 (2认同)

Mic*_*x2a 6

我建议使用组合TypeVar,表示您的self.o值可以是任意类型,并且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
Run Code Online (Sandbox Code Playgroud)

如果您希望类型o更加动态,您可以显式或隐式地给它一种类型Any.


关于你的后一个问题,你会做:

def f(cls: Type[T]) -> T:
    return cls()
Run Code Online (Sandbox Code Playgroud)

请注意,在实例化类时需要小心 - 我不记得Pycharm在这里做了什么,但我知道mypy目前没有检查以确保你__init__正确调用你的函数/使用正确数量的params .

(这是因为T可能是任何东西,但是没有办法暗示构造函数应该是什么样子,因此执行此检查最终会变得不可能或非常困难.)

  • 我真的不喜欢每次想要构造自定义类型时都需要创建一个_named_ TypeVar 对象。我认为在我的情况下我宁愿坚持“类型”。不过还是谢谢你介绍这个 (4认同)