python配方,以获得更灵活的函数curry



内置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)

相关内容

  • 没有找到相关文章

最新更新