一、什么是函数
函数就是代码的一种组织形式,是指将一组语句的集合通过一个名字(函数名)封装起来,要想指向这个函数,只需要调用其函数名即可
函数分为两大类:内置函数 和 自定义函数
二、为何要用函数
减少重复代码
使程序变的可扩展
使程序变得易维护
三、如何用函数
1、原则:函数必须先定义,再调用
1)定义阶段:只检测语法,不执行函数体代码
2)调用阶段:会出发函数体代码的执行
2、定义函数的语法:
def 函数名(参数1, 参数2):
""" 文档注释 """
函数体
return 返回值
3、调用函数的语法:
函数名(值1, 值2)
4、定义一个函数,只是定义的话不会执行
1)def是关键字,后跟一个空格
2)函数名,自己定义,起名需要遵循变量命名规则
3)后面括号和冒号不能省,括号内可以有参数
4)函数内所有代码缩进
5、函数定义的三种形式:
有参函数:通过接受外部传进来的值,进行一系列的操作
无参函数:只是进行函数内部的操作
空函数:什么事情都不做,内部用pass进行占位
6、函数调用的三种形式:
语句形式:仅仅是函数名加括号
表达式形式:将函数的结果与数字类型(整型、浮点型)相计算
当作参数传给另一个函数,例如:range(len("hello"))
四、函数的返回值
1、注意点:
1)函数的返回值没有类型限制
2)函数的返回值没有个数限制
2、返回多个值:多个返回值之间用逗号隔开,返回的是元组形式
3、返回一个值
4、返回零个值或者没有 return
return 除了有返回值的功能,还有函数结束执行的功能:函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将 return 后的值返回
五、函数的参数
1、形式参数:在定义函数阶段,括号内定义的参数称为形参
2、实际参数:在调用函数阶段,括号内传入的值称为实参
在调用函数阶段会将实参的值传递给形参,这种传递关系只在调用函数时生效,在函数执行完后就会失效
3、位置参数
1)站在形参角度(位置形参)
定义:在函数定义阶段,按照从左到右的顺序依次定义的形参称之为位置形参
特点:但凡按照位置定义的形参,必须被传值,多一个不行少一个也不行
def func(x, y, z):
print(x, y, z)
func(1, 2) # 错误
func(1, 2, 3) # 正确
func(1, 2, 3, 4) # 错误
2)站在实参角度(位置实参)
定义:在调用阶段,按照从左到右的顺序依次传入的值称之为位置实参
特点:与形参一一对应
def func(x, y, z):
print(x, y, z)
func(2, 1, 3)
4、关键字参数(关键字形参)
定义:在调用阶段,按照 key=value 的形式定义的实参称之为关键字实参
特点:可以完全打乱顺序,但仍然能为指定的形参传值
def func(x, y, z):
print(x, y, z)
func(x=1, y=2, z=3)
func(1, 2, 3)
func(z=3, y=2, x=1)
实参中位置参数与关键字参数可以混合使用,但是必须遵循以下原则:
1)位置参数必须放在关键字参数的前面
2)不能对同一个形参重复传值
def func(x, y, z):
print(x, y, z)
func(1, z=3, y=2) # 正确
func(z=3, 1, y=2) # 错误
func(1, z=3, x=2, y=3) # 错误
func(x=1, y=2, 3) # 错误
5、默认参数(默认形参)
定义:在函数定义阶段,就已经为形参赋值,该形参称之为默认形参
特点:
1)定义阶段就已经有值,意味着调用阶段可以不用传值
2)位置形参必须放到默认形参的前面
3)默认形参的值在函数定义阶段就已经固定了,定义阶段之后的改动不会影响该值
4)默认形参的值通常应该是不可变类型
def func(x, y, z=100):
print(x, y, z)
func(10, 20)
func(10, 20, 200)
def add_hobby(name, x, hobbies=[]):
hobbies.append(x)
print("%s 的爱好有 %s" %(name, hobbies))
add_hobby("qiu", "read")
add_hobby("xi", "eat")
add_hobby("qiuxi", "play")
# 改进
def add_hobby(name, x, hobbies=None):
if hobbies is None:
hobbies = []
hobbies.append(x)
print("%s 的爱好有 %s" %(name, hobbies))
add_hobby("qiu", "read")
add_hobby("xi", "eat")
add_hobby("qiuxi", "play")
6、可变长参数
定义:指的是在调用阶段,实参的个数是不固定的
实参无非两种方式(位置实参,关键字实参),对应的形参也必须有两种解决方案来分别接收溢出位置实参或关键字实参
其中:
用 * 表示溢出的位置实参
用 ** 表示溢出的关键字实参
1) 一个星号的用法
在形参前加一个星号:星号会将溢出的位置实参存成元组的形式,然后赋值给星号后的形参名
在实参前加一个星号:但凡碰到实参中带一个星号的,先将实参打散成位置实参再与形参做对应
2)两个星号的用法
在形参前加两个星号:星号会将溢出的关键字实参存成字典的形式,然后赋值给星号后的形参名
在实参前加两个星号:但凡碰到实参中带两个星号的,先将实参打散成关键字实参再与形参做对应
7、命名关键字参数
定义:在定义函数时,* 与 ** 之间的参数称之为命名关键字参数
特点:在调用函数时,命名关键字参数必须按照 key=value 的形式传值
def func(x, *, y=1, z):
print(x)
print(y)
print(z)
# func(1, 2, 3, 4, 5) # 错误
func(1, z=2) # 正确, 打印1 1 2
def func(a, b=2, *args, c, **kwargs):
print(a)
print(b)
print(args)
print(c)
print(kwargs)
func(1, 7, 3, 4, c=5, name='qiuxi')
# 打印 1 7 (3, 4) 5 {'name': 'qiuxi'}