Home  >  Article  >  Backend Development  >  A series of problems caused by using GLOBAL in PYTHON

A series of problems caused by using GLOBAL in PYTHON

WBOY
WBOYOriginal
2016-12-05 13:27:141350browse

What went wrong

 In python, using global will make global variables available to this function. At the same time, accessing variables within a function will be done locally first and then globally.

 In nested functions, using global will produce unreasonable behavior.

 Up code:

In [96]: def x():
b = 12
def y():
global a,b
a = 1
b = 2
y()
print "b =",b
....: 
In [97]: a = 111
In [98]: del b
In [99]: x()
b = 12
In [100]: a
Out[100]: 1
In [101]: b
Out[101]: 2

 In function x(), global is not used, and b at this time uses local. So print will print local b

 Why is 12 printed? And how to explain that b in In[101] is 2?

 Y(), the global used did not import b = 12 of x().

 In function y(), the statement global a,b expands a and b to global. Therefore, at the highest level, even if there is no b (In[98]), b (In[101]) will be generated.

 That is to say, global a,b will consider a and b to be the outermost variables.

Try again:

In [102]: def x():
b = 12
def y():
global a,b
a = 1
y() 
print "b =",b
.....: 
In [103]: a = 111
In [104]: del b
In [105]: x()
b = 12
In [106]: a
Out[106]: 1
In [107]: b
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-107-3b5d5c371295> in <module>()
----> 1 b
NameError: name 'b' is not defined

An error was reported! If there is no assignment after y() global b, there will be no b at the top level. This shows that global only introduces names and does not perform operations such as assignment.

 Global does not care whether the variable exists or not, it only imports the name, and operations on the name will be reflected in the ‘top-level namespace’.

Come again:

In [109]: a = 111
In [110]: del b
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-110-745f2abe7045> in <module>()
----> 1 del b
NameError: name 'b' is not defined
In [111]: def x():
b = 12
def y():
global a,b
a = 1
print b
y()
print "b =",b
.....: 
In [112]: x()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-112-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-111-c05fc67a1e82> in x()
5 a = 1
6 print b
----> 7 y()
8 print "b =",b
9 
<ipython-input-111-c05fc67a1e82> in y()
4 global a,b
5 a = 1
----> 6 print b
7 y()
8 print "b =",b
NameError: global name 'b' is not defined

 This confirms that the global of inner layer y() will not import things of x().

 So, how does the inner function use the correct variables of the outer function?

Solve the problem of inner function parameter passing

1.

 First of all, if you just get the value, you don’t need to do any processing.

In [119]: def x():
.....: a = 12
.....: def y():
.....: print a
.....: y()
.....: 
In [120]: x()
12
In [121]: 

 In y(), once a is assigned a value, a immediately becomes an internal variable.

In [121]: def x():
.....: a = 12
.....: def y():
.....: print "before a =",a
.....: a = 1
.....: print "then a =",a
.....: y()
.....: 
In [122]: x()
before a =---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-122-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-121-d8fbc0dba399> in x()
5 a = 1
6 print "then a =",a
----> 7 y()
8 
<ipython-input-121-d8fbc0dba399> in y()
2 a = 12
3 def y():
----> 4 print "before a =",a
5 a = 1
6 print "then a =",a
UnboundLocalError: local variable 'a' referenced before assignment

  Once a is assigned a value somewhere in the function y(), python will think that a does not exist before the assignment.

 At the same time, I found that python2’s print will output one by one. In view of this, I tried it in python3 again and found that it was output together. But this is not the focus of this article, so I’ll fold it.

In [7]: def x():
a = 1
def y():
print("before a=",a)
a = 10
print("then a=",a)
y()
...: 
In [8]: x()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-8-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-7-6e01e7317b24> in x()
a = 10
print("then a=",a)
----> 7 y()
<ipython-input-7-6e01e7317b24> in y()
a = 1
def y():
----> 4 print("before a=",a)
a = 10
print("then a=",a)
UnboundLocalError: local variable 'a' referenced before assignment

At the same time, I found that the python code will be scanned before running, instead of simply executing it line by line.

 At the same time, it was found that UnboundLocalError was returned instead of NameError. Note 'unbound', which is the official concept. To describe it as 'unbound': global will bind the top-level variable name to the local variable name and change at the same time, which is a 'reference'; when python detects a = 1, it realizes that a is local, so when a 'points to An object' (because Python variables are all references), before, calling a was an illegal behavior, but this behavior is different from NameError and is defined as unbound local.

  二、

 Use variable variables, such as list, dict

In [127]: def x():
.....: l = ["in msg"]
.....: def y():
.....: msg = l[0]
.....: print "msg =",msg
.....: l[:] = ["out msg"]
.....: y()
.....: print l[0]
.....: 
In [128]: x()
msg = in msg
out msg

No errors reported, perfect!

 Pay attention to the statement l[:] = ["out msg"] and use slice assignment, otherwise,

In [129]: def x():
l = ["in msg"]
def y():
msg = l[0]
print "msg =",msg
l = ["out msg"]
y()
print l[0]
.....: 
In [130]: x()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-130-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-129-d44e750e285f> in x()
5 print "msg =",msg
6 l = ["out msg"]
----> 7 y()
8 print l[0]
9 
<ipython-input-129-d44e750e285f> in y()
2 l = ["in msg"]
3 def y():
----> 4 msg = l[0]
5 print "msg =",msg
6 l = ["out msg"]
UnboundLocalError: local variable 'l' referenced before assignment

An UnboundLocalError occurs again, because the sixth line of code assigns a new list to l.

 Three,

 Use parameter passing.

In [136]: def x():
.....: a, b = 1, 2
.....: def y(a = a, b = b):
.....: a, b = 3, 4
.....: return a, b
.....: a, b = y()
.....: print a, b
.....: 
In [137]: x()
3 4

Be careful not to put variable objects such as lists on the default parameters.

The above is a series of problems caused by the use of GLOBAL in PYTHON introduced by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank you all for your support of the Script House website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn