It's all right to understand
. But I want to talk about the reasons for this. Before explaining the reason, you need to know the search order of variables in python, which is LGB
(regardless of closures), that is, local local, global global, and builtin built-in. For example:
a = 1
def test():
a = 3
print(a)
test()
The local variable
a
is declared in the
function, which is used in printing and hits in the local environment, so 3 is used.
maybe you will ask this knowledge point I already know, what does this have to do with this question?
Yes, don't you think it's strange? The error is that the variable is not initialized, not that the variable is undefined.
within the function c = center1
in the topic, it has been indicated that the declared variable c belongs to a local variable. In theory, execute the right side of the assignment statement first, but c is not declared at this time and should be hit in the global environment. So the imaginary result should be the local variable c = 2
while the global variable c keeps its original value.
but it's all taken for granted. Having said so much, I actually want to point out that although python is a dynamic statement, it still scans the code and collects useful static information. The information of the function is placed in the code
object, which contains a collection of local variable names, which can be obtained by co_varnames
, as follows:
c = 1
def test():
c= c+1
a = 3 -sharp
print(c)
print(test.__code__.co_varnames) -sharp ('c', 'a')
therefore, variable c is declared in the local variable environment before the function test is executed, rather than what we think it will be in the local variable after the assignment statement runs. As a result, the error message is that the variable is uninitialized rather than the variable is undefined.
= split line =
subject comment requirements:
can you help us understand the initialization, definition and creation of variables?
these three meanings are basically the same, there is no need to separate them too much. It is easy to understand the variable environment as a dictionary name_env = dict ()
(in fact, the underlying python does handle it this way). To create a variable named a
in this environment, it can be in the form of name_env ['a'] = value
.
this process means that the assignment instruction STORE_NAME
is called when the assignment statement looks like a = value
. Let's take a look at the assignment process and you'll understand.
this code is found in ceval.c
. For more information, please see python/cpython/blob/master/Python/ceval.c-sharpL2019" rel=" nofollow noreferrer "> ceval.c
.
TARGET(STORE_NAME) {
PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
PyObject *ns = f->f_locals;
int err;
if (ns == NULL) {
PyErr_Format(PyExc_SystemError,
"no locals found when storing %R", name);
Py_DECREF(v);
goto error;
}
if (PyDict_CheckExact(ns))
err = PyDict_SetItem(ns, name, v);
else
err = PyObject_SetItem(ns, name, v);
Py_DECREF(v);
if (err != 0)
goto error;
DISPATCH();
}
There is not much
code, so you can analyze the name
one by one. The a = value
of the assignment statement exists in the form of python type str
. The second line v
is taken from the stack, that is, the value of value
. The third line ns
is to get the local variable environment from the frame object (mostly a dictionary type, if the frame environment is not in a function or class, the global variable environment is obtained). PyDict_SetItem (ns, name, v);
and PyObject_SetItem (ns, name, v);
can be understood as ns [name] = v
and setattr (ns, name, v)
. This is the creation process.
The underlying layer doesn't care whether the
variable creates, initializes, or overrides the value of an existing variable.
back to the local, the symbol table of the local variable will be saved in the static information. I guess when searching for the variable, it is preferred to get the information from the static information to know more quickly whether the variable should be found locally or globally.
No problem to understand
it is possible to print Category 1 directly.
c = 1
def test():
print(c+1)
test()
2
using golbal will cause global variables to change
c = 1
def test():
global c
c = c + 1
print(c)
test()
print(c)
2
2
- Internal functions do not modify Global variables can access global variables
- Internal function modifies a global variable of the same name, then
python
will consider it to be a local variable
that is, if you modify the global variable assignment in the function, Unbound-LocalError
.
Note: this is true not only for global variables , but also for all child scopes of parent scope, such as nested functions.
of course, you can declare that variable is global with global
.
function scope problem, because c + = 1 c is a local variable within the function, there will be c undefined.
the same variable in the same scope cannot come from two scopes.
c = c + 1. It is not possible to require the left and right sides of the equal sign to come from different scopes.
code cannot be heterosexual