我在python上相当新,所以我对它不太了解:/。但是,这是我的代码:
valid_chars = "0123456789-+/*ans() \n";
while True:
x = "x="
y = input(" >> ")
x += y
def ans():
return z
def ans():
try:
return z
except NameError:
return 0 # appropriate value
if any(c not in valid_chars for c in y):
print("WARNING: Invalid Equation")
continue
try:
exec(x)
except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
print ("WARNING: Invalid Equation")
else:
z = x
print(x)
这有效,但并不完美。如果用户键入“()”,则输出“()”。如何阻止它输出“()”并说出“警告:无效的公式”?提前谢谢!
更新
如果我使用“if not”功能,它会起作用吗?例如:
if not(y == "()"):
continue
except:
print ("WARNING: Invalid Equation")
我知道这不起作用,但我该如何解决它还是有更好的想法?谢谢!
答案 0 :(得分:5)
使用raise
,如下所示:
if y == '()':
raise SyntaxError
以下是您编辑的代码:
valid_chars = "0123456789-+/*ans() \n";
while True:
x = "x="
y = input(" >> ")
x += y
def ans():
try:
return z
except NameError:
return 0 # appropriate value
if y == '()':
print ("WARNING: Invalid Equation")
break
if any(c not in valid_chars for c in y):
print("WARNING: Invalid Equation")
try:
exec(x)
except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
print ("WARNING: Invalid Equation")
break
else:
z = x
print(x)
塔达!感谢raise
...
答案 1 :(得分:3)
以下是对当前代码的直接修改,使()
成为非法值,就像y
包含非法字符一样。
valid_chars = "0123456789-+/*ans() \n";
while True:
x = "x="
y = input(" >> ")
x += y
def ans():
try:
return z
except NameError:
return 0 # appropriate value
if y == "()" or any(c not in valid_chars for c in y): # fix is here!!!
print("WARNING: Invalid Equation")
continue
try:
exec(x)
except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
print ("WARNING: Invalid Equation")
else:
z = x
print(x)
除了添加()
的支票外,我还摆脱了ans
的重复定义。
请注意,这仍然无法避免y
的意外条目为您提供无效值的所有问题。例如,如果输入(())
,您将获得嵌套元组,如果输入ans
(后面没有括号),x
将成为函数对象。这是一种替代方法,它只是声明无效的任何非整数或浮点数的结果。
valid_chars = "0123456789-+/*ans() \n";
while True:
x = "x="
y = input(" >> ")
x += y
def ans():
try:
return z
except NameError:
return 0 # appropriate value
if any(c not in valid_chars for c in y):
print("WARNING: Invalid Equation")
continue
try:
x=eval(y)
except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
print ("WARNING: Invalid Equation")
else:
if isinstance(x, (int, float)): # verify that we got a number
z = x
print(x)
else:
print("WARNING: Invalid Equation")
另一个注意事项:是否有理由对ans
使用函数而不仅仅是z
之类的变量?您可以在开始循环之前将z
初始化为0,然后再使用更简单的代码:
z = 0 # initialize z
valid_chars = "0123456789-+/*() \nz" # z is only letter that is valid
while True:
x = "x="
y = input(" >> ")
x += y
# no ans function needed
if any(c not in valid_chars for c in y):
print("WARNING: Invalid Equation")
continue
else:
if isinstance(x, (int, float)):
z = x # this line does all the work of setting up `z` for later calls
print(x)
else:
print("WARNING: Invalid Equation")
请注意,通常,对不受信任的输入使用exec
或eval
通常不是一个好主意。如果你严格限制将要评估的内容,你可能是安全的(因为我认为你的代码到目前为止),但如果你一点都不粗心,你可能会有人提交一个删除硬盘驱动器的“方程式”或者其他恶意的东西。您可以更轻松地创建自己的解析器,只接受您希望它处理的有限数量的语法,而不是试图超越攻击者并禁止所有此类滥用行为。