HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • Python 新手入门教程

    • Python新手入门教程 - 零基础学Python,8章+HTTP服务实战 | HiHuo
    • Python简介与环境搭建 - 安装配置Python开发环境 | HiHuo
    • Python基础语法 - 缩进、变量、注释、输入输出 | HiHuo
    • Python数据类型详解 - 字符串、列表、字典、元组 | HiHuo
    • Python流程控制 - if条件判断、for/while循环 | HiHuo
    • Python函数与模块 - 定义函数、参数传递、模块导入 | HiHuo
    • Python面向对象编程 - 类、对象、继承、多态 | HiHuo
    • Python文件与异常处理 - 读写文件、try/except异常捕获 | HiHuo
    • Python HTTP服务项目实战 - 构建待办事项API服务 | HiHuo

函数与模块

函数是组织代码的基本单元,模块是组织函数的方式。

函数基础

定义函数

# 基本语法
def greet():
    print("Hello, World!")

# 调用函数
greet()  # Hello, World!

# 带参数的函数
def greet_user(name):
    print(f"Hello, {name}!")

greet_user("张三")  # Hello, 张三!

# 带返回值的函数
def add(a, b):
    return a + b

result = add(3, 5)
print(result)  # 8

参数类型

# 1. 位置参数
def power(base, exp):
    return base ** exp

print(power(2, 3))  # 8

# 2. 关键字参数
print(power(exp=3, base=2))  # 8

# 3. 默认参数
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("张三")              # Hello, 张三!
greet("张三", "Hi")        # Hi, 张三!

# 4. 可变位置参数 *args
def sum_all(*numbers):
    return sum(numbers)

print(sum_all(1, 2, 3, 4, 5))  # 15

# 5. 可变关键字参数 **kwargs
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="张三", age=25, city="北京")

# 6. 混合使用
def func(a, b, *args, c=10, **kwargs):
    print(f"a={a}, b={b}")
    print(f"args={args}")
    print(f"c={c}")
    print(f"kwargs={kwargs}")

func(1, 2, 3, 4, c=20, d=30, e=40)

参数顺序规则

# 正确顺序:位置参数 → *args → 默认参数 → **kwargs
def func(a, b, *args, c=10, **kwargs):
    pass

