在python类型提示中,如何使参数接受基类的任何子类?

时间:2017-05-31 08:40:41

标签: python type-hinting

我有一个看起来有点像这样的功能。我希望函数接受io.IOBase的任何子类 - 换句话说,任何类似文件的对象。

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

当我在IntelliJ中查看对象时,类型提示的JetBrains实现拒绝任何输入,除非我提供了io.IOBase的确切实例 - 但是如果我想传入io子类的实例该怎么办。 IOBASE?有没有办法改变类型提示,说这是允许的?

2 个答案:

答案 0 :(得分:2)

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的值。相反,使用Type [C]注释的变量可以接受类本身的值 - 具体来说,它将接受C的类对象。例如:< / p>

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()

答案 1 :(得分:1)

如果使用基类(在您的情况下为io.IOBase)注释函数参数,那么您也可以传递基类的任何子类型的实例 - 继承也适用于注释类型。

也就是说,您可以使用typing.IO作为表示任何I / O流的泛型类型(分别用于二进制和文本I / O流的typing.TextIOtyping.BinaryIO)。