代碼:
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!
取而代之的是 「純」 的功能,在這裏你會得到一個callab作爲功能的le類。你只評估一次這個名字。當然,如果你想func_name
您可以添加這樣的變量爲property
,並返回str(self)
這是一次評估
我相信在這個複雜的情況簡直是更好地使'curry'一個類,並用自己的對象替換功能'__str__'和'__repr__'完成你想要的功能。這也允許任何懶惰的評估,因爲你可以使用諸如屬性/ getters之類的東西。 – Bakuriu 2013-05-01 16:15:39
我已經嘗試過各種黑客攻擊,並且它看起來並不像在Python中實現這個功能對象一樣可能,儘管您可能可以使用擴展模塊來做到這一點。但是,我會推薦@Bakuriu的建議。如果你在一個類上定義了一個'__call__'方法,那麼你可以像使用一個函數一樣使用一個實例。 – Aya 2013-05-01 16:20:32
你有理由認爲這是一個瓶頸嗎?解決方案將非常複雜,所以我認爲這不值得。 – delnan 2013-05-01 16:26:16