Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.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_Decorator_Mutable - Fatal编程技术网

python用类编写装饰器

python用类编写装饰器,python,decorator,mutable,Python,Decorator,Mutable,以下是我在编写助手装饰器模块时所做的工作: # -*- 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

以下是我在编写助手装饰器模块时所做的工作:

# -*- 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'
来自集合的list、dict或其他可变项的每个输入都会调用这种错误。
我试着把所有的arg都搞定了,但显然没用。我应该如何重写我的代码,以便让我的decorator处理任何类型的输入(好吧,只要dict、list、tuple、set、int、string……就可以了?

我建议在散列之前序列化可变参数,例如使用模块。函数参数中任何dict、list或类似内容都必须是可拾取的,否则将引发
PicklingError
。在
memoizedf
的定义中,可以使用以下代码:

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

许多对象是可拾取的,但不可散列的,因此这应该扩展您可以处理的参数类。

这将实现以下目的:

key = str(tuple(args))

internet上有许多memoize方法,Python 3.2+附带了
functools。lru_cache
请注意,您不能将可变对象用于dict中的键。也许您可以使用
str
来获取对象的哈希表示。您是否只尝试传递一个参数?
str()
函数通常不能保证返回用于记忆对象的有用结果。