什么是"追踪"评估函数的参数?

时间:2016-05-14 07:05:46

标签: python

所以我们开始在我的一个类中学习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") 

1 个答案:

答案 0 :(得分:1)

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