Найти - Пользователи
Полная версия: Помогите с декоратором
Начало » Python для новичков » Помогите с декоратором
1
TravisBarker
Такая задача.

есть функция-генератор пусть такая:

def foo():
    yield 1
    yield 2
    yield 3

нужно написать декоратор “deco”, чтобы при итерации генератора выводилось в stdout время выполнения каждой итерации.

@deco
def foo():
    yield 1
    yield 2
    yield 3
FishHook
import time
class Gen(object):
    def __init__(self, iterable):
        if callable(iterable):
            self.iterable=iterable()
        else:
            self.iterable=iterable
    def __iter__(self):
        for  z in self.iterable:
            start=time.time()
            yield z
            end=time.time()
            print start, end, (end-start)*10000, z
def deco(func):
    def wrapper():
        cls=Gen(func)
        return cls
    return wrapper
@deco
def foo():
    yield 3
    time.sleep(1)
    yield 4
    time.sleep(1)
    yield 5
    time.sleep(1)
@deco
def gen():
    return (x for x in (0,8,9))
@deco
def gen1():
    return [1,2,3,4,5]
@deco
def gen2():
    return range(30,35)
for _ in foo():pass
for _ in gen():pass
for _ in gen1():pass
for _ in gen2():pass
TravisBarker
Супер! Спасибо!
EBFE
Можно и так:
import sys
import time
def time_log(func):
    def wrapper(*args, **kwd):
        gen = func(*args, **kwd)
        while True:
            start = time.clock()
            res = gen.next()
            sys.stdout.write("Gen: {0}, yielding: {1}, clocks: {2}.\n".format(
                            func.__name__, res, time.clock() - start))
            yield res
    return wrapper
@time_log
def simple():
    yield 1
    yield 2
    time.sleep(5)
    yield 3
    time.sleep(0.02)
    yield 4
    yield 5
>>> for _ in simple():pass
Gen: simple, yielding: 1, clocks: 0.000007.
Gen: simple, yielding: 2, clocks: 0.000008.
Gen: simple, yielding: 3, clocks: 4.999413.
Gen: simple, yielding: 4, clocks: 0.019148.
Gen: simple, yielding: 5, clocks: 0.000006.

Если нужно сохранить исходные doc и имя функции:
# from FishHook
def deco(func):
    def wrapper():
        cls=Gen(func)
        return cls
    return wrapper
@deco
def foo():
    yield 3
>>> foo.__name__
'wrapper'
>>> foo.__doc__
>>> foo().__name__
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'Gen' object has no attribute '__name__'
>>> foo().__doc__
=> wraps/update_wrapper => http://docs.python.org/library/functools.html
from functools import wraps, update_wrapper
def deco(func):
    @wraps(func)
    def wrapper():
        cls = Gen(func)
        update_wrapper(cls, func)
        return cls
    return wrapper
>>> foo.__name__
'foo'
>>> foo().__name__
'foo'
o7412369815963
FishHook
Похоже алгоритм не то меряет, вариант EBFE правильный
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB