输入()错误 - NameError:名称'...'未定义

270

当我尝试运行这个简单脚本时,出现了错误:

input_variable = input("Enter your name: ")
print("your name is" + input_variable)

假设我输入了“dude”,那么我会收到以下错误信息:

  line 1, in <module>
    input_variable = input("Enter your name: ")
  File "<string>", line 1, in <module>
NameError: name 'dude' is not defined

我正在运行Mac OS X 10.9.1,并使用随Python 3.3安装的Python Launcher应用程序来运行脚本。


18
你确定是Python 3.3吗?我会期望input的行为是这样的,但只有在2.7中才会出现。当你从命令提示符运行python --version时,它会说什么?或者,如果你在脚本开头写入import sys; print(sys.version),会发生什么? - Kevin
3
你没有在运行Python 3,而是在以某种方式运行Python 2(我对这个“Python Launcher”应用程序不熟悉)。 - Wooble
1
import sys print(sys.version_info) 为了确定您正在使用的版本,请在第一行中输入“import sys”,在第二行中输入“print(sys.version_info)”。 - Hyperboreus
4
我按Kevin的建议做了,现在我的Python版本是2.7.5!但是我不确定具体是怎么做的。我下载并安装了3.3版本,在我的应用程序文件夹中有一个名为"Python 3.3"的文件夹,在这个文件夹里面有一个叫"Python Launcher"的应用程序,我通过将脚本拖放到Python Launcher应用程序上来运行它们。为什么我使用3.3版本的启动器应用程序,但我还在使用2.7版本的Python呢? - chillpenguin
2
@chillpenguin:查看Python Launcher的首选项对话框。显然它不会默认运行安装的版本,这很愚蠢。(我从未使用过它;我发现使用终端更好...) - Wooble
显示剩余5条评论
16个回答

299

简而言之:

在Python 2.7中,input函数会将你输入的任何内容作为Python表达式进行评估。如果你只想读取字符串,则使用raw_input函数,它不会评估所读取的字符串。

如果你正在使用Python 3.x,则raw_input已经更名为input函数。引用Python 3.0发布说明

raw_input()被重命名为input()。也就是说,新的input()函数从sys.stdin读取一行,并返回去除尾随换行符的结果。如果输入提前结束,则会引发EOFError异常。要获取input()的旧行为,请使用eval(input())


在Python 2.7中,有两个函数可用于接受用户输入。一个是input,另一个是raw_input。你可以将它们之间的关系想象成:

input = eval(raw_input)

考虑以下代码片段以更好地理解此概念

>>> dude = "thefourtheye"
>>> input_variable = input("Enter your name: ")
Enter your name: dude
>>> input_variable
'thefourtheye'

input 接受用户输入的字符串,并在当前 Python 上下文中对其进行评估。当我输入 dude 时,它会发现 dude 绑定到值 thefourtheye,因此评估结果变为 thefourtheye 并分配给 input_variable

如果我输入的其他内容不在当前的 Python 上下文中,它将失败并抛出 NameError

>>> input("Enter your name: ")
Enter your name: dummy
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'dummy' is not defined

Python 2.7的input存在安全问题:

由于input函数会评估用户输入的任何内容,因此它也会带来安全问题。例如,如果您在程序中已经使用import os加载了os模块,然后用户输入以下内容:

os.remove("/etc/hosts")

Python将把这个表达式作为函数调用表达式进行评估并执行。如果您使用提升的特权来执行Python,则/etc/hosts文件将被删除。看看,它可能有多危险?

为了证明这一点,让我们再次尝试执行input函数。

>>> dude = "thefourtheye"
>>> input("Enter your name: ")
Enter your name: input("Enter your name again: ")
Enter your name again: dude

现在,当执行 input("Enter your name: ") 时,它会等待用户输入,并且如果用户的输入是一个有效的 Python 函数调用,那么该函数也将被调用。这就是为什么我们再次看到了 Enter your name again: 提示。

因此,最好使用 raw_input 函数,像这样:

input_variable = raw_input("Enter your name: ")

