Let's say you have a small calculator program that takes numbers and an operator to perform on those numbers as input, then prints out the result of applying the specified operation. So if you input "4 + 5" it will print out "9". Simple, right? Well what I want to be able to write is something this:
假设您有一个小型计算器程序,它接受数字和操作员对这些数字作为输入执行,然后打印出应用指定操作的结果。因此,如果您输入“4 + 5”,它将打印出“9”。简单吧?那么我想要写的是这样的:
a, op, b = raw_input().split()
print somehowInvokeOperator(op, a, b)
The problem is that "somehowInvokeOperator()" part. Is there anyway to do this without resorting to either (a) eval() or (b) some type of dictionary mapping keys like "+" and "-" to functions that perform the appropriate operation? getattr() doesn't appear to work for this. I don't really need this code for anything, I'm just curious to see if this can be solved in Python as elegantly as it can in other dynamic languages.
问题是“somehowInvokeOperator()”部分。无论如何要做到这一点,而不是诉诸(a)eval()或(b)某些类型的字典映射键,如“+”和“ - ”执行适当的操作? getattr()似乎不适用于此。我真的不需要这个代码,我只是好奇,看看是否可以像在其他动态语言中一样优雅地解决这个问题。
3 个解决方案
#1
Basically no, you will at least need to have a dictionary or function to map operator characters to their implementations. It's actually a little more complicated than that, since not all operators take the form a [op] b
, so in general you'd need to do a bit of parsing; see https://docs.python.org/library/operator.html for the full list of correspondences, and for the functions you'll probably want to use for the operator implementations.
基本上没有,你至少需要一个字典或函数来将操作符添加到它们的实现中。它实际上比这复杂一点,因为并非所有运算符都采用[op] b形式,因此通常需要进行一些解析;请参阅https://docs.python.org/library/operator.html以获取完整的对应列表,以及您可能希望用于运算符实现的函数。
If you're only trying to implement the binary arithmetic operators like + - * / % ** then a dictionary should be good enough.
如果您只是尝试实现像+ - * /%**这样的二进制算术运算符,那么字典应该足够好了。
#2
If you really wanted to do this, you would need the standard operator
module. See also Emulating numeric types. And, yes, a dictionary full of functions would be a perfectly sound dynamic way to make this happen.
如果你真的想这样做,你需要标准的操作员模块。另请参见模拟数字类型。而且,是的,一个充满功能的字典将是一个完美的动态方式来实现这一点。
import operator
operations = {'+' : operator.add}
result = operations[op](a, b)
#3
Warning: this is not pythonic at all!! (goes against every rule of the Zen of Python!)
警告:这根本不是pythonic !! (违背Python的每一条规则!)
Here's a magical, one-liner dictionary:
这是一本神奇的单线词典:
ops = eval( '{%s}'%','.join([('\''+op + '\' : lambda a,b: a ' + op + ' b') for op in '+-*/%']) )
That defines your dictionary .. which you can use
这定义了你的字典..你可以使用
ops['+'](10,4) #returns 14
the basic idea is mapping each operator to a lambda function:
基本思想是将每个运算符映射到lambda函数:
{ '+' : lambda a,b: a + b }
#1
Basically no, you will at least need to have a dictionary or function to map operator characters to their implementations. It's actually a little more complicated than that, since not all operators take the form a [op] b
, so in general you'd need to do a bit of parsing; see https://docs.python.org/library/operator.html for the full list of correspondences, and for the functions you'll probably want to use for the operator implementations.
基本上没有,你至少需要一个字典或函数来将操作符添加到它们的实现中。它实际上比这复杂一点,因为并非所有运算符都采用[op] b形式,因此通常需要进行一些解析;请参阅https://docs.python.org/library/operator.html以获取完整的对应列表,以及您可能希望用于运算符实现的函数。
If you're only trying to implement the binary arithmetic operators like + - * / % ** then a dictionary should be good enough.
如果您只是尝试实现像+ - * /%**这样的二进制算术运算符,那么字典应该足够好了。
#2
If you really wanted to do this, you would need the standard operator
module. See also Emulating numeric types. And, yes, a dictionary full of functions would be a perfectly sound dynamic way to make this happen.
如果你真的想这样做,你需要标准的操作员模块。另请参见模拟数字类型。而且,是的,一个充满功能的字典将是一个完美的动态方式来实现这一点。
import operator
operations = {'+' : operator.add}
result = operations[op](a, b)
#3
Warning: this is not pythonic at all!! (goes against every rule of the Zen of Python!)
警告:这根本不是pythonic !! (违背Python的每一条规则!)
Here's a magical, one-liner dictionary:
这是一本神奇的单线词典:
ops = eval( '{%s}'%','.join([('\''+op + '\' : lambda a,b: a ' + op + ' b') for op in '+-*/%']) )
That defines your dictionary .. which you can use
这定义了你的字典..你可以使用
ops['+'](10,4) #returns 14
the basic idea is mapping each operator to a lambda function:
基本思想是将每个运算符映射到lambda函数:
{ '+' : lambda a,b: a + b }