2017-05-31 50 views
0

我有一個看起來有點像這樣的功能。我想讓函數接受io.IOBase的任何子類 - 換句話說,就是任何類似文件的對象。在python type-hinting中,如何讓參數接受基類的任何子類?

def import_csv_file(f:io.IOBase)->pandas.DataFrame: 
    return pandas.read_csv(f) 

當我查看的IntelliJ對象,JetBrains的實現類型,提示的拒絕任何輸入,除非我提供io.IOBase的正是一個實例 - 但如果我想在一個子實例傳遞什麼io.IOBase的類?有沒有辦法改變類型提示說這是允許的?

+0

我的回答是錯誤的。這將使該函數接受類,而不是實例。我將刪除此答案。 – gushitong

+0

但爲什麼我不能刪除這個接受的答案? – gushitong

回答

1

如果你用基類註解一個函數參數(你的情況爲io.IOBase),那麼你也可以傳遞基類的任何子類型的實例 - 繼承也適用於註解類型。也就是說,您可以使用typing.IO作爲表示任何I/O流的泛型類型(分別爲二進制文本I/O流和typing.TextIOtyping.BinaryIO)。

+0

typing.IO是一個更好的解決方案。 :-) –

1
def import_csv_file(f: typing.Type[io.IOBase])->pandas.DataFrame: 
    return pandas.read_csv(f) 

引述PEP

有時你想談談類對象,在從給定的類繼承特定類的對象。這可以拼寫爲Type [C],其中C是一個類。澄清:雖然C(當用作註釋時)引用類C的實例,但類型[C]引用C的子類。

的Python doc

使用C註釋可以接受類型C的值相反的變量,與第一類型[C]註釋的變量可以接受是類本身的值 - 即,它將接受C的類對象例如:

a = 3   # Has type 'int' 
b = int  # Has type 'Type[int]' 
c = type(a) # Also has type 'Type[int]' 

注意,類型[C]是協變:

class User: ... 
class BasicUser(User): ... 
class ProUser(User): ... 
class TeamUser(User): ... 

# Accepts User, BasicUser, ProUser, TeamUser, ... 
def make_new_user(user_class: Type[User]) -> User: 
    # ... 
    return user_class() 
+0

這將顯然使功能接受*類*,而不是實例.. –

+0

@eugeney是的,你是對的,我誤解類型[C],我會刪除這個答案。 – gushitong

相關問題