PYTHON 中使用 GLOBAL引发的一系列问题

哪里出问题了

  python 中,使用 global 会将全局变量设为本函数可用。同时,在函数内部访问变量会先本地再全局。

  在嵌套函数中,使用 global 会产生不合常理的行为。

  上代码:

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

  而在函数 x() 中,没有用 global,此时的b使用本地。所以 print 会打印本地 b

  为什么会打印 12 ?还有 In[101]的 b 为 2 该怎么解释?

  y(),使用的 global 竟然没把 x() 的 b = 12 导进来。

  在函数 y() 中,语句 global a,b 使a,b扩展为全局,所以,在最高层,就算没有 b(In[98]),也会产生 b(In[101])。

  也就是说, global a,b ,会认为 a 和 b 是最外层的变量。

  再试一下:

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

  报错了! y() global b 后没赋值,顶层就没有 b。这说明,global 只是引入名称,并不做赋值等操作。

  global 不会管变量存不存在,只导入名称,对该名称的操作会反应到 ‘最高层名称空间‘。

  再来:

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

   这就确定了 内层y() 的 global 不会 导入 x() 的东西。

   那么,内层函数怎么使用正确的外层函数的变量呢?

解决内层函数参数传递问题

  一、

  首先,若只是取值,则不需要做任何处理。

In [119]: def x():

.....: a = 12

.....: def y():

.....: print a

.....: y()

.....:

In [120]: x()

12

In [121]:

  在 y() 中,一旦为 a 赋值,a 立马变内部变量。

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

  一旦在函数 y() 的某处给 a 赋值,则在赋值前,python 会认为 a 不存在。

  同时发现 python2 的 print 会一个一个的 输出。鉴于此,我又在 python3 中试了,发现他是 一起输出。但这不是本文重点,折叠之。

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

同时发现 python代码运行前 会先扫一遍代码的,而不是单纯的一行一行的执行。

  同时发现返回 UnboundLocalError,而不是 NameError。注意到 'unbound‘,这是官方概念。用 'unbound‘ 来描述就是:global 会将顶层变量名称 绑定 到本地变量名称,同时变化,是为 '引用‘;python 检测到 a = 1时,意识到 a 是本地的,所以 在 a '指向一个对象‘(因为python变量均为引用),之前 ,调用 a 是非法 行为,但这种行为区别于于 NameError,就定义为 unbound local。

  二、

  使用 可变变量,如 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

  没有报错,完美!

  要注意 语句 l[:] = ["out msg"] ,使用切片赋值,否则,

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

  又出 UnboundLocalError 了,因为 第六行代码 为 l 分配了 一个新的 list。

  三、

  利用参数传递。

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

  注意,不要在默认参数上放 list等可变对象。

以上所述是小编给大家介绍的PYTHON 中使用 GLOBAL引发的一系列问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是 PYTHON 中使用 GLOBAL引发的一系列问题 的全部内容, 来源链接: utcz.com/z/320219.html

回到顶部