【问题标题】:Is it ever useful to use Python's input over raw_input?在 raw_input 上使用 Python 的输入有用吗?
【发布时间】:2011-10-10 05:57:31
【问题描述】:

我目前教一年级的大学生 Python,我惊讶地发现我的一些学生决定使用的看似无害的 input 函数(并且被奇怪的行为弄糊涂了)隐藏了一个调用到后面的eval

所以我的问题是,为什么input 函数调用eval,这对使用raw_input 不会更安全有什么用处?我知道这在 Python 3 中已经改变,但首先这似乎是一个不寻常的设计决定。

Python 2.x input function documentation

【问题讨论】:

  • 代码高尔夫很有用
  • 回答“为什么”——Python 的第一个 REPL 可能是 while 1: print input()。我敢打赌,在那个古老的时代,支持良好的编程实践在 Python 的优先事项列表中并没有现在那么重要。 Python 3 的 while True: print(eval(input())) 可能看起来更令人困惑——所有这些嵌套的括号!

标签: python user-input python-2.x


【解决方案1】:

在 raw_input 上使用 Python 2 的输入有用吗?

没有。


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()),那么您至少会看到它很危险。并且没有真正的理由在其他情况下使用它。谢谢!
【解决方案2】:

Python 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

运行示例:

示例:1

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

示例:2

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$

问。为什么输入函数会调用eval?

A.考虑用户在输入中输入表达式“45 + 7”的场景,与 python 2.x 中的 raw_input 相比,输入将给出正确的结果

【讨论】:

  • 或者他们可以输入quit(),如果您正在通过代码的关键部分,这是相当危险的......
  • 或者他们可以输入__import__('os').remove('precious_file'),这是相当危险的任何地方ast.literal_eval(raw_input()) 在几乎所有情况下都是更好的选择。难怪Python 3's input() 像 2 的 raw_input() 一样工作。
  • 我不同意这个答案。为什么你认为输入的“正确结果”是 52?我认为正确的结果是“请输入一个数字”。一个程序没有充分的理由要求一个数字来计算用户可能给出的 Python 表达式的结果。正如 Petr 所指出的,这不仅是一种荒谬的行为,而且是一种严重的安全风险。问题是“输入有用”,答案是“否”。
  • 这根本没有帮助,如果你想构建一个计算器,那么通过解析器安全地完成它,例如这里描述的stackoverflow.com/a/9558001/6260170
【解决方案3】:

input 几乎只是作为交互式 python shell 的构建块有用。你当然是对的,它的工作方式令人惊讶,而且它的用途过于特定而不能成为内置 - 我认为这就是它从 Python 3 中删除的原因。

【讨论】:

    【解决方案4】:

    raw_input 更好,它总是返回用户的输入而不做任何更改。 相反,input() 函数会尝试将您输入的内容转换为 Python 代码,它存在安全问题,因此您应该避免使用它。

    在实际程序中不要使用input(),用处理您期望的特定输入格式的东西来解析您的输入,而不是通过将输入评估为 Python 代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多