if hasattr(obj, \'attribute\'):
# do somthing
vs
try:
# access obj.attribute
except AttributeError, e:
# deal with Attr
I almost always use hasattr: it's the correct choice for most cases.
The problematic case is when a class overrides __getattr__: hasattr will catch all exceptions instead of catching just AttributeError like you expect. In other words, the code below will print b: False even though it would be more appropriate to see a ValueError exception:
class X(object):
def __getattr__(self, attr):
if attr == 'a':
return 123
if attr == 'b':
raise ValueError('important error from your database')
raise AttributeError
x = X()
print 'a:', hasattr(x, 'a')
print 'b:', hasattr(x, 'b')
print 'c:', hasattr(x, 'c')
The important error has thus disappeared. This has been fixed in Python 3.2 (issue9666) where hasattr now only catches AttributeError.
An easy workaround is to write a utility function like this:
_notset = object()
def safehasattr(thing, attr):
return getattr(thing, attr, _notset) is not _notset
This let's getattr deal with the situation and it can then raise the appropriate exception.