Python UnboundLocalError和NameError错误根源案例解析

  

如果代码风格相对而言不是那么的神谕的,或许很少碰到这类错误。当然并不是不鼓励使用一些python语言的技巧。如果遇到这这种类型的错误,说明我们对python中变量引用相关部分有不当的认识和理解。而这又是对理解python相关概念比较重要的。这也是本文写作的原因。

  

,本文为理解闭包相关概念的做铺垫,后续会详细深入的整理出闭包相关的博文,敬请关注。

  

  

在整理闭包相关概念的过程中,经常发现UnboundLocalError和NameError这两个错误,刚开始遇到的时候可能很困惑,对这样的错误无从下手。

  

<强> 1.1案例一:

        def outer_func ():   loc_var=熬植勘淞俊?   def inner_func ():   “在内部函数”loc_var +=返回loc_var   返回inner_func   clo_func=outer_func ()   clo_func ()      

错误提示:

  
  

回溯(最近的电话最后):
  ,文件”G: \项目文件\ \主要Python测试。py”, 238行,& lt; module>
  ,,clo_func ()
  ,文件”G: \项目文件\ \主要Python测试。py”, 233行,在inner_func
  ,,loc_var +=蹦诓亢?br/>   UnboundLocalError:局部变量“loc_var”引用之前赋值

     

<强> 1.2案例二:

        def get_select_desc(名称、标志、is_format=True):   如果国旗:   sel_res='做选择name=% s ' %的名字   返回sel_res如果is_format其他人的名字   get_select_desc(“错误”,假的,真的)      

错误提示:

  
  

回溯(最近的电话最后):
  ,文件”G: \项目文件\ \主要Python测试。py”, 247行,& lt; module>
  ,,get_select_desc(“错误”,假的,真的)
  ,文件”G: \项目文件\ \主要Python测试。py”, 245行,在get_select_desc
  ,,返回sel_res如果is_format别的名字
  UnboundLocalError:局部变量“sel_res”引用之前赋值

     

<强> 1.3案例三:

        def outer_func (out_flag):   如果out_flag:   loc_var1='局部变量与国旗的   其他:   loc_var2=熬植勘淞棵挥泄臁?   def inner_func (in_flag):   如果其他in_flag loc_var2 loc_var1返回   返回inner_func      clo_func=outer_func(真正的)   打印clo_func (False)      

,错误提示:

  
  

回溯(最近的电话最后):
  ,文件”G: \项目文件\ \主要Python测试。py”, 260行,& lt; module>
  ,,打印clo_func (False)
  ,文件”G: \项目文件\ \主要Python测试。py”, 256行,在inner_func
  ,,返回loc_var1如果其他in_flag loc_var2
  NameError:自由变量的loc_var2引用赋值之前封闭范围

     

,上面的三个例子可能显得有点矫揉造作,但是实际上类似错误的代码都或多或少可以在上面的例子中找到影子。这里仅仅为了说明相关概念,对例子本身的合理性不必做过多的关注。

  

  

由于python中没有变量,函数或者类的声明概念。按照C或c++者的习惯编写python,或许很难发现错误的根源在哪。

  

首先看一下这类错误的官方解释:

  

时,没有找到一个名字,一个NameError异常。如果名称是指一个局部变量,没有束缚,UnboundLocalError异常。UnboundLocalError NameError的子类。

  

大概意思是:

  

如果引用了某个变量,但是变量名没有找的到,该类型的错误就是NameError。如果该名字是一个还没有被绑定的局部变量名,那么该类型的错误是NameError中的UnboundLocalError错误。

  

下面的这种NameError类型的错误或许还好理解一些:

        my_function ()   def my_function ():   通过      

,如果说python解释器执行到def my_function()时才绑定到my_function,而my_function此时也表示的是内存中函数执行的入口。因此在此之前使用my_function均会有NameError错误。

  

那么上面的例子中使用变量前,都有赋值操作(可视为一种绑定操作,后面会讲),为什么引用时会出错?定义也可判断可见性

  

如果说是因为赋值操作没有执行,那么为什么该变量名在局部命名空间是可见的吗?(不可见的话,会有这类错误:NameError:全局名称“xxx”没有定义,根据UnboundLocalError定义也可判断可见性)

  

问题到底出在哪里?怎样正确理解上面三个例子中的错误?

Python UnboundLocalError和NameError错误根源案例解析