isinstance(foo,bar) vs type(foo) is bar

python, typechecking

Solution

if I'm checking what should ALWAYS BE A BASE OBJECT, what do I really lose from doing type is?

well, it's nice you give the full documented answer in your question, so your answer is you lose nothing! The only times where `isinstance()` is necessary is when checking inheritance of a given class compared to another, as you well said and referenced. `type()` shall be only used to check whether an instance is exactly of a given base type.

Problem

A question of semantics, really. Up until recently, if I had to do any typechecking on a structure, I would use `type(obj) is list` et. al. However since joining SO I've noticed everyone (and I mean EVERYONE) uses `isinstance(obj,list)` instead. It seems they are synonymous, and `timeit` reveals almost IDENTICAL speed between them. ``` def a(): return type(list()) is list def b(): return isinstance(list(),list) from timeit import timeit timeit(a) # 0.5239454597495582 timeit(b) # 0.5021292075273176 ``` Indeed even `dis` agrees they're synonymous, with the exception of `type is`'s `COMPARE_OP` ``` from dis import dis dis(a) # 2 0 LOAD_GLOBAL 0 (type) # 3 LOAD_GLOBAL 1 (list) # 6 CALL_FUNCTION 0 (0 positional, 0 keyword pair) # 9 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # 12 LOAD_GLOBAL 1 (list) # 15 COMPARE_OP 8 (is) # 18 RETURN_VALUE dis(b) # 2 0 LOAD_GLOBAL 0 (isinstance) # 3 LOAD_GLOBAL 1 (list) # 6 CALL_FUNCTION 0 (0 positional, 0 keyword pair) # 9 LOAD_GLOBAL 1 (list) # 12 CALL_FUNCTION 2 (2 positional, 0 keyword pair) # 15 RETURN_VALUE ``` I frankly find it more readable to say `if type(foo) is list:` than `if isinstance(foo,list):`, the first is basically just pseudo-code and the second calls some function (which I have to look up every time to be `isinstance` or `instanceof`) with some arguments. It doesn't look like a type cast, and there's no explicit way of knowing whether `isinstance(a,b)` is checking if `b` is an instance of `a` or vice-versa. I understand from this question that we use `isinstance` because it's nicer about inheritance. `type(ClassDerivedFromList) is list` will fail while `isinstance(ClassDerivedFromList,list)` will succeed. But if I'm checking what should ALWAYS BE A BASE OBJECT, what do I really lose from doing `type is`?

Original source

Related problems