函数——函数的参数,对象
一、函数的参数
函数的参数分两类
1、定义阶段函数内指定的参数称之为形式参数,简称形参
形参就相当于变量名
2、调用阶段括号内传入的值称之为实际参数,简称实参
实参就相当于变量值
调用函数时会将实参的值绑定给形参,变量只能在函数内用
1、第一组形参与实参
1.1、位置形参:按照从左到右的顺序依次定义形参
特点:必须被传值,多一个不行少一个也不行
def func(x,y): # x = 1 # y = 2 print(x,y) func(1,2,3) func(1)
2.2、位置实参:按照从左到右的顺序依次定义实参
特点:按照位置与形参一一对应
def func(x,y): # x = 1 # y = 2 print(x,y) func(1,2) func(2,1)
3.3、关键字实参:按照key=value的形式为指定的形参传值
特点:指名道姓为某个形参传值,可以完全打乱顺序
def func(x, y): print(x, y) func(1,2) func(y=2, x=1)
注意:可以混用位置实参与关键字实参,但是
注意1、不能对同一个形参重复赋值
def func(x,y):
print(x,y)
# func(1,2,x=111)
注意2、关键字实参必须跟在位置实参的后面
def func(x,y):
print(x,y)
func(1,y=2)
func(y=2,1)
4.4、默认参数:
特点:
具有默认值的形参,指的是在定义函数阶段就已经为参数赋值,这意味着在调用函数阶段可以不用为默认参数传值
def func(x,y=1111): print(x,y) func(1) func(1,222)04 def register(name,age,gender="male"): print(name,age,gender) register("张三",18) register("李四",19,) register("王五",20,) register("egon",16) register("陈光照",15,"female") 注意: 注意1、位置形参必须放在默认形参的前面 def func(y=1,x): print(x,y) 注意2、默认形参的值是在函数定义阶段就被固定的,如果调用没有为默认形参传值,那么不会每次调用都重新赋值 函数的调用彼此之间应该做到没有关联,所以说默认形参的通常应该是不可变类型 def func(name, names=[]): # name = "张三" # names=[] names.append(name) # names=["张三"] print(names) func("egon") func("张三") func("李四") def func(name, names=None): if names is None: names = [] names.append(name) # names=["张三"] print(names) func("egon") func("张三") func("李四")
2、第二组形参与实参
可变长参数
可变长指的是在调用函数时,传入的实参个数不固定,而实参是为形参赋值的
所以对应着也应该有新的形参格式来负责接收不固定长度的实参
一:===========形参中带*与** *形参名:*会负责把溢出的位置实参存成元组然后赋值给后面的形参名,形参名通过应该是args def func(x,y,*z): # y = (2,3) print(x,y,z) func(1,2,3) func(1,2,3,4,5) func() # 报错 **形参名:**会负责把溢出的关键字实参存成字典然后赋值给后面的形参名,形参名通过应该是kwargs def func(x,y,**z): # print(x,y,z) func(1,2,a=111,b=222,c=333) 注意:*与**在形参中混用,整体的顺序如下 def func(x,y=2,*m,**n): print(x,y,m,n) func(1,) func(1,2,4,5,6,7,a=1,b=2) def func(*args, **kwargs): print(args, kwargs) func(1,2,3,4,5,6,a=1,b=2,c=3) def add(*args): res=0 for i in args: res+=i print(res) add(1,2,3) 二:===========实参中带*与** def func(x, y): print(x, y) 1、实参中带*,*后跟的那个值应该是一个可以被for循环遍历的值 *会后面的那个值打散成位置实参 func(*(111,222,333)) #func(111,222,333) func(*(111,222)) #func(111,222) func(*"hello") #func("h","e","l","l","o") func(*{"k1": 111, "k2": 222,}) # func("k1","k2") 2、实参中带**,*后跟的那个值应该是一个字典 **会后面的那个值打散成关键字实参 func(**{"k1": 111, "k2": 222, }) # func(k2=222,k1=111) func(**{"x": 111, "y": 222, }) # func(y=222,x=111) func(**[("x",111),("y",222)]) # func(y=222,x=111) 三:形参与实参中混用*与** def func(*args, **kwargs): print(args, kwargs) func(1, 2, 3, 4, 5, a=1, b=2, c=3) func((1, 2, 3, 4, 5), {'a': 1, 'b': 2, 'c': 3}) func(*(1, 2, 3, 4, 5), **{'a': 1, 'b': 2, 'c': 3}) # func(1, 2, 3, 4, 5, a=1, b=2, c=3) def index(x, y): print(x, y)
形参中带*与**是汇总操作 实参中带*与**是打散操作 def wrapper(*args,**kwargs): # args=(1,2,3,4,5) kwargs={"a":1,"b":2,"c":3} index(*args,**kwargs) index(*(1,2,3,4,5),**{"a":1,"b":2,"c":3}) index(1,2,3,4,5,a=1,b=2,c=3) 直接调用的是wrapper,然后通过wrapper间接调用index wrapper(1,2,3,4,5,a=1,b=2,c=3) wrapper(1,2) wrapper(y=2,x=1) wrapper(1,y=2)
了解(**) def func(*args, y, **kwargs): print(args) print(y) print(kwargs) # func(1,2,3,a=1,b=2,c=3) # func(1,2,y=3,a=1,b=2,c=3) def func(*args, x=1, y, **kwargs): print(args) print(x,y) print(kwargs) func(1,2,y=3) def func(x, y=111, *args, z, **kwargs): pass
二、函数的对象
在python函数是第一类对象,简称函数对象
函数对象指的就是可以把函数当做变量一样去使用
1、可以赋值
def foo(): print('from foo') print(foo) f=foo f()
2、可以当做参数传给另外一个函数
def func(aaa): # aaa=函数foo的内存地址 print(aaa) # aaa() def foo(): print('from foo') func(foo)
3、可以当做函数的返回值
def func(aaa): # aaa=函数foo的内存地址 return aaa # 返回的是函数foo的内存地址 def foo(): print('from foo') res=func(foo) print(res) res()
4、可以当做容器类型的元素
def foo(): print('from foo') l=[foo] print(l) l[0]()
示范:
def login(): print('登录功能') def register(): print('注册功能') def transfer(): print('转账功能') def charge(): print('充值') def withdraw(): print('提现') func = { "1": ("登录",login), "2": ("注册",register), "3": ("转账",transfer), "4": ("充值",charge), "5": ("提现",withdraw) } while True: print("0 退出") for k,v in func.items(): print(k,v[0]) choice = input("请输入你的操作编号:").strip() if choice == "0": break if choice in func: func[choice][1]() else: print("输入的指令不存在")