函数进阶
三元运算:
变量 = 条件返回true的结果 if 条件 else 条件返回false的结果
#如:返回a,b中较大的值 a = 1 b = 5 c = a if a>b else b print(c)
使用函数的目的:可用性强,复用性强
默认参数的陷进:
如果默认参数的值是一个可变数据类型,那么每一次调用函数时,如果不传参数就公用这个数据类型的资源。
①def qqxing(L = []): L.append(2) print(L) qqxing() #结果:[2] qqxing() #结果:[2,2] ②def qqxing(L={}): L['k'] = 'v' print(L) qqxing() #结果:{'k':'v'} qqxing() #结果:{'k':'v'} #两个结果一样,因为字典的键值不可重复 ③def qqxing(k,L ={}): L[k] = 'v' print(L) qqxing(1) #结果:{1: 'v'} qqxing(2) #结果:{1: 'v', 2: 'v'}
命名空间和作用域:
函数的命名空间有三种:
内置命名空间———python解释器
①python解释器可以使用的名字存储再内置命名空间中
②内置的名字再启动解释器时被加载到内存里
全局命名空间------我们写的代码但不是函数中的代码
①是在程序从上到下被执行的过程中依次加载进内存的
②放置了我们设置的所有变量名和函数名
局部命名空间————函数
①就是函数内部定义的名字
②当调用函数时才会产生这个命名空间,随着函数调用的结束,这个命名空间就又消失了。
在局部:可以使用全局也可以使用内置命名空间中的名字:
在全局:可以使用内置命名空间中的名字但不能用局部
在内置:不能使用全局和局部的名字
注:
①当我们在全局定义了和内置命名空间中同名的名字时,会使用全局的名字
②在正常情况下直接使用内置的名字
③当自己有的时候就不找上级要了
④如果自己没有,就找上一级要,上一级没有再找上一级,若内置的名字空间都没有就会报错
⑤多个函数应该拥有多个独立的局部名字空间,不能相互共享
作用域(两种):
全局作用域-----作用在全局
①内置和全局名字空间中的名字都属于全局作用域
布局作用域-----作用在局部
①函数(局部名字空间中的名字属于局部作用域)
globals
①对于不可变数据类型,在局部可以查看全局作用域中的变量但是不能修改,
如果想要修改,需要在程序的一开始添加global声明
②如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效
两个方法查看变量和值:
①局部名称空间中的变量和值用locals()查看
②全局名称空间中的变量和值用globals()查看
③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') inner() outer()
内部函数可以使用外部函数的变量
def outer(): a = 1 def inner(): print(a) print(inner) inner() outer()
nonlocal
①声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量
②只能用于局部变量,找上层中里当前函数最近一层的局部变量
③对全局无效,对局部也只是对最近一层有影响
a = 0 def outer(): a = 1 def inner(): a = 2 def inner2(): nonlocal a print(a+2) inner2() inner() outer()
函数名的本质:
函数名加括号等价于函数的内存地址加括号;函数名加括号代表一个函数的执行;
去掉括号表示函数的内存地址;即根据函数名能找到内存地址
①函数名就是内存地址
②函数名可以赋值 func2 = func
③函数名可以作为容器类型的元素 L = [func,func2]
④函数名可以作为函数的参数
⑤函数名可以作为函数的返回值
def func(): print(123) def func2(W): W() #W()相当于func() func2(func) #func作为参数传给W,W得到的时func的地址 #结果:123
函数名是第一类对象:
第一类对象是指:①可在运行期间创建
②可以作为函数的参数和返回值
③可存入变量的实体
闭包:必须是嵌套函数,且内部函数必须调用外部函数的变量
def outer(): a = 1 def inner(): print(a) print(inner.__closure__) #_closure_查看inner是否是闭包 outer()
闭包最常用的形式:
def outer(): a = 1 def inner(): print(a) return inner inn = outer() inn() #在函数得外部使用它得内部函数
闭包的应用:
from urllib.request import urlopen def get_url(): url = 'http://www.xiaohua100.cn/index.html' def get(): ret = urlopen(url).read() print(ret) return get get_func = get_url() get_func()