@wraps () не ведет себя не возвращает исходные значения функций - PullRequest
1 голос
/ 27 мая 2019

Я написал довольно простой декоратор:

def test_speed(f, *args, **kwargs):
    """This decorator will print out the time taken for input function to run."""

    @wraps(f)
    def wrapper():
        """Wrapper function returned by the outer function."""
        start = time.time()
        to_return = f(*args, **kwargs)
        end = time.time()
        print(f"The function {__name__} completed in {end-start} seconds.")

        return to_return
    return wrapper

В сценарии Python, называемом декораторами, в проекте, который называется tools. Я добавил этот проект в свою конфигурацию во втором проекте, который я использую для тренировки с использованием модуля многопроцессорной обработки. Я написал несколько тестовых функций для проверки скорости многопроцессорных циклов:

""" A script to practice using multiprocessing effectively in python."""

from decorators import *
from multiprocessing import *


def _loop(i, process_number):
    for i in range(i):
        if i % 500 == 0:
            print(f'{i} iterations of loop {process_number}.')


def serial_looping():

    _loop(10000, 'one')
    _loop(10000, 'two')
    _loop(10000, 'three')


@test_speed
def parallel_looping():
    loop_one = Process(target=_loop, args=(10000, 'one'))
    loop_two = Process(target=_loop, args=(10000, 'two'))
    loop_three = Process(target=_loop, args=(10000, 'three'))


if __name__ == '__main__':
    serial_looping()
    parallel_looping()

def serial_looping():

    _loop(10000, 'one')
    _loop(10000, 'two')
    _loop(10000, 'three')


@test_speed
def parallel_looping():
    loops = []
    loops.append(Process(target=_loop, args=(10000, 'one')))
    loops.append(Process(target=_loop, args=(10000, 'two')))
    loops.append(Process(target=_loop, args=(10000, 'three')))
    for loop in loops:
        loop.start()
        print('loop')


if __name__ == '__main__':
    serial_looping()
    parallel_looping()

Моя проблема в том, что когда вызывается упакованная функция, вместо имени она указывает имя проекта оболочки, декоратор, вот так:

The function decorators completed in 5.841255187988281e-05 seconds.

конечно, это должно читаться следующим образом: The function serial_looping completed in 5.841255187988281e-05 seconds.

1 Ответ

1 голос
/ 27 мая 2019

Вы должны вызвать __name__ для функции f:

print(f"The function {f.__name__} completed in {end-start} seconds.")

Причина в том, что __name__ по умолчанию относится к функции включения; Я не думаю, что @wraps отменяет это поведение; он не может знать, что именно вы собираетесь печатать.

...