【问题标题】:Flipping a function's argument order in Python在 Python 中翻转函数的参数顺序
【发布时间】:2012-03-24 08:35:23
【问题描述】:

现在,我开始学习 haskell,在学习的同时,我尝试在 Python 中实现我从中学到的一些想法。但是,我发现这具有挑战性。您可以在 Haskell 中编写一个函数,该函数将另一个函数作为参数,并返回相同的函数,但它的参数顺序颠倒了。可以在 Python 中做类似的事情吗?例如,

def divide(a,b):
    return a / b

new_divide = flip(divide)

# new_divide is now a function that returns second argument divided by first argument

你能用 Python 做到这一点吗?

【问题讨论】:

  • 我认为您可以使用 *args 然后 reverse() 该参数列表...或类似的东西。

标签: python functional-programming


【解决方案1】:

您可以使用嵌套函数定义在 Python 中创建闭包。这使您可以创建一个反转参数顺序的新函数,然后调用原始函数:

>>> from functools import wraps
>>> def flip(func):
        'Create a new function from the original with the arguments reversed'
        @wraps(func)
        def newfunc(*args):
            return func(*args[::-1])
        return newfunc

>>> def divide(a, b):
        return a / b

>>> new_divide = flip(divide)
>>> new_divide(30.0, 10.0)
0.3333333333333333

【讨论】:

  • @thg435 仅在 flip 的定义点。恕我直言,这种冗长是冗长,因为它使翻转内部发生的事情变得显而易见。
  • 为什么 functools 中没有这个?
  • 即使不添加 @wraps 装饰器,该解决方案也应该可以工作。
【解决方案2】:

纯函数式风格:

flip = lambda f: lambda *a: f(*reversed(a))

def divide(a, b):
    return a / b

print flip(divide)(3.0, 1.0)

一个更有趣的例子:

unreplace = lambda s: flip(s.replace)

replacements = ['abc', 'XYZ']
a = 'abc123'
b = a.replace(*replacements)
print b
print unreplace(b)(*replacements) # or just flip(b.replace)(*replacements)

【讨论】:

  • lambda 里面的 lambda,太棒了。您能否详细解释一下 '*a' 和 '*reversed(a)' 中发生了什么,这个 * 是如何工作的?
猜你喜欢
  • 1970-01-01
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
  • 2019-11-12
相关资源
最近更新 更多