In python type-hinting, how can I make an argument accept any subclass of a base class?

后端 未结 3 1206
醉话见心
醉话见心 2021-01-18 10:36

I have a function that looks a bit like this. I want the function to accept any subclass of io.IOBase - in other words, any file-like object.

def import_csv_         


        
相关标签:
3条回答
  • 2021-01-18 11:04

    If you annotate a function argument with the base class (io.IOBase in your case) then you can also pass instances of any subtype of the base class – inheritance applies to annotation types as well.

    That said, you could use typing.IO as a generic type representing any I/O stream (and typing.TextIO and typing.BinaryIO for binary and text I/O streams respectively).

    0 讨论(0)
  • 2021-01-18 11:08

    One of answers here explain how to use typing.cast. It may help.

    0 讨论(0)
  • 2021-01-18 11:21
    def import_csv_file(f: typing.Type[io.IOBase])->pandas.DataFrame:
        return pandas.read_csv(f)
    

    Quoting the PEP:

    Sometimes you want to talk about class objects, in particular class objects that inherit from a given class. This can be spelled as Type[C] where C is a class. To clarify: while C (when used as an annotation) refers to instances of class C , Type[C] refers to subclasses of C .

    Python doc:

    A variable annotated with C may accept a value of type C. In contrast, a variable annotated with Type[C] may accept values that are classes themselves – specifically, it will accept the class object of C. For example:

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

    Note that Type[C] is covariant:

    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)
提交回复
热议问题