I was playing around a bit with the new type hinting / typing module with python3.5 trying to find a way to confirm if the hinted type is equal to the actual type of the variable and came across something that rather surprised me.
>>> from typing import List
>>> someList = [1, 2, 3]
>>> isinstance(someList, List[str])
True
Continuing my search for finding a way to compare a variable to it's hinted type I've also tried this:
>>> anotherList = ["foo", "bar"]
>>> type(anotherList) is List[str]
False
Would anyone be able to explain why exactly the former evaluates to True
?
And continuing onwards, is there a sound way to check if a variable's type is equal to a type coming from the typing module?
The isinstance() function returns True if the specified object is of the specified type, otherwise False . If the type parameter is a tuple, this function will return True if the object is one of the types in the tuple.
isinstance is usually the preferred way to compare types. It's not only faster but also considers inheritance, which is often the desired behavior. In Python, you usually want to check if a given object behaves like a string or a list, not necessarily if it's exactly a string.
Generally speaking isinstance is a 'more' elegant way of checking if an object is of a certain "type" (since you are aware of the Inheritance chain). On the other hand, if you are not aware of the inheritance chain and you need to be pick, go for type(x) == ...
Difference Between type() and isinstance() in Python If the value and type given matches it will return true otherwise false. The return value is a Boolean i.e true or false. In case of type the subclass check gives back false. isinstance() gives a truthy value when checked with a subclass.
isinstance
does not do real PEP 484 type checking. The documentation notes this in passing:
In general,
isinstance()
andissubclass()
should not be used with types.
The typing
module, as well as the collections.abc
and abc
modules it’s based on, use extensive __instancecheck__
and __subclasscheck__
magic to make isinstance
and issubclass
behave reasonably. But they’re not doing enough to support your case. Nor is it their goal to support it.
is there a sound way to check if a variable's type is equal to a type coming from the typing module?
You’re not looking for type equality. As you have noted yourself, the type of [1, 2, 3]
is list
, which is not equal to List[str]
, nor to List[int]
. You’re looking for type checking, which is much more complicated.
Consider this:
def my_function():
# ... 1000 lines of very complicated code ...
print(isinstance(my_function, Callable[[], int]))
What would you expect this program to print? You can’t expect isinstance
to dig into my_function
at runtime and infer that it always returns int
. This is not feasible in Python. You need either a “compile” time type checker that has access to the structure of my_function
, or explicit type annotations, or—most likely—both.
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