2017-06-02 77 views
4

我想提示键入下面的函数:Python类型提示为(任何)

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

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

*class*显然这里没有答案,因为它的语法无效。但是的正确答案?我找不到任何文件,任何帮助表示赞赏。


与此类似,如果我有一个函数f(cls: *class*)返回的cls一个实例,是有键入适当的提示的返回值的方法吗?

回答

3

我推荐使用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 

如果你想的o类型更加动态的,你可以明确或含蓄地给它一个类型Any


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

def f(cls: Type[T]) -> T: 
    return cls() 

请注意,您需要实例化类时要小心 - 我不记得是什么Pycharm确实在这里,但我做的知道mypy目前不检查以确保您正确地调用您的__init__函数/具有正确数量的参数。

(这是因为牛逼可以是任何东西,但有没有办法暗示什么构造函数应该是什么样子,所以在执行这一检查将最终被无论是不可能或非常困难的。)

+0

我真的不喜欢每次要构建自定义类型时都需要创建_named_ TypeVar对象。我认为在我的情况下,我宁愿坚持'输入'。但是,谢谢你介绍这个 –

+1

@ nO_OnE_910 - 当定义泛型类和函​​数时,你可以重用相同的TypeVar变量。您可能会发现,由于您只引入了一个名为TypeVar的对象(您可以重复使用),而不是每个泛型类或函数中的一个,因此可能会觉得不那么令人厌恶。 – Michael0x2a

1

我认为这将做的工作:

def get_obj_class(self) -> type 
    return self.o.__class__ 
+0

+为简单起见,虽然'typing.TypeVar'好像是合适的解决方案 –

0

什么typing.Type?

https://docs.python.org/3/library/typing.html#typing.Type

这似乎适合 - 因为__class_应该总是返回一个类型

是的,这个工作(甚至Pycharm不抱怨:

import typing 


def test(t: object) -> typing.Type: 
    return t.__class__ 

class Dummy(object): 
    pass 

test(Dummy()) 

你的第二个问题:应该是一个通用的:https://docs.python.org/3/library/typing.html#user-defined-generic-types

+0

为什么'typing.Type'不只是'type'? –

+0

@ nO_OnE_910我更喜欢使用打字模块来保持连贯的风格。我的大部分退货都是打字.X,所以对我来说看起来更自然 –