函数操作
定义函数时申请内存空间保存函数体代码,将上述内存地址绑定函数名。定义函数时不会执行函数整体代码,但是会检测函数语法。
调用函数时通过函数名找到函数的内存地址,然后触发函数体代码的执行。
1,函数
1.1 无参函数:def func():
1.2 有参函数:
def jisuan(x,y): print(x+y) print(x*y) jisuan(2,3) # 5 # 6
1.3 空函数,函数代码体为pass:
def func(x,y): pass def pai(): name = input("你的姓名:") age = input("你的年龄:") msg = "名字:{} 年龄:{}".format(name,age) print(msg) pai()
2, 函数的参数:
2.1 参数定义: 函数形参, 在定义函数阶段定义的参数称之为形式参数,简称形参,相当于变量名
函数实参, 在调用函数时传入的值称之为实际参数,简称实参,相当于变量值
在调用函数时,实参(变量值)会绑定给形参(变量名),这种绑定关系只能在函数体内使用,调用关系结束后接触绑定关系。
2.2, 位置参数:按照从左到右的顺序依次定义的参数称之为位置参数
位置形参的特点:必须被传值,参数不能多也不能少
位置实参:在函数调用阶段,按照位置的顺序与形参一一对应
def func(x,y): print(x,y) func(1,2)
2.3 关键字实参:在函数调用阶段,按照key=value的形式传入的值
def func1(a=1,b=2): print(a,b) func1(a=7,b=8)
2.4 默认参数:
默认形参:在定义函数阶段,就已经被赋值的形参,在调用阶段不用为其赋值,若后续需要重新赋值也是可以再赋值的。
默认值传的是值的内存地址,虽然可以传任意类型,但是最好不要传可变类型。
函数调用最好不受外界代码的影响
def func(x,y=3): print(x,y) func(x=1) func(x=1,y=5) def func(x,y,z,l=None): if l is None: l = [] l.append(x) l.append(y) l.append(z) print(l) new_l = [11,22] # 最好不要用可变类型来传参 func(1,2,3,new_l)
2.5 可变长参数(收集参数):在调用参数时,传入的值(实参)不固定
(1)、*形参名:用来接收溢出位置实参,*后面约定俗成跟args
def func(x,y,*z): print(x,y,*z) func(1,3,5,2,6,7,4) # 1 3 5 2 6 7 4
def func(x,y,*z): print(x,y,z) func(1,3,5,2,6,7,4) # 1 3 (5, 2, 6, 7, 4)
(2)、**形参名:用来接收溢出的关键字实参,**后面约定俗成跟kwargs
def func(x,y,**kwargs): print(x,y,kwargs) func(x=1,y=2,z=3,zz=7,zzz=9) # 1 2 {'z': 3, 'zz': 7, 'zzz': 9}
2.6 案例:
*和**混合使用:
*args必须在**kwargs的前面
def func(*args,**kwargs): print(args,kwargs) func(1,2,4,2,a=3,b=7,c=8) # (1, 2, 4, 2) {'a': 3, 'b': 7, 'c': 8}
5、命名关键字参数:
在定义函数时,在*后定义的参数,称之为命名关键字参数。命名关键字实参必须按照key=value的形式传参
# 定义方式一: 跟在*后面的一个参数时命名关键字参数,必须要用关键字形式传参 def guanjian(a,b,*,c): print(a,b,c) print("其中{}是关键".format(c)) guanjian("时间","金钱",c="健康") # 时间 金钱 健康 # 其中健康是关键 # 定义方式二: 在*args和**kwargs之间的参数是命名关键字参数,必须要用关键字形式传参 def guanjain(*args,a,**kwargs): print(args,a,kwargs) print("其中{}是关键".format(a)) guanjain("时间","金钱",a="健康",健康="财富") # ('时间', '金钱') 健康 {'健康': '财富'} # 其中健康是关键
3, 函数名的使用:
3.1 可以当成变量用
def func(): print("啥意思") def foo(x): print(x) foo(func) # <function func at 0x000002ABC7CCD268>
3.2 可以赋值
def func(): print(123) f=func print(f,func) f() # <function func at 0x00000239847E1F28> <function func at 0x00000239847E1F28> # 123
3.3 可以当做另外一个函数的返回值
def func(): print(123) def foo(x): return x res = foo(func) print(res) # <function func at 0x000002671377D268>
3.4 可以当做容器类型的一个元素
def func(): print(123) l = [func] l[0]() # 123 print(l[0]) # <function func at 0x000001383D1ED268>
3.5 函数调用小案例:
def quqian(): print("取钱") def cunkuan(): print("存款") def zhuanzhang(): print("转账") def chazhang(): print("查账") def zhuce(): print("注册") def tuichu(): exit() yinhang = { "0":["取钱",quqian], "1":["存款",cunkuan], "2":["转账",zhuanzhang], "3":["查账",chazhang], "4":["注册",zhuce], "5":["退出",tuichu] } while True: for k in yinhang: print(k,yinhang[k][0]) choice = input("请输入编号:").strip() choice = str(choice) if choice in yinhang: yinhang[choice][1]() else: print("请按规定输入数字编号,谢谢。")
3.6 *和**的用法: 在函数的定义处,*和**用来接收数据,*将数据打包成一个元祖,**将数据打包成一个字典
在函数的调用处,*和**用来拆解数据,*一般用于列表或者元祖,**一般用于字典
优点在于可以控制函数参数的个数,不管实参有多少个,形参都只有两个
形参书写的顺序: 普通形参==>默认形参==>普通收集参数==>命名关键字参数==>关键字收集参数
def send(*args,**kwargs): print(args) print(kwargs) list1 = ["蓝天","白云"] dict1 = {"空气":"优","心情":"棒"} send(*list1,**dict1)
4, return的用法: return可以返回函数的自定义值,返回到调用处.
return后面可以跟六大标准数据类型,和函数和类对象,如果没有自定义返回值,默认返回None
在函数中如果执行到return,则return后面的代码都会停止执行
def fanhui(num): for i in range(num): print(i) if i == 8: return "不执行了" fanhui(10) res = fanhui(10) print(res)
5, 全局变量和局部变量: 全局变量:作用域在整个文件,在函数外定义的变量,在函数内部用global关键字将变量变成全局变量
局部变量:作用域在函数体内
def func(): a = 1 print(a) func() # 1 print(a) # 报错 a是局部变量 a = 1 def func(): print(a) func() # 1 此时a 是全局变量 # 将局部变量变成全局变量:global def func(): global a a = 1 print(a) func() # 1 print(a) # 1
6, 函数嵌套:
函数嵌套的调用,就是在调用函数的过程中又调用了其他的函数。
函数嵌套的定义,就是在函数内定义其他函数。
6.1 闭包函数:
闭包函数=名称空间与作用域+函数嵌套+函数对象
“闭”函数是指该函数是内嵌函数,“包”函数指对该函数外层函数的作用域名字的引用
闭包函数与函数对象的应用:
def f(): x=10 def f1(): print(x) return f1 res=f() print(res) # <function f.<locals>.f1 at 0x0000018ACE6859D8> 将f1的内存地址变成了全局变量
6.2 递归函数:
定义:是函数嵌套调用的一种特殊形式,在函数调用的过程中直接或间接的调用到本身。(递归函数默认层数是1000层)
def func(n): if n > 10: return n else: n+=1 func(n) print(n) func(5)
为防函数一直调用,可以加return来结束函数
l=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10]]]]]]]]]] def f1(list1): for i in list1: if type(i) is list: f1(i) else: print(i) f1(l)
利用递归函数取出每个列表里面的值。