Python NameError 异常,如何调试?

Python NameError exception, how do I debug it?

我有一个 Python NameError 异常,例如:

>>> def test():
...   var = 123
...
>>> test()
>>> print(var)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'var' is not defined

我应该采取哪些步骤来调试它?我该如何解决?

第 1 步 - 找出变量的使用位置:

读取NameError异常:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'var' is not defined

最后一行包含变量的名称,在本例中为 var。确保拼写正确,没有错误。

NameError 的正上方,您可以看到文件名和行号。这是您尝试使用变量的位置。

第 2 步 - 找出定义变量的位置:

寻找 var = 或包含 var 作为参数的任何函数:

def func(var):
    ...

您要使用的变量在哪里?它存在于何处?

尝试使用 Windows 中的 ctrl+f 或 Mac 中的 cmd+f 在所有 Python 文件中查找该名称。

第 3 步 - 尝试理解范围规则:

  • 如果变量是在函数中定义的:

    我在同一个函数中吗?

    def test():
        var = 1
    
    print(var)  # This will not work.
    
    def test2():
        print(var)  # This will not work either.
    

    如果您不在同一个函数中,请尝试通过 return 变量进行修复:

    def test():
        var = 1
        return var
    
    var = test()
    
    print(var)  # This will work
    

    或者接受变量作为参数:

    var = test()
    
    def test2(x):  # var is now named 'x'
        print(x)  
    
    test2(var)
    

    您还可以return多个变量:

    def test():
         var1 = "hello"
         var2 = "world" 
         return var1, var2
    var1, var2 = test()
    print(var1, var2)  # Prints hello world.
    

    如果您在同一函数中或使用 global,您是否使用了 if 语句但从未输入过它们?可能抛出异常而你抑制了?

    def test():
         if False:  # Never true
             var = 123
         print(var)  # This will not work
    
    def test2():
         try:
             2/0  # Throws an error
             var = 123
         except:
             pass
         print (var)  # This will not work
    
  • 如果变量定义在class:

    class Test:
        var = 123
        def func(self):
            print(var)  # This will not work
    

    确保使用 self 访问它:

    class Test:
        var = 123
        def func(self):
            print(self.var)  # This will work
    

    使用默认参数传递它:

    class Test:
        var = 123
        def func(self, param=var):
            print(param)
    

    或使用实例访问它:

    class Test:
        var = 123
        def func(self, param=var):
            print(param)
    inst = Test()
    inst.var  # This will work
    inst.func()  # This will work
    
  • 如果变量是函数名或class:

    确保在使用前定义:

    func()
    def func():  # This will not work
        pass
    
  • 如果找不到或不在同一个文件中:

    您是否尝试导入但忘记了?

    import operator
    itemgetter # This will not work
    operator.itemgetter  # This will work
    

    你确定你拼写正确吗?请记住,Python 是 case-sensitive!

有关范围界定的详细信息,请参阅 this answer

如果一切都失败了,但您仍然没有找到答案,我们随时欢迎您打开一个问题并提问,或者在您现有的 Whosebug 问题的评论中写下。

阅读 question checklist 并提供一个最小示例 - 确保您的示例包含足够的代码以查看定义变量的位置以及使用变量的位置,但代码不要太多很难理解。