Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 897
Adam Smith Avatar asked Feb 19 '14 23:02

Adam Smith


People also ask

What is the difference between type and Isinstance?

type() returns the type of the object you put in as an argument, and is usually not useful unless compared with a real type (such as type(9) == int ). isinstance() returns a boolean - true or false - based on whether the object is of given type.

Why is it better to use Isinstance?

Conclusions. isinstance is usually the preferred way to compare types. It's not only faster but also considers inheritance, which is often the desired behavior. In Python, you usually want to check if a given object behaves like a string or a list, not necessarily if it's exactly a string.

What is from foo import bar?

from foo import bar This statement imports bar which could be anything that is declared in the module. It could be a function definition, a class (albeit a not-conventionally-named class) or even a submodule (which make foo a package).

How does Isinstance work in Python?

isinstance() With Python ClassThe isinstance() works as a comparison operator, and it compares the object with the specified class type. You can verify if the emp object is an instance of a user-defined class Employee using the isinstance() function. It must return True.


2 Answers

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.

like image 101
zmo Avatar answered Sep 20 '22 17:09

zmo


Other than the inheritance issue, you also lose the ability to test multiple types when using isinstance. For example:

def chk(typ):     if not isinstance(typ, (str, int)):         raise ValueError('typ must be string or int')     ... 
like image 28
user590028 Avatar answered Sep 19 '22 17:09

user590028