设为首页收藏本站
查看: 64|回复: 0

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

[复制链接]

论坛元老

Rank: 6Rank: 6

积分
34274
主题
17031
UID
1347
M币
67
贡献
17176

  • 发表于 2017-5-14 02:44:00 | 显示全部楼层 |阅读模式
    哪里出问题了
      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) in () ----> 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) in () ----> 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) in () ----> 1 x() in x() 5 a = 1 6 print b ----> 7 y() 8 print "b =",b 9 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) in () ----> 1 x() in x() 5 a = 1 6 print "then a =",a ----> 7 y() 8 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) in () ----> 1 x() in x() a = 10 print("then a=",a) ----> 7 y() 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) in () ----> 1 x() in x() 5 print "msg =",msg 6 l = ["out msg"] ----> 7 y() 8 print l[0] 9 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引发的一系列问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    在我站开通SVIP可同时获得17个站点VIP资源 立即登录 立即注册
    快速回复 返回顶部 返回列表