python - Local variable referenced before assignment

来源:互联网 发布:linux 进程调度 编辑:程序博客网 时间:2024/05/10 10:23

直接上代码

def foo():a = 1def bar():a = a + 1return bar()



运行foo(),报错


import disdef foo():a = 1def bar():a = a + 1dis.dis(bar)return bar()

dis打印的内容如下:



很容易明白其意思,,应该是从某个地方加载a,1,执行加法,写回a;


CPython源码中,搜索“referenced before assignment



#define NAME_ERROR_MSG \    "name '%.200s' is not defined"#define GLOBAL_NAME_ERROR_MSG \    "global name '%.200s' is not defined"#define UNBOUNDLOCAL_ERROR_MSG \    "local variable '%.200s' referenced before assignment"#define UNBOUNDFREE_ERROR_MSG \    "free variable '%.200s' referenced before assignment" \    " in enclosing scope"

接着搜索UNBOUNDLOCAL_ERROR_MSG

TARGET(LOAD_FAST)    x = GETLOCAL(oparg);    if (x != NULL) {        Py_INCREF(x);        PUSH(x);        FAST_DISPATCH();    }    format_exc_check_arg(PyExc_UnboundLocalError,        UNBOUNDLOCAL_ERROR_MSG,        PyTuple_GetItem(co->co_varnames, oparg));    break;
TARGET(DELETE_FAST)    x = GETLOCAL(oparg);    if (x != NULL) {        SETLOCAL(oparg, NULL);        DISPATCH();    }    format_exc_check_arg(        PyExc_UnboundLocalError,        UNBOUNDLOCAL_ERROR_MSG,        PyTuple_GetItem(co->co_varnames, oparg)        );    break;
static voidformat_exc_unbound(PyCodeObject *co, int oparg){    PyObject *name;    /* Don't stomp existing exception */    if (PyErr_Occurred())        return;    if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {        name = PyTuple_GET_ITEM(co->co_cellvars,                                oparg);        format_exc_check_arg(            PyExc_UnboundLocalError,            UNBOUNDLOCAL_ERROR_MSG,            name);    } else {        name = PyTuple_GET_ITEM(co->co_freevars, oparg -                                PyTuple_GET_SIZE(co->co_cellvars));        format_exc_check_arg(PyExc_NameError,                             UNBOUNDFREE_ERROR_MSG, name);    }}


初步判断是在执行LOAD_FAST时,报出的错误;

如果能够调试就好了,以后试试吧;

 

顺便提一下,CpythonDoc目录下有这样的解释



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


results in an UnboundLocalError:


   >>> foo()
   Traceback (most recent call last):
     ...
   UnboundLocalError: local variable 'x' referenced before assignment


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.  Since the last statement in foo assigns a new value to
``x``, the compiler recognizes it as a local variable.  Consequently when the
earlier ``print(x)`` attempts to print the uninitialized local variable and
an error results.





原创粉丝点击