如何阻止用户仅输入“()”并在此之后仅输出“()”

时间:2014-03-01 00:08:49

标签: python input output

我在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")

我知道这不起作用,但我该如何解决它还是有更好的想法?谢谢!

2 个答案:

答案 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")

请注意,通常,对不受信任的输入使用execeval通常不是一个好主意。如果你严格限制将要评估的内容,你可能是安全的(因为我认为你的代码到目前为止),但如果你一点都不粗心,你可能会有人提交一个删除硬盘驱动器的“方程式”或者其他恶意的东西。您可以更轻松地创建自己的解析器,只接受您希望它处理的有限数量的语法,而不是试图超越攻击者并禁止所有此类滥用行为。