Binding
Before the closure python, first comb the closure of the binding operation.
Take a look at two related errors NameError
andUnboundLocalError
When a name is not found at all, a
NameError
exception is raised. If the name refers to a local variable that has not been bound, aUnboundLocalError
exception is raised.UnboundLocalError
is a subclass ofNameError
.
NameError better understanding that the reference is not defined, for example,
fun1()
def fun1():
pass
But UnboundLocalError has been more vague, meaning that reference variables unbound, pay attention to the variables here may be already defined in.
**If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. **This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations.
Here's a look obscure bug on this error.
def outer_func():
loc_var = "local variable"
def inner_func():
loc_var += " in inner func"
return loc_var
return inner_func
clo_func = outer_func()
clo_func()
#UnboundLocalError: local variable 'loc_var' referenced before assignment
Program in the implementation of clo_func () is out of the question.
Note that the statement loc_var += " in inner func"
can be seen as loc_var = loc_var + " in inner func"
, and in the formula to strike loc_var + " in inner func"
when the value of the variable loc_var needs, and within the variables loc_var inner_func function is defined, that is loc_var += " in inner func"
, so inner_func will go to the reference value, but inner_func but did not complete the binding of loc_var Therefore there has been UnboundLocalError errors, somewhat similar to a recursive infinite loop.
Thus, python always take precedence reference variables appearing in their own block of code, regardless of the order .
Note that this is regardless of the order, which may lead UnboundLocalError
If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block.
As another example of a similar
import sys
def add_path(new_path):
path_list = sys.path
if new_path not in path_list:
import sys
sys.path.append(new_path)
add_path('./')
Here path_list = sys.path
will refer to the first two import sys rather than the first , which led to the reference is not binding because sys be treated as a no import.
bind name: The following operations can be regarded as binding operation
- Shape function parameters
- import declaration
- Class and method definitions of
- Assignment
- The for loop header
- Abnormal capture the relevant variable assignment
There are other examples about UnboundLocalError follows
1 def get_select_desc(name, flag, is_format = True):
2 if flag:
3 sel_res = 'Do select name = %s' % name
4 return sel_res if is_format else name
5
6 get_select_desc('Error', False, True)
This error can not go wrong at compile time, but when running certain examples will appear UnboundLocalError.
So how to avoid this mistake? I think we can note the following
-
When the local variable with the same name as a global variable
-
When to choose whether to bind variable by arguments
Such errors such as C, C ++ and other languages are very different, I think it may be because it is clearly defined in the language of these variables, such as int i = 1;
. And in python you do not need to be clearly defined variables, so the python every assignment to some extent, can be said to be defined once.