函数和变量生存区间
1 2 >>> Saysome('袁重阳','你好') 3 袁重阳->你好 4 >>> Saysome('你好','袁重阳') 5 你好->袁重阳 6 >>> Saysome(words='你好',name='袁重阳') 7 袁重阳->你好 8 >>> #可以通过提示形参来避免编译器按照顺序赋值 .
`
1 >>> def saysome(name='小甲鱼',words='让编程改变世界'): 2 print(name+"->"+words) 3 >>> saysome() 4 小甲鱼->让编程改变世界 5 >>> saysome('老甲鱼') 6 老甲鱼->让编程改变世界 7 >>> saysome(words='不让编程改变世界') 8 小甲鱼->不让编程改变世界
收集参数.
>>> def test(*params): print("参数的长度是:",len(params)) print("第二个参数是:",params[1]) >>> test(1,'小甲鱼',3.14,5,6,7,8) 参数的长度是: 7 第二个参数是: 小甲鱼 >>> def test(*params,tex): print("参数的长度是:",len(params)) print("第二个参数是:",params[1]) >>> test(1,2,3,4,5,6,7,8) Traceback (most recent call last): File "<pyshell#38>", line 1, in <module> test(1,2,3,4,5,6,7,8) TypeError: test() missing 1 required keyword-only argument: 'tex' >>> #发生错误 因为调用的时候里面的参数被全部传送至 收集参数那里. >>> test(1,2,3,4,5,6,7,tex=8) 参数的长度是: 7 第二个参数是: 2 >>> #可以通过上述的指定参数来避免 当然也可以通过默认参数避免 >>> def test(*params,tex=8): print("参数的长度是:",len(params)) print("第二个参数是:",params[1]) >>> test() 参数的长度是: 0 Traceback (most recent call last): File "<pyshell#44>", line 1, in <module> test() File "<pyshell#43>", line 3, in test print("第二个参数是:",params[1]) IndexError: tuple index out of range >>> test(1,2,3) 参数的长度是: 3 第二个参数是: 2
>>> def hello(): print("hello") >>> temp=hello() hello >>> type(temp) <class 'NoneType'> >>> print(hello) <function hello at 0x02E32858> >>> print(temp) None >>> # 可以看出没有返回值 >>> def hello(): print("hello") return 1 >>> print(hello()) hello 1 >>> temp=hello() hello >>> print(temp) 1 >>> def hello(): return 1,2,3,4,5,6 >>> #返回多个值 >>> hello() (1, 2, 3, 4, 5, 6)
下面说重点函数变量的作用域问题
在函数之中声明的变量都是局部变量 , 在函数外面声名的就是全局变量 , 在函数中如果要修改全局变量的话当你赋值 , 编译器会再在函数之中声明一个局部变量 而且 当你声明的时候 全局变量会被屏蔽(Shadowing) (用于保护全局变量). 如果小伙子 实在想在函数内部修改全局变量的话 . 可以在函数中 将该全局变量进行一次全局变量定义然后开始修改 . 修改代码如下
1 def dis(price,rate): 2 final_price=price*rate 3 global old_price 4 old_price=10 5 print(old_price) 6 return final_price 7 old_price=float(input('请输入原价:\t')) 8 rate=float(input('请输入折扣率:\t')) 9 new_price=dis(old_price,rate) 10 print('打折后的价格是:\t',new_price) 11 print("这里试图输出修改后的全局变量old_price:\t",old_price)
实验代码如下
def dis(price,rate): final_price=price*rate #print("这里试图打印全局变量old_price的值:\t",old_price) # old_price=88 #这里试图修改 全局变量 #print('修改后old_price的值是:\t',old_price) #old_price=80 #如果在这里试图修改全局变量 old_price的话编译器会再声明一个局部变量. print(old_price) return final_price old_price=float(input('请输入原价:\t')) rate=float(input('请输入折扣率:\t')) new_price=dis(old_price,rate) #print('修改后的old_price的值是:\t',old_price) print('打折后的价格是:\t',new_price) #在函数之中定义的变量都是局部变量在变量外无效 . #因为在执行函数的时候我们将其储存带 "栈" 中当函数执行完毕的时候我们将该函数从 # "栈" 中删除 所以这时候其中的变量也被随之删除了 .在外界不能被访问 . #print('这里试图打印局部变量final_price的值:\t',final_price) # 这一句话有错 , 局部变量在外面不能访问 . # 在和局部变量相对的是全局变量 全局变量是在 函数之外声明的 (其作用于参考局部变量可以得出 : 是整个文件 . 因为整个文件自始至终都存在 . )
内嵌函数和闭包.
1 >>> def fun1(): 2 print("fun1正在被调用") 3 def fun2(): 4 print("fun2正在被调用") 5 fun2() 6 7 8 >>> fun1() 9 fun1正在被调用 10 fun2正在被调用
在fun1函数外面是不能访问 fun2的 .
1 >>> fun2() 2 Traceback (most recent call last): 3 File "<pyshell#14>", line 1, in <module> 4 fun2() 5 NameError: name 'fun2' is not defined
这里附上一个很尴尬的错误 . 前两个是 "局部变量在赋值前就被引用,第三个是x没有被声明" 第三个表明 , 函数之内的只是局部变量不能算作内嵌函数的全局变量 .
1 >>> x=10 2 >>> def aa(): 3 x=x*x 4 return x 5 6 >>> aa() 7 Traceback (most recent call last): 8 File "<pyshell#14>", line 1, in <module> 9 aa() 10 File "<pyshell#13>", line 2, in aa 11 x=x*x 12 UnboundLocalError: local variable 'x' referenced before assignment
1 >>> def fun1(): 2 x=5 3 def fun2(): 4 x=x*x 5 return x 6 return fun2() 7 8 >>> fun1() 9 Traceback (most recent call last): 10 File "<pyshell#6>", line 1, in <module> 11 fun1() 12 File "<pyshell#5>", line 6, in fun1 13 return fun2() 14 File "<pyshell#5>", line 4, in fun2 15 x=x*x 16 UnboundLocalError: local variable 'x' referenced before assignment
1 >>> def fun1(): 2 x=5 3 def fun2(): 4 global x 5 x=x*x 6 return x 7 return fun2() 8 9 >>> fun1() 10 Traceback (most recent call last): 11 File "<pyshell#8>", line 1, in <module> 12 fun1() 13 File "<pyshell#7>", line 7, in fun1 14 return fun2() 15 File "<pyshell#7>", line 5, in fun2 16 x=x*x 17 NameError: name 'x' is not defined
当在aa函数中调用x的时候虽然你是调用但是 你也对其进行了赋值 , 这时候编译器就在函数中又声明了一个名字和该变量相同的局部变量然而这个变量没有赋值 . (有一点难理解 . 好好想想参考上面的那个)
究其原因 为什么会出现这种情况 ? 还是 "栈"式储存搞的鬼 . 我们想避开这个问题该怎么办 ? 答案就是离 "栈" 远远的 . 下面附上结局办法
这个相对来说有一点投机取巧的感觉 .
1 >>> def fun1(): 2 x=[5] # 列表有另外的储存空间 不是"栈式" 储存. 3 def fun2(): 4 x[0]*=x[0] 5 return x[0] 6 return fun2() 7 8 >>> fun1() 9 25
有强迫症的可以用这一种方法(正规)
1 >>> def fun1(): 2 x=5 3 def fun2(): 4 nonlocal x 5 x=x*x 6 return x 7 return fun2() 8 9 >>> fun1() 10 25
意思就是在函数中声明的变量在内嵌函数中声明为非本地变量.
匿名函数 (Lambda).
1 >>> def f(x): 2 return 2*x+1 3 4 >>> y=f(5) 5 >>> y 6 11 7 >>> lambda x: x*2+1 8 <function <lambda> at 0x02DC0150> 9 >>> # 冒号的前面是变量 , 后面的就是得到的值. 10 >>> g=lambda x: x*2+1 11 >>> g(5) 12 11 13 >>> g=5 14 >>> g=lambda x,y:x+y 15 >>> g(5,6) 16 11