risposta di Blckknght è grande se si vuole fare la verifica ogni volta che si chiama la funzione, ma se si dispone di un'impostazione che è possibile leggere una volta e non modificare mai, è possibile che non si desideri controllare l'impostazione ogni volta che viene chiamata la funzione decorata. In alcuni dei nostri demoni ad alte prestazioni sul lavoro ho scritto un decoratore che controlla un file di impostazione una volta quando il file python viene caricato per la prima volta e decide se deve essere incluso o meno.
Ecco un esempio
def timed(f):
def wrapper(*args, **kwargs):
start = datetime.datetime.utcnow()
return_value = f(*args, **kwargs)
end = datetime.datetime.utcnow()
duration = end - start
log_function_call(module=f.__module__, function=f.__name__, start=__start__, end=__end__, duration=duration.total_seconds())
if config.get('RUN_TIMED_FUNCTIONS'):
return wrapper
return f
Supponendo che log_function_call registra la chiamata a un database, file di log, o qualsiasi altra cosa e che config.get ('RUN_TIMED_FUNCTIONS') controlla la configurazione globale, quindi aggiungendo il decoratore @timed a una funzione controllerà una volta sul carico per vedere se si sta cronometrando su questo server, ambiente, ecc. e in caso contrario non cambierà l'esecuzione della funzione in produzione o negli altri ambienti in cui si cura delle prestazioni.
Grazie! La sezione dei commenti non viene formattata, quindi ho aggiunto il codice di esempio alla tua risposta originale. Puoi spiegare perché non viene chiamata la funzione di cronometraggio? – cfpete
Il decoratore viene applicato al momento dell'importazione, quindi le variabili di istanza non vengono consultate in quel momento. Dovresti scrivere un decoratore diverso per questo, uno che ispeziona te stesso quando viene chiamato. Fuori campo per questo Q e il formato dei commenti. :-) –
Come dovrei usarlo se voglio usare questo su metodi basati su classi, cioè viste basate su classi Django. Laggiù dobbiamo usare 'method_decorator'. Come rendere questo codice compatibile con quello? – PythonEnthusiast