English 中文(简体)
p
原标题:Currying decorator in python

我正试图在座标上写一个治愈器。 我是:

def curry(fun):    
    cache = []
    numargs = fun.func_code.co_argcount
    
    def new_fun(*args, **kwargs):
        print(args)
        print(kwargs)
        cache.extend(list(args))        
        if len(cache) >= numargs: # easier to do it explicitly than with exceptions            
            temp = []
            for _ in xrange(numargs):
                temp.append(cache.pop())
            fun(*temp)
            
    return new_fun

@curry
def myfun(a,b):
    print(a,b)

在以下案件中,这部法律课以罚款:

myfun(5)
myfun(5)

对于以下案件,它未能做到:

myfun(6)(7)

我如何能够正确这样做?


If you re just looking to bind arguments to a function and aren t interested in a specific design or the underlying computer science principles, see Python Argument Binders.

最佳回答

以下是一些更准确的例子,即“购买花on”。

def curry(x, argc=None):
    if argc is None:
        argc = x.func_code.co_argcount
    def p(*a):
        if len(a) == argc:
            return x(*a)
        def q(*b):
            return x(*(a + b))
        return curry(q, argc - len(a))
    return p

@curry
def myfun(a,b,c):
    print  %d-%d-%d  % (a,b,c)



myfun(11,22,33)
myfun(44,55)(66)
myfun(77)(88)(99)
问题回答

curry , 载于

https://github.com/pytoolz/toolz/blob/master/toolz/functoolz.py

该科处理rg、 k、建筑功能和错误处理。 它甚至把脚印重新排在 cur子上。

这里的许多答复未能解决这样一种事实,即一项治愈功能只应有一个论点。

A quote from Wikipedia:

In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application).

选择使之脱钩 <> > > 重度和 <<> 无>>>> 代码>co_argcount<>/code>为一种体面的解决方案。

from functools import partial, wraps, reduce

def curry(f):
    @wraps(f)
    def _(arg):
        try:
            return f(arg)
        except TypeError:
            return curry(wraps(f)(partial(f, arg)))
    return _

def uncurry(f):
    @wraps(f)
    def _(*args):
        return reduce(lambda x, y: x(y), args, f)
    return _

As shown above, it is also fairly trivial to write an uncurry decorator. :) Unfortunately, the resulting uncurried function will allow any number of arguments instead of requiring a specific number of arguments, as may not be true of the original function, so it is not a true inverse of curry. The true inverse in this case would actually be something like unwrap, but it would require curry to use functools.wraps or something similar that sets a __wrapped__ attribute for each newly created function:

def unwrap(f):
    try:
        return unwrap(f.__wrapped__)
    except AttributeError:
        return f

This one is fairly simple and doesn t use inspect or examine the given function s args

import functools


def curried(func):
    """A decorator that curries the given function.

    @curried
    def a(b, c):
        return (b, c)

    a(c=1)(2)  # returns (2, 1)
    """
    @functools.wraps(func)
    def _curried(*args, **kwargs):
        return functools.partial(func, *args, **kwargs)
    return _curried

这里是我的治疗版本,它没有部分使用,所有职能都完全接受一个参数:

def curry(func):
"""Truly curry a function of any number of parameters
returns a function with exactly one parameter
When this new function is called, it will usually create
and return another function that accepts an additional parameter,
unless the original function actually obtained all it needed
at which point it just calls the function and returns its result
""" 
def curried(*args):
    """
    either calls a function with all its arguments,
    or returns another functiont that obtains another argument
    """
    if len(args) == func.__code__.co_argcount:
        ans = func(*args)
        return ans
    else:
        return lambda x: curried(*(args+(x,)))

return curried

仅举一旁:

from functools import partial
curry = lambda f: partial(*[partial] * f.__code__.co_argcount)(f)

@curry
def add(x, y, z):
    return x + y + z

print(add(2)(3)(4))
# output = 9

我认为,我做得更好:

def curried (function):
    argc = function.__code__.co_argcount

    # Pointless to curry a function that can take no arguments
    if argc == 0:
        return function

    from functools import partial
    def func (*args):
        if len(args) >= argc:
            return function(*args)
        else:
            return partial(func, *args)
    return func

这一解决办法使用沙捞取自<条码>functools.partial的功能,而不是有效地恢复这一功能。 这还使你能够提出比最低的论点更多的论据,即提出关键词,以及公正通过不需要争论的职能,因为这些职能是毫无道理的。 (原称,方案管理员应比处理零毒性或多毒性功能更清楚,但比在这种情况下产生新功能要好。)

<><>UPDATE: 谁,关键词部分实际上就不可行。 此外,任择论点被算作是粗略的,但并非.。 Weird。

The solution from Roger Christman will not work with every constellation. I applied a small fix to also handle this situation:

curried_func(1)(2,3)

每一轮船的小型固定装置位于返回的Mlambda:

def curried(func):
    def curry(*args):
        if len(args) == func.__code__.co_argcount:
            ans = func(*args)
            return ans
        else:
            return lambda *x: curry(*(args+x))
    return curry




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...