本节内容
- 概述
- 课前前引
- 局部变量和全局变量
- 总结
一、概述
我们之前写代码,都需要声明变量,但是我们思考过变量的作用范围吗?今天我们就来讲讲变量的作用范围,这个作用范围又叫作用域。首先我们根据变量的作用范围把变量分为:局部变量和全局变量,即:
- 局部变量
- 全局变量
二、课前前引
我们先做一个小实验:一个函数体内部调用另外一个函数,代码如下:
def test(name,age=28,**kwargs): print(name) print(age) print(kwargs) logger("test") #调用logger函数 def logger(sounce): print("from %s"%sounce)
①logger函数之后执行
def test(name,age=28,**kwargs): print(name) print(age) print(kwargs) logger("test") def logger(sounce): print("from %s"%sounce) test("luoahong",age=28,sex="L",hobby="tesla") #在logger函数之后调用 #输出 luoahong 28 {'hobby': 'tesla', 'sex': 'L'} from test
ok,很完美,一点问题都没有,那么还有一种情况,就是在logger函数之前调用呐?
②logger函数之前执行
def test(name,age=28,**kwargs): print(name) print(age) print(kwargs) logger("test") test("luoahong",age=28,sex="L",hobby="tesla") #在logger函数之前调用 def logger(sounce): print("from %s"%sounce) #输出 luoahong 28 {'hobby': 'tesla', 'sex': 'L'} Traceback (most recent call last): File "D:/PycharmProjects/pyhomework/day3/局部变量和全局变量/test.py", line 12, in <module> test("luoahong",age=28,sex="L",hobby="tesla") File "D:/PycharmProjects/pyhomework/day3/局部变量和全局变量/test.py", line 10, in test logger("test") NameError: name 'logger' is not defined #命名错误:logger没有被定义
很显然是出错的,为什么呢?我不是定义了logger函数了吗?喔。。。。。。原来在logger函数之前执行,logger函数还没有被读到内存中,所以报错。
三、局部变量和全局变量
1、局部变量
局部变量:顾名思义,指在局部生效,定义在函数体内的变量只能在函数里面生效,出个这个函数体,就不能找到它,这个函数就是这个变量的作用域。
下面我们就用事实说话吧,请看如下代码:
def test(name): print("before change:",name) name = "luoahong" #局部变量name,只能在这个函数内生效,这个函数就是这个变量的作用域 print("after change:",name) name = "luoahong" print("-----调用test-----") test(name) print("------打印name----") print(name) #输出 -----调用test----- before change: alex after change: luoahong #局部变量生效 ------打印name---- alex
2、全局变量
有了局部变量,那就肯定有全局变量,那什么是全局变量呐?全局变量又改怎么定义呢?
全局变量:指的是在整个程序中都生效的变量,在整个代码的顶层声明。
代码如下:
school = "leidu edu" #定义全局变量 def test_1(): print("school:",school) def test_2(): school = "luoahong python " print("school:",school) print("------test_1----") test_1() print("------test_2----") test_2() print("----打印school--") print("school:",school) #输出 ------test_1---- school: leidu edu #打印的是全局变量 ------test_2---- school: luoahong python #打印局部变量 ----打印school-- school: leidu edu #打印全局变量
从上面的例子可看出全局变量的优先级是低于局部变量的,当函数体内没有局部变量,才会去找全局变量。但是有的同学会问了,那我需要在函数体内修改全局变量咋办呢?
①函数里面修改全局变量
- 改前用global先声明一下全局变量
- 将全局变量重新赋值
school = "leidu edu" #定义全局变量 def test(): global school #用global关键字声明全局变量 school = " luoahong python " #将全局变量重新赋值 print("school:",school) print("------test_2----") test() print("----打印school--") print("school:",school) #输出 ------test_2---- school: luoahong python ----打印school-- school: luoahong python #全局变量被改掉
②只在函数里面声明全局变量
def test(): global school #只在里面定义全局变量 school = "luoahong python" print("school:",school) print("--------test-------") test() print("-----打印school----") print("school:",school) #输出 --------test------- school: luoahong linux -----打印school---- school: luoahong linux
也是可以的,但是我们最好不要用以上2种情况,也就是说最好不要用global这个关键字,因为你用了,其他人调你的函数时,就乱套了,而且还不好调试,说不定还冒着被开除的危险,所以请大家忘记它吧,只是知道有这么一个东西就行了。
③修改列表
names = ['alex',"luoahong"] #定义一个列表 def test(): names[0] = "金角大王" print(names) print("--------test-----") test() print("------打印names--") print(names) #输出 --------test----- ['金角大王', 'luoahong'] #函数内的names输出 ------打印names-- ['金角大王', 'luoahong'] #函数外的names输出
从上面的例子可以看出,列表names被当做在函数中全局变量,重新赋值了,是可以被修改的。
小结:
1、只有字符串和整数是不可以被修改的,如果修改,需要在函数里面声明global。
2、但是复杂的数据类型,像列表(list)、字典(dict)、集合(set),包括我们后面即将要学的类(class)都是可以修改的。
四、总结
- 在子程序(函数)中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量。
- 全局变量的作用域是整个程序,局部变量的作用域是定义该变量的子程序(函数)。
- 当全局变量和局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其他地方,全局变量起作用。