python3 函数

一.函数

1.函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段

2.函数能提高应用的模块性,和代码的重复利用率

3.函数文档字符串用三引号引起,python使用它们来生成有关程序中函数的文档,用来说明函数

4.函数可分为:内置函数BIF,自定义函数,第三方函数

 

二.定义和调用

1.定义:以 def 关键词开头,后接函数标识符名称和圆括号 ( )

             def 函数名(形参):
                     函数体

2.调用:(1)直接调用:函数名(实参),(2)变量名=函数名(实参)来把函数返回值赋值给变量

3.函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”

4.函数必须先定义才能调用

5.函数定义若重名,则忽略最旧的,只调用最新的函数,以新覆盖旧

 

三.参数

1.形参和实参

(1)形参:函数定义时,函数完成其工作所需的一项信息

(2)实参:函数调用时,传递给函数的信息

2.函数的形参类型按顺序:必选参数、默认值参数、可变参数、命名关键字参数和关键字参

3.必选参数:一个实参关联一个形参(一个值关联一个变量)

(1)形参:变量名。不能试图用‘元组’等的形式

(2)实参:1.位置实参:值,实参的顺序要与形参的顺序相同;2.关键字实参:每个实参由变量名和值组成

4.默认值参数:默认值参数必须指向不变对象,给形参添加一个默认值

(1)形参:变量名=默认值。使用时,必须列出没有默认值的形参,再列出有默认值的形参,使python能正确地解读位置实参

(2)实参:如果传入参数值,则使用参数值,如果没有传递参数值,则会使用默认值

5.可变参数:可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个;能处理比当初声明时更多的参数,

(1)形参:*变量名。一般使用:*args。表示:python创建一个名为args的空元组,并将收到的所有值都封装到这个元组中

(2)实参:0个或多个值,放在位置实参和关键字实参后面,只能通过位置传值,python自动匹配

6.关键字参数:需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息

(1)形参:**变量名。一般使用:**kwargs。表示:python创建一个名为kwargs的空字典,并将收到的所有值都封装到这个字典中

(2)实参:0个或多个关键字实参(变量名-值),放在最后

7.命令关键字参数:限制关键字参数的名字。命名关键字参数需要一个特殊分隔符**后面的参数被视为命名关键字参数

(1)定义时,如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*

(2)调用时,命名关键字参数必须传入参数名

 1 #参数
 2 def printinfo(a, b,*args,c=4,**kwargs):
 3     print('必选参数',a,b)
 4     print('默认参数',c)
 5     print('可变参数1',args)
 6     print('可变参数2',*args)
 7     print('关键字参数1',kwargs)
 8     print('关键字参数2',*kwargs)
 9 
10 printinfo(3,4,5,(42,35),name='a',c=1,age=16,)
11 #按位置传入参数
12 #3传入a,4传入b
13 #4后面的被认为*args,被判定为一个元组
14 #如果碰到关键字传参,先判定是否是默认参数传参,如果不是,则判定为关键字传参
15 -------------------------------------------------------------------------
16 必选参数 3 4
17 默认参数 1
18 可变参数1 (5, (42, 35))
19 可变参数2 5 (42, 35)
20 关键字参数1 {'name': 'a', 'age': 16}
21 关键字参数2 name age
参数

8.总结:

(1)定义函数时,先设置必选参数(变量名),接着默认值函数(变量名+值),再者可变参数(*变量名),最后关键字参数(**变量名)

(2)调用函数时,依次传递参数,对于必选参数,直接传递参数(值)或根据关键字传参(变量名+值);对于默认值参数,可以不传参或直接传参(值)或根据关键字修改默认值(变量名+值);

对于可变参数,传入0个或多个值(变量名),对于关键字参数,传入传入0个或多个参数(变量名+值)

 

四.函数的拆包和偏函数

1.函数参数的拆包(解包)

装包:把传递的参数,包装成一个集合;拆包:把集合参数再次分解为单独的个体

 1 def my_sum(a,b,c,d):
 2     print(a+b+c+d)
 3 
 4 def test(*args):
 5     '''*args:可变参数,接收0个或多个参数封装成元组'''
 6     print('未拆包表示:',args)#多个参数封装的元组,(1,2,3)一个元素
 7     print('拆包表示:',*args)#把元组拆分成单个元素的形式,1,2,3多个元素
 8     my_sum(args[0],args[1],args[2],args[3])
 9     my_sum(*args)
10 
11 test(1,2,3,4)
12 ---------------------------------------------
13 未拆包表示: (1, 2, 3, 4)
14 拆包表示: 1 2 3 4
15 10
16 10
拆包元组
 1 def mysum(e,f):                                                   
 2     print(e)                                                      
 3     print(f)                                                      
 4                                                                   
 5 def test2(**kwargs):                                              
 6     '''**kwargs:关键字参数,接收0个或多个关键字参数封装成字典'''                        
 7     print('未拆包表示:',kwargs)#字典, {'e': 1, 'f': 2}一个元素               
 8     print('拆包表示:',*kwargs)#*拆解出key,e f多个元素                        
 9     # print(**kwargs)#相当于*(*kwargs)拆包多个元素,所以会报错                   
