typing.Any vs object?

前端 未结 2 1736
灰色年华
灰色年华 2021-01-01 09:02

Is there any difference between using typing.Any as opposed to object in typing? For example:

def get_item(L: list, i: int) -> t         


        
2条回答
  •  迷失自我
    2021-01-01 09:49

    Any and object are superficially similar, but in fact are entirely opposite in meaning.

    object is the root of Python's metaclass hierarchy. Every single class inherits from object. That means that object is in a certain sense the most restrictive type you can give values. If you have a value of type object, the only methods you are permitted to call are ones that are a part of every single object. For example:

    foo = 3  # type: object
    
    # Error, not all objects have a method 'hello'
    bar = foo.hello()   
    
    # OK, all objects have a __str__ method
    print(str(foo))   
    

    In contrast, Any is an escape hatch meant to allow you to mix together dynamic and statically typed code. Any is the least restrictive type -- any possible method or operation is permitted on a value of type Any. For example:

    from typing import Any
    foo = 3  # type: Any
    
    # OK, foo could be any type, and that type might have a 'hello' method
    # Since we have no idea what hello() is, `bar` will also have a type of Any
    bar = foo.hello()
    
    # Ok, for similar reasons
    print(str(foo))
    

    You should generally try and use Any only for cases where...

    1. As a way of mixing together dynamic and statically typed code. For example, if you have many dynamic and complex functions, and don't have time to fully statically type all of them, you could settle for just giving them a return type of Any to nominally bring them into the typechecked work. (Or to put it another way, Any is a useful tool for helping migrate an untypechecked codebase to a typed codebase in stages).
    2. As a way of giving a type to an expression that is difficult to type. For example, Python's type annotations currently do not support recursive types, which makes typing things like arbitrary JSON dicts difficult. As a temporary measure, you might want to give your JSON dicts a type of Dict[str, Any], which is a bit better then nothing.

    In contrast, use object for cases where you want to indicate in a typesafe way that a value MUST literally work with any possible object in existence.

    My recommendation is to avoid using Any except in cases where there is no alternative. Any is a concession -- a mechanism for allowing dynamism where we'd really rather live in a typesafe world.

    For more information, see:

    • https://docs.python.org/3/library/typing.html#the-any-type
    • http://mypy.readthedocs.io/en/latest/kinds_of_types.html#the-any-type

    For your particular example, I would use TypeVars, rather then either object or Any. What you want to do is to indicate that you want to return the type of whatever is contained within the list. If the list will always contain the same type (which is typically the case), you would want to do:

    from typing import List, TypeVar
    
    T = TypeVar('T')
    def get_item(L: List[T], i: int) -> T:
        return L[i]
    

    This way, your get_item function will return the most precise type as possible.

提交回复
热议问题