You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python高级计算器报错:unsupported operand type(s) for -: 'str' and 'float'

错误原因分析

unsupported operand type(s) for -: 'str' and 'float' 说明减法操作中一个操作数是字符串,另一个是浮点数,结合你的代码,触发场景主要有以下几种:

  • 负数处理缺失:输入包含开头负数(如-5+3)时,tokenize会将-和5拆分为两个独立token,后续处理时运算符栈残留-,最终执行减法时操作数栈元素不足,若Stack类空栈pop返回字符串,会导致字符串与浮点数参与运算。
  • 括号优先级处理错误:has_higher_precedence方法未处理括号,栈顶为括号时调用precedence[op2]会抛出KeyError,若错误被捕获后返回字符串,后续运算会出现类型不匹配。
  • 测试代码未拦截错误结果:若测试代码直接对evaluate_list_tokens返回的"Error"字符串进行数值运算,会触发类型错误。

修复步骤

1. 完善tokenize方法,支持负数和小数

修改正则表达式匹配负数、小数,并将数字token转为float(而非int)以支持小数运算:

def tokenize(self, input_expression):
    import re
    # 匹配负数、整数、小数,以及运算符和括号
    tokens = re.findall(r"(-?\d+\.?\d*|-?\.\d+|[+\-*/(){}[\]])", input_expression)
    # 判断是否为数字(支持负号和小数点)
    def is_number(token):
        try:
            float(token)
            return True
        except ValueError:
            return False
    return [float(token) if is_number(token) else token for token in tokens]

2. 修正运算符优先级判断,处理括号

将has_higher_precedence改为更准确的should_pop_operator,明确括号的最低优先级:

def should_pop_operator(self, current_op, stack_top_op):
    precedence = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0, "{":0, "[":0}
    # 栈顶是括号时,不弹出
    if stack_top_op in ["(", "{", "["]:
        return False
    # 栈顶运算符优先级 >= 当前运算符时,弹出计算(保证同级运算符从左到右执行)
    return precedence[stack_top_op] >= precedence[current_op]

然后在evaluate_list_tokens中替换原while循环条件:

# 替换原条件
while not operator_stack.is_empty() and self.should_pop_operator(token, operator_stack.peek()):

3. 优化doeval方法,直接处理float类型

无需先转int,直接转float并增加异常捕获,避免转换错误:

def doeval(self, a, b, c):
    try:
        a = float(a)
        c = float(c)
    except ValueError:
        return "Error"
    if b == "+":
        return a + c
    elif b == "-":
        return a - c
    elif b == "*":
        return a * c
    elif b == "/":
        if abs(c) < 1e-9:  # 避免浮点数精度问题导致的误判
            return "Error"
        return a / c

4. 在evaluate_list_tokens中先检查括号合法性

避免括号不匹配时继续处理导致的错误:

def evaluate_list_tokens(self, list_tokens):
    if not self.check_brackets(list_tokens):
        return "Error"
    # 后续原有代码不变

5. 测试代码需先判断错误结果

确保测试时先检查返回值是否为"Error",再进行数值断言:

result = calculator.evaluate_list_tokens(tokens)
if result == "Error":
    # 处理错误场景(如断言输入非法)
else:
    # 进行数值比较断言

内容的提问来源于stack exchange,提问作者Ayush Shukla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:02:05