我目前教大学一年级学生 python,我惊讶地发现,我的一些学生决定使用的看似无害的 input
函数(并被奇怪的行为弄糊涂了)被隐藏了对其后面的eval
的调用。
所以我的问题是,为什么 input
函数调用 eval
,这有什么用处,使用 raw_input< 会不会更安全? /代码>?据我所知,Python 3 中对此进行了更改,但首先这似乎是一个不寻常的设计决策。
Python 2.x 输入函数文档
I currently teach first year university students python, and I was surprised to learn that the seemingly innocuous input
function, that some of my students had decided to use (and were confused by the odd behaviour), was hiding a call to eval
behind it.
So my question is, why does the input
function call eval
, and what would this ever be useful for that it wouldn't be safer to do with raw_input
? I understand that this has been changed in Python 3, but it seems like an unusual design decision in the first place.
Python 2.x input function documentation
发布评论
评论(4)
使用 Python 2 的输入而不是 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 正在解决的旧设计错误之一。Is it ever useful to use Python 2's input over raw_input?
No.
input()
evaluates the code the user gives it. It puts the full power of Python in the hands of the user. With generator expressions/list comprehensions,__import__
, and theif/else
operators, literally anything Python can do can be achieved with a single expression. Malicious users can useinput()
to remove files (__import__('os').remove('precious_file')
), monkeypatch the rest of the program (setattr(__import__('__main__'), 'function', lambda:42)
), ... anything.A normal user won't need to use all the advanced functionality. If you don't need expressions, use
ast.literal_eval(raw_input())
– theliteral_eval
function is safe.If you're writing for advanced users, give them a better way to input code. Plugins, user modules, etc. – something with the full Python syntax, not just the functionality.
If you're absolutely sure you know what you're doing, say
eval(raw_input())
. Theeval
screams "I'm dangerous!" to the trained eye. But, odds are you won't ever need this.input()
was one of the old design mistakes that Python 3 is solving.Python 输入函数返回一个作为结果的对象
评估表达式。
raw_input 函数返回一个字符串
运行示例:
示例:1
示例:2
问:为什么输入函数调用 eval?
A. 考虑用户在输入中输入表达式“45 + 7”的场景,与 python 2.x 中的 raw_input 相比,输入将给出正确的结果
Python Input function returns an object that's the result
of evaluating the expression.
raw_input function returns a string
examples of that running:
Example: 1
Example: 2
Q. why does the input function call eval?
A. Consider the scenario where user inputs an expression '45 + 7' in input, input will give correct result as compared to raw_input in python 2.x
input
几乎只用作交互式 python shell 的构建块。你当然是对的,它的工作方式令人惊讶,而且它的用途过于特定,无法成为内置函数 - 我认为这就是它从 Python 3 中删除的原因。input
is pretty much only useful as a building block for an interactive python shell. You're certainly right that it's surprising it works the way it does, and is rather too purpose-specific to be a builtin - which I presume is why it got removed from Python 3.raw_input
更好,它总是返回用户的输入,不做任何更改。相反,
input()
函数会尝试将您输入的内容转换为 Python 代码,并且它存在安全问题,因此您应该避免使用它。在实际程序中,不要使用
input()
,而是使用处理您期望的特定输入格式的内容来解析您的输入,而不是通过将输入评估为 Python 代码。raw_input
is better, It always returns the input of the user without changes.Conversely The
input()
function will try to convert things you enter as if they were Python code, and it has security problems so you should avoid it.In real program don't use
input()
, Parse your input with something that handles the specific input format you're expecting, not by evaluating the input as Python code.