Is there any difference between using typing.Any
as opposed to object
in typing? For example:
def get_item(L: list, i: int) -> typing.Any: return L[i]
Compared to:
def get_item(L: list, i: int) -> object: return L[i]
Difference between any and Object in TypeScript:any is way more flexible to use than Object. Object is way more specific in declaration than any. any does not ignore any compile time checks . Objects take more time to compile.
object can be cast to a more specific type, while Any really means anything goes and a type checker disengages from any use of the object (even if you later assign such an object to a name that is typechecked).
If you use any instead you are basically telling the transpiler that anything goes, you are providing no information about what is stored in a - it can be anything! And therefore the transpiler will allow you to do whatever you want with something defined as any .
New in version 3.5. The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.
Yes, there is a difference. Although in Python 3, all objects are instances of object
, including object
itself, only Any
documents that the return value should be disregarded by the typechecker.
The Any
type docstring states that object is a subclass of Any
and vice-versa:
>>> import typing >>> print(typing.Any.__doc__) Special type indicating an unconstrained type. - Any object is an instance of Any. - Any class is a subclass of Any. - As a special case, Any and object are subclasses of each other.
However, a proper typechecker (one that goes beyond isinstance()
checks, and which inspects how the object is actually used in the function) can readily object to object
where Any
is always accepted.
From the Any
type documentation:
Notice that no typechecking is performed when assigning a value of type
Any
to a more precise type.
and
Contrast the behavior of
Any
with the behavior ofobject
. Similar toAny
, every type is a subtype ofobject
. However, unlikeAny
, the reverse is not true: object is not a subtype of every other type.That means when the type of a value is
object
, a type checker will reject almost all operations on it, and assigning it to a variable (or using it as a return value) of a more specialized type is a type error.
and from the mypy documentation section Any vs. object:
The type
object
is another type that can have an instance of arbitrary type as a value. UnlikeAny
,object
is an ordinary static type (it is similar toObject
in Java), and only operations valid for all types are accepted for object values.
object
can be cast to a more specific type, while Any
really means anything goes and a type checker disengages from any use of the object (even if you later assign such an object to a name that is typechecked).
You already painted your function into a an un-typed corner by accepting list
, which comes down to being the same thing as List[Any]
. The typechecker disengaged there and the return value no longer matters, but since your function accepts a list containing Any
objects, the proper return value would be Any
here.
To properly participate in type-checked code, you need to mark your input as List[T]
(a genericly typed container) for a typechecker to then be able to care about the return value. Which in your case would be T
since you are retrieving a value from the list. Create T
from a TypeVar
:
from typing import TypeVar, List T = TypeVar('T') def get_item(L: List[T], i: int) -> T: return L[i]
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...
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With