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

0 投票
1 回答
710 浏览
提问于 2025-04-15 17:36
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 个回答

3

你的代码(在 x+y 中,xayb)试图把两个函数加在一起(比如说,不是调用它们然后把结果相加)。函数对象是不能直接相加的,所以你的代码会报错。

你提到的代码 args+moreargs 是在把两个 tuple(元组)相加:元组当然可以相加,这实际上是把它们连接在一起。和你代码中那个荒谬的“两个函数的和”完全没有关系。

撰写回答