"trace"函数计算参数是什么?



所以我们开始在我的一个类中学习python,现在我们正在乱用后缀/前缀符号。我在网上找了一些例子,找到了这段代码,但我并不完全理解。我的问题是关于求值和解析函数。"trace"是怎么回事?它为什么存在,它做什么(如果trace阻塞)?

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") 

它在代码中的字面意思。如果将trace设置为True,则会在不同的执行点打印出堆栈。这似乎是为了调试/演示目的而存在的。

最新更新