Я собираюсь догадаться, что не ваш декоратор загромождает ваше профилирование, а скорее функция оболочки , созданная декоратором. И это происходит потому, что все функции-оболочки имеют одинаковые имена. Чтобы решить эту проблему, просто попросите декоратора изменить имя функции-оболочки.
def decorator(func):
def wrapper(*args):
print "enter func", func.__name__
return func(*args)
wrapper.__name__ += "_" + func.__name__
return wrapper
Вы также можете использовать functools.wraps()
, но тогда имя функции-оболочки будет совпадать с именем функции, которую она оборачивает. Я думаю, это было бы хорошо для профилирования.
Теперь объект кода функции также имеет имя. Python не хранит ссылки на функции в стеке, только на объекты кода, поэтому, если профилировщик получает имя функции-оболочки из фрейма стека, он получит это имя. Оболочки, определенные обычным способом, совместно используют объект кода (даже если объект функции отличается), если вы явно не перестраиваете объект кода и объект функции для каждой функции оболочки. Это немного больше работы и очень специфично для CPython (может быть, даже для конкретной версии). Но вот как вы можете это сделать:
from types import FunctionType, CodeType
def decorator(func):
def wrapper(*args):
print "enter func", func.__name__
return func(*args)
name = wrapper.__name__ + "_" + func.__name__
func_code = wrapper.func_code
new_code = CodeType(
func_code.co_argcount, func_code.co_nlocals, func_code.co_stacksize,
func_code.co_flags, func_code.co_code, func_code.co_consts,
func_code.co_names, func_code.co_varnames, func_code.co_filename,
name, func_code.co_firstlineno, func_code.co_lnotab,
func_code.co_freevars, func_code.co_cellvars)
wrapper = FunctionType(
new_code, wrapper.func_globals, name, wrapper.func_defaults,
wrapper.func_closure)
return wrapper
И имя функции, и имя объекта кода установлены здесь на wrapper_originalfuncname
, и поэтому они должны учитываться отдельно от встроенной функции в профилировщике. Вы можете легко установить для них только имя исходной функции, чтобы вместо этого время выполнения было заменено исходной функцией.