【问题标题】:NameError: name 'uinput' is not defined error in PythonNameError:名称'uinput'在Python中未定义错误
【发布时间】:2019-04-28 16:02:46
【问题描述】:

我正在尝试为待办事项列表制作一个简单的 CLI 应用程序。这里发生了什么事?是因为我指的是函数内部的变量吗?

我尝试将“全局”放在 uinput 后​​面,但这表示“=”不是有效的语法或类似的东西。不太清楚为什么,我也尝试在谷歌上四处寻找,但找不到任何东西,如果很明显,对不起。

userlist = []

 def maininput():
     uinput = input("What would you like to add to your list?")
     userlist.append(uinput)
     for i in userlist:
         print(userlist)
         break


 while uinput != "exit":
     maininput()

我希望发生的事情是可以识别“uinput”来执行 while 语句

【问题讨论】:

  • 如果你想这样使用它,你需要使 uinput 成为一个全局变量。!
  • 与许多其他语言不同,global uinput 需要单独一行。
  • ...*然而*,让函数修改全局变量通常被认为是糟糕的设计。考虑做其他事情——比如让maininput() 自己检查exit,或者在它退出时让return uinput 让调用者可以检查返回值而不依赖于全局范围(while mainput() != "exit": pass)。

标签: python nameerror


【解决方案1】:

您应该以这样的方式在您的函数中全局声明您的uinput

global uinput
uinput = input("...")

在全局范围内(在声明函数之前)你应该为uinput指定一个值

uinput = input("...")

... 之外,您应该填写您的输入提示

【讨论】:

    【解决方案2】:

    使用while True 循环来打破maininput 中的列表,而不是使用如下的全局变量。您也可以直接使用print(userlist) 打印列表,而不是 for 循环

    userlist = []
    def maininput():
        while True:
            uinput = input("What would you like to add to your list? Type exit to stop>>")
            #Exit the loop when you type exit
            if uinput == "exit":
                break
            #Else append to list and print it
            userlist.append(uinput)
            print(userlist)
    
    #Call the main function
    maininput()
    

    输出看起来像

    What would you like to add to your list? Type exit to stop>>a
    ['a']
    What would you like to add to your list? Type exit to stop>>b
    ['a', 'b']
    What would you like to add to your list? Type exit to stop>>c
    ['a', 'b', 'c']
    What would you like to add to your list? Type exit to stop>>d
    ['a', 'b', 'c', 'd']
    What would you like to add to your list? Type exit to stop>>exit
    

    【讨论】:

      【解决方案3】:

      简短回答:是的,这是因为您指的是在函数内部定义的名称。您现在知道了一个名为“范围界定”的概念。

      在任何 Python 函数中,名称都是通过依次查看三个位置来解析的:

      1. 函数调用的本地命名空间,在函数调用时创建 在返回或退出时被调用并销毁;
      2. 模块的全局命名空间,顶级类和 功能已定义;
      3. 内置命名空间,其中包含 Python 的预定义值,例如 NoneException - 所有属于 Python 语言的名称。

      在函数之外,本地和全局命名空间的语句(有时称为顶级语句)是相同的。

      当解释器编译一个函数调用时,任何绑定的名称(通过为它们分配一个值,或定义一个嵌套的类或函数)都被假定为该调用的本地名称。这就是为什么顶级语句不能引用uinput

      其他答案让您对更好的循环结构有了一些了解。随着你技能水平的提高,我鼓励你研究pickleshelve 甚至dbm 等模块,这将使你的待办事项列表在程序运行之间保持活跃。

      【讨论】:

        【解决方案4】:

        你把最后一个输入词放在userlist中,很容易从主循环访问userlist的内容,因为①userlist在main中初始化②当函数搜索附加用户的列表时输入它在外部范围内找到userlist,③userlist 是一个可变对象,其变化在其范围内的每个点都是可见的。

        userlist = []
        
        def ask():
            new = input('...')
            userlist.append(new)
            if new == 'exit' : return
            print('List contains', ', '.join(s for s in userlist))
        
        while userlist[-1:] != ['exit']:
            ask()
        

        (我们这样编写测试:userlist[-1:] != ['exit'] 因为在第一次通过时userlist 是空的,并且对其进行索引而不是提取切片会引发错误)。

        当然这是不好的做法,因为我们在主函数和函数之间引入了强耦合,最好在参数列表中显式传递列表:

        userlist = []
        
        def update_list(a_list):
            new = input('...')
            a_list.append(new)
            if new == 'exit' : return
            print('List contains', ', '.join(s for s in a_list))
        
        while userlist[-1:] != ['exit']:
            update_list(userlist)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-11
          • 1970-01-01
          • 1970-01-01
          • 2013-01-26
          • 1970-01-01
          • 2012-03-28
          • 2012-01-31
          相关资源
          最近更新 更多