函数
类型提示
def add(x:(1,2,3), y:333333)->int: res = x + y return res r=add()#因为上面的只是提示信息,所以,没有输入参数的话就会报错 # r=add(10,20)#输出30 # r=add("xxx","tttt") print(r) print(add.__annotations__)#查看所有的提示信息
函数的参数
一、函数的参数可以分为两大类
形参:在定义函数时,括号内指定的参数,称之为形式参数,简称形参,形参的本质就是变量名
实参:在调用函数时,括号内传入的值,称之为实际参数,简称实参,实参的本质就是变量值
实参与形参的关系是:在调用函数时,实参的值会绑定给形参,该绑定关系可以在函数内使用
在函数调用结束后,会解除绑定关系
# 一、位置形参:在定义函数时,按照从左到右的顺序依次定义的变量名,称之为位置形参 # 特点:必须被传值,多一个不行,少一个也不行 # def func(x,y):#定义函数 # print(x,y)#输出 值 # func(1,2)#将1,2传入函数 # func(1,2,3)#由于多了一位,所以会报错 # func(1)#少了一位,所以也会报错
# 二、位置实参:在调用函数时,按照从左到右的顺序依次传入的值,称之为位置实参 # 特点:按照位置与形参一一对应 # def func(x,y): # print(x,y) # func(1,2)#x传入1,y传入2 # func(2,1)#x传入2,y传入1,这个会因为传入的位置不同而数值不同
# 三:默认参数(具有默认值的形参):在定义函数时,就已经为某个形参赋值了,该形参就称之为默认参数 # 特点:在调用阶段可以不用给默认形参传值 # def func(x,y=1111): # print(x,y) # # func(1,2)#这里会覆盖默认参数值,输出1,2 # func(1)#输出1,1111 # def register(name,age,gender="male"):#当出现大部分相同,少部分不同的时候,可以设置默认参数,这里的性别就可以 # print(name,age,gender) # # register("egon",18,) # register("lxx",38) # register("hxx",32,"female")#由于是女性,所以要额外设置,这样就可以覆盖默认参数 # register("李建国",30) # register("alex",31) # register("xxx",18) # 注意:位置形参与默认形参可以用混用,但是必须注意 # 1、位置形参应该跟在默认形参前 # def func(y=1111,x):#这样会报错,位置形参必须要在默认形参前面 # print(x,y) # 注意:默认形参的使用,需要注意点 # 1、默认形参的值最好是不可变类型 # # m=222 # def func(x,y=m): # print(x,y) # m=666 # func(111)#输出(111,222),并不会变成666 # m=[222,] # def func(x,y=m): # print(x,y) # m.append(666) # func(111)#会输出111,[222,666]但并不建议这样使用
# def register(name,hobby,hobbies=[]): # hobbies.append(hobby) # print('%s 的爱好们是 %s' %(name,hobbies)) # register("egon","smoke") # register("lxx","lang") # register("hxx","drink") #上述会输出人物以及爱好,但是这样会让后面的人物的爱好增多,并不能达到想要的效果
# def register(name,hobby,hobbies=None):#设置hobbies为None # if hobbies is None:#因为hobbies就是为None,所以条件会一直成立 # hobbies=[]#创建一个新列表 # hobbies.append(hobby)#将hobby得到的参数再送到hobbies里 # print('%s 的爱好们是 %s' %(name,hobbies)) # # register("egon","smoke") # register("lxx","lang") # register("hxx","drink")
# 四:关键字实参:在调用函数时,按照key=value的形式指定的实参,称之为关键字实参 # 特点:可以打乱顺序,但仍能指名道姓地为指定形参赋值 # def func(x,y=22222): # print(x,y) # func(y=2222,x=111) # func(x=111) # 注意:位置实参与关键字实参可以用混用,但是必须注意 # 1、位置实参必须放在关键字实参的前面 # 2、不能为同一个形参重复赋值 # def func(x,y=22222): # print(x,y) # func(1,y=2) # func(y=2,1) # func(1,y=2,x=3)#多了一个x的参数,所以会报错,不能重复赋值
五:可变长参数-》*与**的应用
可变长指的是在调用函数时,传入实参个数不固定,而实参是为形参赋值的,所以,必须必须对应格式的形参来接收溢出的实参
*与**可以用在形参中,专门用于应对溢出的实参
# 5.1 在形参中带*:*会将溢出位置实参汇总成元组,然后赋值给其后变量名,通常应该是args # def func(x,y,*z): # x=1 y=2 z=(3,4,5) # print(x,y,z) # func(1,2,3,4,5) # func(1,2) # func(1) # def my_sum(*args): # res=0 # for i in args: # res+=i # print(res) # # my_sum(1) # my_sum(1,2)#输出3 # my_sum(1,2,3)#输出6
# 5.2 在形参中带**:**会将溢出关键字实参汇总成字典,然后赋值给其后变量名,通常应该是kwargs # def func(x,y,**kwargs): # x=1 y=2 kwargs={"b":2,"c":3,"a":1} # print(x,y,kwargs) # # func(1,y=2,a=1,b=2,c=3) *与**也可以用在实参中
# 5.3 在实参带*: *会将紧跟其后的实参打散成位置实参,注意*后跟的应该是一个可以被for循环循环的类型 # def func(a,b,c,d): # print(a,b,c,d) # # # func(*"hell") # func("h","e","l","l") # # func(*[11,22,33,44]) # func(11,22,33,44) # # func(11,22,*[33,44]) # func(11,22,33,44) # func(11,22,*{"k1":333,"k2":4444}) # func(11,22,"k1","k2")
# 5.4 在实参带**: **会将紧跟其后的实参打撒成关键字实参,注意**后跟的必须是一个字典 # def func(a,b,c,d): # print(a,b,c,d) # func(**{"k1":333,"k2":4444}) # func(k2=4444,k1=333) # func(**{"d":333,"b":4444,"a":1111,"c":2222}) # func(a=1111,c=2222,b=4444,d=333) # func(**[("a",111),("b",111),("c",111),("d",111)]) # 错误
# 混用 # 1、在形参中,*必须放在**前 # 2、在实参中,*必须放在**前 def index(x,y,z): print('index======>',x,y,z) def wrapper(*args,**kwargs): # args=(1,2,3,4) kwargs={"a":1,"b":2,"c":3} index(*args,**kwargs) # index(*(1,2,3,4),**{"a":1,"b":2,"c":3}) # index(1,2,3,4,a=1,b=2,c=3) # wrapper(1,2,3,4,a=1,b=2,c=3) # wrapper(1,2,3) # wrapper(z=3,y=2,x=1)
# 六 命名关键字形参:在*与**之间后定义的形参 # 特点:必须按照key=value的形式传值 def func(x,y=1,*args,a=666,b,**kwargs): print(x) print(y) print(args) print(a) print(b) print(kwargs) # func(1,2,3,4,5,6,7,a=111,b=222,c=333)#2,1,(3,4,5,6,7),111,222,{'c':333} func(1,2,3,4,5,6,7,b=222,c=333)
函数对象
函数是第一等公民
def func(): # func=函数的内存地址 print('from func')
# 1、可以赋值 # f=func # f() # 2、可以当做参数传给另外一个函数 #def func(): # func=函数的内存地址 # print('from func') # def bar(x): # print(x) # mmm=1111111 # bar(mmm) # bar(func) # 3、可以当做一个函数的返回值 # def add(x): # x=函数func的内存地址 # return x # return 函数func的内存地址 # # res=add(func) # add(函数func的内存地址) # print(res) # 4、可以当做容器类型的元素 # x=10 # l=[x,func] # # print(l) # l[-1]()
def login():#定义一个login函数 print('login') def register():#定义一个register函数 print('register') def tranfer():#定义一个tranfer函数 print('transfer') def withdraw():#定义一个withdraw函数 print('withdraw') #下面这段为了能够对两种状态输出不同的内容,所以采用列字典和列表结合,需要添加新功 #能时就可以直接在下面添加新列表就可以了 func_dic={ "1":[login,"登录"], "2":[register,"注册"], "3":[tranfer,"转账"], "4":[withdraw,"提现"] } while True:#当条件为真。所以会一直满足条件 print("0 退出")#输出括号里面的内容 for k in func_dic:#当输入的内容在上面的字典里时 print(k,func_dic[k][-1]) #输出字典里的key并且输出key对应的列表里的最后一个内容 choice=input("请输入操作编号: ").strip()#将输入的内容赋值给choice if choice == "0":#如果输入为0 break#退出 if choice in func_dic:#如果输入的内容在定义的函数里 func_dic[choice][0]() #先不看最后的括号,,前面通过输入的数字与o能够获取到里面的字符串, #字符串再与后面的括号相结合就能调用上面定义好的函数 else:#如果都不满足 print("输入的操作不存在")
函数嵌套
# def f1(): # print('from f1') # def f2(): # print('from f2') # # print(f2) # f2() # f1() #from f1----结果 #from f2
# from math import pi#从math导入pi # # def circle(radius,mode=0):#radius半径需要传入,mode是要选用的模式 # def perimiter(radius):#定义函数周长 # return 2 * pi * radius#返回2Πr的结果 # # def area(radius):#定义函数面积 # return pi * (radius ** 2)#返回Πr^2的结果 # # if mode == 0:#如果选择的模式为0 # return perimiter(radius)#调用周长的函数,并返回结果 # elif mode == 1:#如果选择的模式为1 # return area(radius)#调用面积的函数,并返回结果 # # res=circle(10,mode=1)#调用circle函数,传入参数,并赋值给res # print(res)#输出res
# 函数的嵌套调用 def max2(x,y):#定义max2函数 if x > y:#如果x大 return x else:#如果y大 return y def max4(a,b,c,d): res1=max2(a,b)#将1,2传入函数max2里 res2=max2(res1,c)#将上面得到的结果拿来与3再传入函数max2里 res3=max2(res2,d)#将上面得到的结果拿来与4再传入函数max2里 return res3#返回res3的内容 res=max4(1,2,3,4)#调用函数max4,并且参数时1,2,3,4,赋值给res print(res)#输出内容
浙公网安备 33010602011771号