说明
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
语法
Python 定义函数使用 def 关键字
def 函数名(参数列表): ["注释"] 函数体 return定义返回值
示例
示例1
def test(): a = "this is test" #函数体 return a #返回结果print(test()) #打印结果
this is test
示例2
def test(x): """ "计算数值的平方" :param x: 输入值 :return: 返回结果 """ y = x ** 2 return ytest(3) #运行函数,因为函数里无print所以无输出内容print(test) #打印函数内存地址print(test(3)) #打印函数结果
9
自定义函数
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
函数参数
形参
只有变量在调用时才分配内存单元,在调用结束后即释放所分配的内存单元,因此,形参值在函数内部有效。函数调用结束返回主调用函数后则不能在使用该形参变量
实参
实参可以是变来那个、常量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等方法使参数获得确定值
位置参数
标准调用:实参与形参位置一一对应
def test(x,y,z): print(x) print(y) print(z)test(1,2,3)
123
位置参数组
def test(x,*args): print(x) print(args)test(1,2,3,4,5,6)
1(2, 3, 4, 5, 6)
关键字参数
关键字调用:位置无需固定
def test(x,y,z): print(x) print(y) print(z)test(1,2,z=3)
123
关键字参数组
def test(x,**kwargs): print(x) print(kwargs)test(1,kwargs=[2,3,4,5])
1{'kwargs': [2, 3, 4, 5]}
位置&关键字参混搭
位置参数必须要在关键字参数左边
def test(x,y,z): print(x) print(y) print(z)test(1,2,z=3)
123
参数组混搭
*args 接收剩余位置参数,**kwargs接收剩余关键字参数
def test(x,*args,**kwargs): print(x) print(args) print(kwargs)test(1,[2,3,4,5,6],kwargs=(7,8,9))
1([2, 3, 4, 5, 6],){'kwargs': (7, 8, 9)}
默认参数
默认参数在定义变量的同时定义
def test(x,y,z=3): print(x) print(y) print(z)test(1,2)
123
函数变量
全局变量
全局变量是在所有作用域都可访问的变量,作用域为全局
name = '小明'#[代码块]print(name)
小明
局部变量
程序中只在特定过程或函数中可以访问的变量,作用域为定义的子函数范围
name = '小明'def test(): name = '小王' print(name)test()
小王小明
局部变量引用全局变量
name = '小明'def test(x): global name #引用全局name变量 print(name)test('x')print(name)
小明小明
局部变量引用上一级变量
name = '小明'def test(): name = '小刚' def test2(): nonlocal name #引用上一级name变量 print(name) test2()test()
小刚
前向引用
被引用的类在没有完全定义时不能 实例化即声明该类的对象,也不能 在内联成员函数中使用该类的对象 可以做函数的参数 示例1
def test(): #第一步:找到函数 new_test() #第二步:运行函数体,指向另外一个函数def new_test(): #第三步:找到指向的函数 print("this is test!!!") #运行指向的函数体,输出内容【“this is test!!!”】test() #运行函数
this is test!!!
示例2
def test(): print("this is test")def test2(): #第三步:找到test2()函数 print("this is test2") #第四步:执行test2()函数体内容【输出“this is test2”】def test3(): #第一步:找到test3()函数 test2() #第二步:执行test3()函数体,内容包含指向test2()函数 print("this is test3") #第五步:执行test3()函数体,指向其它函数后的代码【输出“this is test3”】test3() #运行函数test3()
this is test2this is test3
递归
特性
必须有一个明确的结束条件
每次进入更深一层,问题规模相比上次递归都应该有所减少
递归效率不高,递归层数过多会导致栈溢出(在计算机中函数通过栈实现,没进入一个函数会增加一层栈帧,返回函数会减少一层栈针)
示例
函数式循环递归
def test(a): print(a) #输出当前值 if int(a) % 5 == 0: #当前值判断 return a #符合条件返回值 return test(int(a) - 1) #不符合条件变更值并再次调用函数本身test(9)
98765
列表中查找元素
li = ['a','b','c','d','e'] #默认列表NAME = "d" #需要查找的内容num = int(0) #记录次数,默认查找次数为“0”def test(li): #定义查找函数 global num #引用函数上一层变量 num += 1 #查找次数自加1 if len(li) == 0: #判断列表是否为空,即长度为0 return "列表中无此选项!!!" #列表为空结束并输出自定义内容 syli=li.pop(0) #pop方法删除第一个序列号元素,因为pop方法删除可以获取删除元素并赋值 if syli == NAME: #判断删除的元素是否是需要查找的内容 return '您要找的选项是第',num,'个选项','选项内容是',NAME,"!!!" #如果是,输出循环次数和查找内容 print("第",num,"选项错误,需要查找下一个选项!") #如果不是,输出查找次数和需要查找下一个选项提示 return test(li) #函数返回值,即定义的函数自身,其它情况做循环重复函数处理print(test(li)) #使用函数并打印出结果
第 1 选项错误,需要查找下一个选项!第 2 选项错误,需要查找下一个选项!第 3 选项错误,需要查找下一个选项!('您要找的选项是第', 4, '个选项', '选项内容是', 'd', '!!!')
匿名函数
简介
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
-
lambda 只是一个表达式,函数体比 def 简单很多。
-
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
-
lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
-
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法
lambda 函数的语法只包含一个语句
lambda [arg1 [,arg2,.....argn]]:expression
示例
示例1
a = lambda x:x+1print(a(2))
3
相当于
def a(x): x = x + 1 return xprint(a(2))
3
示例2
a = lambda x,y,z:x+y+zprint(a(1,2,3))
6
示例3
a = lambda x,y,z:(x+1,y+1,z+1)print(a(1,2,3))
(2, 3, 4)
函数编程
是让计算机为解决某个问题,而使用某种程序设计语言编写程序代码,并最终得到结果的过程。叫做编程,现阶段编程常用的手法有 函数式编程、面向过程编程、面向对象编程。
函数式编程
用编程语言去实现数学函数。这种函数内对象是永恒不变的,要么参数是函数,要么返回值是函数,没有for和while循环,所有的循环都是由递归去实现的,无变量的赋值(即不用变量去保存状态),无赋值即不改变。
特征
- 不可变数据
- 第一类对象
- 尾调用优化(尾递归)
简单示例
示例1
def a(x): x = x + 1 return xprint(a(2))
3