UnboundLocalError, explore the Python bindings

Binding

Before the closure python, first comb the closure of the binding operation.

Take a look at two related errors NameErrorandUnboundLocalError

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, a UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError.

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.pathwill 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.

Reference https://www.cnblogs.com/yssjun/p/9873689.html

Guess you like

Origin www.cnblogs.com/friedCoder/p/12571983.html