python中的全局变量和局部变量
当你在用python封装一个函数时,遇到了下面这样的情况
# 记骰子的点数
total = 0
def roll_dice(n=2): # 可以设计默认值为2
for _ in range(n):
total += randint(1,6)
return total
result = roll_dice(6)
print(result)
初略一看,代码没什么问题,但是一运行,给你一个大大的UnboundLocalError:
UnboundLocalError: local variable ‘total’ referenced before assignment
意思是 “局部变量total在赋值前被引用”
也就是说,total这个变量还没有给它赋值,我们就引用它了。那为什么会这样呢?这是因为我们在初始化total时并不是在函数体中初始化的,是在函数外定义的,这样做的结果就会让系统在函数体中执行代码时找不到total的初始值,所以它认为你没有定义过total。
但有时我们并不想在函数体内定义它,就行用函数外的变量
解决方法:在函数体中的变量total前global关键字,如下:
# 记骰子的点数
total = 0
def roll_dice(n=2): # 可以设计默认值为2
global total # global关键字加在这里
for _ in range(n):
total += randint(1,6)
return total
result = roll_dice(6)
print(result)
这样做后就可以正常运行了。
问题倒是解决了,但是为什么要这样做呢?
如果你是来解决问题的,那你可以走了,如果是来学习的,请看完本文。
全局变量和局部变量
一般来说,在函数体外定义的变量叫全局变量
,而在函数体内定义的变量叫做局部变量
,C语言中也称为内部变量,而局部变量只能在这个函数内部使用,全局变量则是可以作用到整个文件(模块)的范围。
在使用局部变量和全局变量时,下面几点是需要格外注意的:
-
1.局部变量只能在这个函数内部使用,全局变量则是可以作用到整个文件(模块)的范围
-
2.在python程序中搜索一个变量按照LEGB顺序进行搜索的
是这样的顺序:
Local(局部作用域)———> Embeded(嵌套作用域)——>Global(全局作用域)——>Built-in(内置作用域)——>NameError :name… not defined
如:
x = 100 # 全局变量X
def foo():
x = 200 # 嵌套作用域的局部变量X,函数foo中又嵌套了bar函数
def bar():
x = 300 # 局部变量x
print(x)
bar()
print(x)
foo() # 先思考以下输出结果是什么
print(x) # 这里输出什么呢?
输出结果
300
200
100
也就是说,它是这样变量x是这样找的
那么,现在改一下,现在又输出什么呢?
x = 100 # 全局变量X
def foo():
# 嵌套作用域的局部变量X,函数foo中又嵌套了bar函数
def bar():
# 局部变量x
print(x)
bar()
print(x)
foo() # 先思考以下输出结果是什么
print(x) # 这里输出什么呢?
输出结果
100
100
100
可知,他的搜索顺序是这样的:
若在全局范围域还是没有找到,就看是不是python内置的变量名,若都没有找到就返回
NameError: name ‘x’ is not defined这样的异常,意思是说,x这个名字是没有被定义的
那么知道这样的搜索顺序之后,第三点是
- 3.如过在函数体中要使用全局变量请使用关键字global,如
x = 100
def foo():
# 如果我不想在函数foo中定义局部变量x,想直接使用全局变量x,应该怎么做???
global x
x = 200 # 使用全局变量后,这里重新赋值,全局变量的值也就等于了现在的200
def bar():
x = 300
print(x)
bar()
print(x)
foo() # 输出300,200
print(x) # 输出200
- 4.不想在函数bar中定义局部变量x,想直接使用嵌套作用域中的x
这时候使用nonlocal关键字,如
x = 100
def foo():
x = 200
def bar():
# 如果我不想在函数bar中定义局部变量x,想直接使用嵌套作用域中的x,应该怎么做???
nonlocal x
x = 300
print(x)
bar()
print(x)
foo() # 300,300
print(x) # 100
好了,这下知道为什么文章开头那样会报错了吧!
如果对你有帮助,不要忘记点赞、关注、评论加收藏哦!