函数的简介
- 我们为什么要使用函数呢?
- 为了更高效的工作,减少重复代码的编写。
- 函数与循环有什么不同呢?
- 函数在不同的位置重复执行相同的代码,而循环是在相同的位置重复执行相同的代码。
函数的本质
- 我们可以先提前定义好函数,然后就能在开发中反复使用。
举例
我们可以把函数比喻为一把现成的工具,每次需要时直接就可以用。
当我们没有工具时,每次都需要重新制作。所以我们需要用到函数。
函数的语法结构
- 结构
def 函数名(参数1,参数2):
'''函数注释'''
函数体代码
return 返回值
- 语法结构的解释
1. def # 定义函数的关键字,是固定的
2.函数名 # 与变量名相似,要做到见名知意
3.()括号 # 定义函数名时后面必须跟括号
4.参数 # 参数个数不固定,多个参数时,参数与参数中间加逗号。
# 参数是用于接收外界传递给函数体代码内部的数据
5.函数注释 # 类似于说明书,主要是介绍这个函数的功能以及用法
6.函数体代码 # 函数的最核心(逻辑代码)
7.return # 控制函数的返回值
8.返回值 # 调用函数之后有没有相应的反馈
函数的定义与调用
- 1.函数必须先被定义之后才可以使用(定义的函数必须在调用的前面)
- 2.定义函数关键字为def
- 3.调用函数使用函数名加(),可能需要添加额外的参数
- 4.函数在定义时只会检测函数体代码的整体语法,不会执行函数体代码
- 5.函数只有在调用时才会执行函数体代码
- 6.函数名是什么?
- 函数名绑定了一块内存地址,函数体代码存放在其中。
- 想要运行函数体代码就需要调用函数
除定义阶段外,函数名加括号执行优先级最高
定义并调用一个函数
def my_func(): # 使用def定义一个函数。
pass
my_func() # 调用该被定义的函数。
函数的分类
内置函数
- python解释器提前定义好的函数,用户可以直接调用。
- 相当于是数据类型独有的一些内置方法
- 内置函数是可以直接进行调用的
数据类型的内置方法必须使用数据类型点(例如:str.)的方式才可以调用
自定义函数
1.空函数
- 函数体代码使用pass,没有功能,主要用于项目搭建前期的功能提示。
def 函数名():
pass
2.无参函数
- 函数定义阶段括号内没有写入参数,使用函数名加括号可以直接调用。
def 函数名(): #括号内没有参数
print('hello')
3.有参函数
- 函数定义阶段括号内写入参数,调用需要函数名加括号并且给数据值。
def 函数名(a, b): # 参数没有个数限制
print('hello')
函数的返回值
- 1.返回值是调用函数之后产生的结果,有没有无所谓
- 2.获取函数返回值的方式是固定的: 变量名 = 函数()
- 3.有无return关键字,有就获取,没有返回none
1.函数体代码没有return关键字,默认返回none
def age(): # 定义一个函数
print('21') # 函数体代码,定义时不执行
res = age() # 获取res的返回值,执行age()函数体内的代码
print(res) # 输出res的数据值,函数体代码没有return关键字,默认返回
none
输出结果:
2.函数体代码有return关键字,但是return后不写返回值,也默认返回none
def age():
print('21')
return # 添加关键字return,不添加返回值
res = age()
print(res) # 默认返回none
输出结果:
3.函数体代码有return关键字,后面返回值写什么返回什么
def age():
print('21')
return 886 # 添加关键字return,添加返回值
res = age()
print(res) # 返回返回值
输出结果:
4.函数体代码有return关键字,后面返回值位置有多个数据值用逗号隔开(1,2,3,4)
def age():
print('21')
return 1,2,3,4 # 添加多个返回值
res = age()
print(res) # 以组织成元组的形式返回(1,2,3,4)
输出结果:
5.函数体代码代码有return关键字,但是在关键字下面添加函数体代码不会执行.
代码遇到return立刻结束函数体代码
def age():
print('21')
return 886 # 代码已经结束
print('31') # 返回值下方添加,不执行
res = age()
print(res)
age()
输出结果:
函数的参数
- 函数的参数主要分为两大类
- 1.形式参数:函数在定义阶段括号里填写的参数,简称为形参。
- 2.实际参数:函数在调用阶段括号里填写的参数,简称为实参。
- 形参与实参的关系
- 形参相当于变量名,实参相当于数据值。
- 函数调用阶段形参会临时与实参进行绑定(动态绑定),函数运行结束立刻解除绑定(动态解除)。 参数从左到右的复杂程度依次增大,不能出现复杂程度大到小,或者混合
位置参数
- 位置形参
- 在函数定义阶段括号内从左往右依次填写的变量名称之为位置形参
- 位置实参
- 在函数调用阶段括号内从左往右依次填写的数据值 称之为位置实参 举例:
def num(a, b, c, d): # 这里的abcd就是位置形参
print(num)
return
num(1, 2, 3, 4) # 这里的1234就是位置实参
# 1.实参可以是数据值,也可以是绑定了数据值的变量名
# 2.实参与形参的个数是一致的,不能多或者少。
输出结果:
关键字参数
- 关键字实参
- 函数调用阶段括号内为a = 1之类的形式进行传值的就称为关键字实参
# 1.给某一指定的形参传值(打破了位置的限制)
# 2.位置实参要在关键字实参的前面
def name(name1, name2):
print(name1, name2)
name('tom', 'jarry')
name('tom', name2='jarry')
输出结果:
def name(name1, name2):
print(name1, name2)
name(name1='tom', 'jarry')
输出结果:
默认值参数
- 默认值形参
- 在函数定义阶段括号内以a = 1之类的形式填写的形参称之为默认值形参
# 1.在函数定义阶段给形参绑定值,后续调用阶段就可以不用传值
# 2.调用的时候没有进行传值就使用默认值
# 3.调用阶段进行了传值就使用新传的值
def name(name1, name2='juzi'): # 定义时就给括号内传值
print(name1, name2)
name('tom',) # 输出时就用定义时传的值
name('tom','jarry') # 新传了值就用新值
输出结果:
def name(name1='juzi', name2): # 前面形式复杂,没有按照规范,报错
print(name1, name2)
name('tom','jarry')
输出结果:
可变长参数
- 可变长形参 * / **
- 可以打破形参和实参的个数限制,任意传值
- 单个星号* 在形参中可以接受多余的位置参数然后组织成元组的形式赋值给* 后面的变量名
def name(*x): print(x)- 两个星号** 在形参中接受多余的关键字参数并组织成字典的形式赋值给** 其后面的变量名
输出结果:def image(**x): print(x) image() image(name1='tom', age=21 )
可变长实参
- *在实参中的作用
- 能够吧* 后面的内容用for循环方式取出来,一次性传给函数。
def func(*args, **kwargs):
print(args)
print(kwargs)
l1 = [1, 2, 3, 4, 5, 6]
func(*l1)
输出结果:
(1, 2, 3, 4, 5, 6)
{}
- ** 在实参中的作用
- 将字典里的键值对变为关键字参数传给函数
命名关键字参数
- 需要形参在传实参的时候 必须按照关键字参数才可以。形参要在* 后面,** 前面