大爽Python入门教程 6-2 变量进阶 局部变量`local`与全局变量`global`
大爽Python入门公开课教案 点击查看教程总目录
1 定义
这里来看一个例子。
不妨猜一下这个输出是多少。
def change_local(x):
x += 1
x = 5
change_local(x)
print(x)
答案是
5
这个例子中,函数内部的改动,没有对函数外部生效。
这是因为函数内部的x
和函数外面的x
其实是两个。
函数外面定义的,是全局(global
)变量。
函数里面定义的,是局部(local
)变量。
在python中,局部变量和全局变量的定义差不多就是这样。
把上面的代码这么来写,应该就很容易看懂了
def change_local(local_x):
local_x += 1
gloabl_x = 5
change_local(gloabl_x)
print(gloabl_x)
2 作用域
什么是作用域?
可以简单理解为,能生效的范围,
或者说能使用能调用的范围。
之前讲过,变量要先声明后调用,
在声明之前调用,会报错
NameError: name 'var' is not defined
其中var
是调用的变量名
局部变量
局部变量的作用域是在函数内,
即在函数内能调用(先声明后调用),
函数外调用会报错NameError
。
示例如下
def create_local():
x = 1
create_local()
print(x)
报错如下
NameError: name 'x' is not defined
全局变量
全局变量的作用域是整个程序(目前可以简单理解为整个代码文件),
即在所有位置都能调用(先声明后调用),
也包括函数里面
x = 10
def use_global():
print(x)
use_global()
输出为
10
x
的声明放在函数声明之后都是可以的,只要保证在调用之前就先行。
def use_global():
print(x)
x = 10
use_global()
此时输出也是10
x
的声明放在函数调用之后则不行,会报错,如下
def use_global():
print(x)
use_global()
x = 10
会报错
NameError: name 'x' is not defined
优先级
函数中,有同名的全局变量和局部变量时,
优先使用局部变量。
示例如下
def use_who():
x = 5
print(x)
x = 10
use_who()
输出如下
5
3 修改全局变量
在函数外,修改全局变量很简单,
即正常的修改或赋值。
函数内如何修改全局变量呢,
或者说让函数内的修改在函数外生效。
函数内可以调用全局变量,但是不能直接修改,
直接修改要么不会生效,要么会报错。
不生效
x = 20
def invalid_change():
x = 10
invalid_change()
print(x)
x = 20
def invalid_change(x):
x = 10
invalid_change(x)
print(x)
两段代码输出都是20
。
这个现在大家应该能理解。
简单来讲,就是在函数内部使用的x,
其声明是在函数内部的,是局部变量,
正确方法
def change():
global x
x = 20
x = 10
change()
print(x)
输出如下
20
即在本来使用局部变量的函数区域内,
使用global
进行全局变量声明,则此时的调用和修改是在全局上生效的。
注意: 可以认为只有这个写法。
此时不能通过函数传参x
了,此时会报错SyntaxError
示例如下
def change(x):
global x
x = 20
x = 10
change(x)
print(x)
报错
SyntaxError: name 'x' is parameter and global
参数会和全局变量声明冲突
4 直接修改报错探究
偏难,属于探究内容
直接修改报错
那么如果不声明,直接在函数内部先调用全局变量并修改呢。
x = 20
def wrong_change():
x += 1
wrong_change()
print(x)
其报错如下
UnboundLocalError: local variable 'x' referenced before assignment
这个错误现在看英文,比较难理解。
换个写法还报错
我们换个写法,并逐步分析。
x += 1
可以换成 x = x + 1
。
x = 20
def wrong_change():
x = x + 1
wrong_change()
print(x)
此时仍然报错UnboundLocalError
,和上面一样。
拆开执行不报错
那么把赋值符号两边的拆开执行看看。
x = 20
def wrong_change():
print(x+1)
wrong_change()
这个能执行,输出为21
x = 20
def wrong_change():
x = 20 + 1
wrong_change()
这个也可以执行,无输出(未print
)
合到一起再报错
但是将这两个合到一起,就无法执行了。
即如下
x = 20
def wrong_change():
print(x+1)
x = 20 + 1
wrong_change()
会报错
UnboundLocalError: local variable 'x' referenced before assignment
这是为什么呢?
原因
因为函数里面这个x
只能有一个意义,或者说一个身份。
它可以是全局变量(此时不是局部),也可以是局部变量(此时不是全局)。
但它不能同时都是,不能一个函数里面,
第一行的x
是全局变量,第二行的x
是局部变量。
再回来看报错,这种冲突情况下,
会认为x
是局部变量,所以错误在于赋值之前进行调用。
5 练习实践
要求
使用全局变量实现简易计数功能
具体为在控制台中
能够输出Count num
(初始值设定为10)
输入一个w
, Count num
增加1
输入一个s
, Count num
减少1
输入一个e
, 退出
输入其他字符不处理。
可以一次输入多个字符串,从前往后按上面的逻辑处理
运行效果如下
COUNT NUM: 10
input: w
COUNT NUM: 11
input: w
COUNT NUM: 12
input: s
COUNT NUM: 11
input: www
COUNT NUM: 14
input: ss
COUNT NUM: 12
input: e
BYE
框架
def increase_count():
pass
def decrease_count():
pass
def main():
count = 10
while True:
print("COUNT NUM: %s" % count)
s = input("input: ")
for c in s:
# handle
pass
main()
答案
要点说明:
- 如果在函数外部声明过全局变量,函数内部就可以
global
调用并修改。 - 函数内部使用了局部变量之后,不能对局部变量使用
global
。就是说,如果函数内部想添加全局变量,必须先声明后赋值(语句还不能合并)。
def increase_count():
global count
count += 1
def decrease_count():
global count
count -= 1
def main():
global count
count = 10
while True:
print("COUNT NUM: %s" % count)
s = input("input: ")
for c in s:
if c == "w":
increase_count()
elif c == "s":
decrease_count()
elif c == "e":
print("BYE")
return
main()