python-3.x - 在 Python3 中计算没有 eval() 的数学表达式

标签 python-3.x eval mathematical-expressions

我正在研究一个“复制粘贴计算器”,它检测复制到系统剪贴板的任何数学表达式,评估它们并将答案复制到准备粘贴的剪贴板。然而,虽然代码使用了 eval() 函数,但考虑到用户通常知道他们在复制什么,我并不十分担心。话虽如此,我想找到一种更好的方法,而不会给计算带来障碍(= 例如。删除计算乘法或指数的能力)。

这是我的代码的重要部分:

#! python3
import pyperclip, time

parsedict = {"×": "*",
             "÷": "/",
             "^": "**"} # Get rid of anything that cannot be evaluated

def stringparse(string): # Remove whitespace and replace unevaluateable objects
    a = string
    a = a.replace(" ", "")
    for i in a:
        if i in parsedict.keys():
            a = a.replace(i, parsedict[i])
    print(a)
    return a

def calculate(string):
    parsed = stringparse(string)
    ans = eval(parsed) # EVIL!!!
    print(ans)
    pyperclip.copy(str(ans))

def validcheck(string): # Check if the copied item is a math expression
    proof = 0
    for i in mathproof:
        if i in string:
            proof += 1
        elif "http" in string: #TODO: Create a better way of passing non-math copies
            proof = 0
            break
    if proof != 0:
        calculate(string)

def init(): # Ensure previous copies have no effect
    current = pyperclip.paste()
    new = current
    main(current, new)

def main(current, new):
    while True:
        new = pyperclip.paste()
        if new != current:
            validcheck(new)
            current = new
            pass
        else:
            time.sleep(1.0)
            pass

if __name__ == "__main__":
    init()

问:我应该用什么代替 eval() 来计算答案?

最佳答案

您应该使用 ast.parse :

import ast

try:
    tree = ast.parse(expression, mode='eval')
except SyntaxError:
    return    # not a Python expression
if not all(isinstance(node, (ast.Expression,
        ast.UnaryOp, ast.unaryop,
        ast.BinOp, ast.operator,
        ast.Num)) for node in ast.walk(tree)):
    return    # not a mathematical expression (numbers and operators)
result = eval(compile(tree, filename='', mode='eval'))

请注意,为了简单起见,这允许所有的一元运算符(+-~not)以及该算术和逐位二进制运算符(+-*/%// **<<>>&|^ ) 但不是逻辑或比较运算符。如果应该直接改进或扩展允许的运算符。

关于python-3.x - 在 Python3 中计算没有 eval() 的数学表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38860682/

相关文章:

c - 如何将数学表达式转换为C语句?

python - 拆分后获取子串的值

python-3.x - Python 3:Python 3不支持pyzipcode

python-3.x - Tkinter GUI 生成器

javascript - 如何在 Javascript 中显示 2^3

c - printf 和 for 函数中的后缀和前缀 (C)

python - 无法使用 openpyxl Workbook 将数据写入 Excel-Sheet

javascript - 如何检测我在 eval() 调用中?

Bash 有条件地使用 sudo

javascript - eval() 不起作用