#__author:"Feng Lin" #date: 2018/8/28 #函数进阶 #1.命名空间和作用域 #内置命名空间--python解释器 #就是python解释器一启动就可以使用的名字存储在内置命名空间中,例如print、input() #内置的名字在启动解释器的时候被加载到内存里 #全局命名空间--我们写的代码但不是函数中的代码 #是在程序从上到下被执行的过程中一次加载进内存的 #放置了我们设置的所有变量名和函数名 #局部命名空间--函数 #就是函数内部定义的名字 #当调用函数的时候才会产生这个名称空间,随着函数执行的结束,这个命名空间又消失了 #在局部:可以使用全局、内置命名空间的名字 #在全局:可以使用内置命名空间的名字,但是不能用局部命名空间的名字 #在内置空间:不能使用全局和局部的名字 #def func(): # a=1 #func() #print(a) def max(l): print('in max func') print(max([1,2,3])) #在正常情况下直接使用内置命名空间 #但是如果在全局定义了和内置名字空间的同名字的时候,会使用全局的名字 def func(): #input=1 print(input) #func==函数的内存地址 #函数名()==函数的调用 #函数的内存地址()==函数的调用 #作用域两种 #全局作用域 ----------作用在全局------内置和全局名字空间中的名字属于全局作用域 #局部作用域 ----------作用在局部------函数(局部名字空间中的名字属于局部作用域) b=1 def func1(): global b b+=1 print(b) #对于不可变数据类型,在局部可以查看全局作用域中的变量,但不能直接修改 #除非在局部作用域将该数据类型声明为全局使用global a=1 b=2 def func(): x='aaa' u='bbb' print(locals()) #查看局部作用域的名字有哪些 func() print(globals()) #查看全局作用域的名字有哪些 print(locals()) #globals 永远打印全局的名字 #locals 根据locals所在的位置打印名字 #函数的嵌套调用 def max(a,b): return a if a>b else b def the_max(x,y,z): c=max(x,y) return max(c,z) print(the_max(1,2,3)) #函数的嵌套定义 def outer(): def inner(): print('inner') print('outer') inner() outer() #内部函数可以读外部函数的变量,但是不能修改 def outer(): a=1 def inner(): print(a) print('outer') inner() outer() #nonlocal关键字,用于函数嵌套时,修改函数的局部变量 #nonlocal只能用于局部变量,找上层中离当前函数最近一层的局部变量 #声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量 t=1 def outer(): t=1 def inner(): c=2 print(t) print('inner') def inner2(): nonlocal t #声明一个上一层的局部变量 t+=1 #不可变数据类型的修改 print('inner2') inner2() inner() print('局部的t:',t) outer() print('全局的t:',t) #函数名(第一类对象) #函数名就是内存地址,并且可以赋值 def fun(): print(123) print(fun) fun1=fun print(fun1) fun1() #函数名可以作为容器类型的元素 list1=[fun1,fun] print(list1) #函数名可以作为函数的参数 def waha(f): f() return f #函数名可以作为函数的返回值 qqxin=waha(fun) #闭包:嵌套函数,内部函数调用外部函数(读写都算)的变量 def out(): a=1 def inn(): print(a) print(inn.__closure__) out() print(out.__closure__) #闭包的调用,在函数外部使用闭包 def outter(): a=1 def inne(): print(a) return inne #将闭包的内存地址返回 inn=outter() #用一个变量接收,此时闭包的内存地址不会随着outter函数执行结束后被释放 inn() #此时要使用时只需要用这个接收到闭包的变量加()直接使用 #闭包的运用 from urllib.request import urlopen def get_url(): url='http://www.xiaohuar.com/' #运用闭包节省资源,不用每次使用url这个变量,并保存在内存里 def geturi(): ret=urlopen(url).read() print(ret) return geturi get_func=get_url() get_func()