# 强制关键字参数(*后面的参数必须用关键字)
def greet(name, *, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("张三")                    # Hello, 张三!
greet("张三", greeting="Hi")     # Hi, 张三!
# greet("张三", "Hi")  # TypeError!

返回值

# 返回单个值
def square(x):
    return x ** 2

# 返回多个值(实际是元组)
def get_min_max(numbers):
    return min(numbers), max(numbers)

minimum, maximum = get_min_max([3, 1, 4, 1, 5, 9])
print(f"最小: {minimum}, 最大: {maximum}")

# 提前返回
def check_age(age):
    if age < 0:
        return "无效年龄"
    if age < 18:
        return "未成年"
    return "成年"

# 没有 return 语句时返回 None
def do_nothing():
    pass

print(do_nothing())  # None

典型案例:用户注册验证

def validate_registration(username, password, email):
    """验证用户注册信息"""
    errors = []

    # 验证用户名
    if len(username) < 3:
        errors.append("用户名至少3个字符")
    if not username.isalnum():
        errors.append("用户名只能包含字母和数字")

    # 验证密码
    if len(password) < 6:
        errors.append("密码至少6个字符")

    # 验证邮箱
    if "@" not in email or "." not in email:
        errors.append("邮箱格式不正确")

    if errors:
        return False, errors
    return True, []

# 使用
is_valid, errors = validate_registration("ab", "123", "test")
if not is_valid:
    for error in errors:
        print(f"错误: {error}")

变量作用域

# 全局变量
global_var = "我是全局变量"

def func():
    # 局部变量
    local_var = "我是局部变量"
    print(global_var)   # 可以读取全局变量
    print(local_var)

func()
# print(local_var)  # NameError: 局部变量在外部不可见

# 修改全局变量需要 global 声明
counter = 0

def increment():
    global counter
    counter += 1

increment()
print(counter)  # 1

# 嵌套函数的 nonlocal
def outer():
    x = 10
    def inner():
        nonlocal x
        x += 1
        print(f"inner: x = {x}")
    inner()
    print(f"outer: x = {x}")

outer()
# inner: x = 11
# outer: x = 11

匿名函数 (lambda)

# 基本语法
square = lambda x: x ** 2
print(square(5))  # 25

# 多个参数
add = lambda a, b: a + b
print(add(3, 5))  # 8

# 常用于排序
students = [
    {"name": "张三", "score": 85},
    {"name": "李四", "score": 92},
    {"name": "王五", "score": 78}
]

# 按分数排序
sorted_students = sorted(students, key=lambda s: s["score"])
print([s["name"] for s in sorted_students])  # ['王五', '张三', '李四']

# 按分数降序
sorted_students = sorted(students, key=lambda s: s["score"], reverse=True)

高阶函数

高阶函数是接收函数作为参数或返回函数的函数。

map()

# 对每个元素应用函数
numbers = [1, 2, 3, 4, 5]

# 使用 map
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# 等价的列表推导式
squares = [x**2 for x in numbers]

# 多个序列
a = [1, 2, 3]
b = [4, 5, 6]
sums = list(map(lambda x, y: x + y, a, b))
print(sums)  # [5, 7, 9]

filter()

# 过滤元素
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 使用 filter
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# 等价的列表推导式
evens = [x for x in numbers if x % 2 == 0]

reduce()

from functools import reduce

# 累积计算
numbers = [1, 2, 3, 4, 5]

# 求和
total = reduce(lambda x, y: x + y, numbers)
print(total)  # 15

# 求积
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120

# 求最大值
maximum = reduce(lambda x, y: x if x > y else y, numbers)
print(maximum)  # 5

sorted() 与 key

# 字符串按长度排序
words = ["apple", "pie", "banana", "cherry"]
sorted_words = sorted(words, key=len)
print(sorted_words)  # ['pie', 'apple', 'cherry', 'banana']

# 忽略大小写排序
words = ["Apple", "banana", "Cherry"]
sorted_words = sorted(words, key=str.lower)
print(sorted_words)  # ['Apple', 'banana', 'Cherry']

# 复杂对象排序
from operator import itemgetter

students = [
    {"name": "张三", "age": 20, "score": 85},
    {"name": "李四", "age": 19, "score": 92},
    {"name": "王五", "age": 21, "score": 78}
]

# 按年龄排序
by_age = sorted(students, key=itemgetter("age"))

# 多字段排序:先按分数降序,再按年龄升序
by_score_age = sorted(students, key=lambda s: (-s["score"], s["age"]))

装饰器

装饰器用于在不修改函数代码的情况下增强函数功能。

# 基本装饰器
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("函数执行前")
        result = func(*args, **kwargs)
        print("函数执行后")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("张三")
# 函数执行前
# Hello, 张三!
# 函数执行后

典型案例:计时装饰器

import time
from functools import wraps

def timer(func):
    @wraps(func)  # 保留原函数信息
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 执行耗时: {end - start:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    print("函数执行完成")

slow_function()
# 函数执行完成
# slow_function 执行耗时: 1.0012秒

典型案例:权限检查装饰器

def require_auth(func):
    @wraps(func)
    def wrapper(user, *args, **kwargs):
        if not user.get("is_authenticated"):
            print("请先登录!")
            return None
        return func(user, *args, **kwargs)
    return wrapper

@require_auth
def get_user_profile(user):
    return f"用户资料: {user['name']}"

# 测试
guest = {"name": "访客", "is_authenticated": False}
member = {"name": "张三", "is_authenticated": True}

print(get_user_profile(guest))   # 请先登录! None
print(get_user_profile(member))  # 用户资料: 张三

递归函数

# 阶乘
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # 120

# 斐波那契(低效版本)
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

# 带缓存的斐波那契(高效)
from functools import lru_cache

@lru_cache(maxsize=None)
def fib_cached(n):
    if n <= 1:
        return n
    return fib_cached(n - 1) + fib_cached(n - 2)

print(fib_cached(100))  # 354224848179261915075

模块

导入模块

# 导入整个模块
import math
print(math.sqrt(16))  # 4.0

# 导入特定函数
from math import sqrt, pi
print(sqrt(16))  # 4.0
print(pi)        # 3.141592653589793

# 导入所有(不推荐)
from math import *

# 别名
import numpy as np
from math import sqrt as square_root

# 导入自己的模块
# 假设有文件 mymodule.py
import mymodule
from mymodule import my_function

创建模块

# mymath.py

"""这是我的数学模块"""

PI = 3.14159

def circle_area(radius):
    """计算圆的面积"""
    return PI * radius ** 2

def circle_circumference(radius):
    """计算圆的周长"""
    return 2 * PI * radius

# 仅在直接运行时执行
if __name__ == "__main__":
    print(circle_area(5))
# main.py
import mymath

print(mymath.PI)
print(mymath.circle_area(5))

包

包是包含多个模块的目录,必须有 __init__.py 文件。

mypackage/
    __init__.py
    module1.py
    module2.py
    subpackage/
        __init__.py
        module3.py
# 导入包中的模块
from mypackage import module1
from mypackage.subpackage import module3

常用标准库

# os - 操作系统接口
import os
print(os.getcwd())           # 当前目录
print(os.listdir("."))       # 列出目录内容
os.makedirs("path/to/dir", exist_ok=True)  # 创建目录

# sys - 系统相关
import sys
print(sys.version)           # Python 版本
print(sys.path)              # 模块搜索路径
sys.exit(0)                  # 退出程序

# datetime - 日期时间
from datetime import datetime, timedelta
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))
tomorrow = now + timedelta(days=1)

