假设我有一个字符串op
,可以等于<,>,==,< =,或> =。
我想对两个值执行关联操作。除了下面显示的简单if / else方法之外,还有更多的pythonic方法吗?
def doit(op, val1, val2):
if op == ">":
return val1 > val2
elif op == "<":
return val1 < val2
etc....
答案 0 :(得分:8)
您可以使用operator
:
import operator
operations = {'>':'gt', '>=':'ge', '<':'lt', '==':'eq', '!=':'ne', '<=':'le'}
def doit(op, *vals):
return getattr(operator, operations[op])(*vals)
使用getattr
相当于调用operator.eq
,operator.lt
等,除了要调用的函数的字符串名称传递给getattr
。
修改:更短的解决方案需要从operator
导入特定的功能:
from operator import gt, ge, lt, eq, ne, le
operations = {'>':gt, '>=':ge, '<':lt, '==':eq, '!=':ne, '<=':le}
def doit(op, *vals):
return operations[op](*vals)
答案 1 :(得分:3)
Ajax1234's answer中的第二个版本可能就是您真正想要的,但是,为了好玩,您甚至可以动态地将运算符从operator
函数中拉出来:
import inspect
import operator
import re
ops = inspect.getmembers(operator, callable)
pubops = (op for opname, op in ops if not opname.startswith('_'))
opmatches = ((op, re.search('ame as a\s*(.*?)\s*b\.', op.__doc__)) for op in pubops)
operations = {match.group(1): op for op, match in opmatches if match}
现在operations
不仅包含比较运算符,还包含可以覆盖的每个运算符。
我不确定这对什么有用。 1 (我的确认为你可能想要Ajax的答案。)但是一起打电话很有趣。
<子> 1。最好的我可以提出:使用更多的代码行(使用ast
),你可以编写一个opexpr_eval
,它只允许括号内的literal_eval
运算符表达式 - 没有其他值,这不会比literal_eval
本身更危险。 (即使在那时,我也不确定iops会对你有什么好处。或者matmul,因为numpy数组不是文字可评估的。但是你可以测试是否(1, (2, 3)) is (1, (2, 3))
。 )子>