一、函数

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
jsonJSON处理dumps, loads, dump, load
re正则表达式search, findall, sub
collections高级容器Counter, defaultdict
itertools迭代工具permutations, combinations
hashlib哈希算法md5, sha256
Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