# random - 随机数
import random
print(random.randint(1, 100))     # 随机整数
print(random.choice([1, 2, 3]))   # 随机选择
random.shuffle([1, 2, 3, 4, 5])   # 打乱列表

# json - JSON 处理
import json
data = {"name": "张三", "age": 25}
json_str = json.dumps(data, ensure_ascii=False)
parsed = json.loads(json_str)

# re - 正则表达式
import re
pattern = r"\d+"
matches = re.findall(pattern, "abc123def456")
print(matches)  # ['123', '456']

典型案例:日志模块

# logger.py
import datetime

LOG_LEVELS = {
    "DEBUG": 0,
    "INFO": 1,
    "WARNING": 2,
    "ERROR": 3
}

current_level = "INFO"

def log(level, message):
    if LOG_LEVELS.get(level, 0) >= LOG_LEVELS.get(current_level, 0):
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print(f"[{timestamp}] [{level}] {message}")

def debug(message):
    log("DEBUG", message)

def info(message):
    log("INFO", message)

def warning(message):
    log("WARNING", message)

def error(message):
    log("ERROR", message)

def set_level(level):
    global current_level
    current_level = level

练习

练习1:实现 map 函数

def my_map(func, iterable):
    result = []
    for item in iterable:
        result.append(func(item))
    return result

# 测试
numbers = [1, 2, 3, 4, 5]
squares = my_map(lambda x: x**2, numbers)
print(squares)  # [1, 4, 9, 16, 25]

练习2:缓存装饰器

def memoize(func):
    cache = {}
    @wraps(func)
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrapper

@memoize
def expensive_computation(n):
    print(f"计算 {n}")
    return n ** 2

print(expensive_computation(5))  # 计算 5 → 25
print(expensive_computation(5))  # 直接返回 25(没有重新计算)

小结

  • 函数使用 def 定义,return 返回值
  • 参数类型:位置参数、默认参数、*args、**kwargs
  • lambda 创建匿名函数
  • map、filter、reduce 是常用高阶函数
  • 装饰器用于增强函数功能
  • 使用 import 导入模块
  • if __name__ == "__main__" 用于模块的入口代码
Prev
Python流程控制 - if条件判断、for/while循环 | HiHuo
Next
Python面向对象编程 - 类、对象、继承、多态 | HiHuo