编码:
class Curried(object):
def __init__(self, func, args=None, kwargs=None):
self._func = func
self._args = () if args is None else args[:]
self._kwargs = {} if kwargs is None else dict(kwargs)
self._name = None
def __call__(self, *args, **kwargs):
if args or kwargs:
return Curried(self._func,
self._args + args,
dict(self._kwargs.items() + kwargs.items()))
else:
return self._func(*self._args, **self._kwargs)
def __str__(self):
if self._name is None:
self._name = self._get_curried_name()
return self._name
def _get_curried_name(self):
_args = ([str(a) for a in self._args] +
['{}={}'.format(k, v) for k, v in self._kwargs.iteritems()])
all_args = ", ".join(_args)
return '<curried {}({}) at 0x{:x}>'.format(
self._func.func_name, all_args, id(self))
def curry(func):
_curried = Curried(func)
return _curried
测试:
@curry
def f(a, b, c, flag_foo=True, flag_bar=False):
return 'horray!'
print f
print f(1, 2, flag_bar=True)
print f(1, 2, flag_bar=True)(3, flag_foo=False)
print f(1, 2, flag_bar=True)(3, flag_foo=False)()
结果:
<curried f() at 0x100484210>
<curried f(1, 2, flag_bar=True) at 0x100484250>
<curried f(1, 2, 3, flag_bar=True, flag_foo=False) at 0x100484310>
horray!
而不是一个“纯”函数,在这里你得到一个作为函数的可调用类。您只评估一次名称。当然,如果你愿意,func_name
你可以添加这样的变量property
并返回str(self)
,它会被评估一次