10     mysum(**kwargs) #把整个字典作为参数传递给函数,相当mysum(e=1,f=2)             
11 test2(e=1,f=2)           
12 --------------------------------------------         
13 未拆包表示: {'e': 1, 'f': 2}
14 拆包表示: e f
15 1
16 2
17                                 
拆包字典

2..偏函数:指定函数的参数为某个固定值。当函数的参数个数太多,需要简化时,functools.partial创建一个偏函数,可以接收函数对象、*args**kw这3个参数

偏函数把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

 1 def test(a,b,c,d):
 2     print(a+b+c+d)
 3 
 4 def test2(a,b,c,d=2):
 5     test(a,b,c,d)
 6 
 7 test2(1,2,3)
 8 
 9 import functools
10 newfunction=functools.partial(test,d=3)
11 print(newfunction,type(newfunction))
12 newfunction(1,2,3)
13 ---------------------------------------------------------------------------
14 
15 8
16 functools.partial(<function test at 0x056BDFA8>, d=3) <class 'functools.partial'>
17 9
偏函数

 

五.return语句

1.如果没有使用return语句指定返回值,python也不是什么都不返回,它会返回一个None对象,所以说python所有函数都有返回值

2.函数调用时return返回一个表达式,有返回值的函数可以对改值进行保存赋值等操作

3.return可以返回多个值并调用,可以以列表,元组,字典的形式以一个整体返回,默认以元组形式

4.return还有一个功能:结束函数(相当于函数中break功能),下面的不执行

5.返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量

6.函数中return和print的区别

(1)print是函数调用直接打印出来,输出数据到控制端

(2)return是这个函数调用返回一个值,如果一个函数没有返回值,那么这个函数的计算结果无法在其他地方使用

 1 def test():
 2     i=7
 3     return i#返回计算的值
 4 
 5 print('1:',' ');test()#调用test函数,控制台没有输出
 6 print('2:',test())#调用并操作(打印)test()函数。test函数中没有输出,test函数的返回值为7
 7 print('3:',test()==7) #调用并操作(打印)test()函数,调用时没有打印的操作,test函数的值为7,输出比较的值True
 8 
 9 
10 def test2():
11     i=7
12     print(i)#输出数据到控制端
13 print('4:',end=' ');test2()#调用test2函数,(主要看里面有什么操作),函数中有print输出7
14 print('5:',test2())#调用并操作(打印)test2()函数。test函数中打印7,test函数中没有返回值(None)
15 print('6:',test2()==7)#调用并操作(打印)test2()函数,调用时打印7,test函数的值为None,输出比较的值False
16 -------------------------------------------------------------------------------
17 1:  
18 2: 7
19 3: True
20 4: 7
21 7
22 5: None
23 7
24 6: False
return和print

 

六.匿名函数lambda 函数

1.lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去,lambda函数只能写一个表达式,表达式的结果就是返回值

2.lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数

3.lambda [arg1 [,arg2,.....argn]]:expression

1 q=lambda x:x*x+1#定义一个函数q,参数x满足x*x+1
2 print(type(q))
3 print(q(2))
4 -----------------------------------------------------------------
5 <class 'function'>
6 5
lambda

 

七.变量作用域

1.程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的

2.变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称

3.作用域一共有4种:L (Local) 局部作用域,E (Enclosing) 闭包函数外的函数中(比如闭包),G (Global) 全局作用域,B (Built-in) 内建作用域;以 L –> E –> G –>B 的规则查找

4.Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域

5.其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问

1 x = int(2.9)  # 内建作用域
2 g_count = 0  # 全局作用域
3 def outer():
4     o_count = 1  # 闭包函数外的函数中
5     def inner():
6         i_count = 2  # 局部作用域
作用域

6.闭包:在函数嵌套的前提下,内层函数引用外层函数的变量(包括参数),外层函数又把内层函数当做返回值进行返回

 闭包中,如果要修改引用的外层变量需要使用nonlocal,否则当做是闭包内新定义的变量

 1 #闭包 有函数动态生成的函数
 2 def mi_num(x):
 3     def mi(y):
 4         y=y**x
 5         return y
 6     return mi#函数以参数的形式返回
 7 a=mi_num(4)#4次方,a是一个函数
 8 print(a(2))#输出2的4次方
 9 -------------------------------------------------------------------
10 16
闭包

7.定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域

8.全局变量和局部变量

(1)局部变量是在一个函数内部定义的变量;作用域为函数内部;可以用locals()函数查看局部变量

(2)全局变量是在函数外部,文件最外层定义的变量;作用域为整个文件内部;可以利用golbals()函数查看全局变量

(3)局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问

(4)当内部作用域想修改外部作用域的变量时(比如函数中修改全局变量的值),就要用到global关键字,里面用外面的变量;函数内部可以更新外部的变量

