Решение:
Вы должны использовать @functools.wrap
:
<b>import functools</b>
# ...
def some_decorator(func):
<b>@functools.wraps(func)</b>
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
Вывод:
The main thread is "MainThread"
some_function is running on thread "Dummy-1"
Объяснение:
Чтобы проанализировать разницу с использованием @functools.wrap
или нет, необходимо использовать следующий код:
def some_decorator(func):
print(func.__name__, func.__module__, func.__doc__, func.__dict__)
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
print(wrapper.__name__, wrapper.__module__, wrapper.__doc__, wrapper.__dict__)
return wrapper
Удалив @functools.wrap
, вы должны получить следующее:
some_function __main__ None {}
wrapper __main__ None {}
Не удаляя @functools.wrap
, вы должны получить следующее:
some_function __main__ None {}
some_function __main__ None {'__wrapped__': <function Worker.some_function at 0x7f610d926a60>}
Основное различие заключается в __name__, в случае @ functools.wrap это делает функцию-оболочку с тем же именем, что и "fun c ", а какая разница? Он служит для определения, принадлежит ли функция классу Worker или нет, то есть, когда создается класс Worker, создается словарь, в котором хранятся методы, атрибуты и т. Д. c., Но когда сигнал вызывает some_function, тогда он возвращает обертку с именем «обертка», которой нет в словаре Worker, но в случае использования @ functools.wrapper вызывается some_function, а затем возвращается обертке с именем «some_function», вызывающей объект Worker.