Python函数与模块
·
一、函数
1. 无参函数
基本定义和调用
python
# 定义无参函数
def greet():
"""简单的问候函数"""
print("Hello, World!")
print("欢迎学习Python")
# 调用函数
greet()
greet() # 可以多次调用
# 示例1:打印系统信息
def system_info():
"""显示系统信息"""
import platform
import datetime
print("=" * 40)
print("系统信息")
print("=" * 40)
print(f"操作系统:{platform.system()}")
print(f"主机名:{platform.node()}")
print(f"Python版本:{platform.python_version()}")
print(f"当前时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 40)
system_info()
# 示例2:生成随机验证码
import random
import string
def generate_captcha():
"""生成4位随机验证码"""
chars = string.ascii_letters + string.digits
captcha = ''.join(random.choice(chars) for _ in range(4))
print(f"验证码:{captcha}")
return captcha # 返回值
code = generate_captcha()
print(f"获取到的验证码:{code}")
# 示例3:打印菜单
def show_menu():
"""显示程序菜单"""
print("\n" + "=" * 30)
print("学生管理系统")
print("=" * 30)
print("1. 添加学生")
print("2. 查看学生")
print("3. 修改学生")
print("4. 删除学生")
print("5. 退出系统")
print("-" * 30)
show_menu()
2. 带参函数
2.1 位置参数
python
# 基本带参函数
def greet_user(name):
"""向指定用户问好"""
print(f"Hello, {name}!")
greet_user("Alice")
greet_user("Bob")
# 多个参数
def introduce(name, age, city):
"""介绍个人信息"""
print(f"我叫{name},今年{age}岁,来自{city}")
introduce("张三", 25, "北京")
introduce("李四", 30, "上海")
# 示例:计算两个数的和
def add(a, b):
"""计算两数之和"""
result = a + b
print(f"{a} + {b} = {result}")
return result
sum_result = add(10, 20)
print(f"返回结果:{sum_result}")
# 示例:判断奇偶
def check_even(num):
"""判断数字是否为偶数"""
if num % 2 == 0:
print(f"{num}是偶数")
return True
else:
print(f"{num}是奇数")
return False
result = check_even(7)
print(f"判断结果:{result}")
2.2 默认参数
python
# 带默认值的参数
def greet(name, greeting="Hello"):
"""带默认问候语的问候函数"""
print(f"{greeting}, {name}!")
greet("Alice") # 使用默认值
greet("Bob", "Hi") # 使用自定义值
greet("Charlie", greeting="Hey") # 关键字参数
# 示例:创建用户
def create_user(name, age=18, city="未知", active=True):
"""创建用户账户"""
user = {
"name": name,
"age": age,
"city": city,
"active": active,
"created_at": "2024-01-01"
}
return user
# 不同调用方式
user1 = create_user("张三")
user2 = create_user("李四", 25)
user3 = create_user("王五", 30, "上海")
user4 = create_user("赵六", city="深圳", age=28)
print("用户1:", user1)
print("用户2:", user2)
print("用户3:", user3)
print("用户4:", user4)
# 注意:默认参数必须是不可变对象
def bad_append(item, list=[]): # 错误:列表是可变对象
list.append(item)
return list
print(bad_append(1)) # [1]
print(bad_append(2)) # [1, 2] - 默认列表被修改了!
def good_append(item, list=None): # 正确:使用None作为默认值
if list is None:
list = []
list.append(item)
return list
print(good_append(1)) # [1]
print(good_append(2)) # [2] - 每次都是新列表
2.3 可变参数
python
# *args:接收任意数量的位置参数
def sum_all(*numbers):
"""计算所有参数的和"""
print(f"接收到的参数:{numbers}")
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(10, 20, 30, 40, 50)) # 150
print(sum_all()) # 0
# 示例:打印所有学生
def print_students(*names):
"""打印所有学生姓名"""
print("学生列表:")
for i, name in enumerate(names, 1):
print(f"{i}. {name}")
print_students("张三", "李四", "王五", "赵六")
# **kwargs:接收任意数量的关键字参数
def print_info(**kwargs):
"""打印关键字参数"""
print("接收到的信息:")
for key, value in kwargs.items():
print(f" {key}: {value}")
print_info(name="张三", age=25, city="北京", job="工程师")
# 组合使用
def complex_function(a, b, *args, **kwargs):
"""演示参数组合"""
print(f"必选参数:a={a}, b={b}")
print(f"可变位置参数:{args}")
print(f"可变关键字参数:{kwargs}")
complex_function(1, 2, 3, 4, 5, x=10, y=20, z=30)
# 示例:格式化日志
def log_message(level, message, *args, **kwargs):
"""格式化日志输出"""
import datetime
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] [{level}] {message}"
if args:
log_entry += f" | 额外参数:{args}"
if kwargs:
log_entry += f" | 额外信息:{kwargs}"
print(log_entry)
# 实际应用中可能会写入文件
log_message("INFO", "用户登录成功")
log_message("ERROR", "数据库连接失败", retry=3, timeout=30)
log_message("DEBUG", "处理数据", 1, 2, 3, user="admin")
2.4 关键字参数
python
# 强制关键字参数(*后面的参数必须用关键字传参)
def person_info(name, age, *, city, job):
"""*后面的city和job必须是关键字参数"""
print(f"姓名:{name}")
print(f"年龄:{age}")
print(f"城市:{city}")
print(f"职业:{job}")
# 正确调用
person_info("张三", 25, city="北京", job="工程师")
# 错误调用
# person_info("张三", 25, "北京", "工程师") # TypeError
# 示例:配置函数
def configure_app(host, port, *, debug=False, log_level="INFO"):
"""配置应用程序"""
config = {
"host": host,
"port": port,
"debug": debug,
"log_level": log_level
}
return config
config1 = configure_app("localhost", 8080)
config2 = configure_app("0.0.0.0", 80, debug=True, log_level="DEBUG")
print(config1)
print(config2)
3. 函数中变量的作用域
3.1 局部变量和全局变量
python
# 全局变量
global_var = "我是全局变量"
def test_scope():
# 局部变量
local_var = "我是局部变量"
print("函数内部访问:")
print(f" global_var = {global_var}") # 可以访问全局变量
print(f" local_var = {local_var}") # 可以访问局部变量
# 修改全局变量(需要global声明)
# global_var = "尝试修改" # 这会在函数内创建新的局部变量
test_scope()
# 函数外部无法访问局部变量
# print(local_var) # NameError
# 使用global修改全局变量
count = 0
def increment():
global count # 声明count是全局变量
count += 1
print(f"count = {count}")
increment() # count = 1
increment() # count = 2
increment() # count = 3
print(f"函数外部:{count}") # 3
# 示例:计数器函数
def create_counter():
"""使用nonlocal创建闭包计数器"""
count = 0
def increment():
nonlocal count # 声明count是外部函数的局部变量
count += 1
return count
def decrement():
nonlocal count
count -= 1
return count
def get_count():
return count
# 返回多个函数
return increment, decrement, get_count
inc, dec, get = create_counter()
print(inc()) # 1
print(inc()) # 2
print(dec()) # 1
print(get()) # 1
3.2 变量作用域规则(LEGB规则)
python
# LEGB规则:Local -> Enclosing -> Global -> Built-in
# 1. Local(局部作用域)
def func1():
x = 10 # 局部变量
print(f"局部变量x = {x}")
# 2. Enclosing(嵌套函数的外部作用域)
def outer():
x = 20 # 外部函数的变量
def inner():
print(f"访问外部变量x = {x}") # 可以访问
inner()
outer()
# 3. Global(全局作用域)
y = 30 # 全局变量
def func2():
print(f"访问全局变量y = {y}") # 可以访问
func2()
# 4. Built-in(内置作用域)
def func3():
print(len([1, 2, 3])) # len是内置函数
func3()
# 作用域查找示例
z = 100 # 全局
def outer_func():
z = 200 # 外部
def inner_func():
z = 300 # 局部
print(f"局部z = {z}")
inner_func()
print(f"外部z = {z}")
outer_func()
print(f"全局z = {z}")
4. lambda函数
4.1 基本语法
python
# lambda函数定义
# lambda 参数: 表达式
# 普通函数
def add(x, y):
return x + y
# lambda表达式
lambda_add = lambda x, y: x + y
print(add(10, 20)) # 30
print(lambda_add(10, 20)) # 30
# 无参lambda
lambda_hello = lambda: print("Hello, Lambda!")
lambda_hello()
# 示例:简单运算
operations = {
'add': lambda x, y: x + y,
'sub': lambda x, y: x - y,
'mul': lambda x, y: x * y,
'div': lambda x, y: x / y if y != 0 else None
}
print(operations['add'](10, 5)) # 15
print(operations['sub'](10, 5)) # 5
print(operations['mul'](10, 5)) # 50
print(operations['div'](10, 5)) # 2.0
4.2 lambda的实际应用
python
# 1. 与sorted()结合
students = [
{'name': '张三', 'age': 25, 'score': 85},
{'name': '李四', 'age': 22, 'score': 92},
{'name': '王五', 'age': 24, 'score': 78},
{'name': '赵六', 'age': 23, 'score': 88}
]
# 按年龄排序
sorted_by_age = sorted(students, key=lambda s: s['age'])
print("按年龄排序:")
for s in sorted_by_age:
print(f" {s['name']}: {s['age']}岁")
# 按成绩排序
sorted_by_score = sorted(students, key=lambda s: s['score'], reverse=True)
print("按成绩排序:")
for s in sorted_by_score:
print(f" {s['name']}: {s['score']}分")
# 2. 与filter()结合
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 筛选偶数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(f"偶数:{evens}")
# 筛选大于5的数
greater_than_5 = list(filter(lambda x: x > 5, numbers))
print(f"大于5:{greater_than_5}")
# 3. 与map()结合
# 对每个元素进行操作
squared = list(map(lambda x: x ** 2, numbers))
print(f"平方:{squared}")
# 格式化输出
names = ['alice', 'bob', 'charlie']
formatted = list(map(lambda n: n.capitalize(), names))
print(f"格式化后:{formatted}")
# 4. 与reduce()结合
from functools import reduce
# 计算乘积
product = reduce(lambda x, y: x * y, numbers)
print(f"1-10的乘积:{product}")
# 找最大值
max_num = reduce(lambda x, y: x if x > y else y, numbers)
print(f"最大值:{max_num}")
# 5. 条件表达式
# lambda中可以使用条件表达式
max_func = lambda x, y: x if x > y else y
print(max_func(10, 20)) # 20
# 判断奇偶
parity = lambda x: "偶数" if x % 2 == 0 else "奇数"
print(parity(7)) # 奇数
print(parity(8)) # 偶数
# 6. 实际案例:数据处理
data = [
"2024-01-01,张三,85",
"2024-01-01,李四,92",
"2024-01-02,王五,78",
"2024-01-02,赵六,88"
]
# 解析数据行
parsed = list(map(lambda line: line.split(','), data))
print("解析后的数据:")
for record in parsed:
print(f" {record}")
# 计算平均分
scores = list(map(lambda record: int(record[2]), parsed))
avg_score = reduce(lambda x, y: x + y, scores) / len(scores)
print(f"平均分:{avg_score:.1f}")
二、模块与包
1. 模块(Module)
1.1 什么是模块
python
"""
模块是一个包含Python定义和语句的文件
文件名就是模块名加上.py后缀
"""
# 创建模块 mymodule.py
"""
# mymodule.py
def greet(name):
print(f"Hello, {name}!")
def add(a, b):
return a + b
PI = 3.14159
class Person:
def __init__(self, name):
self.name = name
"""
# 导入整个模块
import mymodule
mymodule.greet("Alice")
result = mymodule.add(10, 20)
print(result)
# 导入特定函数/变量
from mymodule import greet, PI
greet("Bob")
print(PI)
# 导入所有内容
from mymodule import *
greet("Charlie")
# 给模块起别名
import mymodule as mm
mm.greet("David")
# 导入时重命名
from mymodule import add as addition
print(addition(30, 40))
1.2 模块搜索路径
python
import sys
# 查看模块搜索路径
print("Python模块搜索路径:")
for path in sys.path:
print(f" {path}")
# 动态添加搜索路径
sys.path.append('/my/custom/path')
# 查看已加载的模块
print("已加载的模块:")
for module in sorted(sys.modules.keys())[:10]: # 只显示前10个
print(f" {module}")
1.3 if name == "main"
python
# module_example.py
"""
这个模块演示__name__变量的使用
"""
def main():
"""主函数"""
print("这是模块的主程序")
print("执行一些测试...")
test_function()
def test_function():
"""测试函数"""
print("测试函数被调用")
def utility_function():
"""工具函数"""
print("这是一个工具函数")
# 当直接运行此文件时执行
if __name__ == "__main__":
print(f"__name__ = {__name__}")
main()
else:
# 当被导入时执行
print(f"模块 {__name__} 被导入")
print("可以在这里进行初始化")
1.4 创建和使用模块
python
# 创建一个完整的模块:math_utils.py
"""
数学工具模块
提供常用的数学函数
"""
import math
# 模块变量
__version__ = "1.0.0"
__author__ = "Python Learner"
# 常量
PI = math.pi
E = math.e
def factorial(n):
"""计算n的阶乘"""
if n < 0:
raise ValueError("负数没有阶乘")
if n == 0:
return 1
result = 1
for i in range(1, n + 1):
result *= i
return result
def is_prime(n):
"""判断是否为素数"""
if n < 2:
return False
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
def fibonacci(n):
"""生成斐波那契数列的前n项"""
if n <= 0:
return []
if n == 1:
return [0]
fib = [0, 1]
for i in range(2, n):
fib.append(fib[-1] + fib[-2])
return fib
def gcd(a, b):
"""计算最大公约数"""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""计算最小公倍数"""
return a * b // gcd(a, b)
# 测试代码
if __name__ == "__main__":
print("测试数学工具模块")
print(f"PI = {PI}")
print(f"5! = {factorial(5)}")
print(f"17是素数吗?{is_prime(17)}")
print(f"斐波那契数列前10项:{fibonacci(10)}")
print(f"12和18的最大公约数:{gcd(12, 18)}")
print(f"12和18的最小公倍数:{lcm(12, 18)}")
# 在其他文件中使用
"""
import math_utils
print(math_utils.PI)
print(math_utils.factorial(5))
print(math_utils.is_prime(17))
print(math_utils.fibonacci(10))
"""
2. 包(Package)
2.1 创建包
python
"""
包是一个包含多个模块的目录
必须包含 __init__.py 文件
包结构:
my_package/
__init__.py
module1.py
module2.py
subpackage/
__init__.py
submodule1.py
submodule2.py
"""
# __init__.py 示例
"""
# my_package/__init__.py
__version__ = "1.0.0"
__author__ = "Python Learner"
# 导入常用的模块和函数
from .module1 import func1, func2
from .module2 import Class1, Class2
# 在导入包时执行的初始化代码
print(f"初始化包 {__name__},版本 {__version__}")
# 定义__all__列表,指定from package import *时导入的内容
__all__ = ['func1', 'func2', 'Class1', 'module2']
"""
# module1.py
"""
def func1():
print("这是func1")
def func2():
print("这是func2")
def helper():
print("辅助函数,不导出")
"""
# module2.py
"""
class Class1:
def __init__(self):
self.name = "Class1"
class Class2:
def __init__(self):
self.name = "Class2"
"""
2.2 使用包
python
# 导入整个包 import my_package # 导入包中的模块 from my_package import module1 module1.func1() # 导入包中的函数/类 from my_package.module1 import func1, func2 from my_package.module2 import Class1 # 使用相对导入 """ # 在subpackage/submodule1.py中 # 相对导入 from ..module1 import func1 # 导入上级目录的module1 from .submodule2 import func2 # 导入同级目录的submodule2 # 绝对导入 from my_package.module1 import func1 """ # 示例:创建和使用数据科学包 """ # data_science/ # __init__.py # preprocessing/ # __init__.py # scaling.py # encoding.py # models/ # __init__.py # linear.py # tree.py # utils/ # __init__.py # metrics.py # visualization.py """
3. 常用模块
3.1 sys模块 - 系统相关
python
import sys
# 命令行参数
print(f"脚本名:{sys.argv[0]}")
print(f"命令行参数:{sys.argv[1:]}")
# Python版本信息
print(f"Python版本:{sys.version}")
print(f"版本信息:{sys.version_info}")
print(f"平台:{sys.platform}")
# 退出程序
# sys.exit(0) # 正常退出
# sys.exit(1) # 错误退出
# 标准输入输出
print("请输入一些内容:")
data = sys.stdin.readline()
sys.stdout.write(f"你输入了:{data}")
sys.stderr.write("这是错误信息\n")
# 路径操作
sys.path.append('/custom/path')
print(f"模块搜索路径:{sys.path[:3]}...")
# 内存管理
print(f"引用计数:{sys.getrefcount(sys)}")
print(f"当前递归深度:{sys.getrecursionlimit()}")
3.2 os模块 - 操作系统接口
python
import os
# 当前工作目录
current_dir = os.getcwd()
print(f"当前目录:{current_dir}")
# 改变工作目录
os.chdir('/tmp')
print(f"改变后目录:{os.getcwd()}")
# 目录操作
os.mkdir('test_dir') # 创建目录
os.makedirs('a/b/c') # 创建多层目录
print(os.listdir('.')) # 列出目录内容
os.rmdir('test_dir') # 删除目录
os.removedirs('a/b/c') # 删除多层目录
# 文件操作
os.rename('old.txt', 'new.txt') # 重命名
os.remove('file.txt') # 删除文件
# 路径操作
path = '/home/user/file.txt'
print(f"目录名:{os.path.dirname(path)}")
print(f"文件名:{os.path.basename(path)}")
print(f"分割:{os.path.split(path)}")
print(f"扩展名:{os.path.splitext(path)}")
print(f"是否存在:{os.path.exists(path)}")
print(f"是否是文件:{os.path.isfile(path)}")
print(f"是否是目录:{os.path.isdir(path)}")
print(f"文件大小:{os.path.getsize(path) if os.path.exists(path) else 0}")
# 环境变量
print(f"PATH环境变量:{os.environ.get('PATH')}")
print(f"HOME环境变量:{os.environ.get('HOME')}")
# 执行系统命令
os.system('ls -l') # Linux
# os.system('dir') # Windows
# 进程管理
print(f"进程ID:{os.getpid()}")
print(f"父进程ID:{os.getppid()}")
print(f"用户名:{os.getlogin()}")
3.3 datetime模块 - 日期时间
python
from datetime import datetime, date, time, timedelta
import time as time_module
# 当前日期时间
now = datetime.now()
print(f"当前时间:{now}")
print(f"当前日期:{date.today()}")
# 创建特定日期时间
dt1 = datetime(2024, 1, 1, 12, 30, 45)
print(f"指定时间:{dt1}")
d = date(2024, 1, 1)
t = time(12, 30, 45)
print(f"日期:{d}")
print(f"时间:{t}")
# 获取各个部分
print(f"年:{now.year}")
print(f"月:{now.month}")
print(f"日:{now.day}")
print(f"时:{now.hour}")
print(f"分:{now.minute}")
print(f"秒:{now.second}")
print(f"微秒:{now.microsecond}")
print(f"星期几:{now.weekday()}") # 0是周一
print(f"ISO星期几:{now.isoweekday()}") # 1是周一
# 格式化
print(f"自定义格式:{now.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"中文格式:{now.strftime('%Y年%m月%d日 %H时%M分%S秒')}")
# 字符串转datetime
date_str = "2024-01-01 12:30:45"
dt2 = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(f"解析字符串:{dt2}")
# 时间运算
today = date.today()
tomorrow = today + timedelta(days=1)
yesterday = today - timedelta(days=1)
print(f"今天:{today}")
print(f"明天:{tomorrow}")
print(f"昨天:{yesterday}")
# 时间差
start = datetime(2024, 1, 1, 10, 0, 0)
end = datetime(2024, 1, 1, 15, 30, 0)
diff = end - start
print(f"时间差:{diff}")
print(f"总秒数:{diff.total_seconds()}")
# 时间戳
timestamp = time_module.time()
print(f"当前时间戳:{timestamp}")
print(f"时间戳转datetime:{datetime.fromtimestamp(timestamp)}")
3.4 random模块 - 随机数
python
import random
# 随机浮点数
print(f"0-1随机数:{random.random()}")
print(f"1-10随机数:{random.uniform(1, 10)}")
# 随机整数
print(f"1-100随机整数:{random.randint(1, 100)}")
print(f"0-100步长为2:{random.randrange(0, 101, 2)}")
# 序列操作
fruits = ['apple', 'banana', 'orange', 'grape', 'watermelon']
print(f"随机选择:{random.choice(fruits)}")
print(f"多个随机:{random.choices(fruits, k=3)}")
print(f"随机取样:{random.sample(fruits, k=2)}")
# 打乱顺序
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(f"打乱后:{numbers}")
# 设置种子(使随机结果可重现)
random.seed(42)
print(f"种子为42:{random.randint(1, 100)}")
random.seed(42)
print(f"再次种子42:{random.randint(1, 100)}") # 相同结果
# 随机密码生成
def generate_password(length=8):
"""生成随机密码"""
import string
chars = string.ascii_letters + string.digits + "!@#$%"
return ''.join(random.choice(chars) for _ in range(length))
print(f"随机密码:{generate_password()}")
print(f"强密码:{generate_password(12)}")
# 随机验证码
def generate_code(length=4):
"""生成数字验证码"""
return ''.join(str(random.randint(0, 9)) for _ in range(length))
print(f"验证码:{generate_code()}")
print(f"6位验证码:{generate_code(6)}")
3.5 math模块 - 数学函数
python
import math
# 常量
print(f"圆周率π:{math.pi}")
print(f"自然常数e:{math.e}")
print(f"无穷大:{math.inf}")
print(f"不是数字:{math.nan}")
# 基本函数
print(f"绝对值:{math.fabs(-10.5)}")
print(f"向上取整:{math.ceil(3.2)}")
print(f"向下取整:{math.floor(3.8)}")
print(f"截断取整:{math.trunc(3.7)}")
print(f"四舍五入:{round(3.5)}") # 内置函数
# 幂和对数
print(f"2^3 = {math.pow(2, 3)}")
print(f"平方根:{math.sqrt(16)}")
print(f"自然对数:{math.log(10)}")
print(f"以10为底:{math.log10(100)}")
print(f"以2为底:{math.log2(8)}")
print(f"exp(2) = {math.exp(2)}")
# 三角函数
angle = math.pi / 4 # 45度
print(f"sin(45°) = {math.sin(angle)}")
print(f"cos(45°) = {math.cos(angle)}")
print(f"tan(45°) = {math.tan(angle)}")
print(f"角度转弧度:{math.radians(180)}")
print(f"弧度转角度:{math.degrees(math.pi)}")
# 其他函数
print(f"最大公约数:{math.gcd(12, 18)}")
print(f"阶乘:{math.factorial(5)}")
print(f"组合数:{math.comb(5, 2)}") # C(5,2)
print(f"排列数:{math.perm(5, 2)}") # P(5,2)
print(f"判断有限数:{math.isfinite(10)}")
print(f"判断无穷:{math.isinf(float('inf'))}")
print(f"判断NaN:{math.isnan(float('nan'))}")
3.6 json模块 - JSON处理
python
import json
# Python对象转JSON
data = {
"name": "张三",
"age": 25,
"city": "北京",
"skills": ["Python", "Linux", "SQL"],
"is_student": False,
"scores": {
"math": 95,
"english": 88
},
"graduation": None
}
# 序列化为JSON字符串
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("JSON字符串:")
print(json_str)
# 写入JSON文件
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# JSON字符串转Python对象
json_data = '{"name": "李四", "age": 30, "city": "上海"}'
parsed = json.loads(json_data)
print(f"解析JSON:{parsed}")
# 从文件读取JSON
with open('data.json', 'r', encoding='utf-8') as f:
loaded_data = json.load(f)
print(f"从文件加载:{loaded_data['name']}")
# 处理复杂数据类型
from datetime import datetime
def datetime_encoder(obj):
"""自定义JSON编码器"""
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
raise TypeError(f"Type {type(obj)} not serializable")
now = datetime.now()
data_with_date = {
"name": "王五",
"created_at": now
}
# 使用自定义编码器
json_str = json.dumps(data_with_date, default=datetime_encoder, indent=2)
print(json_str)
3.7 re模块 - 正则表达式
python
import re
# 基本匹配
text = "我的邮箱是:zhangsan@example.com,电话:138-1234-5678"
# search:搜索第一个匹配
email = re.search(r'[\w.-]+@[\w.-]+\.\w+', text)
if email:
print(f"找到邮箱:{email.group()}")
# findall:查找所有匹配
phones = re.findall(r'\d{3}-\d{4}-\d{4}', text)
print(f"找到电话:{phones}")
# 验证邮箱格式
def is_valid_email(email):
"""验证邮箱格式"""
pattern = r'^[\w.-]+@[\w.-]+\.\w+$'
return bool(re.match(pattern, email))
print(is_valid_email("test@example.com")) # True
print(is_valid_email("invalid-email")) # False
# 替换
text = "Hello, 我的电话是138-1234-5678,请尽快联系"
new_text = re.sub(r'\d{3}-\d{4}-\d{4}', '***-****-****', text)
print(new_text)
# 分割
text = "apple,banana;orange|grape"
fruits = re.split(r'[,;|]', text)
print(f"分割结果:{fruits}")
# 分组提取
log = "2024-01-01 12:30:45 - ERROR - 数据库连接失败"
pattern = r'(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) - (\w+) - (.+)'
match = re.match(pattern, log)
if match:
date, time, level, message = match.groups()
print(f"日期:{date}")
print(f"时间:{time}")
print(f"级别:{level}")
print(f"消息:{message}")
3.8 其他常用模块
python
# 1. collections模块 - 高级容器
from collections import Counter, defaultdict, deque, namedtuple
# Counter:计数器
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
counter = Counter(words)
print(f"单词计数:{counter}")
print(f"最常见:{counter.most_common(2)}")
# defaultdict:默认字典
dd = defaultdict(int)
dd['a'] += 1
dd['b'] += 2
print(f"默认字典:{dict(dd)}")
# deque:双端队列
dq = deque([1, 2, 3])
dq.appendleft(0)
dq.append(4)
print(f"双端队列:{list(dq)}")
# namedtuple:命名元组
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(f"点坐标:({p.x}, {p.y})")
# 2. itertools模块 - 迭代工具
from itertools import count, cycle, repeat, permutations, combinations
# permutations:排列
items = [1, 2, 3]
perms = list(permutations(items, 2))
print(f"排列:{perms}")
# combinations:组合
combs = list(combinations(items, 2))
print(f"组合:{combs}")
# 3. hashlib模块 - 哈希算法
import hashlib
password = "my_password123"
md5_hash = hashlib.md5(password.encode()).hexdigest()
sha256_hash = hashlib.sha256(password.encode()).hexdigest()
print(f"MD5哈希:{md5_hash}")
print(f"SHA256哈希:{sha256_hash}")
# 4. logging模块 - 日志记录
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.debug("调试信息") # 不会显示
logger.info("信息消息")
logger.warning("警告消息")
logger.error("错误消息")
# 5. argparse模块 - 命令行参数解析
import argparse
"""
# 在命令行中运行:python script.py --name Alice --age 25
parser = argparse.ArgumentParser(description='示例程序')
parser.add_argument('--name', required=True, help='姓名')
parser.add_argument('--age', type=int, default=18, help='年龄')
args = parser.parse_args()
print(f"姓名:{args.name}")
print(f"年龄:{args.age}")
"""
三、综合应用案例
案例1:计算器程序(模块化设计)
python
"""
calculator/
__init__.py
core.py
operations.py
utils.py
main.py
"""
# core.py
"""计算器核心模块"""
class Calculator:
"""计算器类"""
def __init__(self):
self.history = []
self.memory = 0
def add(self, a, b):
result = a + b
self._log_operation(f"{a} + {b} = {result}")
return result
def subtract(self, a, b):
result = a - b
self._log_operation(f"{a} - {b} = {result}")
return result
def multiply(self, a, b):
result = a * b
self._log_operation(f"{a} × {b} = {result}")
return result
def divide(self, a, b):
if b == 0:
raise ValueError("除数不能为0")
result = a / b
self._log_operation(f"{a} ÷ {b} = {result}")
return result
def power(self, a, b):
result = a ** b
self._log_operation(f"{a} ^ {b} = {result}")
return result
def _log_operation(self, operation):
"""记录操作历史"""
self.history.append(operation)
def get_history(self):
"""获取历史记录"""
return self.history.copy()
def clear_history(self):
"""清空历史记录"""
self.history.clear()
def memory_store(self, value):
"""存储到内存"""
self.memory = value
def memory_recall(self):
"""从内存召回"""
return self.memory
def memory_clear(self):
"""清除内存"""
self.memory = 0
# operations.py
"""高级运算模块"""
import math
def factorial(n):
"""计算阶乘"""
if n < 0:
raise ValueError("负数没有阶乘")
return math.factorial(n)
def is_prime(n):
"""判断素数"""
if n < 2:
return False
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
def fibonacci(n):
"""生成斐波那契数列"""
if n <= 0:
return []
if n == 1:
return [0]
fib = [0, 1]
for i in range(2, n):
fib.append(fib[-1] + fib[-2])
return fib
def gcd(a, b):
"""最大公约数"""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""最小公倍数"""
return a * b // gcd(a, b)
# utils.py
"""工具函数模块"""
import json
from datetime import datetime
def validate_number(value):
"""验证是否为有效数字"""
try:
float(value)
return True
except ValueError:
return False
def format_result(value, precision=2):
"""格式化结果"""
if isinstance(value, float):
return f"{value:.{precision}f}"
return str(value)
def save_history(history, filename="history.json"):
"""保存历史记录"""
data = {
"timestamp": datetime.now().isoformat(),
"history": history
}
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def load_history(filename="history.json"):
"""加载历史记录"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
return data.get('history', [])
except FileNotFoundError:
return []
# main.py
"""计算器主程序"""
from core import Calculator
import operations as ops
import utils
def main():
"""主函数"""
calc = Calculator()
print("=" * 40)
print("Python计算器")
print("=" * 40)
while True:
print("\n可用的操作:")
print("1. 加法")
print("2. 减法")
print("3. 乘法")
print("4. 除法")
print("5. 幂运算")
print("6. 阶乘")
print("7. 素数判断")
print("8. 斐波那契数列")
print("9. 最大公约数")
print("10. 最小公倍数")
print("11. 查看历史")
print("12. 内存操作")
print("0. 退出")
choice = input("\n请选择操作 (0-12): ")
if choice == '0':
print("感谢使用,再见!")
# 保存历史记录
utils.save_history(calc.get_history())
break
elif choice == '1':
a = float(input("输入第一个数:"))
b = float(input("输入第二个数:"))
result = calc.add(a, b)
print(f"结果:{utils.format_result(result)}")
elif choice == '2':
a = float(input("输入第一个数:"))
b = float(input("输入第二个数:"))
result = calc.subtract(a, b)
print(f"结果:{utils.format_result(result)}")
elif choice == '3':
a = float(input("输入第一个数:"))
b = float(input("输入第二个数:"))
result = calc.multiply(a, b)
print(f"结果:{utils.format_result(result)}")
elif choice == '4':
a = float(input("输入第一个数:"))
b = float(input("输入第二个数:"))
try:
result = calc.divide(a, b)
print(f"结果:{utils.format_result(result)}")
except ValueError as e:
print(f"错误:{e}")
elif choice == '5':
a = float(input("输入底数:"))
b = float(input("输入指数:"))
result = calc.power(a, b)
print(f"结果:{utils.format_result(result)}")
elif choice == '6':
n = int(input("输入整数:"))
try:
result = ops.factorial(n)
print(f"{n}! = {result}")
except ValueError as e:
print(f"错误:{e}")
elif choice == '7':
n = int(input("输入整数:"))
if ops.is_prime(n):
print(f"{n} 是素数")
else:
print(f"{n} 不是素数")
elif choice == '8':
n = int(input("输入项数:"))
fib = ops.fibonacci(n)
print(f"斐波那契数列前{n}项:{fib}")
elif choice == '9':
a = int(input("输入第一个数:"))
b = int(input("输入第二个数:"))
result = ops.gcd(a, b)
print(f"最大公约数:{result}")
elif choice == '10':
a = int(input("输入第一个数:"))
b = int(input("输入第二个数:"))
result = ops.lcm(a, b)
print(f"最小公倍数:{result}")
elif choice == '11':
history = calc.get_history()
if history:
print("\n历史记录:")
for i, op in enumerate(history, 1):
print(f"{i}. {op}")
else:
print("暂无历史记录")
elif choice == '12':
print("\n内存操作:")
print("1. 存入内存")
print("2. 读取内存")
print("3. 清除内存")
mem_choice = input("请选择:")
if mem_choice == '1':
value = float(input("输入要存储的值:"))
calc.memory_store(value)
print(f"已存储:{value}")
elif mem_choice == '2':
value = calc.memory_recall()
print(f"内存中的值:{value}")
elif mem_choice == '3':
calc.memory_clear()
print("内存已清除")
if __name__ == "__main__":
main()
案例2:文件处理工具模块
python
"""
file_utils.py
文件处理工具模块
"""
import os
import shutil
import hashlib
from datetime import datetime
from pathlib import Path
class FileHandler:
"""文件处理器"""
def __init__(self, base_dir=None):
self.base_dir = base_dir or os.getcwd()
self.operations_log = []
def list_files(self, pattern="*", recursive=False):
"""列出文件"""
path = Path(self.base_dir)
if recursive:
files = list(path.rglob(pattern))
else:
files = list(path.glob(pattern))
return [str(f) for f in files]
def read_file(self, filename, encoding='utf-8'):
"""读取文件"""
try:
filepath = self._get_path(filename)
with open(filepath, 'r', encoding=encoding) as f:
content = f.read()
self._log_operation(f"读取文件:{filename}")
return content
except Exception as e:
self._log_operation(f"读取失败:{filename} - {e}")
raise
def write_file(self, filename, content, encoding='utf-8'):
"""写入文件"""
filepath = self._get_path(filename)
# 确保目录存在
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w', encoding=encoding) as f:
f.write(content)
self._log_operation(f"写入文件:{filename}")
return True
def copy_file(self, src, dst):
"""复制文件"""
src_path = self._get_path(src)
dst_path = self._get_path(dst)
shutil.copy2(src_path, dst_path)
self._log_operation(f"复制文件:{src} -> {dst}")
return True
def move_file(self, src, dst):
"""移动文件"""
src_path = self._get_path(src)
dst_path = self._get_path(dst)
shutil.move(src_path, dst_path)
self._log_operation(f"移动文件:{src} -> {dst}")
return True
def delete_file(self, filename):
"""删除文件"""
filepath = self._get_path(filename)
os.remove(filepath)
self._log_operation(f"删除文件:{filename}")
return True
def get_file_info(self, filename):
"""获取文件信息"""
filepath = self._get_path(filename)
stat = os.stat(filepath)
info = {
'name': os.path.basename(filepath),
'path': filepath,
'size': stat.st_size,
'created': datetime.fromtimestamp(stat.st_ctime),
'modified': datetime.fromtimestamp(stat.st_mtime),
'accessed': datetime.fromtimestamp(stat.st_atime),
'is_dir': os.path.isdir(filepath),
'is_file': os.path.isfile(filepath),
'extension': os.path.splitext(filepath)[1]
}
return info
def calculate_hash(self, filename, algorithm='md5'):
"""计算文件哈希值"""
filepath = self._get_path(filename)
hash_func = hashlib.new(algorithm)
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
hash_func.update(chunk)
return hash_func.hexdigest()
def search_in_files(self, pattern, file_pattern="*.txt"):
"""在文件中搜索内容"""
results = []
files = self.list_files(file_pattern)
for file in files:
try:
content = self.read_file(file)
if pattern in content:
results.append({
'file': file,
'lines': [
i+1 for i, line in enumerate(content.split('\n'))
if pattern in line
]
})
except:
continue
return results
def backup_file(self, filename):
"""备份文件"""
filepath = self._get_path(filename)
backup_name = f"{filename}.{datetime.now().strftime('%Y%m%d_%H%M%S')}.bak"
backup_path = self._get_path(backup_name)
shutil.copy2(filepath, backup_path)
self._log_operation(f"备份文件:{filename} -> {backup_name}")
return backup_name
def split_file(self, filename, lines_per_file=1000):
"""分割大文件"""
filepath = self._get_path(filename)
base, ext = os.path.splitext(filename)
with open(filepath, 'r', encoding='utf-8') as f:
part_num = 1
current_lines = []
for line in f:
current_lines.append(line)
if len(current_lines) >= lines_per_file:
part_filename = f"{base}_part{part_num:03d}{ext}"
self.write_file(part_filename, ''.join(current_lines))
part_num += 1
current_lines = []
# 写入剩余行
if current_lines:
part_filename = f"{base}_part{part_num:03d}{ext}"
self.write_file(part_filename, ''.join(current_lines))
self._log_operation(f"分割文件:{filename} -> {part_num}个文件")
return part_num
def _get_path(self, filename):
"""获取完整路径"""
if os.path.isabs(filename):
return filename
return os.path.join(self.base_dir, filename)
def _log_operation(self, message):
"""记录操作"""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.operations_log.append(f"[{timestamp}] {message}")
def get_log(self):
"""获取操作日志"""
return self.operations_log.copy()
# 使用示例
if __name__ == "__main__":
handler = FileHandler("/tmp")
# 创建测试文件
handler.write_file("test.txt", "Hello, World!\nThis is a test file.")
# 读取文件
content = handler.read_file("test.txt")
print(f"文件内容:{content}")
# 获取文件信息
info = handler.get_file_info("test.txt")
print(f"文件信息:{info}")
# 计算哈希
md5 = handler.calculate_hash("test.txt")
print(f"MD5:{md5}")
# 备份文件
backup = handler.backup_file("test.txt")
print(f"备份文件:{backup}")
# 查看操作日志
print("\n操作日志:")
for log in handler.get_log():
print(log)
四、总结
1. 函数要点回顾
| 函数类型 | 特点 | 使用场景 |
|---|---|---|
| 无参函数 | 不接受参数 | 执行固定操作,如打印菜单 |
| 位置参数 | 按顺序传参 | 基本函数调用 |
| 默认参数 | 有默认值 | 可选参数,简化调用 |
| 可变参数 | *args | 不确定参数个数 |
| 关键字参数 | **kwargs | 处理命名参数 |
| lambda函数 | 匿名,单行 | 简单操作,回调函数 |
2. 模块化设计原则
-
单一职责:每个模块只负责一个功能
-
接口清晰:提供明确的函数和类接口
-
高内聚:模块内部功能紧密相关
-
低耦合:模块之间依赖最小化
3. 常用模块速查
| 模块 | 主要功能 | 常用函数/类 |
|---|---|---|
| sys | 系统相关 | argv, path, exit |
| os | 操作系统 | getcwd, listdir, path |
| datetime | 日期时间 | datetime, date, timedelta |
| random | 随机数 | random, choice, shuffle |
| math | 数学运算 | sqrt, sin, cos, log |
| json | JSON处理 | dumps, loads, dump, load |
| re | 正则表达式 | search, findall, sub |
| collections | 高级容器 | Counter, defaultdict |
| itertools | 迭代工具 | permutations, combinations |
| hashlib | 哈希算法 | md5, sha256 |
更多推荐



所有评论(0)