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
?