Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将输入函数传递给多个类装饰器_Python_Python 2.7_Decorator_Python Decorators_Memoization - Fatal编程技术网

Python 将输入函数传递给多个类装饰器

Python 将输入函数传递给多个类装饰器,python,python-2.7,decorator,python-decorators,memoization,Python,Python 2.7,Decorator,Python Decorators,Memoization,我有一个计时器装饰器,在屏幕上打印一个记忆装饰功能所用的时间。但是,decorator print语句将memoize类打印为屏幕上的函数名,而不是要memoize的函数输入。例如,使用此代码: from memoization import Memoize import time import logging from timer import Timer @Timer @Memoize def pass_and_square_time(seconds): time.s

我有一个计时器装饰器,在屏幕上打印一个记忆装饰功能所用的时间。但是,decorator print语句将memoize类打印为屏幕上的函数名,而不是要memoize的函数输入。例如,使用此代码:

from memoization import Memoize


import time


import logging


from timer import Timer


@Timer
@Memoize
def pass_and_square_time(seconds):
    time.sleep(seconds)
    return seconds**2


def main():
    logging.getLogger().setLevel(logging.ERROR)

    print '\nFor pass_and_square_time({30}):'.format(n=num)
    print '\n\tThe initial call of pass_and_square_time(30) yields: {ret}'.format(ret=pass_and_square_time(30))
    print '\n\tThe second call of pass_and_square_time(30) yields: {ret}'.format(ret=pass_and_square_time(30))
返回以下内容:

For pass_and_square_time(30):
    Timer Time Elapsed: 30.0 seconds

    <memoization.Memoize object at 0x02E5BBD0> 30.0 seconds

    The initial call of pass_and_square_time(30) yields: 900
    Timer Time Elapsed: 0.0 seconds

    <memoization.Memoize object at 0x02E5BBD0> 0.0 seconds

    The second call of pass_and_square_time(30) yields: 900
我的Memoize类实现如下:

class Timer(object):
    def __init__(self, fcn=None, timer_name='Timer'):
        self._start_time = None
        self._last_timer_result = None
        self._display = 'seconds'
        self._fcn = fcn
        self._timer_name = timer_name

    def __call__(self, *args):
        self.start()
        fcn_res = self._fcn(*args)
        self.end()
        print '\n\t{func} {time} seconds'.format(func=self._fcn, time=self.last_timer_result)
        return fcn_res

    def __get__(self, obj, objtype):
        return partial(self.__call__, obj)

    '''
    start(), end(), and last_timer_result functions/properties implemented 
    below in order to set the start_time, set the end_time and calculate the 
    last_timer_result,  and return the last_timer_result. I can include more
    if you need it. I didn't include it just because I didn't want to make
    the post too long
    '''
from functools import update_wrapper, partial


class Memoize(object):
    def __init__(self, fcn):
        self._fcn = fcn
        self._memo = {}
        update_wrapper(self, fcn)

    def __call__(self, *args):
        if args not in self._memo:
            self._memo[args] = self._fcn(*args)

        return self._memo[args]

    def __get__(self, obj, objtype):
        return partial(self.__call__, obj)

使用闭包比使用类简单得多

import functools
import time

def memoize(f):
    _memo = {}
    @functools.wraps(f)
    def _(*args):
        if args not in _memo:
            _memo[args] = f(*args)
        return _memo[args]
    return _                
我将类似地编写
计时器

def timer(f):
    @functools.wraps(f)
    def _(*args):
        start = time.time()
        rv = f(*args)
        end = time.time()
        print '\n\t{func} {t} seconds'.format(func=f.__name__, t=end - start)
        return rv
    return _
然后


Timer
Memoize
都是作为类实现的,它们在修饰函数时返回自己类的实例。因此,无法使用
functools.wrap
或在返回的函数上设置
\uuuu name\uuuu
(因为没有返回的函数)

相反,我建议在
Timer
Memoize
上实现,这将更好地表示修饰过的函数。当Python解释器需要获取对象的字符串表示形式时,它将调用该函数

这就是目前的情况和问题:

def pass_and_square_time(seconds):
    time.sleep(seconds)
    return seconds**2

print(pass_and_square_time)         # <function pass_and_square_time at 0x00000000029A1620>
print(Memoize(pass_and_square_time))  # <Memoize object at 0x000000000295BDA0>
然后,它会按预期工作:

print(pass_and_square_time)         # <function pass_and_square_time at 0x00000000029A1620>
print(Memoize(pass_and_square_time))  # <function pass_and_square_time at 0x00000000029A1620>
请注意,
Timer(Memoize(传递时间和平方时间))
正是装饰者在这里所做的:

@Timer
@Memoize
def pass_and_square_time(seconds):
    time.sleep(seconds)
    return seconds**2

“我想要那
记忆化。记忆化
成为
传递时间”
“这真的是你想要的吗?看起来很简单,但我不明白这有什么意义。我非常感谢你的帮助,如果我能记下2个正确答案,我会的,但我最终改变了备忘录,这样它就不是一门课了,因为我真的没有理由把它作为一门课。谢谢你@那很好。我很高兴你能接受这个答案。无论如何,正如您所写,您只能接受一个答案,但您可以对任意多个答案给出+1;)当我获得15个声誉时,我一定会回过头来,给两个都打+1。不幸的是,我现在处于10分以下@zvone@strwars啊,我明白了:)如果你碰巧知道关于多重处理的任何事情,我有一个完全不同的问题@zvone…:D
print(pass_and_square_time)         # <function pass_and_square_time at 0x00000000029A1620>
print(Memoize(pass_and_square_time))  # <function pass_and_square_time at 0x00000000029A1620>
print(Timer(Memoize(pass_and_square_time)))  # <function pass_and_square_time at 0x00000000029A1620>
@Timer
@Memoize
def pass_and_square_time(seconds):
    time.sleep(seconds)
    return seconds**2