(5)修改嵌套作用域中的变量(比如在嵌套函数中,希望在内部函数修改外部函数的局部变量)则需要 nonlocal 关键字,函数中对于不可变数据类型作为全局变量时,一定加global,对于操作可变数据类型全局变量时,可不加global

 1 num = 1
 2 def fun1():
 3     global num  # 需要使用 global 关键字声明
 4     print(num)
 5     num = 123
 6     print(num)
 7 fun1()
 8 
 9 def outer():
10     num = 10
11     def inner():
12         nonlocal num   # nonlocal关键字声明
13         num = 100
14         print(num)
15     inner()
16     print(num)
17 outer()
18 -------------------------------------------------------------
19 1
20 123
21 100
22 100
global和nonlocal

 

八.函数装饰器

1.在函数名以及函数体不改变的前提下,给一个函数附加一些额外代码,扩展函数功能

2.装饰器的执行时间是立即执行

3.本身是一个函数,以函数作为一个输入,返回另一个函数

4.对有返回值的函数进行修饰,无论什么场景,保证函数返回值一致

 1 def zhanshi():
 2     print('ok')
 3 
 4 def jiaprint(func):                       #func以函数为参数的装饰器函数
 5     def wrapper():
 6         print('运行的函数名',func.__name__)#输出函数的名称
 7         func()                               #执行参数函数的功能
 8         print('over')
 9     return wrapper
10 zhanshi = jiaprint(zhanshi)          #调用函数装饰器
11 zhanshi()
12 
13 
14 #等价于:
15 #def zhanshi():
16 #  print('ok')
17 # def jiaprint(func):
18 #     print('运行的函数名',func.__name__)
19 #     func()
20 #     print('over')
21 # jiaprint(zhanshi)
22 ----------------------------------------------------------------------
23 运行的函数名 zhanshi
24 ok
25 over
函数装饰器
 1 def jiaprint(func):                       #func以函数为参数的装饰器函数
 2     def wrapper():
 3         print('运行的函数名',func.__name__)#输出函数的名称
 4         func()                            #执行参数函数的功能
 5         print('over')
 6     return wrapper
 7 
 8 @jiaprint#等价于zhanshi = jiaprint(zhanshi)用函数装饰器
 9 def zhanshi2():
10     print('nono')
11 zhanshi2()#zhanshi2已经用了装饰器
12 --------------------------------------------------------------------
13 运行的函数名 zhanshi2
14 nono
15 over
函数装饰器2
 1 def checklogin(func):#利用checklogin函数对某一函数进行操作
 2     def inner():#定义一个新的函数进行返回
 3         print('登录验证...')#增加的功能
 4         func()#保持原有函数的功能
 5     return inner#返回值是一个新的函数
 6 
 7 
 8 #语法糖 写法
 9 @checklogin#利用checklogin函数对下面的函数进行增加功能的操作
10 def fss():
11     print('发说说')
12 # fss=checklogin(fss)相当于@checklogin
13 
14 @checklogin#利用checklogin函数对下面的函数进行增加功能的操作
15 def ftp():
16     print('发图片')
17 # ftp=checklogin(ftp)相当于@checklogin
18 
19 a=1
20 if a==1:
21     fss()
22 else:
23     ftp()
24 ---------------------------------------------------------------------------
25 登录验证...
26 发说说
函数装饰器3
 1 def line(func):
 2     def inner():
 3         print('-'*30)
 4         func()
 5     return inner
 6 
 7 def star(func):
 8     def inner():
 9         print('*'*30)
10         func()
11     return inner
12 
13 
14 #从上到下装饰,从下到上执行
15 @line#print_=line(print_)先装饰
16 @star#print_=star(print_)先执行
17 def print_():
18     print('打印')
19 
20 print_()
21 ------------------------------------------
22 ------------------------------
23 ******************************
24 打印
函数装饰器4
 1 def zsq(func):
 2     def inner(*args,**kwargs):
 3         print('*'*30)
 4         print(args,kwargs)
 5         func(*args,**kwargs)
 6     return inner
 7 #对有参函数进行装饰,利用不定长参数
 8 @zsq
 9 def pnum(num,num2):
10     print(num,num2)
11 @zsq
12 def pnum2(num):
13     print(num)
14 
15 pnum(123,234)
16 pnum2(26)
17 ---------------------------------------------------
18 ******************************
19 (123, 234) {}
20 123 234
21 ******************************
22 (26,) {}
23 26
函数装饰器5
 1 #带有参数的装饰器
 2 #通过@装饰器(参数)的方式,调用这个函数,并传递参数,并把返回值再次当做装饰器进行使用
 3 #先计算@后面的内容,把这个内容当做是装饰器
 4 def getzsq(char):
 5     def zsq(func):
 6         def inner():
 7             print(char*30)
 8             func()
 9         return inner
10     return zsq
11 @getzsq('*')
12 def f1():
13     print('66')
14 
15 f1()
16 ------------------------------------------------------
17 ******************************
18 66
函数装饰器6

 

九.递归函数

1.在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数

2.递归:(1)函数调用自身;(2)设置正确的返回条件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2018-05-26 20:41  温润有方  阅读(259)  评论(0编辑  收藏  举报