目录
概念:函数指被封装起来的、实现某种功能的一段代码。Python安装包、 标准库中自带的函数统称为内置函数,用户自己编写的函数称为自定义函数,不管是哪种函数,其定义和调用方式都是一样的。
一、函数的定义
1.格式:
def 函数名([参数列表]):
["函数文档字符串"]
函数体
[return语句]
2.参数说明:
(1)def: 是关键字,表示定义一个函数;
(2)函数名:是一个标识符,注意不能与关键字重复;
(3)参数列表:可以有零个、一个或多个,没有参数时圆括号也需要保留;
(4)函数体的起始位置:可以选择以注释形式进行函数说明,此时的注释在Python中被称为文档字符串;
(5)return语句: 可以省略, 当需要返回值时,return是函数结束的标志,会将返回值列表返回给调用者。没有return语句或者只有return语句而没有返回数据时,则Python会认为此函数返回的是None, None表示空值。
3.实例代码:
# 定义无参函数,显示天气状况
def weather():
print("*"*13)
print("日期:3月9日")
print("温度:10~15℃")
print("空气质量:优")
print("*"*13)
weather()
# 定义有参函数,显式指定日期的天气状况
def weather(date,temp,air):
print("*"*13)
print(f"日期:{date}")
print(f"温度:{temp}")
print(f"空气质量:{air}")
print("*"*13)
weather("3月9日","10~15℃","优")
# 有参有返回值的函数 求两个数的最大值
def m_max(a,b):
if a>b:
max=a
else:
max=b
return max
result=max(4,8)
print(result)
# 有参有多个返回值的函数
def yu_digit(number):
a1 = number % 10
a2 = number // 10 % 10
a3 = number // 100
return a1, a2, a3
result = yu_digit(157)
print(result) # 输出 (7, 5, 1)
print(type(result)) # 返回的result是元组类型 输出 <class 'tuple'>
a, b, c = yu_digit(168) # 输出 8 6 1
print(a, b, c)
二、函数的调用
1.定义好的函数直到被程序调用时才会执行。
2.格式:函数名([参数列表])
3.调用
(1)无返回值:函数名(参数值1, 参数值2, ....)
(2)有返回值:变量名=函数名(参数值1, 参数值2,....)
三、函数的返回值
Python 3的返回值有4种形式: None、 一个值、多个值、yield语句。
1. None
(1)None是函数没有返回值时默认的返回值,其可以用在逻辑判断中,作用和False类似。
(2)例:定义空函数
当定义函数却没有写函数体时,代码会高亮显示,表示语法有问题,程序无法顺利运行,此时pass可以充当未完成的代码,使得整个程序能够正常运行。在if、 for、while等语句后的语句块,也可以用pass进行占位。
def test():
pass # 占位语句
data=test()
print(data) # 返回值为None。函数没有返回值时默认返回None
2.返回一个值
(1)格式: return expression
(2)expression可以为一个变量、常量或表达式
(3)实例:
# 实现计算器的四则运算:
num = input("请输入选择功能:")
def jisuanqi(num, a, b):
if num == "+":
return a + b
elif num == "-":
return a - b
elif num == "*":
return a * b
elif num == "/":
if b == 0:
return "除数不能为0"
else:
return a / b
a = int(input("请输入一个数:"))
b = int(input("请输入另一个数:"))
print(jisuanqi(num, a, b))
# 输出
# 请输入选择功能:*
# 请输入一个数:3
# 请输入另一个数:5
# 15
3.返回多个值
(1)和C语言、Java语言不同的是,Python的函数可以有多个返回值。
(2)格式: return expression1, expresion2...
(3)注: return返回的多个值在调用的语句块处表现为一个元组, 即当函数返回多个值时,等价于返回了一个元组。
(4)实例:
def func_m():
return 1, 2.1, 'hello world'
data = func_m()
print(type(data)) # 输出 <class 'tuple'>
for i in data:
print(i, end=" ") # 输出 1 2.1 hello world
4.返回一个迭代器对象
(1)除了return语句外,Python还有一 种特殊的用于返回值的语句——yield语句。和return语句不同的是,yield语句返回的是一 个迭代器对象, 带有yield语句的函数在Python中被称为生成1器 (generator) 。
(2)实例:
def num():
for i in range(5):
yield i
data = num()
print(type(data))
for i in data:
print(i)
# 输出
# <class 'generator'>
# 0
# 1
# 2
# 3
# 4
四、函数注释
1.为函数添加注释:在函数体的起始位置键入三引号进行函数注释(注:在PyCharm中输入三引号并按回车,可以自动生成部分函数注释),也称为文档字符串。 文档字符串中一般包括函数的功能、参数以及返回值,查看文档字符串可以通过_ _doc__ 属性。
实例:
def cal__digit(number):
"""
求一个三位数的各位数的值:数据:
:return:返回个、十、百位的值
"""
a1 = number % 10
a2 = number // 10 % 10
a3 = number // 100
return a1, a2, a3
# 调用函数:
result = cal__digit(853)
print(result)
a, b, c = cal__digit(927)
print(a, b, c)
print(cal__digit.__doc__) # 输出 求一个三位数的各位数的值:数据::return:返回个、十、百位的值
五、函数的参数传递
函数的参数传递是指将实际参数传递给形式参数的过程。根据不同的传递形式,函数的参数可分为位置参数、关键字参数、默认值参数、不定长参数。
1.位置参数
(1)参数的位置传递是指调用函数时,根据函数定义的形参位置传递实参,将形参和实参顺序关联。
(2)函数调用时,实参的传递顺序与形参-致、 实参和形参的类型和个数必须匹配。
(3)实例:
def info(name, age, address):
print(f"姓名:{name}")
print(f"年龄:{age}")
print(f"地址:{address}")
info("李四", "成都", 35)
# 输出:
# 姓名:李四
# 年龄:成都
# 地址:35
2.关键字参数
(1)通过“形式参数=实际参数”的格式将实际参数与形式参数相关联,根据形参的名称进行参数传递。
(2)实例:
def info(name, age, address):
print(f"姓名: {name}")
print(f"年龄: {age}")
print(f"地址:{address}")
info(name="李四", address="成都", age=35)
# 输出
# 姓名: 李四
# 年龄: 35
# 地址:成都
3.默认参数
(1)定义函数时可以指定形式参数的默认值。
(2)实例:
def conn(ip, port=3306):
print(f"连接地址为:{ip}")
print(f"连接端口为:{port}")
conn("127.0.0.1") # 输出 连接地址为:127.0.0.1
# 连接端口为:3306
conn("127.0.0.2", port=8080) # 输出 连接地址为:127.0.0.2
# 连接端口为:8080
(3)注:有默认值的形参必须要在没有默认值的形参的后面,否则函数将会报错
4.不定长参数
(1)概述:不定长参数也叫可变参数, 即: 参数的个数是可变的.
(2)格式:在形参名的前边写上 *, 或者 **;
如果是 * 则表示可以接收所有的位置参数, 形成元组;
如果是 ** 则表示可以接收所有的关键字参数, 形成字典。
(3)参数的解包裹传递:不定长参数(*、**) 在调用函数时,作为实参传递,即参数的解包裹传递。·
(4)实例:
def multiple(a, b, c):
return a * b * c
tuple1 = (3, 5, 6)
s = multiple(*tuple1)
print(s) # 输出 90
dict1 = {"a": 2, "b": 3, "c": 5}
s = multiple(**dict1)
print(s) # 输出 30
五、关于参数传递
关于参数传递,需要理解的是值传递还是引用传递。如果实参是不可变对象,则是值传递;如果实参是可变对象,则是引用传递。由于引用传递,在函数内修改引用对象的值时,也会改变实参引用对象的值。但是如果在函数内又重新创建了对象,并且是形参指向了新的对象,则不会修改实参引用对象的值。通过以下示例来进一步理解引用传递。
def fun_1(x): # 定义一个函数
print(x) # 输出传递过来的列表 [0, 1, 2, 3]
x.append(8) # 给列表追加一个元素8,修改了列表的值
print(x) # 输出新列表的值 [0, 1, 2, 3, 8]
list = [0, 1, 2, 3]
fun_1(list) # 实参列表为可变对象
print(list) #输出 [0, 1, 2, 3, 8]
# 这个案例说明,在用列表作实参调用函数时,在函数内部修改了列表的值,则实参引用对象list的值也改变了
def fun_2(x):
print(x) # 输出 [0, 1, 2, 3]
x = x + [88] # 创建了一个列表
print(x) # 输出 [0, 1, 2, 3, 88]
list = [0, 1, 2, 3]
fun_2(list)
print(list) # 输出 [0, 1, 2, 3]
# 由于函数内的语句 " x =x +[88]"是创建了新的列表对象,所以实参引用对象就不会改变了