第七章 函数
1. 函数的概念
如果在开发程序时,需要某块代码多次,为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织成一个小模块,这就是函数。
定义函数的格式如下:
def 函数名():
代码
demo:
def yue():
print('拿出手机')
print('打开陌陌')
print('找个漂亮妹子')
print('问她约不约')
print('ok,走起')
2. 函数的调用
使用函数名加小括号就可以调用了 写法:函数名() 这个时候函数的函数体会被执行
def yue():
print('拿出手机')
print('打开陌陌')
print('找个漂亮妹子')
print('问她约不约')
print('ok,走起')
yue()
3. 函数的返回值
执行完函数之后,我们可以使用return来返回结果
def yue():
print("约你")
print("约我")
print("约他")
return
print("约谁呀") # 这句话不会被执行
yue()
函数中遇到return,此函数结束.不在继续执行
我们现在有return返回值,我们试试返回个东西
def yue():
print("约你")
print("约我")
print("约他")
return "美女一枚"
yue()
我们现在返回了一个字符串,但是返回给谁了呢? 这个返回值返回给函数的调用者了,我们来看一下
def yue():
print("约你")
print("约我")
print("约他")
return '美女一枚'
girl = yue()
print(girl)
结果:
约你
约我
约他
美女一枚
过程:
定义了一个函数yue
调用函数
执行函数里的约你
执行函数里的约我
执行函数里的约他
返回给调用者一个字符串,这个调用者就是yue()
将返回的字符串通过一个等号赋值给白变量girl
打印变量girl的值
函数的返回值可以有多个结果:
def yue():
print("约你")
print("约我")
print("约他")
return "美女一枚", "萝莉一枚"
girl = yue()
print(type(girl)) # tuple
总结
1.遇到return,此函数结束,return后面的东西将不会在执行
2.return 关于返回值:
如果return什么都不写或者干脆就没写return,返回的结果就是None
如果return后面写了一个值,返回给调用者这个值
如果return后面写了多个结果,返回给调用者一个tuple(元祖),调用者可以直接使用解构获取多个变量
4. 函数的参数
参数,也就是函数括号里的内容 函数在调用的时候指定一个具体的变量的值 就是参数.写法如下:
def 函数名(参数):
函数体
参数分为形参和实参,写在函数声明的位置的变量叫形参,在函数调用的时候给函数传递的值叫实参。给函数传递信息的时候将实际参数交给形式参数的过程被称为传参。
4.1 实参
在函数调用的时候给函数传递的值.加实参,实际执行的时候给函数传递的信息.表示给函数xxx.
位置参数
def yue(chat, address, age):
print("拿出手机")
print("打开"+chat)
print("找个"+address+"附近漂亮的"+str(age)+"岁妹子")
print("约不约")
上述代码分析: 在访问yue()的时候,我们按照位置的顺序分别把”陌陌”,”北京”,18赋值给了chat,addr,age,在传参过程中.系统会按照位置把实参赋值到形参.形参就是一个变量名,实参就是值 传参就是在赋值
关键字参数
位置参数好不好呢? 如果是少量的参数还算OK, 没有问题. 但是如果函数在定义的时候参数非常多怎么办? 程序员必须记住, 我有哪些参数, 而且还有记住每个参数的位置, 否则函数就不能正常调用了. 那则么办呢? python提出了一种叫做关键字参数. 我们不需要记住每个参数的位置. 只要记住每个参数的名字就可以了
def yue(chat, address, age):
print("拿出手机")
print("打开"+chat)
print("找个"+address+"附近漂亮的"+str(age)+"岁妹子")
print("约不约")
yue(chat="微信", age=18, address="北京") # 关键字参数.
搞定, 这样就不需要记住繁琐的参数位置了.
混合参数
可以把上面两种参数混合着使用. 也就是说在调用函数的时候即可以给出位置参数, 也可以指定关键字参数.
# 混合参数
yue("微信", age=18, address="上海") # 正确.第一个位置赋值给chat, 后面的参数开始指定关键字.
yue(age="18", "微信", address="广州") # 错误, 最开始使用了关键字参数, 那么后面的 微信的位置就串了, 容易出现混乱
注意: 在使用混合参数的时候, 关键字参数必须在位置参数后面
4.2 形参
写在函数声明的位置的变量叫形参,形式上的一个完整.表示这个函数需要xxx
位置参数
位置参数,按照位置来赋值,到目前为止,我们编写的函数都是这种
def yue(chat,addr,age): # chat 形参
print("拿出手机")
print("打开"+chat)
print("找个" + addr +"附近漂亮的" + str(age) + "岁妹子")
print("约不约")
yue("陌陌","北京",18) # 实参
结果:
拿出手机
打开陌陌
找个北京附近漂亮的18岁妹子
约不约
默认值参数
在函数声明的时候, 就可以给出函数参数的默认值. 在调用的时候可以 给出具体的值, 也可以不给值, 使⽤用默认值. 比如, 我们录入咱们班学生的基本信息. 通过调查发现. 我们班大部分学生都是男生. 这个时 候就可以给出⼀一个sex=’男’的默认值.
def stu_info(name, age, sex='男'):
print("录入学生信息")
print(name, age, sex)
print("录入完毕")
stu_info("张强", 18)
注意:必须先声明在位置参数,才能声明默认值参数
动态参数
首先我们来回顾下位置参数
def eat(a,b,c):
print('我想吃%s%s%s'%(a,b,c))
eat('大米饭','中米饭','小米饭')
现在有个问题,你们看我这体型也知道吃的不止这些,数量也没有写,这时我们就要用到动态参数.
动态接收位置参数
在参数位置用*表示接受任意参数
def eat(*args):
print('我想吃',args)
eat('大米饭','中米饭','小米饭') # 收到的结果是一个tuple元祖
动态接收参数的时候要注意: 动态参数必须在位置参数后面
def eat(*args,a,b):
print('我想吃',args,a,b)
eat('大米饭','中米饭','小米饭')
结果:
TypeError: eat() missing 2 required keyword-only arguments: 'a' and 'b'
# eat函数在调用的时候发现缺少俩个位置参数没有进行传递
通过上述代码发现一个问题就是,我们明明给了多个参数,为什么还会提示参数未传递呢?
原因就是因为这个在搞鬼 把所有的位置参数都给接受了,所有会报错.我们尝试着把a,b放在的前面试试
def eat(a,b,*args):
print('我想吃',args,a,b)
eat('大米饭','中米饭','小米饭')
结果:
我想吃 ('小米饭',) 大米饭 中米饭
动态接收参数的时候要注意:动态参数必须在位置参数后面
那默认值参数呢?
def eat(a,b,c='白菜',*args):
print('我想吃',a,b,c,args)
eat('豆腐','粉条','猪肉','大葱')
结果:
我想吃 豆腐 粉条 猪肉 ('大葱',) # 我们定义好的白菜没有生效,被猪肉给覆盖了
我们发现默认值参数写在动态参数前面,默认值的参数是不会生效的
def eat(a,b,*args,c='白菜'):
print('我想吃',a,b,args,c)
eat('猪肉','粉条','豆腐','大葱')
结果:
我想吃 猪肉 粉条 ('豆腐', '大葱') 白菜 # 这样默认参数就生效了
这个时候如果你不给出关键字传参,那么你的默认值是永远都生效的
注意: 形参的顺序: 位置参数 , 动态参数 , 默认参数
动态接收关键字参数
在python中可以动态的位置参数,但是*这种情况只能接收位置参数无法接收关键字参数,在python中使用**来接收动态关键字参数
def func(**kwargs):
print(kwargs)
func(a=1, b=2, c=3)
结果:
{'a': 1, 'b': 2, 'c': 3}
动态关键字参数最后获取的是一个dict字典形式
顺序的问题, 在函数调用的时候, 如果先给出关键字参数, 则整个参数列表会报错.
def func(a,b,c,d):
print(a,b,c,d)
func(1,2,c=3,4)
关键参数必须要放在位置参数后边,由于实参是这个顺序,所以形参接收的时候也是这个顺序.也就是说位置参数必须在关键字参数前面.动态接收关键字参数也要在后面
最终顺序:
位置参数 > *args(动态位置参数) > 默认值参数 > **kwargs(动态默认参数)
这四种参数可以任意的使用
如果想接收所有的参数:
def func(*args,**kwargs):
print(args,kwargs)
func(1,23,5,a=1,b=6)
动态参数还可以这样传参:
lst = [1,4,7]
# 方法一
def func(*args):
print(args)
func(lst[0],lst[1],lst[2])
# 方法二
def func(*args):
print(args)
func(*lst)
# 在实参的位置上用*将lst(可迭代对象)按照顺序打散
# 在形参的位置上用*把收到的参数组合成一个元祖
字典也可以进行打散,不过需要**
dic = {'a':1,'b':2}
def func(**kwargs):
print(kwargs)
func(**dic)
4.3 传参
给函数传递信息的时候将实际参数交给形式参数的过程被称为传参.
def yue(chat): # chat 形参
print("拿出手机")
print("打开"+chat)
print("找个漂亮的妹子")
print("约不约")
yue("陌陌") # 实参
len("字符串") # "字符串"在这里就是实参
print("麻花藤") # "麻花藤"就是实参
练习
编写函数,给函数传递两个参数a,b a,b相加 返回a参数和b参数相加的和
def f(a,b):
c = a+b
return c
num_sum = f(5,8)
print(num_sum)
编写函数,给函数传递两个参数a,b 比较a,b的大小 返回a,b中最大的那个数
def f(a,b):
if a>b:
return a
else:
return b
num_sum = f(5,8)
print(num_sum)
比较大小的这个写法有点麻烦,我们在这里学一个三元运算符
def f(a,b):
c = a if a > b else b #当a>b就把a赋值给c,否则就把b赋值给c
return c
msg = f(5,7)
print(msg)