Skip to content
Fragmented Development

Python `hasattr` method headache

Python's hasattr function checks to see if an object has an attribute - a fairly straightforward and sensible purpose. When I used it, however, it caused some very subtle problems that were tricky and unintuitive to debug.

The problem came when I used hasattr on a dict, to check for a particular index. hasattr does not work with dicts - it only works with objects. It doesn't throw an exception when used on a dict, though. It always returns false.

data = {'test': 'value'}

def process_data(data):

    if hasattr(data, 'test'):
		# do_something_smart is never called,
		# hasattr only returns False with dicts
		do_something_smart(data['test'])
	else:
		# Fallback logic is ALWAYS executed
		...

The proper way to check for a dict index is to use the in keyword. You could replace the check in the function above to get the right behavior:

data = {'test': 'value'}

def process_data(data):

	# Will actually check if data['test'] is set
	if 'test' in data:
		do_something_smart(data['test'])
	else:
		# Fallback code won't be called if 'test' is set
		...

If you only wanted the value from data['test'], I think the most pythonic thing to do would be to skip the check altogether, and just put everything in a try - except block. The get method also works, allowing you to provide a default value:

test_data = data.get('test', "Default value (only if data['test'] is unset")

Hopefully this saves someone the headache I endured!

Tags: python


Add Your Comment