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

Adam Smith picture Adam Smith · Feb 20, 2014 · Viewed 13.7k times · Source

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?

Answer

zmo picture zmo · Feb 20, 2014

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.