Sto scrivendo Python che indirizza le versioni 3.2 e successive. Sembra che usare la funzione built-in callable sia il modo più diretto ed efficiente per farlo. Ho visto raccomandazioni per hasattr(x, "__call__")
, collections.Callable(x)
e semplicemente usando try/except
in prossimità di una chiamata tentata.Utilizzo di callable (x) contro hasattr (x, "__call__")
Ho testato elementi richiamabili (una classe e una funzione), utilizzando timeit
con 100.000 iterazioni; in entrambi i casi l'utilizzo di callable richiede solo il 75% circa del tempo di verifica dell'attributo. Quando l'oggetto non è callable (un intero e una stringa) usando callable rimane allo stesso costo di una classe o di una funzione mentre il controllo per l'attributo è circa 2,3 volte più costoso rispetto a una classe o funzione. Non mi aspettavo questa differenza, ma preferisco anche l'approccio chiaro e conciso callable(x)
.
Ma sono relativamente nuovo a Python e non esperto, quindi ci sono ragioni per cui non sono a conoscenza del fatto che dovrei usare l'approccio hasattr o un altro approccio?
FWIW, seguono i risultati dei vari tempi. Il primo carattere è solo t per timeit, il secondo indica quale sia il tipo dell'oggetto sottoposto a test (c = class, f = function, i = intero, s = stringa) e il resto indica il metodo (attr - check attribute, call - usa callable, prova - usa 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
sidenote: callable è stato [rimosso in python3.0] (http://www.python.org/dev/peps/pep-3100/#built-in-namespace) e - dopo aver notato che questo [era un brutto scelta] (http://bugs.python.org/issue10518) - [riportato in 3.2] (http://docs.python.org/3.2/library/functions.html?highlight=callable#callable) – mata