DAY9 函数初识(各种参数的用法)
函数初始
为什么需要函数?
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() #因为没有设置返回值,所以默认返回None
print(str_len)
>>>None
'''返回一个值'''
def mylen():
s1 = 'hello,world'
length = 0
for i in s1:
length = length + 1
return length
str_len = mylen()
print(str_len)
'''返回多个值:可以返回多个,任意数据类型的值'''
def demo1():
return 1,2,3,4
def demo2():
return 1,['a','b'],3,4
res1 = 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_max
max_num = mymax(y=10,x=20) #位置不用一一对应了。
print(max_num)
3.混合型参数(位置参数+关键字参数)
# 位置参数与关键字参数混合调用,但是关键字参数必须在位置参数之后。
def mymax(x,y):
the_max = x if x>y else y
return the_max
max_num = mymax(10,y=20) #关键字参数必须在位置参数之后
print(max_num)
'''站在形参的角度来看'''
1.位置参数,与上面的是一样的。
2.默认参数
''' 默认参数:把变化比较小的参数可以设置成一个默认值,在传参时可以忽略不传,如果不传就使用默认值;如果传,就会覆盖掉默认值。 默认参数使用场景:“参数的值不经常改变,但是一直在用” 谨记:默认参数的陷进!!!默认参数不要设置为可变数据类型。 ''' #默认参数 def stu_info(name,sex='male'): print(name,sex) stu_info('alex') #sex可以忽略不传 >>> alex,male stu_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 L
print(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), <class 'tuple'>) #所以可以观察到,*args会把接受到的位置参数组成一个元组。
#二。既然*args是一个元组的形式,那么就可以对它进行遍历。
def mysum(*args):
the_sum = 0
for i in args:
the_sum = the_sum + i
return the_sum
res = 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接受了1
2 #根据位置参数,形参与实参一一对应,b接受了2
3 #根据位置参数,形参与实参一一对应,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'} <class 'dict'> #**kwargs接受多个关键词参数,将他们组织成一个字典的形式。
#二。所以**kwargs符合字典的所有特性。
def car(**kwargs):
for k,v in kwargs.items():
print(f'{k}:{v}')
car(color='red',price=20,user='he')
>>>
color:red
price:20
user: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

浙公网安备 33010602011771号