内置python提供functools.partial
用于curry,但单独使用它相当有限。我的猜测是,还有其他的内置程序,它们与partial
的结合将克服这些限制。它们是什么?
几个例子
我可以这样做:
asdf_is_instance_of = partial(isinstance, 'asdf')
assert asdf_is_instance_of(str)
但我不能这样做(可以说是更常用的东西):
isinstance_of_str = partial(isinstance, class_or_tuple=str)
isinstance_of_str('asdf')
becauseisinstance() takes no keyword arguments
.
这是一种限制:无法直接绕过partial
的参数类型限制。对于这种情况,可以这样做:
def my_isinstance(obj, class_or_tuple): # just to get rid of position only parameter kinds
return isinstance(obj, class_or_tuple)
isinstance_of_str = partial(my_isinstance, class_or_tuple=str)
assert isinstance_of_str('asdf') # now it works
还有一个常见的限制:参数顺序。我们可以编写一个partial_ext
来同时处理参数的类型和顺序。这个套用函数应该是这样的
def foo(x,y,z):
return x + y * z
xz_foo_with_y_equal_228 = partial_ext(foo, y=228)
等于
def xz_foo_with_y_equal_228(x, y, z):
return foo(x, y=228, z)
在python中似乎没有这样的内置curry,所以我的猜测是有一些涉及其他内置的食谱来处理它。
有人知道这个秘密吗?
Python不是函数式编程语言;它是一种多范式语言,支持一些有限的函数式编程技术。如果你想用函数的第二个位置参数做部分应用,我怀疑标准库中没有任何东西支持"开箱即用"。您可以像这样编写自己的辅助函数:
def partial_second(f, y):
def partial_f(x, *vargs, **kwargs):
return f(x, y, *vargs, **kwargs)
return partial_f
is_string = partial_second(isinstance, str)
但是我只建议在你经常需要做这种curry的情况下这样做,在这种情况下,你可能不会写习惯的Python。根据Python的禅意,"显式优于隐式"。而且"简单"总比"复杂"好,所以不用套用,你可以这样写,而不用局部应用:
def is_string(x):
return isinstance(x, str)