如果您需要将结果转换为其他类型,那么您可以使用适当的函数来转换raw_input返回的字符串。例如,要将输入读取为整数,请使用int函数,如此答案所示。

在Python 3.x中,只有一个函数用于获取用户输入,它被称为input,它等价于Python 2.7的raw_input


61

您正在运行Python 2,而不是Python 3。要使其在Python 2中工作,请使用raw_input

input_variable = raw_input ("Enter your name: ")
print ("your name is" + input_variable)

18

由于您正在编写Python 3.x,因此您需要在脚本开始时添加以下内容:

#!/usr/bin/env python3

如果您使用:

#!/usr/bin/env python

默认情况下,它将使用Python 2.x。如果没有以#!(也称为shebang)开头的内容,请将其放在脚本的第一行。

如果您的脚本仅以以下内容开头:

#! python

然后你可以将其更改为:

#! python3

虽然只有一些程序(如launcher)才能识别这种更短的格式,因此它并不是最好的选择。

前两个示例更加广泛地使用,并将确保您的代码可以在安装了Python的任何计算机上运行。


9

我也遇到了一个模块问题,它应该支持python 2.7和3.7。

我发现解决这个问题的方法是导入:

from six.moves import input

这解决了两种解释器的可用性问题。
你可以在这里阅读有关six库的更多信息。

6
你应该使用raw_input,因为你正在使用Python 2.7版本。当你在一个变量上使用input()(例如:s=input('Name:')),它将在Python环境中执行命令,而不保存你在变量s中输入的内容,如果输入的内容未被定义,则会出现错误。 raw_input()会正确保存你在变量中输入的内容(例如:f=raw_input('Name:')),并且不会在Python环境中执行任何可能导致错误的操作。
input_variable = raw_input('Enter Your Name : ')
print("Your Name Is  : " + (input_variable))

5

对于 Python 3 及以上版本

s = raw_input()

如果您是在 PyCharm IDE 上解决问题,则可以使用以下方法解决问题。 如果您正在 Hackerrank 等在线网站上解决问题,则请使用:

s = input()

在Python 3中未定义raw_input。这是“Python 2”的打字错误吗? - wjandrea

5
input_variable = input ("Enter your name: ")
print ("your name is" + input_variable)

您需要在单引号或双引号中输入输入内容

Ex:'dude' -> correct

    dude -> not correct

4

解决这些问题有两种方法:

  • 第一种方法很简单,不需要更改代码,只需
    使用Python3运行脚本
    如果你还想在Python2上运行脚本,那么在输入时请注意以下几点:

    1. 如果要输入字符串,则以"双引号"开始输入即可,在Python 2.7中可以正常工作
    2. 如果要输入字符,请使用带有单引号的输入,例如 'your input goes here'
    3. 如果要输入数字,则直接输入即可
  • 第二种方法需要更改代码:
    使用以下导入并在任何版本的Python下运行:

    1. from six.moves import input
    2. 在代码中使用raw_input()函数而不是input()函数,无论导入哪个库
    3. 使用str()函数对您的代码进行清理,例如str(input()),然后将其分配给任何变量

错误信息的含义为
名称'dude'未定义,即在Python中'dude'成为变量,但它没有分配任何Python定义类型的值,因此它像婴儿一样哭泣,所以如果我们定义一个'dude'变量并分配任何值并将其传递给它,它会工作,但这不是我们想要的,因为我们不知道用户会输入什么,而且我们想要捕获用户输入。

这些方法的事实:
input()函数:此函数接受您输入的值和类型,而不进行任何修改。
raw_input()函数:此函数显式地将您提供的输入转换为字符串类型,

注意:
input()方法中的漏洞在于访问输入值的变量可以被任何人使用变量或方法名称轻松访问。


4
我们正在使用以下内容,适用于python 2和python 3。
#Works in Python 2 and 3:
try: input = raw_input
except NameError: pass
print(input("Enter your name: "))

4

如果您只想读取字符串,请使用 raw_input 而不是 input

print("Enter your name: ")
x = raw_input()
print("Hello, "+x)

Image contains the output screen


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接