Python开发者遇到的UnboundLocalError错误怎么解决

这篇“Python开发者遇到的UnboundLocalError错误怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python开发者遇到的UnboundLocalError错误怎么解决”文章吧。

为新城等地区用户提供了全套网页设计制作服务,及新城网站建设行业解决方案。主营业务为做网站、网站设计、新城网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

比如下面的代码在 foo 函数中给 x 自增 1:

x = 10
def foo():
   x += 1
   print(x)
foo()

调用 foo() 的时候,堆栈日志告诉我们:局部变量 x 赋值前在其它地方被引用了,换句话说就是 x 在当前作用域内还没有定义就拿来使用了。

Traceback (most recent call last):
 File "unboundtest.py", line 8, in
   foo()
 File "unboundtest.py", line 4, in foo
   x += 1
UnboundLocalError: local variable 'x' referenced before assignment

明明 x 在函数 foo 的外面定义了,为什么却告知我们说 x 没赋值就被引用了呢?

因为这是几乎每个人都会遇到的错误,所以 Python 官方把这个问题收入到了它的 FAQ 中,它是这样说的:

This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope.

翻译过来就是,当你在局部作用域中给变量赋值时,那么这个变量就会变成一个局部变量,不管它在外部有没有初始化。如果外部作用域有相同名字的变量,那么对局部空间来说这些相同名字的全局变量都将被隐藏为不可见的。

在这里,x += 1 等价于 x = x + 1,首先会执行 x + 1 操作,然后再赋值给 x。而执行加法操作之前它会先查找变量 x,根据官方的这个解释所述, Python 认为 x 对函数 foo 来说一个局部变量,因为它有赋值操作,既然 x 是局部变量,在执行加法操作时,又引用了 x,所以抛出了 UnboundLocalError 异常。

那么,该异常如何解决?办法非常简单,Python 提供了一个关键字 globlal,用来显示地标识 x 为全局变量,x 设置为全局变量后,执行加操作的时候就会去全局命名空间查找 x 。

如果在局部作用域中没有给变量 x 重新赋值,而是直接引用它,那么 Python 会沿着 LEGB(local->-enclosing->global->built-in) 的规则顺序查找变量。

lst = [1, 2, 3]

def foo():
   lst.append(5)   # 正常执行,lst 没有重新赋值,首先在局部作用域查找,没找到再往全局作用域查找 lst
   #lst += [5]     # UnboundLocalError 错误,因为重新赋值了,而在局部作用域没定义就引用了

foo()
print(lst)

这个问题解决之后,再来看另外一个类似的问题:

def external():
   x = 10
   def internal():
       x += 1
       print(x)
   internal()

external()

这是一个 Python 闭包,执行 external 函数的时候,看代码你也知道会报同样的 UnboundLocalError 错误,那么用 global 来 修复可行吗?试试:

def external():
   x = 10
   def internal():
       global x
       x += 1
       print(x)
   internal()

external()

新的错误出现了, NameError: global name ‘x’ is not defined,全部变量 x 没有定义,仔细想想也是啊,你看 x 是定义在 external 函数中的一个局部变量,现在你要把 internal 函数中的 x 声明为全局变量,Python 在全局作用域空间 找不到 x ,所以出现了 NameError,那么这个问题又该如何解决呢?如果你是使用 Python3,恭喜你,Python3 中新增了一个关键字 nolocal,用于表示非局部变量。

用 dis.dis(foo) 可以看到 Python 内部字节码指令的执行过程,从字节码中可以知道,第三行代码 x= x+1 操作的指令是 LOAD_FAST ,LOAD_FAST  0 (x) 表示 Python 解释器 从局部作用域加载 x,而 x 由找不到,因此出现了UnboundLocalError。


3       0 LOAD_FAST          0 (x)
       3 LOAD_CONST         1 (1)
       6 INPLACE_ADD    
       7 STORE_FAST         0 (x)

4      10 LOAD_FAST          0 (x)
      13 PRINT_ITEM    
      14 PRINT_NEWLINE  
      15 LOAD_CONST         0 (None)
      18 RETURN_VALUE

以上就是关于“Python开发者遇到的UnboundLocalError错误怎么解决”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注创新互联行业资讯频道。


新闻名称:Python开发者遇到的UnboundLocalError错误怎么解决
转载来于:http://hbruida.cn/article/jpsccp.html