python isinstance vs hasattr vs try/except: What is better? python isinstance vs hasattr vs try/except: What is better? python python

python isinstance vs hasattr vs try/except: What is better?


I believe that the last method is generally preferred by Python coders because of a motto taught in the Python community: "Easier to ask for forgiveness than permission" (EAFP).

In a nutshell, the motto means to avoid checking if you can do something before you do it. Instead, just run the operation. If it fails, handle it appropriately.

Also, the third method has the added advantage of making it clear that the operation should work.


With that said, you really should avoid using a bare except like that. Doing so will capture any/all exceptions, even the unrelated ones. Instead, it is best to capture exceptions specifically.

Here, you will want to capture for an AttributeError:

try:    obj.do_stuff()   # Try to invoke do_stuffexcept AttributeError:    print 'Do something else'  # If unsuccessful, do something else


Checking with isinstance runs counter to the Python convention of using duck typing.

hasattr works fine, but is Look Before you Leap instead of the more Pythonic EAFP.

Your implementation of way 3 is dangerous, since it catches any and all errors, including those raised by the do_stuff method. You could go with the more precise:

try:    _ds = obj.do_stuffexcept AttributeError:    print('Do something else')else:    _ds()

But in this case, I'd prefer way 2 despite the slight overhead - it's just way more readable.


The correct answer is 'neither'hasattr delivers functionality however it is possibly the worst of all options.

We use the object oriented nature of python because it works. OO analysis is never accurate and often confuses however we use class hierarchies because we know they help people do better work faster. People grasp objects and a good object model helps coders change things more quickly and with less errors. The right code ends up clustered in the right places. The objects:

  • Can just be used without considering which implementation is present
  • Make it clear what needs to be changed and where
  • Isolate changes to some functionality from changes to some other functionality – you can fix X without fearing you will break Y

hasattr vs isinstance

Having to use isinstance or hasattr at all indicates the object model is broken or we are using it incorrectly. The right thing to do is to fix the object model or change how we are using it. These two constructs have the same effect and in the imperative ‘I need the code to do this’ sense they are equivalent. Structurally there is a huge difference. On meeting this method for the first time (or after some months of doing other things), isinstance conveys a wealth more information about what is actually going on and what else is possible. Hasattr does not ‘tell’ you anything.

A long history of development lead us away from FORTRAN and code with loads of ‘who am I’ switches. We choose to use objects because we know they help make the code easier to work with. By choosing hasattr we deliver functionality however nothing is fixed, the code is more broken than it was before we started. When adding or changing this functionality in the future we will have to deal with code that is unequally grouped and has at least two organising principles, some of it is where it ‘should be’ and the rest is randomly scattered in other places. There is nothing to make it cohere. This is not one bug but a minefield of potential mistakes scattered over any execution path that passes through your hasattr.

So if there is any choice, the order is:

  1. Use the object model or fix it or at least work out what is wrongwith it and how to fix it
  2. Use isinstance
  3. Don’t use hasattr