类型提示
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
函数的嵌套调用
d
ef 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)#输出内容