函数的定义
def 函数名(参数): 函数体 return 返回值 #def: 定义函数的关键字 #函数名: 函数的名字,用于函数的调用 #参数: 为函数体提供数据 #函数体: 函数里的一系列运算 #返回值: 函数执行完毕后,返回的值
函数传递参数
按照形参来划分 (位置参数》动态参数》默认参数)
位置形参
def func(a, b, c): #必须与形参按照顺序一一对应 print(a, b, c) func(1, 2, 'oldboy')
默认参数
def func(a, b, c=3, d=4): #默认参数必须在位置参数的后边 print(a, b, c, d) func(1, 2)
动态参数
def func(*args, **kwargs): #函数定义的时候*代表聚合 print(args) # args接受所有的位置参数,放在一个元组中 print(kwargs) # kwargs接受所有的关键字参数,放在一个字典中 func(1, 2, 3, name='lidawei', age=18)
func(*[1,2,3],*(22,333)) 函数执行的时候*代表打散
按照实参来划分
位置参数
def func(a, b, c): #必须与形参按照顺序一一对应 print(a, b, c) func(1, 2, 'oldboy')
关键字参数
def func(a, b ): #必须与形参一一对应,顺序可以变,但是个数不能变 print(a, b) func(b=1,a=2)
混合参数(包括位置参数与关键字参数)
def func(a, b, c, d): #关键字参数必须在位置参数的后边 print(a, b, c, d) func(1, 2, d=4, c=3)
函数的名称空间和作用域
名称空间:
当程序运行时代码从上至下一次执行,他会将变量与值的关系存储到一个空间中,这个空间叫做名称空间也叫命名空间
python中的名称空间分三种
内置名称空间:python自带的名称空间,在python解释器启动是产生,存放了python内置的变量名与值的绑定关系
全局名称空间:在执行python程序时,存放变量与值关系的空间
局部名称空间:当程序遇到函数时,会将函数名存到内存中,函数体不关心,当函数执行时,内存会开辟一个空间,存放函数的代码,变量等,函数外面访问不到临时空间的内容,随着函数执行完毕,临时空间 会被释放掉,像这个临时开辟出来的空间叫做临时名称空间,也叫局部名称空间
作用域:
全局作用域:
内置名称空间
全局名称空间
局部作用于:
局部名称空间
加载顺序 :内置名称空间 ---> 全局名称空间(程序执行时) ---> 局部名称空间(函数执行时)
取值顺序:局部名称空间(函数调用时) --->全局名称空间(程序执行时) --->内置名称空间
函数的嵌套:
嵌套调用:
def max(x,y): return x if x > y else y def max4(a,b,c,d): res1=max(a,b) res2=max(res1,c) res3=max(res2,d) return res3 print(max4(1,2,3,4))
嵌套定义:
def f1(): def f2(): def f3(): print('from f3') f3() f2() f1()
内置函数globals() 和 locals()
globals()返回一个字典,字典里边的内容是全局作用域的内容
locals()返回一个字典,字典里边是当前位置的所有变量
关键字 global()和 nonlocal()
global(使函数可以引用并改变一个全局变量,在局部作用域声明一个全局变量)
count = 1 def func1(): global count count = count + 1 print(count) func1() print(count)
nonlocal(不能操作全局变量,从哪层开始引用的,就从哪层开始改变)
def func1(): count = 1 def inner(): nonlocal count count = count + 3 print(count) def inner2(): pass inner() print(count) func1()
取值:引用而不是改变,取值是从小到大取值(LEGB),想改变上层空间的变量,就要用到global nonlocal
如果默认参数是一个可变的数据类型,那么他在内存中永远只是一个
def extendList(val,list=[]): list.append(val) return list list1 = extendList(10) list2 = extendList(123,[]) list3 = extendList('a') print('list1=%s'%list1) # [10,] print('list2=%s'%list2) # [123,] print('list3=%s'%list3) #[10,'a']
函数名的应用:
函数是第一类对象,可以当做数据传递
①可以被引用
②可以作为函数的参数
③可以作为函数的返回值
④可以作为函数的容器类数据的元素
闭包:内层函数对外层函数非全局变量的引用
def wrapper(): name = 'alex' def inner(): print(name) inner() wrapper()
#如果python解释器遇到了闭包函数,他有一个机制,这个闭包不会随着函数的结束而释放
装饰器
在不修改被装饰对象源代码和被装饰对象的调用方式的前提下,为被装饰对象添加新的功能
目的:查看一个函数的运行效率
①引用time模块,得到函数结束时间和开始时间计算得出运行时间
def func1(): time.sleep(0.3) print('正在登陆') start_time = time.time() func1() end_time = time.time() print('此函数的执行效率%s' %(end_time-start_time))
②把上述计算封装在一个函数中
def timer(): start_time = time.time() time.sleep(0.3) print('正在登陆') end_time = time.time() print('此函数的执行效率%s' %(end_time-start_time)) timer()
③被测试函数当做参数传入,可以测试多个函数的执行效率
import time def func1(): time.sleep(0.3) print('正在登陆') def timmer(f): start_time = time.time() f() end_time = time.time() print('此函数的执行效率%s' %(end_time-start_time)) timmer(func1)
④测试函数执行效率的同时,不改变原函数的调用方式
import time def func1(): time.sleep(0.3) print('非常复杂......') def timmer(f): start_time = time.time() f() end_time = time.time() print('此函数的执行效率%s' % (end_time - start_time)) f1 = func1 func1 = timmer func1(f1) # timmer(func1)
⑤最简单的装饰器
import time def func1(): time.sleep(0.3) print('非常复杂......') def timmer(f): # f = func1 函数名 def inner(): start_time = time.time() f() end_time = time.time() print('此函数的执行效率%s' % (end_time - start_time)) return inner func1 = timmer(func1) # inner func1() # inner()
⑥带语法糖@的简单装饰器
import time def timmer(f): # f = func1 函数名 def inner(): start_time = time.time() f() end_time = time.time() print('此函数的执行效率%s' % (end_time - start_time)) return inner @timmer # func1 = timmer(func1) inner def func1(): time.sleep(0.3) print('非常复杂......') func1() # inner()
⑦被装饰的函数带有参数的装饰器
import time def timmer(f): # f = func1 函数名 def inner(*args,**kwargs): start_time = time.time() f(*args,**kwargs) end_time = time.time() print('此函数的执行效率%s' % (end_time - start_time)) return inner @timmer # func1 = timmer(func1) inner def func1(a,b): time.sleep(0.3) print(a,b) print('非常复杂......') func1(1,2)
⑧被装饰的函数带参数且有返回值的装饰器
import time def timmer(f): # f = func2 函数名 def inner(*args,**kwargs): # args = (1,2),kwargs {sex:'nv',name:'alex'} start_time = time.time() ret = f(*args,**kwargs) # f(1,2,,sex='nv',name='alex') end_time = time.time() print('此函数的执行效率%s' % (end_time - start_time)) return ret return inner @timmer # func2 = timmer(func2) inner def func2(a,b,name,sex='man'): # f(1,2,,sex='nv',name='alex') time.sleep(0.3) print('非常复杂......') return 666 func2(1,2,sex='nv',name='alex') # inner()
装饰器的本质就是闭包