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?

