第三单元:函数与模块
掌握函数定义与模块导入,构建模块化、可复用的代码
预计学习时间:4-5小时
单元介绍
欢迎来到Python基础课程的第三单元!在这个单元中,你将学习函数和模块的使用,这是构建大型、可维护Python程序的基础。
学习目标
- 掌握函数的定义和调用
- 理解函数参数的不同类型
- 学习使用Lambda函数
- 掌握模块的导入和使用
- 了解Python标准库的常用模块
- 学会创建和使用自定义模块
- 理解包的概念和结构
学习提示
💡 重要提示:函数和模块是Python编程的核心概念,它们可以帮助你将代码组织成可复用的块,提高代码的可读性和 maintainability。建议你多做练习,加深对这些概念的理解!
3.1 函数基础:封装代码块
函数是一种将相关代码组织在一起的方式,它可以接收输入参数,执行特定的任务,并返回结果。
定义函数
在Python中,使用def关键字来定义函数:
# 定义一个简单的函数
def greet():
print("Hello, World!")
# 调用函数
greet()
# 定义带参数的函数
def greet_name(name):
print(f"Hello, {name}!")
# 调用带参数的函数
greet_name("John")
# 定义带返回值的函数
def add(a, b):
return a + b
# 调用带返回值的函数
result = add(5, 3)
print(f"5 + 3 = {result}")
函数的文档字符串
文档字符串(docstring)是函数的说明文档,使用三引号包围:
def calculate_area(length, width):
"""计算矩形的面积
参数:
length (float): 矩形的长度
width (float): 矩形的宽度
返回:
float: 矩形的面积
"""
return length * width
# 查看函数的文档字符串
print(calculate_area.__doc__)
# 调用函数
area = calculate_area(5, 3)
print(f"面积: {area}")
函数的作用域
变量的作用域决定了它在程序中的可见性:
# 全局变量
global_var = "I'm global"
def test_scope():
# 局部变量
local_var = "I'm local"
print(f"局部变量: {local_var}")
print(f"全局变量: {global_var}")
test_scope()
print(f"全局变量: {global_var}")
# 下面的代码会报错,因为local_var是局部变量
# print(f"局部变量: {local_var}")
# 在函数中修改全局变量
def modify_global():
global global_var
global_var = "I'm modified"
print(f"函数内的全局变量: {global_var}")
modify_global()
print(f"函数外的全局变量: {global_var}")
3.2 函数参数:传递数据的多种方式
Python函数支持多种类型的参数,让函数调用更加灵活。
位置参数
位置参数是最基本的参数类型,按照参数的位置进行传递:
def describe_pet(animal_type, pet_name):
"""描述宠物"""
print(f"我有一只{animal_type}。")
print(f"它的名字叫{pet_name}。")
# 位置参数调用
describe_pet("狗", "旺财")
describe_pet("猫", "咪咪")
关键字参数
关键字参数通过参数名来指定值,顺序可以任意:
def describe_pet(animal_type, pet_name):
"""描述宠物"""
print(f"我有一只{animal_type}。")
print(f"它的名字叫{pet_name}。")
# 关键字参数调用
describe_pet(animal_type="狗", pet_name="旺财")
describe_pet(pet_name="咪咪", animal_type="猫")
默认参数
默认参数为参数提供默认值,调用时可以省略:
def describe_pet(pet_name, animal_type="狗"):
"""描述宠物"""
print(f"我有一只{animal_type}。")
print(f"它的名字叫{pet_name}。")
# 使用默认参数
describe_pet("旺财")
# 覆盖默认参数
describe_pet("咪咪", "猫")
可变参数
可变参数允许函数接收任意数量的位置参数:
def sum_numbers(*numbers):
"""计算任意数量数字的和"""
total = 0
for number in numbers:
total += number
return total
# 调用可变参数函数
print(sum_numbers(1, 2, 3))
print(sum_numbers(1, 2, 3, 4, 5))
print(sum_numbers())
# 解包列表作为可变参数
numbers = [1, 2, 3, 4, 5]
print(sum_numbers(*numbers))
关键字可变参数
关键字可变参数允许函数接收任意数量的关键字参数:
def build_profile(first, last, **user_info):
"""构建用户信息字典"""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
# 调用关键字可变参数函数
user_profile = build_profile('John', 'Doe', age=30, city='New York', job='Engineer')
print(user_profile)
3.3 Lambda函数:简洁的匿名函数
Lambda函数是一种小型的匿名函数,使用lambda关键字定义。
基本语法
Lambda函数的语法格式:lambda 参数: 表达式
# 定义一个简单的lambda函数
greet = lambda name: f"Hello, {name}!"
# 调用lambda函数
print(greet("John"))
# lambda函数作为参数
def apply_function(func, value):
return func(value)
result = apply_function(lambda x: x * 2, 5)
print(result)
# 在列表排序中使用lambda
students = [
{"name": "Alice", "grade": 90},
{"name": "Bob", "grade": 85},
{"name": "Charlie", "grade": 95}
]
# 按成绩排序
students.sort(key=lambda student: student["grade"])
print(students)
# 按姓名排序
students.sort(key=lambda student: student["name"])
print(students)
Lambda函数的应用场景
Lambda函数常用于需要简短函数的场景,如:
# 1. 作为内置函数的参数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)
# 2. 过滤列表
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)
# 3. 作为返回值
def make_multiplier(factor):
return lambda x: x * factor
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
# 4. 作为回调函数
import tkinter as tk
# 注意:在实际浏览器环境中,tkinter可能无法运行
# root = tk.Tk()
# button = tk.Button(root, text="点击我", command=lambda: print("按钮被点击了"))
# button.pack()
# root.mainloop()
3.4 模块与导入:组织代码的方式
模块是一个包含Python定义和语句的文件,文件名就是模块名加上.py后缀。
导入模块
使用import语句导入模块:
# 导入整个模块
import math
# 使用模块中的函数
print(math.sqrt(16))
print(math.pi)
# 导入模块中的特定函数
from math import sqrt, pi
print(sqrt(25))
print(pi)
# 导入模块中的所有函数
from math import *
print(cos(0))
print(sin(math.pi/2))
# 使用别名
import math as m
print(m.sqrt(36))
from math import sqrt as square_root
print(square_root(49))
模块的搜索路径
Python会按照以下顺序搜索模块:
- 当前目录
- PYTHONPATH环境变量中的目录
- 标准库目录
- 任何.pth文件中的目录
import sys
print("Python模块搜索路径:")
for path in sys.path:
print(path)
3.5 标准库:Python的内置工具
Python标准库包含了大量有用的模块,下面介绍一些常用的标准库模块。
os模块
os模块提供了与操作系统交互的功能:
import os
# 获取当前目录
print("当前目录:", os.getcwd())
# 列出目录内容
print("目录内容:", os.listdir("."))
# 创建目录
# os.mkdir("test_dir")
# 删除目录
# os.rmdir("test_dir")
# 路径操作
print("绝对路径:", os.path.abspath("."))
print("是否是文件:", os.path.isfile("python-course.html"))
print("是否是目录:", os.path.isdir("."))
print("文件是否存在:", os.path.exists("python-course.html"))
datetime模块
datetime模块提供了处理日期和时间的功能:
import datetime
# 获取当前日期和时间
now = datetime.datetime.now()
print("当前时间:", now)
# 获取日期部分
print("日期:", now.date())
# 获取时间部分
print("时间:", now.time())
# 创建特定日期
birthday = datetime.datetime(2000, 1, 1)
print("生日:", birthday)
# 计算时间差
delta = now - birthday
print("距离生日的天数:", delta.days)
# 格式化日期
print("格式化日期:", now.strftime("%Y-%m-%d %H:%M:%S"))
print("格式化日期(中文):", now.strftime("%Y年%m月%d日 %H:%M:%S"))
random模块
random模块提供了生成随机数的功能:
import random
# 生成0-1之间的随机浮点数
print("随机浮点数:", random.random())
# 生成指定范围内的随机整数
print("随机整数(1-10):", random.randint(1, 10))
# 从序列中随机选择元素
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print("随机水果:", random.choice(fruits))
# 打乱序列
random.shuffle(fruits)
print("打乱后的水果:", fruits)
# 生成随机样本
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print("随机样本:", random.sample(numbers, 3))
json模块
json模块提供了处理JSON数据的功能:
import json
# Python对象转JSON
person = {
"name": "John",
"age": 30,
"city": "New York",
"is_student": False
}
json_str = json.dumps(person, indent=2)
print("JSON字符串:", json_str)
# JSON转Python对象
json_str = '{"name": "Alice", "age": 25, "city": "London"}'
person = json.loads(json_str)
print("Python对象:", person)
print("姓名:", person["name"])
# 读写JSON文件
# 写入JSON文件
# with open("person.json", "w") as f:
# json.dump(person, f, indent=2)
# 读取JSON文件
# with open("person.json", "r") as f:
# data = json.load(f)
# print("从文件读取的数据:", data)
3.6 自定义模块:组织自己的代码
你可以创建自己的模块来组织代码,提高代码的可重用性。
创建自定义模块
创建一个名为my_module.py的文件:
# my_module.py
"""我的第一个自定义模块"""
def greet(name):
"""问候函数"""
return f"Hello, {name}!"
def add(a, b):
"""加法函数"""
return a + b
def multiply(a, b):
"""乘法函数"""
return a * b
# 模块级变量
PI = 3.14159
VERSION = "1.0.0"
# 当模块被直接运行时执行
if __name__ == "__main__":
print("这是一个模块,不是一个可执行程序")
print(f"模块版本: {VERSION}")
print(f"PI的值: {PI}")
使用自定义模块
在另一个文件中导入并使用自定义模块:
# 导入自定义模块
import my_module
# 使用模块中的函数
print(my_module.greet("John"))
print(my_module.add(5, 3))
print(my_module.multiply(4, 6))
# 使用模块级变量
print(f"PI: {my_module.PI}")
print(f"版本: {my_module.VERSION}")
# 导入模块中的特定函数和变量
from my_module import greet, add, VERSION
print(greet("Alice"))
print(add(10, 20))
print(f"版本: {VERSION}")
包的概念
包是一个包含多个模块的目录,必须包含一个__init__.py文件:
# 包结构示例
# my_package/
# __init__.py
# module1.py
# module2.py
# __init__.py 文件
"""我的包"""
__version__ = "1.0.0"
# 导入包中的模块
from . import module1
from . import module2
# 直接导入模块中的函数
from .module1 import function1
from .module2 import function2
# 使用包
# import my_package
# print(my_package.__version__)
# print(my_package.module1.function1())
# print(my_package.function1()) # 直接从包中导入的函数
3.7 单元练习题
太棒了!你已经学完了第三单元的所有内容。现在让我们通过一些练习来巩固所学知识吧!
练习题1:函数基础
编写一个函数,计算一个数的阶乘。
查看参考答案
def factorial(n):
"""计算阶乘"""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n-1)
# 测试函数
print(factorial(5)) # 120
print(factorial(10)) # 3628800
练习题2:函数参数
编写一个函数,接收任意数量的数字,返回它们的平均值。
查看参考答案
def average(*numbers):
"""计算任意数量数字的平均值"""
if not numbers:
return 0
return sum(numbers) / len(numbers)
# 测试函数
print(average(1, 2, 3, 4, 5)) # 3.0
print(average(10, 20, 30)) # 20.0
print(average()) # 0
练习题3:Lambda函数
使用Lambda函数对列表中的元素进行排序,按照字符串长度排序。
查看参考答案
words = ["apple", "banana", "cherry", "date", "elderberry"]
# 使用Lambda函数按照字符串长度排序
words.sort(key=lambda word: len(word))
print(words)
# 使用Lambda函数按照字符串长度降序排序
words.sort(key=lambda word: len(word), reverse=True)
print(words)
练习题4:模块使用
使用标准库模块,生成一个包含10个随机整数的列表,并计算它们的和与平均值。
查看参考答案
import random
# 生成10个1-100之间的随机整数
numbers = [random.randint(1, 100) for _ in range(10)]
print("随机数列表:", numbers)
# 计算和
total = sum(numbers)
print("总和:", total)
# 计算平均值
average = total / len(numbers)
print("平均值:", average)
练习题5:自定义模块
创建一个自定义模块,包含计算圆面积和周长的函数,然后在另一个文件中使用它。
查看参考答案
# circle.py
"""圆相关的计算模块"""
PI = 3.14159
def area(radius):
"""计算圆的面积"""
return PI * radius ** 2
def circumference(radius):
"""计算圆的周长"""
return 2 * PI * radius
# 使用模块
# import circle
#
# r = 5
# print(f"半径为{r}的圆的面积: {circle.area(r)}")
# print(f"半径为{r}的圆的周长: {circle.circumference(r)}")
单元总结
🎉 恭喜你完成了第三单元的学习!
- 你掌握了函数的定义和调用
- 你理解了不同类型的函数参数
- 你学会了使用Lambda函数
- 你掌握了模块的导入和使用
- 你了解了Python标准库的常用模块
- 你学会了创建和使用自定义模块
- 你理解了包的概念和结构
继续加油,下一个单元我们将学习面向对象编程!