odpowiedź Blckknght jest wielki, jeśli chcesz zrobić sprawdzanie przy każdym wywołaniu funkcji, ale jeśli masz ustawienie, które możesz przeczytać raz i nigdy się nie zmienia, możesz nie chcieć sprawdzać ustawienia za każdym razem, gdy wywoływana funkcja jest wywoływana. W niektórych z naszych wysokowydajnych demonów w pracy napisałem dekorator, który sprawdza plik ustawień raz, gdy najpierw jest załadowany plik Pythona i decyduje, czy powinien go zawinąć, czy nie.
Oto próbka
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
Zakładając, że log_function_call rejestruje swoje połączenia do bazy danych, pliku dziennika lub cokolwiek i że config.get („RUN_TIMED_FUNCTIONS”) sprawdza konfigurację globalną, a następnie dodanie @timed dekorator do funkcji sprawdzi raz przy obciążeniu, aby sprawdzić, czy mierzysz czas na tym serwerze, środowisku itp., a jeśli nie, to nie zmieni to wykonania funkcji w produkcji ani w innych środowiskach, w których zależy Ci na wydajności.
Dzięki! Sekcja komentarzy nie jest formatowana, dlatego dodałem przykładowy kod do oryginalnej odpowiedzi. Czy możesz wyjaśnić, dlaczego funkcja czasowa nie jest wywoływana? – cfpete
Dekorator jest stosowany w czasie importu, więc zmienne instancji nie są w tym czasie konsultowane. Musiałbyś napisać do tego innego dekoratora, który sprawdzałby siebie po wywołaniu. Poza zakresem tego formatu Q i komentarza. :-) –
Jak bym go używał, jeśli chcę użyć tego na metodach opartych na klasach, np. Widokach opartych na klasie Django. Tam musimy użyć 'method_decorator'. Jak uczynić ten kod zgodny z tym? – PythonEnthusiast