Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 10, 2012 15:55:19

TravisBarker
Зарегистрирован: 2012-09-10
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите с декоратором

Такая задача.

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

def foo():
    yield 1
    yield 2
    yield 3

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

@deco
def foo():
    yield 1
    yield 2
    yield 3

Отредактировано TravisBarker (Сен. 10, 2012 15:56:00)

Офлайн

#2 Сен. 10, 2012 16:49:21

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Помогите с декоратором

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



Отредактировано FishHook (Сен. 10, 2012 16:53:24)

Офлайн

#3 Сен. 10, 2012 16:55:44

TravisBarker
Зарегистрирован: 2012-09-10
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите с декоратором

Супер! Спасибо!

Офлайн

#4 Сен. 10, 2012 18:23:22

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

Помогите с декоратором

Можно и так:

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'

Отредактировано EBFE (Сен. 10, 2012 19:56:11)

Офлайн

#5 Сен. 10, 2012 18:48:03

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

Помогите с декоратором

FishHook
Похоже алгоритм не то меряет, вариант EBFE правильный

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version