2017-06-02 76 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,所以對我來說看起來更自然 –