从django.utils.functional.py模仿memoize()时出错

时间:2010-01-04 01:33:19

标签: python caching

def a():
    print 'aa'
def b():
    print 'bb'

def c(*x):
    print x

def d(x,y):
    c(*(x+y))

d(a,b)

Traceback (most recent call last):
  File "D:\zjm_code\mysite\zjmbooks\a.py", line 15, in <module>
    d(a,b)
  File "D:\zjm_code\mysite\zjmbooks\a.py", line 13, in d
    c(*(x+y))
TypeError: unsupported operand type(s) for +: 'function' and 'function'

django.utils.functional.py中的代码:

def curry(_curried_func, *args, **kwargs):
    def _curried(*moreargs, **morekwargs):
        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
    return _curried

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
                   wrapped,
                   assigned = WRAPPER_ASSIGNMENTS,
                   updated = WRAPPER_UPDATES):
    for attr in assigned:
        try:
            setattr(wrapper, attr, getattr(wrapped, attr))
        except TypeError: # Python 2.3 doesn't allow assigning to __name__.
            pass
    for attr in updated:
        getattr(wrapper, attr).update(getattr(wrapped, attr))
    return wrapper

def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):
    return curry(update_wrapper, wrapped=wrapped,
                 assigned=assigned, updated=updated)

### End from Python 2.5 functools.py ##########################################

def memoize(func, cache, num_args):
    def wrapper(*args):
        mem_args = args[:num_args]
        if mem_args in cache:
            return cache[mem_args]
        result = func(*args)
        cache[mem_args] = result
        return result
    return wraps(func)(wrapper)

我的分析:

def curry(update_wrapper, *args, **kwargs):
    def _curried(*wrapper, **morekwargs):
        return update_wrapper(wrapper,{wrapped:func})#this is the result
    return _curried
def update_wrapper(wrapper,wrapped)

def wraps(func):
    return curry(update_wrapper, wrapped=func)

wraps(func)(wrapper)

1 个答案:

答案 0 :(得分:3)

您的代码(在x+yxayb)正试图将两个函数相加(而不是调用它们例如,总结他们的结果):函数对象不能求和,所以你的代码提出了一个例子。

你在args+moreargs中引用的代码总结了两个tuple s:元组当然可以很好地求和,它意味着连接它们。绝对没有与你的代码尝试的荒谬的“两个函数之和”的关系。