函数进阶
楔子
1 >>> def my_max(x,y): 2 ... m = x if x>y else y 3 ... 4 >>> my_max(10,20) 5 >>> print(m) 6 Traceback (most recent call last): 7 File "<stdin>", line 1, in <module> 8 NameError: name 'm' is not defined
报错了!错误是“name 'm' is not defined”。变量m没有被定义。。。为啥?我明明定义了呀!
在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的。
从python解释器开始执行之后,就在内存中开辟了一个空间
每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。
但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。
等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
“存放名字与值的关系”的空间起了一个名字——叫做命名空间
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间,在函数的运行中开辟的临时的空间叫做局部命名空间
一、命名空间和作用域
(1)内置命名空间--Python解释器
就是python解释器一启动就可以使用的名字存储在内置命名空间中,内置的名字在启动解释器的时候被加载进内存里。
(2)全局命名空间
是在程序从上到下被执行的过程中依次加载进内存的,放置了我们设置的所有变量名和函数名。
(3)局部命名空间--函数
就是函数内部定义的名字,当调用函数的时候才会产生这个名称空间,随着函数执行的结束 这个命名空间就又消失了。
(4)三者的关系
- 在局部:可以使用全局、内置命名空间中的名字。
- 在全局:可以使用内置命名空间中的名字,但是不能用局部中使用。
- 在内置:不能使用局部和全局的名字的。
(5)栗子
1 def max(l) 2 print("in max func") 3 print(max([1,2,3]))
结果:in max func
- 在正常情况下,直接使用内置的名字。但当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字。
- 当我自己有的时候 我就不找我的上级要了。如果自己没有 就找上一级要 上一级没有再找上一级 如果内置的名字空间都没有就会报错。
- 多个函数应该拥有多个独立的局部名字空间,不互相共享。
二、作用域
- 全局作用域 —— 作用在全局 —— 内置和全局名字空间中的名字都属于全局作用域 ——globals()
- 局部作用域 —— 作用在局部 —— 函数(局部名字空间中的名字属于局部作用域) ——locals()
三、数据修改
对于不可变数据类型,在局部可是查看全局作用域中的变量,但是不能直接修改。如果想要修改,需要在程序的一开始添加global声明,如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效。
1 a=1 2 def func(): 3 global a 4 a=2 5 6 func() 7 print(a) #结果a=2
四、作业
1、写函数,接收n个数字,求这些参数数字的和。
1 def func(*args): 2 s=0 3 for i in args: 4 s+=i 5 return s 6 ret=func(1,2,3,4,5) 7 print(ret)
2、读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
1 a=10 2 b=20 3 def test5(a,b): 4 print("***",a,b) #a应该等于20,b等于10,c = test5(b,a)传的值为test5(20,10) 5 c = test5(b,a) 6 print(c) #c=None
3、读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
1 a=10 2 b=20 3 def test5(a,b): 4 a=3 5 b=5 6 print(a,b) #因为局部有自己有a,b的值,就不需要在用外面的值,所打印出来a=3,b=5 7 c = test5(b,a) 8 print(c) #c的值为空,因为函数返回值为空。
疑惑!!!

posted on 2018-09-22 16:41 cherish-LL 阅读(221) 评论(0) 收藏 举报
浙公网安备 33010602011771号