当前课程知识点:Python 交互式程序设计导论 > 第2周 > B 课程视频(输入框、全局变量) > 局部变量和全局变量
返回《Python 交互式程序设计导论》慕课在线视频课程列表
欢迎回到Python交互式程序设计课程中
今天我们要研究一个非常重要的问题
全局变量和局部变量
所谓的全局和局部其实是描述变量的作用范围
这个概念在程序设计中是极其重要的
好 下面我们开始今天的内容
为了能让同学们直观的认识和理解
局部和全局这两个概念
我先来举个例子
我们每个人一出生会被赋一个编号
这个编号呢叫身份证号
在你的一生 在中华人民共和国的范围内
这个身份证号都是合法有效的
那么同学们今年9月份迈入新疆农业大学的大门
你们又被赋予了一个新的编号
我们称之为学号
那么这个学号仅仅是在你大学四年或者五年
在新疆农业大学的范围内它是合法有效的
那么显然 学号和身份证号对我们每个人来讲
它的作用范围是不同的
或者说作用域 或者是有效范围是不同的
下面我们来看一个例子
在左边这个程序中变量x和y的作用范围是一样的么
我们来看一下分析一下这几行代码
首先我们定义了一个变量x赋予了值是1
然后又定义了一个函数 这个函数的名叫fun1()
f u n 1
在这个函数里面我们定义了一个变量叫y
y的值是2
然后用print输出语句对x的值和y的值进行输出
分别得到的是x是1 y等于2
好 那么第三部分呢
是我们调用这个fun1()这个函数
然后又重新写了print x和print y这两条语句
这个程序大家看一看有没有问题
我在右边已经列出了它可能出现的错误
这个错误呢是y这个变量是没有被定义的
怎么理解
我们再回过头来看一下这个程序
这个fun1()里面定义了一个变量y
它的值是2
但它并没有定义x
为什么在function里面可以调用x呢
是因为这的x是在
所有函数体外部定义的一个全局变量
它的含义是在整个程序中这个x都是合法有效的
这叫全局变量他的作用域是全局的
所以在fun1()这个函数体内部
即便你没有定义x我也可以调用x
它指的是这个全局变量x
而在函数体外部
大家看一下
你调用fun1()
它可以输出x和y的值没有问题
你调用x 它也会找到这个全局变量x 也没问题
但是第三句 你又调用了y这个变量
y这个变量大家看是在哪定义的呢
是在function函数体内部定义的
也就意味着这个y仅仅是在fun1()
这个函数体内部有效
一旦出了这个范围
这个y实际上是非法的无效的
所以你在函数体外部的这条输出语句调用y这个变量
在程序中实际上是无法找到y变量的
所以它会报这样一个错误
y是没有被定义的
出错的是哪一行呢
同学们应该能看得到
实际上是最后一行
因为你在这个地方调用的y是在一个函数内部定义的局部变量
而它的生存周期或者作用范围仅仅局限于这个函数内部
一旦出了这个函数内部这个y就是无效的非法的
所以这句话报错了
那么从这个例子上我们可以看出
实际上全局变量是指的在所有函数外部定义的这个变量
这个变量的作用域是全局的
在整个程序中是有效的
那么局部变量是在某个函数体内部定义的变量
它的作用域或者作用范围仅限于函数体内部
一旦出了这个函数
那么这个变量是无效的或者说未定义的
好 用比较准确的语言来定义下局部变量和全局变量
我们首先来看一下局部变量
定义在某个函数体内部的
作用域仅限于该函数体内部
函数结束 局部变量就消亡了 就不存在了
就像大家 大学毕业了
你的学号就消亡了 就不存在了
对你来讲就没有意义了
全局变量 定义在所有函数体外部
作用域为整个程序
程序中各个函数都可以共享
这就像大家的身份证号一样
不管你到哪个单位
不管你在人生的哪个阶段
这个身份证号都会伴随你一生
在中华人民共和国的范围内都是合法有效的
这就是全局的
好 我们来看一个具体的例子
看看同学们能不能理解全局变量和局部变量的区别
左边这个程序非常简单 一共也就6行
同学们来看一下输出的结果是什么呢
我们来看一下 分析一下
首先定义变量x=1
然后又定义了一个函数叫fun1()
在fun1()里面我又定义了一个变量x=2
然后显示这个x
好 疑问一 这个x指的哪个x
好 再往下看
调用了fun1()这个函数
紧接着我又执行了一遍输出语句
再输出这个x
那么这个x又指的哪个x呢
好 梳理一下
在整个程序中有两个变量叫x
一个在这里定义的x=1
另外一个是在function内部定义的x=2
有两个变量
同时又有两个输出语句
一个是输出x变量
另外一个是在函数外部输出x变量
现在的问题是这里的x指的是1这个x还是2这个x
这里的x又是对应的哪个x呢
好 大家看一下
在function函数体内部你定义了一个x
而恰恰有一个全局变量也是x
这个时候局部变量会屏蔽同名的全局变量
换句话说
在函数体内部这个局部的变量x会覆盖全局变量
这个时候呢这里的x显示的是2
于是我们就会看到x=2这个结果
那么在函数体外部你输出一个x
这个x只可能对应这个全局变量x
因为它压根就不知道局部变量x的存在
因为它的生存周期仅仅是在function内部
所以这个x一定会对应x=1这个x
所以x=1
总结一下
在函数体内部 如果出现了一个局部变量
它跟一个全局变量同名的话
那么它会屏蔽这个同名的全局变量
换句话说在函数体内部
如果出现一个与全局变量同名的局部变量
它会把全局变量给遮盖掉
在函数体内部的代码中全部显示的是这个局部变量
这个是需要大家注意的
当然尽可能在我们的编程过程中
不要定义与全局变量同名的局部变量
这样可能会引起一个混乱
起码使得你的程序不易阅读
好 下面一个问题我们来研究
如何修改全局变量
全局变量大家都知道是定义在所有函数体外部的
那我如果在函数体的内部我想修改它的值
怎么做呢 大家看
必须要用global这个关键字对全局变量进行说明
然后我们才能对它进行合法有效的修改
那我们来看一下这个程序执行结果是不是我这里列出的2
我们来看
首先定义一个全局变量x=1
在function里面我们说明这个x是一个global
这是全局的全球的意思
表示我下面要提到的x是指的全局变量的x
不是我另外定义的局部变量
那这个时候呢这个x就指代的全局变量x
然后我把这个x的值重新赋为2
好 实际上这就已经修改了全局变量
那么当然 这里打印的print这个函数
打印出来的x的值当然是2
那么此外 在函数外部打印的这个x
它打印的也是这个全局变量x
因为这个全局变量已经被修改了
所以它打印的也是新的值
总结一下
如果你想要在某个函数体内部对全局变量的值进行修改
那么就需要对x(对这个变量)
进行global的这样一个全局的声明
表示这个x是全局变量 不是新定义的局部变量
这个时候我们就可以对全局变量进行修改
看一个例子
以下程序会输出什么结果我们来分析一下
这个很短的例子只有五行代码
首先依然定义一个全局变量x=1
然后我们定义一个fun1()这个函数
这个函数里面只有一条语句
输出x
然后我们调用fun1()然后再重新输出x
好 我们来看一下
在fun1()里面我们并没有定义任何变量
那么这里所指的x就一定是全局变量的x
如果我们在这里又重新定义一个x
那这里面的x就指的局部变量x
请大家注意这一点
那么显然这句话执行的结果一定是x=1
那么在函数体外部进行x的输出呢
它当然对应的也是这个全局变量
输出的结果也是1 这个很好理解
那么我要说明的是 如果在函数体内部
你仅仅是对全局变量的访问 显示 不修改的话
是不需要用global进行显示的声明的
或者说 就不需要用global对他进行重新的声明
表示它是一个全局变量
当然 你即便加上global 空格 x这个声明呢
也不会报错 是一样的效果
有两点问题需要大家格外留意一下
也是我们在不断的实践当中总结的一些经验
第一点
函数间数据共享使用全局变量是最简单的方法
大家可以想象 我定义一个全局变量
所有函数都可以使用
而且都可以通过global这样的声明对他进行修改
是非常容易的
但是全局变量不能滥用
否则的话就会随着程序规模的增大
出现很多的混乱 不易调试
尤其作为初学者
你程序规模越大 你就越难驾驭的了
第二点 定义局部变量的时候
应该尽量避免与全局变量同名
以免引起不必要的混乱
虽然这种语法是合法的
但是这不是一个好的实践
好 下面呢 我们会在pycharm的环境当中给大家做一个演示
打开pycharm
我在test.py这个文件中呢
已经把三个示例的代码输入进去了
为了节约时间
好 下面呢 我们逐一讲解
首先来看示例1
在课件中已经提到了一个例子
来看一下
定义一个全局变量x=1
然后定义一个函数叫fun1()
在函数体内部呢定义了一个变量叫y=2
这个变量显然是一个局部变量
然后输出x和y的值
这是定义的部分
那么程序从哪开始执行呢
调用fun1()当然会输出x和y的值
然后调用完以后 我又重新输出x和y的值
我们运行一下
好 报错了 报什么错呢
在第12行报错
错误是name y 就是y这个名字或者这个变量啊
是一个没有定义的
实际上细心的同学已经看到
在我们示例1里面
这个y的下面已经被波浪线给标示出来了
表明此处有问题
这就是给大家讲的什么呢
局部变量的作用域仅仅局限在这个函数体内部
一旦出了这个函数体
那么在外部想调用局部变量
就会产生这样的错误
好 我们来看一下
这个y是一个局部变量
所以你在这个函数内部调用x 它调用的是全局变量
这个y呢是局部变量
OK 这两句话当然都是正确的
那么在这个函数的外部
你再要调用x
它依然指向的是这个x 全局变量
那么你再想调用y就存在问题了
因为这个y程序并不知道它的存在
这个y出了这个函数它已经消亡了
所以此处会报错
这就是示例1 我们课件中提到的
好 把这是示例呢我们把它注释一下
下面我们来看示例2
我们首先呢 运行一下
看结果x=2 x=1
好 我们来看为什么会有这样的结果
定义一个全局变量x=1
然后定义了一个函数叫fun1()
在fun1()里面我又定义了一个变量x
注意这个x下面也有波浪线只是很淡的波浪线
它表明呢这个x呢可能也有些问题
什么问题呢
实际上这个局部变量的命名
跟这个全局变量已经发生了重名
那么看
这个print语句打印出来的x
指的是全局的x呢还是局部的x呢
当然是局部的
就近 它是输出的局部的这个x
所以这个x是2
那么出了这个函数以外
这句话在函数体外部再调用x调用的当然是全局的x
所以这个x输出的是1
这个示例2说明什么呢
当函数体内部有与全局变量同名的局部变量的时候
这个局部变量在函数体内部会屏蔽这个全局变量
也就是说在函数体内部
以局部变量优先
函数体外部是无法调用这个局部变量的
它只能调用外部的全局变量
这是我们示例2说明的问题
下面我们来看是示例3
示例3呢我要说明一个问题是如何修改全局变量
好 我们来看一下
首先运行一下
答案是x=2 x=2
怎么理解呢 大家看
我定义了一个全局变量x
在function这个函数里面
我用global来声明这个x是一个全局的
注意 这句话可不是重新定义一个变量x
这句话是说我这想用一个变量叫x
这个x不是我重新定义的
它是一个global
系统会自动找到你找的是这个x
于是下面的这两个操作呢
其实都是针对全局变量x的
于是在这呢我们会把全局变量的x的值变成2
在这输出一次x
它当然是2了
那么在函数外部
又输出了一次x呢
它的结果也是2
我们在这呢做一个小的测试
如果我不要这个
好 大家看一下
我不要这个global x 的这个声明
大家想 结果应该是多少
运行一下
结果是2和1
什么意思呢 大家看一看
实际上这就相当于示例2了
在fun1()当中
这句话相当于我重新定义了一个局部变量叫x
所以你这句话输出的就是x=2
但是出了fun1()这个函数以外
这句输出语句的x他只会找到全局变量的x
所以这个x依然保持这个x最早的值1
输出x=1
那么示例3是要告诉大家
如果我想在函数内部修改一个全局变量
一定要记得要用global这个关键字对它进行声明
只要声明过后
那么下面这些语句针对的全都是全局变量x
好 今天的课程就讲到这里
-课程简介
--课程简介
-A 课程视频(算数操作符及表达式)
--绪论
-B 课程视频(变量及赋值)
--变量
--项目提交
-C 辅助视频(计算机结构、Python开发环境安装)
-D 辅助视频(如何提交项目)
--项目提交
-第0周--小测验
-本周项目:"我喜欢Python"
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
--项目提交
-A 课程视频(函数)
--函数
--其它操作符
--随机函数
-B 课程视频(逻辑及表达式)
--逻辑值和比较
--条件
--编程技巧
-第1周--小测验
-本周项目:“老虎杠子鸡虫”游戏
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(Python交互式应用)
--事件驱动编程
--按钮
-B 课程视频(输入框、全局变量)
--输入框
--编程技巧
-第2周--小测验A
-第2周--小测验B
-本周项目:猫咪藏在哪个房间
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(画布绘图)
--画布和图形绘制
--字符串处理
--图片和音效
-B 课程视频(计时器)
--计时器
--交互式绘图
--“神奇时钟”游戏
--编程技巧
-第3周--小测验A
-第3周--小测验B
-本周项目:“神奇时钟”
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(列表)
--列表
--键盘输入
--碰撞和反射
-B 课程视频(键盘控制)
--速度控制
--运动
--编程技巧
--“桌上冰球”游戏
-第4周--小测验A
-第4周--小测验B
-本周项目:“桌上冰球”游戏
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(鼠标输入、列表进阶)
--鼠标输入
--Video
--Video
--Video
-B 课程视频(字典和图片)
--Video
--Video
--Video
--Video
-第5周--小测验A
-第5周--小测验B
-本周项目:“世界杯八强连连看”
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(类)
--华容道中的类
-B 课程视频(平铺图片)
--平铺图片
--理解对象
--编程技巧
--“华容道”游戏
-第6周--小测验A
-第6周--小测验B
-本周项目:“华容道”游戏
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(类进阶及文件操作)
--集合
--文件操作
--文字块类
--处理停止的文字块
-B 课程视频(游戏状态控制)
--游戏记分规则
--编程技巧
-第7周--小测验A
-第7周--小测验B
-本周项目:决战三字经
--游戏说明
--程序说明
--编程步骤
--评分标准
--项目模板
-A、课程视屏(精灵集合)
--Video
--精灵类
--战士类
--编程技巧
-B、课程视屏(动画)
--精灵碰撞
--精灵动画
--编程技巧
--保卫家园游戏
-第8周--小测验
-本周项目:守卫家园
--游戏说明
--程序说明
--编程步骤
--评分标准
--项目模板