侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

Python  /  管理员 发布于 7年前   227

哪里出问题了

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

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

  上代码:

In [96]: def x():b = 12def y():global a,ba = 1b = 2y()print "b =",b....: In [97]: a = 111In [98]: del bIn [99]: x()b = 12In [100]: aOut[100]: 1In [101]: bOut[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 = 12def y():global a,ba = 1y() print "b =",b.....: In [103]: a = 111In [104]: del bIn [105]: x()b = 12In [106]: aOut[106]: 1In [107]: b---------------------------------------------------------------------------NameError Traceback (most recent call last)<ipython-input-107-3b5d5c371295> in <module>()----> 1 bNameError: name 'b' is not defined

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

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

  再来:

In [109]: a = 111In [110]: del b---------------------------------------------------------------------------NameError Traceback (most recent call last)<ipython-input-110-745f2abe7045> in <module>()----> 1 del bNameError: name 'b' is not definedIn [111]: def x():b = 12def y():global a,ba = 1print by()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 = 16 print b----> 7 y()8 print "b =",b9 <ipython-input-111-c05fc67a1e82> in y()4 global a,b5 a = 1----> 6 print b7 y()8 print "b =",bNameError: global name 'b' is not defined

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

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

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

  一、

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

In [119]: def x():.....: a = 12.....: def y():.....: print a.....: y().....: In [120]: x()12In [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 = 16 print "then a =",a----> 7 y()8 <ipython-input-121-d8fbc0dba399> in y()2 a = 123 def y():----> 4 print "before a =",a5 a = 16 print "then a =",aUnboundLocalError: local variable 'a' referenced before assignment

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

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

In [7]: def x():a = 1def y():print("before a=",a)a = 10print("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 = 10print("then a=",a)----> 7 y()<ipython-input-7-6e01e7317b24> in y()a = 1def y():----> 4 print("before a=",a)a = 10print("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 msgout msg

  没有报错,完美!

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

In [129]: def x():l = ["in msg"]def y():msg = l[0]print "msg =",msgl = ["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 =",msg6 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 =",msg6 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使用str & repr转换字符串
    下一条:
    CentOS 6.X系统下升级Python2.6到Python2.7 的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客