在eval [Python 3.4.2]中使用用户定义的变量/函数?

时间:2015-07-29 04:21:11

标签: python function python-3.x eval calculator

我有一个可以使用eval进行正常操作的计算器(python 3.4.2)。

def calculator(user_input):
    if any(c not in config.valid_cal_chars for c in user_input):
        print("- Invalid Equation | Bad characters")
        return
    elif not any(c in user_input for c in "0123456789"):
        print("- Invalid Equation | No numbers found")
        return
    sys.stdout.write("calculating " + "-".join(gfx.load_sequence))
    time.sleep(0.1)
    print (" | 100%")
    try:
        current_ans = eval(user_input)
    except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
        print ("- Invalid Equation | Error")
        return
    config.ans = current_ans
    print (current_ans)

这是config.ans,config.valid_cal_char引用的config.py:

ans = ("0.0") 
valid_cal_chars = ("0123456789-+/*ansqrt() \n")

如果你想知道

是什么
user_choice

变量是指,它指的是我在此函数之前的输入函数。那部分有效,所以不用担心。

但是,我想知道是否可以做这样的事情:

input equation here: 4*4 #this would be saved as the user_input variable
> 16 #the output of the equation
input equation here: sqrt(ans) #this would use the previous answer saved in config.ans (ans) and the sqrt() to find the square root of the previous printed value, so:
> 4

因此输入ans会导致:

input equation here: 1+1
> 2
input equation here: ans
> 2

使用sqrt()会导致:

input equation here: 2+2
> 4
input equation here: sqrt(4)
> 2

因此,如果您还没有得到它,sqrt()会找到输入值的平方根。 ans使用之前返回的值。所以结合两个" sqrt(ans)"将给出前一个返回值的平方根。

在背景信息不受影响的情况下,我想要做的是允许用户在计算时使用这些信息。虽然" eval"可能不起作用,我很乐意使用" exec" (知道危险)。但是,这是一个multitool.py(主文件),它导入这个文件(functions.py)以使用我在那里的所有函数,包括这个函数。

import os, sys, glob, math, random, login, gfx, config, functions, time

path = "******" #creates path to folder (can be changed by commenting this line out and creating new one)
dirs = os.listdir( path ) #not used currently

functions.load_sequence_complete()

functions.username_login()
time.sleep(0.05)
functions.password_login()
print ("\n[credentials have been verified! proceeding to main program " + "-".join(gfx.load_sequence) + "]\n")
time.sleep(0.1)

program = True
while (program == True):
    user_choice = functions.choice_selecter()
    functions.validate_choice(user_choice)

如果您还需要其他信息,请将其放在下面的评论或答案中,以便我可以对此进行编辑以帮助您:)

2 个答案:

答案 0 :(得分:2)

您可以在第一种方法中执行此操作,您可以在函数的开头将ans定义为全局,然后在eval(user_input)的结果中定义ans,并使用current_ans代替def calculator(user_input): global ans if any(c not in config.valid_cal_chars for c in user_input): print("- Invalid Equation | Bad characters") return sys.stdout.write("calculating " + "-".join(gfx.load_sequence)) time.sleep(0.1) print (" | 100%") try: ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{}) except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError): print ("- Invalid Equation | Error") return config.ans = ans print (ans) 无处不在。

假设一切正常,你的功能会是什么样子 -

elif

请注意我摆脱了函数中的ans部分,否则它不会让像>>> def calculator(user_input): ... global ans ... if any(c not in "0123456789-+/*ansqrt() \n" for c in user_input): ... print("- Invalid Equation | Bad characters") ... return ... time.sleep(0.1) ... print (" | 100%") ... try: ... ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{}) ... except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError): ... print ("- Invalid Equation | Error") ... return ... print (ans) ... >>> >>> calculator('1+2') | 100% 3 >>> calculator('ans') | 100% 3 >>> from math import sqrt >>> calculator('sqrt(ans)') | 100% 1.7320508075688772 这样的输入通过 - 你可能会重新思考如何重写它。

示例/演示 -

ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{})

虽然您也可以使用eval作为 -

ans

这会将eval限制为仅将sqrteval()作为名称。

但是仍然应该重新考虑使用ECHO Access to this system is restricted to authorized personnel for authorized business purpose only!! CHOICE /M "Do you want to continue" If Errorlevel 2 GoTo N :Y ECHO. ECHO You choose: YES set /p id=Enter Name/ID: ECHO Hello %id% timeout /t 5 GoTo ErrorFunc :N Echo. Echo You choose: NO and you are required to exit from cmd ! Echo. ECHO EXITING IN 5 SECOND timeout /t 5 exit test.bat > C:\test.log ,因为即使限制了全局变量和局部变量,用户仍然会造成伤害。为什么? Check here.

答案 1 :(得分:0)

由于多种原因,Eval在这里是一个坏主意。虽然您可以通过致电:

轻松完成您所描述的内容
eval(user_input, {'ans': config.ans})

您应该调查正确的表达式解析。类似pyparsing模块的东西应该可以帮到你。您可以在此处找到该项目的示例计算器:https://github.com/pyparsing/pyparsing/blob/master/examples/fourFn.py