繁体   English   中英

python用类写一个装饰器

[英]python writing a decorator with class

这是我写一个帮手装饰模块的努力:

# -*- coding: utf8 -*-

import time
def timer(func):
    def timed(*args, **kwargs):
        init = time.clock()
        result = func(*args, **kwargs)
        print (time.clock()-init)*1000, 'ms'

        return result    
    return timed

class memo(object):
    def __init__(self, func):
        self.func = func
        self.memo = {}
        self.memohit = 0   

    def memoizedf(self, *args):
        key = tuple(args)
        print key
        lookup = self.memo.setdefault(key, None)
        if lookup:
            self.memohit += 1 
            return lookup

        result = self.func(*args)
        self.memo[key]=result
        return result

    def __call__(self, *args):
        return self.memoizedf(*args)

所以,用法:

@timer
def foo():
    print 'foo'

'foo'
00023.1231203879 ms


@memo
def bar(fooobject):
    print fooobject

问题来自这里:

>>bar({'foo':'bar'})

traceback : ...........
    lookup = self.memo.setdefault(key, None)
TypeError: unhashable type: 'dict'

列表,字典或其他可变集合的每个输入都会调用此类错误。 我尝试了所有的args,但显然这没有帮助。 我应该如何重写我的代码,以便我的装饰器可以使用任何(好吧,只是字典,列表,元组,集合,整数​​,字符串...会没关系)这种输入?

我建议在散列之前序列化可变参数,例如使用pickle模块。 任何字典,列表,或在功能参数类似的内容必须是picklable,否则PicklingError将提高。 memoizedf的定义中,您可以使用以下代码:

key = pickle.dumps((args,kwargs))
lookup = self.memo.setdefault(key, None)

很多对象都是可选择的,但不是可以删除的,所以这应该扩展你可以处理的参数类。

这样就可以了:

key = str(tuple(args))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM