"
This article is part of in the series
Last Updated: Wednesday 29th December 2021

Since everything in Python is an object and objects have attributes (fields and methods), it's natural to write programs that can inspect what kind of attributes an object has. For example, a Python program could open a socket on the server and it accepts Python scripts sent over the network from a client machine. Upon receiving a new script, the server-side Python program can inspect or more precisely introspect objects, modules, and functions in the new script to decide how to perform the function, log the result, and various useful tasks.

hasattr vs. try-except

There're two ways to check if a Python object has an attribute or not. The first way is to call the built-in function hasattr(object, name), which returns True if the string name is the name of one of the object's attributes, False if not. The second way is to try to access an attribute in an object and perform some other function if an AttributeError was raised.

[python]
>>> hasattr('abc', 'upper')
True
>>> hasattr('abc', 'lower')
True
>>> hasattr('abc', 'convert')
False
[/python]

And:

[python]
>>> try:
... 'abc'.upper()
... except AttributeError:
... print("abc does not have attribute 'upper'")
...
'ABC'
>>> try:
... 'abc'.convert()
... except AttributeError:
... print("abc does not have attribute 'convert'")
...
abc does not have attribute 'convert'
[/python]

What's the difference between these two styles? hasattr is often referred as a Python programming style called "Look Before You Leap" (LBYL) because you check whether an object has an attribute or not before you access it. While try-except is referred as "Easier to Ask for Forgiveness than Permission" (EAFP) because you try the attribute access first and ask for forgiveness in the except block instead of asking for permission like hasattr.

Which way is better, then? Well, both doctrines have loyal supporters and both styles seem to be well-versed to deal with any real-world programming challenge. Sometimes, it makes sense to use LBYL if you want to make sure an attribute definitely exists and stop execution if it doesn't. For example, you know for certain at a point in the program that a passed-in object should have a valid file pointer attribute on which the following code can work. On the other hand, it also makes sense to use EAFP if you know an attribute might not exist at some point during the program's execution. For example, a music player could not guarantee a MP3 file is always on-disk at the same location, because it might be deleted, modified, or moved by the user at any time. In this case, the music player can try to access the MP3 file first and notify the user that the file does not exist in an except block.

hasattr vs __dict__

Although hasattr is a built-in function that is designed to check if an attribute exists in an object, sometimes it might be more accurate to check an object's __dict__ for an attribute's existence instead due to the fact that hasattr does not care about the reason why an attribute's attached to an object while you may want to know why an attribute's attached to an object. For example, an attribute might be attached to an object due to its parent class instead of the object itself.

[python]
>>> class A(object):
... foo = 1
...
>>> class B(A):
... pass
...
>>> b = B()
>>> hasattr(b, 'foo')
True
>>> 'foo' in b.__dict__
False
[/python]

In the previous code, since class B is a subclass of class A, class B also has the attribute "foo". However, because "foo" is inherited from A, B.__dict__ does not contain it. Sometimes, it might be crucial to know whether an attribute comes from an object's class itself or from the objects' superclass.

Tips and Suggestions

  • hasattr follows the duck-typing principle in Python:

    When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.

    So, most of the time you want to use hasattr to check if an attribute exists in an object.

  • try-except and __dict__ have their own use cases which are actually quite narrow compared to hasattr. So, it is beneficial to keep these special use cases in the back of your head so that you will recognize them during coding and use the proper idioms accordingly.

Once you've learnt how to check if an object has an attribute in Python, checkout how to get an attribute from an object.

About The Author