input
函数,有些学生决定使用它(并对奇怪的行为感到困惑),实际上隐藏着一个eval
调用。
那么我的问题是,为什么input
函数会调用eval
,这有什么用处,而不使用raw_input
更安全呢?我知道这在Python 3中已经改变了,但这似乎是一个不寻常的设计决策。
input
函数,有些学生决定使用它(并对奇怪的行为感到困惑),实际上隐藏着一个eval
调用。
那么我的问题是,为什么input
函数会调用eval
,这有什么用处,而不使用raw_input
更安全呢?我知道这在Python 3中已经改变了,但这似乎是一个不寻常的设计决策。
在使用Python时,是否有必要使用Python 2的input()功能而不是raw_input()?
没有。
input()
会评估用户输入的代码。它将Python的全部能力交给了用户。使用生成器表达式/列表推导式,__import__
和if/else
运算符,任何Python可以做到的事情都可以用一个表达式实现。恶意用户可以使用input()
删除文件(__import__('os').remove('precious_file')
),monkeypatch程序的其余部分(setattr(__import__('__main__'), 'function', lambda:42)
),等等。
普通用户不需要使用所有高级功能。如果不需要表达式,请使用ast.literal_eval(raw_input())
- literal_eval
函数是安全的。
如果你正在为高级用户编写代码,请给他们更好的输入代码的方式。插件、用户模块等——拥有完整的Python语法,而不仅仅是功能。
如果你绝对确定自己知道在做什么,请使用eval(raw_input())
。对于有经验的人来说,eval
会让他们察觉到“我很危险!”但是,你可能永远不需要这个功能。
input()
是Python 3正在解决的旧设计错误之一。
input
的功能,如果你使用 eval(raw_input())
,那么你至少会意识到它是危险的。而且除此之外,没有真正好的理由去使用它。谢谢! - luketparkinsonPython的Input函数返回一个对象,该对象是表达式求值的结果。raw_input函数返回一个字符串。
name = "Arthur"
age = 45
first = raw_input("Please enter your age ")
second = input("Please enter your age again ")
# first will always contain a string
# second could contain any object and you can even
# type in a calculation and use "name" and "age" as
# you enter it at run time ...
print "You said you are",first
print "Then you said you are",second
Prompt$ python yraw
Please enter your age 45
Please enter your age again 45
You said you are 45 Then you said you are 45
Prompt$ python yraw
Please enter your age 45 + 7
Please enter your age again 45 + 7
You said you are 45 + 7 Then you said you are 52
Prompt$
问:为什么input函数会调用eval函数?
答:考虑这样一种情况,用户在input函数中输入一个表达式'45 + 7',与Python 2.x中的raw_input相比,input函数将给出正确的结果。
quit()
,但如果您正在执行关键代码部分,则相当危险... - tobyodavies__import__('os').remove('precious_file')
,这在任何地方都是相当危险的。在几乎所有情况下,ast.literal_eval(raw_input())
是更好的选择。难怪Python 3的input()
的工作方式类似于Python 2的raw_input()
。 - Petr Viktorininput
函数在交互式 Python shell 中作为构建块非常有用。你肯定是对它的工作方式感到惊讶,而且它过于特定于某个目的,因此被认为不适合作为内置函数 - 这也是我认为它在 Python 3 中被删除的原因。
raw_input
更好,它始终返回用户输入的内容而不进行任何更改。
相反,input()
函数会尝试将您输入的内容转换为 Python 代码,并且它存在安全问题,因此应避免使用。
在实际程序中不要使用 input()
,请使用能够处理特定输入格式的解析器来解析输入,而不是通过评估输入作为 Python 代码来解析。
while 1: print input()
。我敢打赌,在那个古老的时代,支持良好的编程实践并不是Python优先考虑的事情,就像现在这样。Python 3的while True: print(eval(input()))
甚至可能更加令人困惑 - 所有这些嵌套的括号! - Petr Viktorin