在 eval [Python 3.4.2] 中使用用户定义的 variables/functions?
Using user defined variables/functions in eval [Python 3.4.2]?
我有一个计算器(python 3.4.2)可以使用 eval 进行正常运算。
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)
如果您需要任何其他信息,请将其放在下面的评论或答案中,以便我对其进行编辑以帮助您帮助我:)
出于多种原因,Eval 在这里不是一个好主意。虽然您可以通过调用轻松地执行您描述的操作:
eval(user_input, {'ans': config.ans})
您应该研究一下表达式的正确解析。 pyparsing
模块之类的东西应该可以帮助你。您可以在此处找到该项目的示例计算器:https://github.com/pyparsing/pyparsing/blob/master/examples/fourFn.py
你可以在第一种方法中完成,你可以在函数的开头定义 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
这样的输入通过 - 你可能会重新考虑如何重写它。
Example/Demo -
>>> 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
尽管您也可以将 eval
用作 -
ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{})
这会将 eval 限制为仅使用 ans
和 sqrt
作为名称。
但是您仍然应该重新考虑使用 eval()
,因为即使在限制其中的全局变量和局部变量之后,用户仍然可以造成伤害。为什么? Check here.
我有一个计算器(python 3.4.2)可以使用 eval 进行正常运算。
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)
如果您需要任何其他信息,请将其放在下面的评论或答案中,以便我对其进行编辑以帮助您帮助我:)
出于多种原因,Eval 在这里不是一个好主意。虽然您可以通过调用轻松地执行您描述的操作:
eval(user_input, {'ans': config.ans})
您应该研究一下表达式的正确解析。 pyparsing
模块之类的东西应该可以帮助你。您可以在此处找到该项目的示例计算器:https://github.com/pyparsing/pyparsing/blob/master/examples/fourFn.py
你可以在第一种方法中完成,你可以在函数的开头定义 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
这样的输入通过 - 你可能会重新考虑如何重写它。
Example/Demo -
>>> 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
尽管您也可以将 eval
用作 -
ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{})
这会将 eval 限制为仅使用 ans
和 sqrt
作为名称。
但是您仍然应该重新考虑使用 eval()
,因为即使在限制其中的全局变量和局部变量之后,用户仍然可以造成伤害。为什么? Check here.