一、函数的语法
在Python中,可以使用def关键字来定义一个函数。函数定义通常包括以下几个组成部分:
函数名:函数的名称应该遵循Python的标识符命名规则,通常使用小写字母和下划线的组合。函数名应该能够简要地描述函数的作用。
参数列表:参数是可选的,用于接收传递给函数的输入值。多个参数之间用逗号分隔。如果函数不需要参数,则可以省略参数列表或使用空的括号()。
函数体:函数执行的代码块,用于实现函数的功能。可以使用Python的控制结构、表达式和变量等来编写函数体。函数体可以包括多个语句,通常使用缩进表示代码块。
返回值:函数可以使用return语句返回一个值,用于表示函数执行的结果。如果没有指定return语句,则函数默认返回None。
def 函数名称(参数1,参数2):
# 函数体
return #返回值
二、函数的作用
函数是一段可以重复调用的代码块,它具有以下几个作用:
代码重用:将一段常用的代码封装在函数中,可以避免在多个地方重复编写相同的代码。这样可以提高代码的可读性、可维护性和可复用性,减少代码冗余。
模块化设计:将一个大问题分解为多个小问题,每个小问题可以由一个函数解决。这样可以提高程序的模块化程度,让程序更易于理解和维护。
抽象和封装:函数将一组操作抽象为一个单一的操作,屏蔽了内部实现的细节。这样可以提高程序的可读性和可维护性,使程序更加安全和可靠。
提高代码的可测试性:将程序拆分成多个小函数,可以更容易地对每个函数进行单元测试,从而提高代码的可测试性和可靠性。
函数作为参数或返回值:函数可以作为参数传递给其他函数或作为返回值返回,这样可以实现更加灵活的编程方式,提高程序的抽象能力和表现力。
三、函数的执行逻辑
当Python解释器执行一个函数时,会按照以下逻辑来执行函数:
执行函数调用语句:当函数被调用时,Python解释器会创建一个函数栈帧(function frame),将函数的局部变量和参数存储在栈帧中,并将控制权转移到函数体中的第一条语句。
执行函数体语句:Python解释器会依次执行函数体中的语句,包括赋值语句、控制语句、函数调用语句等。
遇到return语句:如果函数体中遇到了return语句,Python解释器会将return语句后面的表达式计算出来,并将其作为函数调用的结果返回给调用者。此时函数的栈帧被销毁,并将控制权转移回函数调用处。
函数结束:如果函数没有遇到return语句或者return后面没有表达式,那么函数会自动返回None。此时函数的栈帧被销毁,并将控制权转移回函数调用处。
在函数执行过程中,如果遇到了异常,Python解释器会抛出异常并停止函数的执行。此时,函数的栈帧会被销毁,并将异常传递给调用者处理。
四、参数的分类
函数参数分为形式参数和实际参数。
形式参数(Formal Parameters)是在函数定义时声明的参数,也称为形参。
实际参数(Actual Arguments)是在函数调用时传递给函数的参数值,也称为实参。
根据参数的传递方式和作用范围,参数可以分为以下几种分类:
位置参数
位置参数(Positional Arguments)是在函数定义时需要明确声明参数名,并在函数调用时按照相应的位置传入参数值。(形式参数和实际参数位置要一一对应)。
#位置参数
def func(a, b, c): #a、b、c是形参(参数名称)
print(a,b, c) #输出结果:1 2 3
func(1,2,3) #1,2,3是实参(参数值)
ps:在使用位置参数时,需要保证参数顺序正确,否则可能导致程序错误。
默认参数
默认参数(Default Arguments)是在函数定义时可以为参数设置默认值,如果函数调用时没有提供相应参数的值,则会使用默认值。
#默认参数
def func(a, b=2, c=3): #参数名b和c给出了默认值
print(a, b, c ) #输出结果:1 2 3
func(1) #此处仅指给一个参数值
ps:默认参数通常在函数定义中的最后一个位置,如果在函数定义时将默认参数设置为非最后一个参数,会引发语法错误。
关键字参数
关键字参数(Keyword Arguments)是在函数调用时可以通过指定参数名来传递参数值,而不必按照参数定义的顺序传递。
#关键字参数
def func(a, b, c):
print(a,b,c ) #输出结果:3 1 2
func(b=1, c=2, a=3)
ps:关键字参数的顺序可以是任意的,因为它们是通过参数名来匹配的。
可变参数
分为位置可变参数(位置不定长参数)和关键字可变参数(关键字不定长参数)
位置不定长参数
表示接受任意数量的位置参数,将这些参数作为一个元组传递给函数体内部的变量args。在函数定义中,使用一个星号(*)表示位置不定长参数。
#位置不定长参数
def func(*b):
print(b)
func(1,2,3,4)
func('a','b','c','d')
func('樱花','桃花')
输出结果:
(1, 2, 3, 4)
('a', 'b', 'c', 'd')
('樱花', '桃花')
关键字不定长参数
表示接受任意数量的关键字参数,将这些参数作为一个字典传递给函数体内部的变量kwargs。在函数定义中,使用两个星号(**)关键字不定长参数。
#关键字不定长参数
def func(**b):
print(b)
func(a=1,b=2,c=3,d=4)
func()
func(a='樱花',b='桃花')
输出结果:
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
{}
{'a': '樱花', 'b': '桃花'}
五、函数的常用操作
定义函数
定义函数指在程序中创建一个可重复使用的代码块。定义函数可以让我们在程序中封装一个操作,并在需要的时候重复执行该操作。
def greet(flower):
print(flower ) #定义函数
调用函数
调用函数是指在程序中使用定义好的函数。在 Python 中,我们可以使用函数名和传递给函数的参数来调用函数。
普通函数调用
def greet(flower):
print(flower ) #定义函数
#调用函数
greet("樱花")
greet("桃花")
greet("玫瑰")
输出结果:
樱花
桃花
玫瑰
一个函数调用另一个函数(函数嵌套)
在 Python 中,一个函数可以调用另一个函数,这也被称为函数嵌套或函数组合。
def get_username():
"""从用户输入中获取用户名"""
username = input("请输入用户名:")
return username
def get_password():
"""从用户输入中获取密码"""
password = input("请输入密码:")
return password
def validate(username, password):
"""验证用户信息"""
if username == "zqw" and password == "123456":
return True
else:
return False
def show_login_success():
"""显示登录成功的提示"""
print("登录成功!")
def show_login_failure():
"""显示登录失败的提示"""
print("用户名或密码错误,请重试。")
def login():
"""主登录函数"""
username = get_username()
password = get_password()
if validate(username, password): #验证用户信息(用户名, 密码):
show_login_success() #显示登录成功提示()
else:
show_login_failure() #显示登录失败提示()
# 测试登录
login()
输出结果:
请输入用户名:zqw
请输入密码:123456
登录成功!
参数传递
函数可以接受多个参数,并且可以使用位置参数、关键字参数和默认参数等方式进行传递。
(参考参数的分类)
函数返回值return
函数返回值return用于在函数中将计算结果返回给调用者。
如果函数没有指定返回值,则默认返回 None。
函数的返回值可以是任何数据类型,包括数字、字符串、列表、元组、字典等等。
def add_numbers(a, b):
"""计算两个整数的和,并返回结果"""
result = a + b
return result
# 调用
sum = add_numbers(3, 5)
print("3 + 5 = ", sum) #输出结果:3 + 5 = 8
#根据身份证号获取出生日期
def get_birthday(id_num):
"""通过切片方式从身份证号中获取出生日期"""
year = id_num[6:10]
month = id_num[10:12]
day = id_num[12:14]
return year, month, day
#测试
id_num = '372925199808112929'
year, month, day = get_birthday(id_num)
print(f'出生日期:{year}年{month}月{day}日') #输出结果:出生日期:1998年08月11日
函数的递归
函数可以调用自身,这种技术被称为递归。
#计算阶乘的递归函数
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
result = factorial(5)
print(result) #输出结果:120
函数的作用域
在 Python 中,变量的作用域分为全局作用域和局部作用域。
全局作用域中的变量可以在函数内部和外部使用,而局部作用域中的变量只能在函数内部使用。当在函数内部定义变量时,它们默认是局部变量。当在函数外部定义变量时,它们默认是全局变量。
ps:全局作用域不能获取局部变量,但是局部可以获取全局变量
ps:全局不能修改局部变量,局部不可以直接修改全局变量(简单了解)
x = 10 # 全局变量
def foo():
y = 5 # 局部变量
print("x inside function:", x) # 可以访问全局变量 x
print("y inside function:", y) # 可以访问局部变量 y
foo()
print("x outside function:", x) # 可以访问全局变量 x
#print("y outside function:", y) # 报错,访问不了局部变量 y
输出结果:
x inside function: 10
y inside function: 5
x outside function: 10
封装函数
封装一个函数需要遵循以下几个步骤:
定义函数名,函数名应该简明、准确地描述函数的功能;
定义函数参数,确定函数所需的参数,以便在函数体内进行处理;
编写函数体,实现函数的功能;
添加函数注释,描述函数的功能和参数信息;
调用函数,传入相应参数,执行函数并返回结果。
#定义函数名和参数
def sum(a, b):
"""
求两个数的和
参数:
a: 数值
b: 数值
返回值:
两个数的和
"""
#编写函数体
result = a + b
return result
# 调用函数
x = 1
y = 2
result = sum(x, y)
print(f"{x} + {y} = {result}") #输出结果:1 + 2 = 3
八、练习题
定义函数,商场打折
"""题目1:定义函数,并通过给函数传递不同的参数(要想清楚哪些做为参数哦!!)
一家商场在降价促销,所有原价都是整数(不需要考虑浮点情况),
如果购买金额50-100元(包含50元和100元)之间,会给10%的折扣,如果购买金额大于100元会给20%折扣
编写一程序,询问购买价,再显示出折扣(%10或20%)和最终价格。"""
def get_price(price):
discount=1
if 50 <= price <= 100:
discount=0.9
elif price > 100:
discount=0.8
print(f"""购买折扣":{discount*10}折,优惠价格:{price*discount}""")
get_price(10)
get_price(100)
get_price(120)
输出结果:
购买折扣":10折,优惠价格:10
购买折扣":9.0折,优惠价格:90.0
购买折扣":8.0折,优惠价格:96.0
列表去重函数
def remove_element(a_list):
"""去除列表中重复元素"""
result = [] # 用于存放去重后的元素
for element in a_list: # 遍历列表中的每个元素
if element not in result: # 如果当前元素不在结果列表中
result.append(element) # 将当前元素加入结果列表
return result # 返回去重后的结果列表
#测试函数
a_list = [10, 1, 2, 20, 10, 3, 2, 1, 15, 20, 44, 56, 3, 2, 1]
result = remove_element(a_list)
print(result) #输出结果:[10, 1, 2, 20, 3, 15, 44, 56]