函数
产生原因:
在软件开发中,时常出现功能相同,处理数据不同的代码块,复制该段代码到相应位置稍加修改,不利于后期维护。
解决方法:
将可能需要返回执行的代码封装为函数(组织代码的最小单元),然后在需要该功能的地方调用函数,不仅可以实现代码的复用,更重要的是保证代码的一致性。
实际要求:
在设计时要提高函数的内聚性,减少不同函数之间的耦合性;尽量减少副作用,只实现指定功能;在实际开发中,需要把调用的函数封装到一个模块中,使得管理方便。
函数的定义
函数是组织好的、可重复使用的代码段,用来实现单一、或相关联功能。函数可以提高代码的模块化和可重用性。Python 使用 def 关键字定义函数。
def <函数名> (<参数列表>):
<函数体>
注意:
- 函数形参不需要声明其类型,也不需要指定函数的返回类型;
- 即使该函数不需要接收任何参数,也必须保留一对空括号;
- 括号后面的冒号不能少;
- 函数体相对于 def 关键字必须保持一定的空格缩进。
函数的使用
- 函数定义,只是声明了一个函数,它不会被执行,需要调用;
- 调用的方式,就是函数名加上小括号,括号内写上参数;
- 调用时写的参数是实际参数,是实实在在传入的值,简称实参;
def greet():
print("Hello, world!")
# 调用函数
greet() # 输出: Hello, world!
函数的参数传递
位置参数
按位置顺序传递参数。实参与形参的数量必须相同。
def add(a, b):
return a + b
# 按位置传递参数
result = add(3, 5)
print(result) # 输出: 8
关键字参数
按参数名传递参数,参数的顺序可以不同于定义时的顺序。
def greet(name, message):
print(f"{message}, {name}!")
# 使用关键字参数传递
greet(name="Alice", message="Good morning") # 输出: Good morning, Alice!
greet(message="Good evening", name="Bob") # 输出: Good evening, Bob!
默认参数
在调用时可以选择性传递参数,不传递时使用默认值。
def greet(name, message="Hello"):
print(f"{message}, {name}!")
# 使用默认参数
greet("Alice") # 输出: Hello, Alice!
# 覆盖默认参数
greet("Bob", "Hi") # 输出: Hi, Bob!
可变长度参数
可变长度参数主要有两种形式:*param 和**param;
*param 接收任意多个参数放在一个元组中;
**param 接收任意多个关键字参数放入字典中。
def print_numbers(*nums):
for number in nums:
print(number)
# 传递任意数量的参数
print_numbers(1, 2, 3, 4)
# 输出:
# 1
# 2
# 3
# 4
def print_info(**kvs):
for key, value in kvs.items():
print(f"{key}: {value}")
# 传递任意数量的关键字参数
print_info(name="Li", age=25, city="XiAn")
# 输出:
# name: Li
# age: 25
# city: XiAn
传递参数时的序列解包
序列解包是一种强大的特性,允许你将序列(如列表、元组)中的元素分配给多个变量。当传递参数给函数时,也可以利用这种特性来传递多个参数。
对列表、元组的解包
序列解包最常见的形式是将一个元组或列表的元素分别赋值给多个变量。
当你有一个包含多个参数的列表或元组,可以使用 * 操作符将其解包,并作为单独的参数传递给函数。
def my_function(a, b, c):
print(a, b, c)
args = (1, 2, 3)
my_function(*args) # 等效于 my_function(1, 2, 3)
对字典、集合的解包
如果你有一个包含参数的字典,可以使用 ** 操作符将其解包,并作为关键字参数传递给函数。
def my_function(a, b, c):
print(a, b, c)
kwargs = {'a': 1, 'b': 2, 'c': 3}
my_function(**kwargs) # 等效于 my_function(a=1, b=2, c=3)
总结:
- 多个位置可变参数在形参前使用一个星号*;
- 多个关键字可变参数在形参前使用两个星号**;
- 位置可变参数和关键字参数可以收集若干个实参,多个位置可变参数收集形成一个tuple,多个关键字可变参数收集形成一个 dict;
- 混合使用参数时,遵循的参数顺序为:普通参数、位置可变参数、关键字可变参数、可变长度参数。
函数的返回值
- return语句用来结束函数并将程序返回到函数被调用的位置继续执行;
- return语句可以出现在函数中的任何部分;
- 可以同时返回0个或多个函数运算的结果给函数被调用处的变量;
- 函数可以没有返回值,也可以有多个返回值,当return 返回多个值时,返回的值形成元组数据类型。
def add(a, b):
return a + b , a * b
result = add(3, 4)
print(result) # 输出 (7, 12)
变量的作用域
局部变量
局部作用域指的是在函数或代码块内部定义的变量。它们只能在该函数或代码块中访问。当函数退出时销毁。
def my_function():
local_var = 10 # 局部变量
print(local_var) # 输出: 10
my_function()
print(local_var) # NameError: name 'local_var' is not defined
全局变量
全局作用域指的是在整个脚本或模块中都可访问的变量。这些变量在函数或类定义之外创建。全局变量在函数内部使用时,需要用global 关键字声明。且该变量与外部变量全局变量同名。
global_var = 20 # 全局变量
def my_function():
print(global_var) # 输出: 20
my_function()
print(global_var) # 输出: 20
代码复用
指的是在不同的地方使用相同的代码,以提高效率、减少重复工作和提高代码的可维护性。
函数是最基本的代码复用方式。通过定义函数,可以将常用的代码封装起来,在需要时调用。
模块化设计指通过函数的封装功能将程序划分为主程序、子程序和子程序间关系的表达。模块化设计是使用函数设计程度的思考方法,以功能为基本单位,一般由两个基本要求:
- 紧耦合:尽可能合理划分功能模块,功能块内部耦合紧密;
- 松耦合:模块间关系尽可能简单,功能块之间耦合度低。
lambda函数
Lambda 函数,也称为匿名函数,是 Python 中用于创建小型匿名函数的一种方式。与常规函数不同,lambda 函数没有名字,只能包含一个表达式,并且它的语法更加简洁。Lambda 函数通常用于需要简短、一次性使用的函数。
基本语法:
<函数对象名>=lambda<形式参数列表>:<表达式>
# 定义一个 lambda 函数,计算两个数的和
add = lambda x, y: x + y
# 调用 lambda 函数
result = add(2, 3)
print(result) # 输出: 5