I am writing Python that targets version 3.2 and higher. It seems that using the built-in function called is the easiest and most efficient way to do this. I saw recommendations for hasattr(x, "__call__") , collections.Callable(x) and just used try/except around the call attempt.
I tested the elements called (class and function) using timeit with 100,000 iterations; in both cases, using the called object takes only about 75% of the attribute verification time. When an element cannot be called (an integer and a string) using called residuals with the same cost as a class or function, when checking an attribute is approximately 2.3 times more expensive than for a class or function. I did not expect this difference, but it also contributes to the clear and concise callable(x) approaches.
But I'm relatively new to Python and not an expert, so are there reasons why I don't know if I should use the hasattr approach or another approach?
FWIW, the results of various time periods follow. The first character is just t for timeit, the second is the type of object being tested (c = class, f = function, i = integer, s = string), and the rest is indicated by the method (attr - check attribute, call - use callable, try - use try / except).
tcattr 0.03665385400199739
tccall 0.026238360142997408
tctry 0.09736267629614304
tfattr 0.03624538065832894
tfcall 0.026362861895904643
tftry 0.032501874250556284
tiattr 0.08297350149314298
ticall 0.025826044152381655
titry 0.10657657453430147
tsattr 0.0840187013927789
tscall 0.02585409547373274
tstry 0.10742772077628615
bmacnaughton
source share