Created
May 1, 2013 14:21
-
-
Save zhangyoufu/5495522 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__all__ = ['curry'] | |
# Modified from http://mtomassoli.wordpress.com/2012/03/18/currying-in-python/ | |
# Not perfect, but almost there | |
# Note: func_name must be ascii string | |
def generate_curry_func_name(func, *args, **kwargs): | |
argument = map(repr, args) | |
argument += [u'%s=%s' % (k,repr(kwargs[k])) for k in func.func_code.co_varnames if k in kwargs] | |
argument = u', '.join(argument) | |
return func.func_name + ('(%s)' % argument.encode('raw_unicode_escape') if argument else '') | |
def curry(func, unique_kwargs=True, require_force_evaluate=False): | |
""" Generates a 'curried' version of a function. | |
Example: | |
>>> @curry | |
>>> def f(a,b,c,d=1,e=2,f=3): | |
... print 'Hello', a, b, c, d, e, f | |
... | |
>>> f(1,f=1)(c=3, d=3)(2) | |
Hello 1 2 3 3 2 1 | |
""" | |
num_default_args = len(func.func_defaults) | |
required_args = set(func.func_code.co_varnames[:-num_default_args]) | |
def g(*args, **kwargs): | |
def f(*_args, **_kwargs): | |
if _args or _kwargs: | |
new_args = args + _args | |
new_kwargs = dict.copy(kwargs) | |
if unique_kwargs and not set(_kwargs.keys()).isdisjoint(new_kwargs): | |
raise ValueError('Duplicate keyword argument while currying') | |
new_kwargs.update(_kwargs) | |
# check whether it's time to evaluate | |
if not require_force_evaluate and \ | |
len(required_args.intersection(new_kwargs.keys())) + \ | |
len(new_args) >= len(required_args): | |
return func(*new_args, **new_kwargs) | |
else: | |
return g(*new_args, **new_kwargs) | |
else: | |
# force evaluation | |
return func(*args, **kwargs) | |
f.func_name = generate_curry_func_name(func, *args, **kwargs) | |
return f | |
return g() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment