Why does isinstance([1, 2, 3], List[str]) evaluate to true?
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?
isinstance
does not do real PEP 484 type checking. The documentation notes this in passing:
In general, isinstance()
and issubclass()
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.
上一篇: 何时适合使用HTML表格进行布局?