所以我们开始在我的一个类中学习python,现在我们正在搞乱后缀/前缀表示法。我在网上浏览了一些例子,发现了这段代码,但我并不完全理解它。我的问题是关于评估和解析功能。什么是"跟踪"它为什么存在,它做什么(如果跟踪块)?
import operator
import string
import operator
import string
class EvaluationError(Exception):
pass
class InvalidParse(Exception):
pass
class InvalidNumber(Exception):
pass
class InvalidOperator(Exception):
pass
class UnbalancedParens(Exception):
pass
def cast(value):
if isinstance(value, (int, float)):
return value
try:
return int(value)
except ValueError:
pass
try:
return float(value)
except ValueError:
pass
raise InvalidNumber(value)
class Operator(object):
def __init__(self, op, precedence):
self._op = op
self._prec = precedence
def __call__(self, *args):
return self._op(*args)
def __lt__(self, op):
return self._prec < op._prec
def __gt__(self, op):
return self._prec > op._prec
def __eq__(self, op):
return self._prec == op._prec
def __repr__(self):
return repr(self._op)
def __str__(self):
return str(self._op)
class Calculator(object):
operators = {
'+' : Operator(operator.add, 1),
'-' : Operator(operator.sub, 1),
'*' : Operator(operator.mul, 2),
'/' : Operator(operator.div, 2),
'^' : Operator(operator.pow, 3),
}
def __init__(self):
pass
def calculate(self, expr):
tokens = self.parse(expr)
result = self.evaluate(tokens)
return result
def evaluate(self, tokens, trace=False):
stack = []
for item in tokens:
if isinstance(item, Operator):
if trace:
print stack
b, a = cast(stack.pop()), cast(stack.pop())
result = item(a, b)
stack.append(result)
if trace:
print stack
else:
if item.endswith('.'):
raise InvalidNumber(item)
stack.append(item)
if len(stack) > 1:
raise EvaluationError(str(stack))
return stack[0]
def parse(self, expr, trace=False):
tokens = []
op_stack = []
last = None
for c in expr:
if c in string.whitespace:
last = c
elif c in string.digits:
value = str(c)
if last and last in string.digits:
value = tokens.pop() + value
last = c
tokens.append(value)
elif c == '.':
if last and last in string.digits:
tokens.append(tokens.pop() + ".")
else:
raise InvalidParse()
elif c == '(':
op_stack.append('(')
elif c == ')':
if not op_stack:
raise UnbalancedParens(c)
while op_stack:
curr = op_stack.pop()
if curr is '(':
break
else:
tokens.append(curr)
else:
op = self.operators.get(c, None)
if op is None:
raise InvalidOperator(c)
while op_stack:
curr = op_stack[-1]
if curr is '(':
break
elif curr < op:
break
tokens.append(op_stack.pop())
op_stack.append(op)
last = c
if trace:
print "----"
print tokens
print op_stack
print "----"
while op_stack:
op = op_stack.pop()
if op is '(':
raise UnbalancedParens()
tokens.append(op)
if trace:
print "----"
print tokens
print op_stack
print "----"
return tokens
if __name__ == '__main__':
import sys
calc = Calculator()
print calc.calculate("12^2.5-10")
答案 0 :(得分:1)
字面意思是代码中的内容。如果trace
设置为True
,您将在不同的执行点打印出堆栈。这似乎存在用于调试/演示目的。