函数初始
为什么需要函数?
1.合并重复,减少代码的重复率。
2.测试方便
3.修改方便
4.打包
5.映射
函数的最主要目的:封装一个功能。
函数的定义:
def 函数名(argv): 函数体
def : 定义函数的关键字。
函数名:自定义函数名,一般都为小写字母,与变量名一样最好具有良好的描述性。
argv : 参数,可以有多个,用","逗号分隔
statement : 函数体,具体的代码
return :函数的返回值,默认不写的话返回的是None;可以没有返回值,可以返回一个值,可以返回多个值。
创建函数,调用函数:
def mylen(): """ 创建了一个名为mylen的函数 计算s1的长度 """ s1 = "hello world" length = 0 for i in s1: length = length+1 print(length)mylen() #执行函数,函数名()表示执行函数。
函数的返回值:return
作用:
1.函数一旦遇到return,就会结束。
2.给函数的执行者返回值,方便后续使用
类型:
1.没有返回值,默认返回的是None。
2.返回一个值。
3.返回多个值,以元组的形式返回。
'''没有返回值,默认返回的是None'''def mylen(): s1 = 'hello,world' length = 0 for i in s1: length = length +1 print(length)str_len = mylen() #因为没有设置返回值,所以默认返回Noneprint(str_len)>>>None'''返回一个值'''def mylen(): s1 = 'hello,world' length = 0 for i in s1: length = length + 1 return lengthstr_len = mylen()print(str_len)'''返回多个值:可以返回多个,任意数据类型的值'''def demo1(): return 1,2,3,4def demo2(): return 1,['a','b'],3,4res1 = demo1()res2 = demo2()print(res1)print(type(res1)) # 元组print(res2)print(type(res2)) #元组
函数的参数:形参与实参
形参:函数完成其工作所需要的一项信息,只是一个形式,用于接受实参。
实参:调用函数时,实际传递给函数的信息。
'''站在实参的角度来看'''
1.位置参数
#位置参数:调用函数时,python必须将函数调用中的实参与每一个形参关联,为此最简单的关联就是按照位置关联。因此,位置参数中,形参与实参的个数必须一样,位置一一对应。def describe_pet(animal_type,pet_name): print('I have a '+ animal_type + '.') print('My '+ animal_type +"'s name is " + pet_name.title())describe_pet('dog','herry')>>>I have a dog.My dog's name is Herry#如果改变参数的位置describe_pet('dog','herry')>>>I have a herry. #animal_type这个形参接受的就是‘herry’了.My herry's name is Dog
2.关键字参数
# 关键字参数:用在函数调用的时候,通过关键字传值,可以不需要一一对应位置顺序。def mymax(x,y): the_max = x if x>y else y return the_maxmax_num = mymax(y=10,x=20) #位置不用一一对应了。print(max_num)
3.混合型参数(位置参数+关键字参数)
# 位置参数与关键字参数混合调用,但是关键字参数必须在位置参数之后。def mymax(x,y): the_max = x if x>y else y return the_maxmax_num = mymax(10,y=20) #关键字参数必须在位置参数之后print(max_num)
'''站在形参的角度来看'''
1.位置参数,与上面的是一样的。
2.默认参数
'''默认参数:把变化比较小的参数可以设置成一个默认值,在传参时可以忽略不传,如果不传就使用默认值;如果传,就会覆盖掉默认值。默认参数使用场景:“参数的值不经常改变,但是一直在用”谨记:默认参数的陷进!!!默认参数不要设置为可变数据类型。'''#默认参数def stu_info(name,sex='male'): print(name,sex)stu_info('alex') #sex可以忽略不传>>>alex,malestu_info('eva_j','female') #sex的默认值会被覆盖>>>alex,female#默认参数的陷进:默认参数不要为可变数据类型。def default_para(a,l=[]): l.append(a) print(l)default_para('alex')# >>>['alex']default_para('egon')# >>>['alex', 'egon']!!!通过查看id,发现两次调用函数列表的内存地址都是一样的,说明列表都是同一个列表!!!
#像列表这种可变类型的改进方法:def default_para(a,L=None): if L is None: L = [] L.append(a) return Lprint(default_para('alex'))>>>['alex']print(default_para('egon'))>>>['egon']
3.任意参数,动态参数:在函数定义的时候,在上*代表的是聚合。
一. *args:接受位置传值,把所有位置参数都由*args接受,聚合保存为一个元组。
#一。观察*args的表现形式def foo(*args): return args,type(args)print(foo(1,2,3,4,5))>>>((1, 2, 3, 4, 5),) #所以可以观察到,*args会把接受到的位置参数组成一个元组。#二。既然*args是一个元组的形式,那么就可以对它进行遍历。def mysum(*args): the_sum = 0 for i in args: the_sum = the_sum + i return the_sumres = mysum(1,2,3,4)print(res)#三。观察位置参数,与*args接受参数def foo2(a,b,c,*args): print(a) print(b) print(c) print(args)foo2(1,2,3,4,5,6,7,8)>>>1 #根据位置参数,形参与实参一一对应,a接受了12 #根据位置参数,形参与实参一一对应,b接受了23 #根据位置参数,形参与实参一一对应,c接受了3(4, 5, 6, 7, 8) #*args接受了剩下的所有位置参数;*args就相当于一个大胃王,把剩余的位置参数都吃掉。#四。如果没有给*args传值,它会报错吗???def foo3(a,b,c,*args): print(a) print(b) print(c) print(args) foo3(1,2,3) #根据形参与实参一一对应,a接受了1,b接受了2,c接受了3,*args没有参数,会如何?>>>1 2 3() #根据结果我们可以知道,就算没有给*args传值,它会形成一个()空元祖。'''从上面的代码,我们可以知道。*args就是一个胃口极大的家伙,会把多个位置参数都接受。所以位置参数必须放置在*args的前面。'''
1.1 位置参数,默认参数,*args的顺序
#前提:从上面的代码,我们已经知道:#1.位置参数需要放在默认参数的前面。#2.位置参数需要放在*args的前面。#那么,默认参数和*args的排序位置又是怎么样的呢?我们接下来就来分析~#一。默认参数在*args的前面def foo4(a,b,c,d='alex',*args): print(a) print(b) print(c) print(d) print(args)foo4('he','bob','taibai','wusir','evj')>>>he #a接受'he'bob #b接受'bob'taibai #c接受'taibai'wusir #d原本是默认参数,这里接受到了新的值,所以原值被覆盖了('evj',) #*args接受剩下的位置参数##从上面看出,默认参数如果在*args的前面,原值就会被覆盖掉,所以默认参数需要放置到*args的后面##
参数顺序: ‘位置参数 *args 默认参数’
1.2 *args的拓展以及魔法方法
# 如果有现成的列表,可以通过“*列表名”把列表传入#一。如果传入不加“*”l1 = [1,2,3]l2 = ['he','alex','wusir']def func(*args): print(args)func(l1,l2) >>> ([1, 2, 3], ['he', 'alex', 'wusir']) #会把每个列表当成一个独立的元组的元素#魔法方法:打散l1 = [1,2,3]l2 = ['he','alex','wusir']def func(*args): print(args)func(*l1,*l2)>>>(1, 2, 3, 'he', 'alex', 'wusir') #会把列表的元素打散,然后组成一个元组。
二. **kwargs:keyword args,顾名思义关键词动态参数,与字典对应。
# 一。**kwargs接受关键字参数,观察其表现形式def func(**kwargs): print(kwargs,type(kwargs))func(name='he',age=23,sex='male')>>>{'name': 'he', 'age': 23, 'sex': 'male'}#**kwargs接受多个关键词参数,将他们组织成一个字典的形式。#二。所以**kwargs符合字典的所有特性。def car(**kwargs): for k,v in kwargs.items(): print(f'{k}:{v}')car(color='red',price=20,user='he')>>>color:redprice:20user:he#三。从上面我们已经理清楚了位置参数,默认参数,*args的顺序的问题。现在,加入**kwargs会如何?###系统规定了**kwargs放在所有参数的最后面。####def func(a,b,*args,sex='male',**kwargs): print(a) print(b) print(args) print(sex) print(kwargs)func(1,2,3,4,5,6,name='he',age=23,sex='female')#所以,参数的位置为:位置参数,*args,默认参数,**kwargs
参数顺序: ‘位置参数 *args 默认参数 **kwargs’
2.1 **kwargs的拓展以及魔法方法
#如果现在有现成的列表,可以通过**dict把字典传入dic = {'color':'red','price':100}def car(**kwargs): print(kwargs)car(**dic)>>>{'color': 'red', 'price': 100}# 魔术方法:打散def func(**kwargs): print(kwargs)dic = {'name1':'he','age1':23}dic1 = {'name2':'alex','age2':33}func(**dic,**dic1)>>>{'name1': 'he', 'age1': 23, 'name2': 'alex', 'age2': 33}
三. 结合*args,**kwargs的函数,称为万能参数。
# *args接受所有的位置参数,**kwargs接受所哟关键字参数。def func(*args,**kwargs); pass