そこで、Pythonでカリー化関数を試してみましたが、functools.partialが実際の関数ではなく部分的なオブジェクトを返すことに気づきました。これについて私を悩ませたのは、次のようなことをした場合です。
five = partial(len, 'hello')
five('something')
その後、
TypeError: len() takes exactly 1 argument (2 given)
でも私がしたいのは
TypeError: five() takes no arguments (1 given)
このように機能させるためのクリーンな方法はありますか?私は回避策を書きましたが、それは私の好みにはあまりにもハッキーです(varargsを持つ関数ではまだ機能しません):
def mypartial(f, *args):
argcount = f.func_code.co_argcount - len(args)
params = ''.join('a' + str(i) + ',' for i in xrange(argcount))
code = '''
def func(f, args):
def %s(%s):
return f(*(args+(%s)))
return %s
''' % (f.func_name, params, params, f.func_name)
exec code in locals()
return func(f, args)
編集:コンテキストを追加すると役立つと思います。私は次のような関数を自動的にカレーするデコレータを書いています:
@curry
def add(a, b, c):
return a + b + c
f = add(1, 2) # f is a function
assert f(5) == 8
fがパーシャルから作成されたという事実を隠したい(おそらく悪い考え:P)。上記のTypeErrorメッセージが表示するメッセージは、何かが部分的であるかどうかを明らかにできる一例です。それを変えたい。
これは一般化可能である必要があるため、EnricoGiampieriとmgilsonの提案はその特定の場合にのみ機能します。