目录
一、定义
1、方便代码重用,分解任务简化程序逻辑,使代码更加模块化。
2、内建函数、三方函数、自定义函数
二、传入不定长参数
1、接收到的是一个元组
def func(*ele): print(ele, type(ele))=>(1, 2) <class 'tuple'> func(1, 2)
2、接受到的是一个字典
def func(**ele): print(ele, type(ele))=>{'das': '1', 'sadasd': '2'} <class 'dict'> func(das="1", sadasd="2")
3、参数装包拆包
def func(*ele): print(ele)=>(1, 2, 3)装包 print(*ele)=>1 2 3拆包 func(1, 2, 3)
但对字典的解包调用{'a': '1', 'b': '2'},func(**dict)传入参数为a='1',b='2',故要注意参数名称是否对应。133-Python函数-参数-不定长参数-参数的拆包和装包_哔哩哔哩_bilibili
4、缺省参数,写函数形参时将其=“默认值”
5、python中参数传递都是引用传递(传地址),对于可变数据类型,改变的是同一地址空间的值,对于不可变数据类型,改变参数会开辟一块新的空间。
三、返回值
1、return 参数
2、返回多个参数时,返回参数使用列表、元组或字典等。
四、函数使用:写注释,在函数体前写三引号注释。
1、函数功能
2、参数:
含义、类型、是否可省略、默认值
3、返回值:
含义、类型
4、可以用help(函数)进行查询功能
五、函数高级用法
1、偏函数
用新偏函数指明某个函数里面一个参数偏爱某个值,方便的处理各种默认情况。
def func(a, b, c=1): newFunc = functools.partial(func, b=2)
2、高阶函数
把一个函数当作参数传给另一个函数,eg:
def getKey(x): return x[1] stu = [("std2", 18), ("std1", 20), ("std3", 16)] resu1=sorted(stu, key=getKey) print(resu1)=>[('std3', 16), ('std2', 18), ('std1', 20)]
3、返回函数
一个函数内部,它返回值是另一个函数,eg:
def getfunct(str): def sum(a, b, c): print(a + b + c) def dedu(a, b, c): print(a - b - c) if str == "+": return sum elif str == "-": return dedu
4、匿名函数
lambda 参数1,参数2 : 表达式
(1)名称:无(匿名),参数:给了,返回值:表达式的值
(2)使用:上述getkey()函数可以替换掉了,比如sort中key=lambda x:x["name"]
5、闭包
(1)前提函数嵌套
(2)内层函数引用了外层函数的参数或传进外层的参数
(3)外层函数将内层函数作为返回值返回
(4)闭包指内层函数和引用外层函数的整体
eg:
def test(): a = 1 def test2(): print(a) return test2
(5)在内部函数修改外部变量的时候需要使用nolocal进行声明是修改外部的函数而不是定义内部函数的新参数
(6)函数执行时才会查找函数的内部标识,所以下面列子,结果为2
def test(): a = 1 def test2(): print(a) a = 2 return test2 newFunct = test() newFunct()==>2
6、装饰器
(1)将业务逻辑和功能函数分离:逻辑更加清楚、便于维护、提升代码重用
(2)增加功能:修改业务逻辑最繁琐复杂<修改功能函数也可能很多<增加新的函数定义在功能函数中调用最好
(3)上述最后一种方法违背了单一功能原则,即功能函数内部功能不纯粹
(4)面向对象、过程编程的开放封闭原则;
封闭:写好的代码尽可能不要修改
开放:欲增加新的功能,在原代码的基础上单独进行拓展
(5)装饰器:在不改变函数名及函数体的情况下,给函数增加额外功能(用上述闭包)
eg:使用语法糖方式
def test(func): def inner(): #ftp = inner() print("happy") func() # func==ftp return inner @test # == ftp=test(ftp) def ftp(): print("sad") ftp()==>happy\nsad
(6)装饰器是立即执行,执行到@test时候就已经执行了
(7)装饰器的叠加:装饰器从上到下去装饰,从下到上去执行,eg:
@test_star # == ftp=test_star(ftp) @test_line # == ftp=test_line(ftp) def ftp(): print("sad")=>***************\n--------------\nsad
(8)对不定长参数的装饰,可使用元组及字典*args、**kwargs,在装饰器内部func函数应该传入解包的参数,即func(*args,**kwargs)才能返回原来函数执行
(9)装饰有返回值的函数,需要inner中return返回func()的值
(10)有参数的装饰器,根据参数不同生成不同的装饰器
def getTest(char): #获取一个装饰器 def test(func): #装饰器本身 def inner(): print(char * 30) func() return inner return test @getTest("-") #用传入了参数的装饰器对下面函数进行装饰
7、生成器
(1)特殊的迭代器,但迭代器的抽象层级更高,生成器拥有迭代器的一些特性
(2)迭代器特性:
惰性计算数据节省内存;
能够记录状态,通过next()函数访问下一个状态
具备可迭代特性 for in
(3)创建
a、将列表生成式的[]改为()即可
b、函数中包含yield语句就会定义出一个生成器,使用next()可以是这个函数执行在yield处中断
def test(): print("ddd") yield 1 print("a") yield 2 print("b") print("c") yield 3 print("----") g = test() print(g) #<generator object test at 0x00000176FADBDCF0> print(next(g)) #ddd\n1 print("***") print(next(g)) #a\n2 print("***") print(next(g)) #b\nc\n3 print("***")
(4)send方法:跟next()作用差不多,但是可以给上一次挂起的yield语句指定返回值(原本是没有返回值的),但第一次使用时必须t.send(None),因为找不到上一次挂起的yield
(5)g.close()使用此函数后,若继续调用next(),会出现停止迭代的异常提示
(6)注意:遇到return会马上抛出异常,且return的值会写在异常提示中;生成器也不能多次迭代 。
8、递归函数 (一种函数调用方式):传递+回归,没啥写的
9、作用域
(1)变量的作用域(静态):因为位置的不同而有不同的作用域
(2)命名空间(LEGB):
L-Local函数内命名空间:整个函数体范围
E-Encloseing function locals外部嵌套函数的命名空间:闭包函数
G-Global全局命名空间:当前模块、文件
B-Buitin内建模块命名空间:所有模块、文件,eg:print、__name__
(3)python中不存在块级作用域,块比如for、if
(4)nolocal a声明,nolocal语句仅适用于闭包改变外层变量值;global a声明用于改变函数中的全局变量
(5)查询局部变量的函数locals();查询全部变量的函数glocals(),包括系统自带的
(6)访问原则:从内到外
(7)定义规范:全局变量在文件最上面