date: 2021-06-12title: Python函数介绍 #标题
tags: python #标签
categories: python # 分类
python中函数的使用场景一般常见于有大量重复代码,这样可以通过将重复代码定义为一个函数,当有需要时,直接调用函数即可,python也给我们提供了很多内置函数,比如len()、count()、open()…,关于函数的好处我们不多说,这篇博文主要是记录下函数相关的知识点。
函数传参的三种方式
我们在定义一个函数时,支持三种传参方式,分别是位置传参,关键字传参和混合传参,先来看看这三种方式的代码是什么样的:
def my_info(name, age, sex, hight, weight):
return '我叫{},年龄:{},性别{},身高:{},体重:{}'.format(name, age, sex, hight, weight)
# 位置传参
print(my_info('吕建钊', '18', '男', '175', '160'))
# 关键字传参
print(my_info(age='18', name='吕建钊', hight='175', sex='男', weight='160'))
# 混合传参
print(my_info('吕建钊', '18', hight='175', sex='男', weight='160'))
# 打印结果如下
我叫吕建钊,年龄:18,性别男,身高:175,体重:160
我叫吕建钊,年龄:18,性别男,身高:175,体重:160
我叫吕建钊,年龄:18,性别男,身高:175,体重:160
三种传参方式的特性:
- 位置参数:调用函数时,写参数必须按照顺序来写,不可以颠倒顺序;
- 关键字参数:调用函数传参时,需要指明参数接收名字和值,对参数传入顺序没有要求
- 混合传参:位置参数必须在关键字传参之前,并且位置参数顺序不能乱,后面关键字传参,对顺序没有要求。
什么是形参、实参
我们先来看一段代码:
def my_info(name, age, sex, hight, weight):
return '我叫{},年龄:{},性别{},身高:{},体重:{}'.format(name, age, sex, hight, weight)
print(my_info('吕建钊', '18', '男', '175', '160'))
在上面的代码中,定义函数my_info的括号中的参数,就可以理解为是形参,而在下面print语句中调用函数时,传入的参数,就是实参。
函数的默认参数
我们在使用系统内置函数时,会发现有些函数的参数是可传可不传的,传参的话,需要使用关键字传参,所以不难发现,python内置的函数,大多数是属于混合传参的形式的,这里以open()函数为例:
# open函数使用示例如下,可以看出来使用的是混合传参
open('改文件测试',encoding='utf-8')
# 我们可以看看open函数的定义:
def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True): # known special case of open
上面就是open函数的定义,可以看到mode参数默认为r模式,也就是说,我们在使用open函数打开文件时,默认是以读的方式打开文件的,也是最常用的方式,所以才会设置默认值。
下面来一个带默认参数的函数示例:
def my_info(name, age, hobby='唱歌'):
return '我叫{},今年{}岁,爱好{}'.format(name, age, hobby)
print(my_info('吕建钊', '18'))
# 打印如下:
我叫吕建钊,今年18岁,爱好唱歌
# 也可以传入hobby参数,覆盖默认值,如下:
def my_info(name, age, hobby='唱歌'):
return '我叫{},今年{}岁,爱好{}'.format(name, age, hobby)
print(my_info('吕建钊', '18',hobby='跑步'))
# 打印如下:
我叫吕建钊,今年18岁,爱好跑步
注意,如果设置了默认参数值,那么位置参数一定要在前面写,顺序不能乱,关键字参数写在位置参数后,对顺序没要求。
函数的万能参数
*args—接收所有位置参数
我们先来看一段代码:
'''
在定义函数时,* 是将所有位置参数聚合到了一个元组中,然后赋值给了args这个变量
'''
def eat(*args):
return '我想吃%s,%s,%s,%s,%s' % args
print(eat('鸡', '鸭', '鱼', '猪肉', '白菜'))
打印如下:
我想吃鸡,鸭,鱼,猪肉,白菜
可以看到,一个*args
接收了所有位置参数,这就是它的功能。
**kwargs—接收所有关键字参数
还是先来代码:
'''
在函数定义时,** 是将所有的关键字参数聚合到了一个字典中,然后赋值给了变量kwargs
'''
def eat(**kwargs):
return kwargs
print(eat(food1='鸡', food2='鸭', food3='鱼', food4='猪肉', food5='白菜'))
args和kwargs的混合使用
如果代码如下:
def test(*args, **kwargs):
return args, kwargs
l = [1, 2, 3, 4]
d = {'a': 1, 'b': 2}
如果我们在调用函数时,想将上述两个变量分别传给*args
和**kwargs
,正常第一反应是这样写:
print(test(l, d))
# 打印如下:
(([1, 2, 3, 4], {'a': 1, 'b': 2}), {})
可以看到l
和d
这两个变量,都赋值给了*args
参数,而**kwargs
参数打印出了一个空字典,那么,如果想达到我们想要的效果应该这样写:
print(test(*l, **d))
# 打印如下:
((1, 2, 3, 4), {'a': 1, 'b': 2})
万能参数和位置参数、关键字参数同时存在
如果你需要在函数中,同时定义位置参数、关键字参数、万能参数,那么请按照如下顺序:
def my_info(a,b,*args,sex='男',**kwargs):
print(a)
print(b)
print(args)
print(sex)
print(kwargs)
my_info(1,2,3,4,5,sex='女',name='张三',hobby='跳舞')
# 打印结果如下:
1
2
(3, 4, 5)
女
{'name': '张三', 'hobby': '跳舞'}
# 上述代码,如果能看懂原理,就自己理解,不能的话,死记格式即可
调用函数时的函数聚合和函数打散
先看代码:
def fuc(*args):
print(args)
fuc([11, 22], [33, 44])
# 打印如下:
([11, 22], [33, 44])
从上面代码输出结果可以看出,将传入的两个列表聚合到了一个列表中,那么我如果想要(11, 22, 33, 44)
这样的效果呢?那就得用到函数调用时的聚合,正确代码如下:
def fuc(*args):
print(args)
# 在元素前加一个*表示聚合
fuc(*[11, 22], *[33, 44]) # 等同于 fuc(11,22,33,44)
我们看到一颗*
是这种效果,那么两颗*
是什么效果呢?我们来看下面的代码:
def fuc(**kwargs):
print(kwargs)
fuc(**{'name': '张三'}, **{'age': 18}) # 等同于fuc(name='张三',age=18)