有没有办法在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)
有没有办法在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)
使用运算符模块和字典:
>>> 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 中不是有效的标识符。
您可以使用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)
您可以通过这种方式使用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
函数,但是“应该有一个——最好只有一个——明显的方法”,所以我更喜欢使用 operator 模块
# Is there any way to get this working?
apply(+,1,1)
operator
不,正如其他人已经提到的那样,模块中的所有运算符都有函数形式。但是,您不能使用运算符本身,因为那是 aSyntaxError
并且无法动态更改 python 的核心语法。您可以通过使用字典和传递字符串来接近:
_mapping = {'+':operator.add}
def apply(op,*args):
return _mapping[op](*args)
apply('+',1,1)
你可以使用匿名函数:apply(lambda x,y : x + y, 1,1)
可以使用魔术方法为类赋予运算符、、+
和特殊行为,您可以在此处阅读: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 (除了一些特殊情况,其中+
or-
被解释为生成下一个元素正面或负面)。