I have been reading lately some tweets and the python documentation about hasattr and it says:
hasattr(object, name)
The arguments are an object and a string. The result is True if the string is the name of >> one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an AttributeError or not.)
There is a motto in Python that says that is Easier to ask for forgiveness than permission where I usually agree.
I tried to do a performance test in this case with a really simple python code:
import timeit
definition="""\
class A(object):
a = 1
a = A()
"""
stm="""\
hasattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)
stm="""\
getattr(a, 'a')
"""
print timeit.timeit(stmt=stm, setup=definition, number=10000000)
With the results:
$ python test.py
hasattr(a, 'a')
1.26515984535
getattr(a, 'a')
1.32518696785
I´ve tried also what happens if the attribute doesn´t exists and the differences between getattr and hasattr are bigger. So what I´ve seen so far is that getattr is slower than hasattr, but in the documentation it says that it calls getattr.
I´ve searched the CPython implementation of hasattr and getattr and it seems that both call the next function:
v = PyObject_GetAttr(v, name);
but there is more boilerplate in getattr than in hasattr that probably makes it slower.
Does anyone knows why in the documentation we say that hasattr calls getattr and we seem to encourage the users to use getattr instead of hasattr when it really isn´t due to performance? Is just because it is more pythonic?
Maybe I am doing something wrong in my test :)
Thanks,
Raúl