【问题标题】:Python NameError: name 'encrypt' is not definedPython NameError:未定义名称“加密”
【发布时间】:2016-07-28 08:52:31
【问题描述】:

当我尝试运行它时,它显示 NameError: name 'encrypt' is not defined.

MAX_KEY_SIZE = 26
def getMode():
    while True:
           print('Do you wish to encrypt or decrypt a message?')
           mode = input().lower()
           if mode in "encrypt" 'e' 'decrypt' 'd'.split():
                return mode
           else:
                 print('Enter either "encrypt" or "e" or "decrypt" or "d".')

【问题讨论】:

  • 您使用的是 Python 2 还是 Python 3? print 函数看起来像 3,但你得到的 NameError 来自 input 的 2 版本。 (请参阅 progo's answer 了解其重要性。)
  • 这似乎是 Python 2 代码,这里没有显示 from __future__ import print_function

标签: python nameerror


【解决方案1】:

根据我对您代码的理解,“加密”是一个字符串值。您需要使用所需的字符串值创建一个列表,并检查模式变量是否与该列表中的值匹配。

MAX_KEY_SIZE=26
def getMode():
    while True:
        mode=input().lower()
        if mode in ['encrypt','e','decrypt','d']:
            return mode
        else:
            print('Enter either "encrypt" or "e" or "decrypt" or "d".')

如果您想使用 .split() 方法,您可以执行以下操作:

if mode in "encrypt e decrypt d".split()

【讨论】:

  • "encrypt e decrypt d".split() 将使列表到位。
  • 另外,可以先ALLOWED_ANSWERS = ['encrypt','e','decrypt','d'] 然后if mode in ALLOWED_ANSWERS: 然后print("Enter either " + " or ".join(ALLOWED_ANSWERS) + ".") 或者甚至print("Enter either " + " or ".join('"' + i + '"' for i in ALLOWED_ANSWERS) + ".")
  • 虽然这解决了 a 问题,但它并没有解决 Nic Pismiris 遇到的NameError。请参阅pogo's answer。 (为了它的价值,我也爱上了它。)
【解决方案2】:

明白了! input 尝试评估您的输入(因此,它的命名非常具有误导性)。使用raw_input以字符串格式捕获用户的愿望。

基本上input 所做的是将raw_input 传递给eval:现在您尝试将字符串“加密”评估为Python 代码,因此它与编写“加密”具有相同的效果到你的文件。这自然会导致错误,因为在任何地方都没有引入这样的变量。 evalinput 都是非常危险的东西,所以尽量不要使用它们,它们很少有真正的用例。

有关此站点的这种差异的更多信息: https://stackoverflow.com/a/15129556/308668

【讨论】:

  • 好收获。我看到 print 带有括号的函数,并假设代码是 Python 3(和大多数其他人一样,似乎......)。
【解决方案3】:
MAX_KEY_SIZE = 26
def getMode(): 
    while True:
        print ('Do you wish to encrypt or decrypt a message?') 
        mode = input().lower()
        if mode in "encrypt" 'e' 'decrypt' 'd'.split():
            return mode 
        else: 
            print('Enter either "encrypt" or "e" or "decrypt" or "d".')

希望这是你的代码.. 如果是,那么它不应该给出任何错误,而且你试图得到结果的方法也不能解决你的目的,因为"encrypt" 'e' 'decrypt' 'd'.split() 会给你['encryptedecryptd'] 和您无法通过您正在尝试的“in”方法搜索模式。您可以搜索模式如:if any(mode in s for s in "encrypt" 'e' 'decrypt' 'd'.split()): or you can store"encrypt" 'e' 'decrypt' 'd'` in list 然后使用 "in" 方法匹配用户的输入。

希望对你有帮助..

【讨论】:

  • 这不能解决 Python 2 的 input 产生的 NameError。 (Nic Pismiris 没有指定他使用的 Python 版本,但 Python 3 的 input 不会产生该错误。)
  • 另外,if any(mode in s for s in ....split()): 将遍历相同的字符串列表,使其与if mode in 'encryptedecryptd': 有效相同。因此,如果mode'encrypt',那么它将返回True,但如果它是'ted''cry''edecr',它也会返回。您的最后一个选项 --- 允许的字符串列表 --- 更加精确。
  • 感谢 Kevin 提供 "any" 失败的用例,同时查看代码,确定代码是用 python 3 编写的,也使用 input() 将给出 "NameError" 就像 python 3 如果用户需要输入字符串或字符,用户需要将输入包含在在双引号/单引号中,所以在上述情况下,输入应该是:"encrypt" 而不仅仅是encrypt
  • 您的意思是 Python 2,而不是 Python 3,对吗? 3 的 input 总是返回一个字符串(与 2 的 raw_input 相同)。 2input 试图评估用户输入的任何内容。
  • 是的,你是对的。我把它与 python 2.* input() 函数混淆了。
【解决方案4】:

pogo's answer 上展开,这是正确的...

让我(显然还有很多其他人)感到惊讶的是if mode in ...: 行中的字符串簇不是语法错误。

if mode in "encrypt" 'e' 'decrypt' 'd'.split():

这些字符串都是编译时常量,所以string literal concatenation在执行开始前将它们粘合到一个字符串中:

>>> "encrypt" 'e' 'decrypt' 'd'
'encryptedecryptd'

然后对该字符串调用split() 方法,该字符串偶然不包含任何空格。返回值是一个包含单个字符串的列表:

>>> "encrypt" 'e' 'decrypt' 'd'.split()
['encryptedecryptd']

in 运算符不会抱怨给定一个字符串 (mode) 和一个字符串列表,但它会为 mode 的每个值返回 False,除了一个...没有一个可能会输入:

>>> 'encrypt' in ['encryptedecryptd']
False
>>> 'encryptedecryptd' in ['encryptedecryptd']
True

【讨论】:

    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 2020-09-04
    • 2021-10-18
    • 2016-08-09
    • 2016-01-08
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多