如何使用中缀运算符作为高阶函数?

时间:2013-06-10 15:45:44

标签: python higher-order-functions

有没有办法在python中使用中缀运算符(如+, - ,*,/)作为高阶函数而不创建“包装”函数?

def apply(f,a,b):
  return f(a,b)

def plus(a,b):
  return a + b

# This will work fine
apply(plus,1,1)

# Is there any way to get this working?
apply(+,1,1)

6 个答案:

答案 0 :(得分:4)

您可以使用operator模块,该模块已经为您编写了“包装”功能。

import operator

def apply(f,a,b):
  return f(a,b)

print apply(operator.add,1,1)

结果:

2

您还可以使用lambda函数定义包装器,这样可以省去独立def的麻烦:

print apply(lamba a,b: a+b, 1, 1)

答案 1 :(得分:4)

使用操作员模块和字典:

>>> from operator import add, mul, sub, div, mod
>>> dic = {'+':add, '*':mul, '/':div, '%': mod, '-':sub}
>>> def apply(op, x, y):
        return dic[op](x,y)
... 
>>> apply('+',1,5)
6
>>> apply('-',1,5)
-4
>>> apply('%',1,5)
1
>>> apply('*',1,5)
5

请注意,您不能直接使用+-等,因为它们不是python中的有效标识符。

答案 2 :(得分:2)

您可以这样使用operator模块:

import operator

def apply(op, a, b):
    return op(a, b)

print(apply(operator.add, 1, 2))
print(apply(operator.lt, 1, 2))

输出:

3
True

另一个解决方案是使用lambda函数,但“应该有一个 - 最好只有一个 - 显而易见的方法”,所以我更喜欢使用运算符模块

答案 3 :(得分:1)

您可以使用匿名函数:apply(lambda x,y : x + y, 1,1)

答案 4 :(得分:1)

# Is there any way to get this working?
apply(+,1,1)

没有。正如其他人已经提到的那样,operator模块中的所有运算符都有函数形式。但是,您不能使用运算符本身,因为它是SyntaxError,并且无法动态更改python的核心语法。你可以通过使用字典和传递字符串来接近:

_mapping = {'+':operator.add}
def apply(op,*args):
    return _mapping[op](*args)

apply('+',1,1)

答案 5 :(得分:0)

可以使用魔术方法为运算符+-*/提供特殊行为,你可以在这里阅读:http://www.rafekettler.com/magicmethods.html

这并不是您要求的,因为这仍然需要为每个运算符创建一个方法,但它允许您在代码中使用符号运算符。请注意,我认为这不比其他方法更好,它只是说明如何为运营商定义行为:

class Prefix(object):
    def __add__(self, other):
        """ Prefix() + (a, b) == a + b """
        return other[0] + other[1]
    def __sub__(self, other):
        """ Prefix() - (a, b) == a - b """
        return other[0] - other[1]
    def __mul__(self, other):
        """ Prefix() * (a, b) == a * b """
        return other[0] * other[1]
    def __div__(self, other):
        """ Prefix() / (a, b) == a / b """
        return other[0] / other[1]

例子:

>>> prefix = Prefix()
>>> prefix + (12, 3)
15
>>> prefix - (12, 3)
9
>>> prefix * (12, 3)
36
>>> prefix / (12, 3)
4

当然这个方法不能用于更复杂的前缀方程,如* / 6 2 5,因为无法定义相邻运算符的行为,这将始终给出一个SyntaxError(除了少数特殊情况, +-被解释为使下一个元素为正或负。)