Skip to content

Python高级特性 ​

装饰器 ​

装饰器的概念 ​

装饰器是Python中一种强大的编程工具,它允许我们在不修改原函数代码的情况下,增强函数的功能。装饰器本质上是一个接收函数作为参数并返回新函数的函数。

基本装饰器 ​

python
def decorator(func):
    def wrapper():
        print("函数执行前的操作")
        func()
        print("函数执行后的操作")
    return wrapper

@decorator
def hello():
    print("Hello, World!")

hello()
# 输出:
# 函数执行前的操作
# Hello, World!
# 函数执行后的操作
def decorator(func):
    def wrapper():
        print("函数执行前的操作")
        func()
        print("函数执行后的操作")
    return wrapper

@decorator
def hello():
    print("Hello, World!")

hello()
# 输出:
# 函数执行前的操作
# Hello, World!
# 函数执行后的操作

带参数的装饰器 ​

python
def decorator_with_args(arg1, arg2):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"装饰器参数: {arg1}, {arg2}")
            print("函数执行前的操作")
            result = func(*args, **kwargs)
            print("函数执行后的操作")
            return result
        return wrapper
    return decorator

@decorator_with_args("参数1", "参数2")
def add(a, b):
    return a + b

result = add(1, 2)
print(f"函数结果: {result}")
# 输出:
# 装饰器参数: 参数1, 参数2
# 函数执行前的操作
# 函数执行后的操作
# 函数结果: 3
def decorator_with_args(arg1, arg2):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"装饰器参数: {arg1}, {arg2}")
            print("函数执行前的操作")
            result = func(*args, **kwargs)
            print("函数执行后的操作")
            return result
        return wrapper
    return decorator

@decorator_with_args("参数1", "参数2")
def add(a, b):
    return a + b

result = add(1, 2)
print(f"函数结果: {result}")
# 输出:
# 装饰器参数: 参数1, 参数2
# 函数执行前的操作
# 函数执行后的操作
# 函数结果: 3

类装饰器 ​

python
class Decorator:
    def __init__(self, func):
        self.func = func
    
    def __call__(self, *args, **kwargs):
        print("类装饰器执行前的操作")
        result = self.func(*args, **kwargs)
        print("类装饰器执行后的操作")
        return result

@Decorator
def multiply(a, b):
    return a * b

result = multiply(3, 4)
print(f"函数结果: {result}")
# 输出:
# 类装饰器执行前的操作
# 类装饰器执行后的操作
# 函数结果: 12
class Decorator:
    def __init__(self, func):
        self.func = func
    
    def __call__(self, *args, **kwargs):
        print("类装饰器执行前的操作")
        result = self.func(*args, **kwargs)
        print("类装饰器执行后的操作")
        return result

@Decorator
def multiply(a, b):
    return a * b

result = multiply(3, 4)
print(f"函数结果: {result}")
# 输出:
# 类装饰器执行前的操作
# 类装饰器执行后的操作
# 函数结果: 12

常用内置装饰器 ​

  1. @property: 将方法转换为只读属性
  2. @staticmethod: 将方法转换为静态方法
  3. @classmethod: 将方法转换为类方法
  4. @functools.wraps: 保留原函数的元信息
python
import functools

class MyClass:
    def __init__(self, value):
        self._value = value
    
    @property
    def value(self):
        return self._value
    
    @value.setter
    def value(self, new_value):
        if new_value > 0:
            self._value = new_value
    
    @staticmethod
    def static_method():
        return "这是静态方法"
    
    @classmethod
    def class_method(cls):
        return f"这是类方法,类名: {cls.__name__}"

# 使用functools.wraps保留原函数元信息
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper
import functools

class MyClass:
    def __init__(self, value):
        self._value = value
    
    @property
    def value(self):
        return self._value
    
    @value.setter
    def value(self, new_value):
        if new_value > 0:
            self._value = new_value
    
    @staticmethod
    def static_method():
        return "这是静态方法"
    
    @classmethod
    def class_method(cls):
        return f"这是类方法,类名: {cls.__name__}"

# 使用functools.wraps保留原函数元信息
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

生成器 ​

生成器的概念 ​

生成器是一种特殊的迭代器,它允许我们在循环中动态生成值,而不需要一次性将所有值存储在内存中。生成器使用yield关键字来产生值。

生成器函数 ​

python
def generator_function(n):
    for i in range(n):
        yield i * 2

# 使用生成器
gen = generator_function(5)

# 方法1:使用next()函数
print(next(gen))  # 0
print(next(gen))  # 2
print(next(gen))  # 4

# 方法2:使用for循环
for value in gen:
    print(value)  # 6, 8
def generator_function(n):
    for i in range(n):
        yield i * 2

# 使用生成器
gen = generator_function(5)

# 方法1:使用next()函数
print(next(gen))  # 0
print(next(gen))  # 2
print(next(gen))  # 4

# 方法2:使用for循环
for value in gen:
    print(value)  # 6, 8

生成器表达式 ​

python
# 生成器表达式
gen_expr = (i * 3 for i in range(5))

for value in gen_expr:
    print(value)  # 0, 3, 6, 9, 12

# 对比列表推导式(会一次性生成所有值)
list_comp = [i * 3 for i in range(5)]
print(list_comp)  # [0, 3, 6, 9, 12]
# 生成器表达式
gen_expr = (i * 3 for i in range(5))

for value in gen_expr:
    print(value)  # 0, 3, 6, 9, 12

# 对比列表推导式(会一次性生成所有值)
list_comp = [i * 3 for i in range(5)]
print(list_comp)  # [0, 3, 6, 9, 12]

生成器的应用场景 ​

  1. 处理大数据集:避免一次性加载所有数据到内存
  2. 无限序列:生成无限序列,如斐波那契数列
  3. 惰性计算:只在需要时才计算值
python
# 生成无限斐波那契数列
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# 使用islice限制输出数量
from itertools import islice

fib = fibonacci()
for num in islice(fib, 10):
    print(num)  # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
# 生成无限斐波那契数列
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# 使用islice限制输出数量
from itertools import islice

fib = fibonacci()
for num in islice(fib, 10):
    print(num)  # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

迭代器 ​

迭代器的概念 ​

迭代器是一种对象,它实现了迭代器协议,即__iter__()和__next__()方法。迭代器允许我们逐个访问容器中的元素,而不需要知道容器的内部结构。

迭代器协议 ​

  1. __iter__():返回迭代器对象本身
  2. __next__():返回容器中的下一个元素,如果没有更多元素,则抛出StopIteration异常

自定义迭代器 ​

python
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index < len(self.data):
            value = self.data[self.index]
            self.index += 1
            return value
        else:
            raise StopIteration

# 使用自定义迭代器
my_iter = MyIterator([1, 2, 3, 4, 5])

for value in my_iter:
    print(value)  # 1, 2, 3, 4, 5
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index < len(self.data):
            value = self.data[self.index]
            self.index += 1
            return value
        else:
            raise StopIteration

# 使用自定义迭代器
my_iter = MyIterator([1, 2, 3, 4, 5])

for value in my_iter:
    print(value)  # 1, 2, 3, 4, 5

内置迭代器 ​

Python中的许多内置数据结构都实现了迭代器协议,如列表、元组、字典、集合和字符串。

python
# 列表迭代器
my_list = [1, 2, 3]
list_iter = iter(my_list)
print(next(list_iter))  # 1
print(next(list_iter))  # 2

# 字典迭代器
my_dict = {"a": 1, "b": 2}
# 迭代字典的键
dict_iter = iter(my_dict)
print(next(dict_iter))  # a
# 迭代字典的值
value_iter = iter(my_dict.values())
print(next(value_iter))  # 1
# 迭代字典的键值对
item_iter = iter(my_dict.items())
print(next(item_iter))  # ('a', 1)
# 列表迭代器
my_list = [1, 2, 3]
list_iter = iter(my_list)
print(next(list_iter))  # 1
print(next(list_iter))  # 2

# 字典迭代器
my_dict = {"a": 1, "b": 2}
# 迭代字典的键
dict_iter = iter(my_dict)
print(next(dict_iter))  # a
# 迭代字典的值
value_iter = iter(my_dict.values())
print(next(value_iter))  # 1
# 迭代字典的键值对
item_iter = iter(my_dict.items())
print(next(item_iter))  # ('a', 1)

迭代器与生成器的关系 ​

  • 生成器是一种特殊的迭代器
  • 生成器自动实现了迭代器协议
  • 生成器使用yield关键字,而迭代器需要手动实现__iter__()和__next__()方法

高级迭代工具 ​

itertools模块 ​

itertools模块提供了许多用于高效迭代的工具函数。

python
import itertools

# 1. 无限迭代器
# count: 从指定数字开始,无限递增
for i in itertools.islice(itertools.count(10, 2), 5):
    print(i)  # 10, 12, 14, 16, 18

# cycle: 无限循环迭代一个序列
for i, val in enumerate(itertools.islice(itertools.cycle(["A", "B", "C"]), 5)):
    print(f"{i}: {val}")  # 0:A, 1:B, 2:C, 3:A, 4:B

# repeat: 重复一个值指定次数
for val in itertools.repeat("Hello", 3):
    print(val)  # Hello, Hello, Hello

# 2. 组合迭代器
# product: 笛卡尔积
for combo in itertools.product([1, 2], ["a", "b"]):
    print(combo)  # (1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')

# permutations: 排列
for perm in itertools.permutations([1, 2, 3], 2):
    print(perm)  # (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)

# combinations: 组合
for comb in itertools.combinations([1, 2, 3], 2):
    print(comb)  # (1, 2), (1, 3), (2, 3)

# 3. 迭代器操作
# chain: 连接多个迭代器
for val in itertools.chain([1, 2], [3, 4], [5, 6]):
    print(val)  # 1, 2, 3, 4, 5, 6

# groupby: 分组
from operator import itemgetter

data = [
    {"name": "张三", "age": 20},
    {"name": "李四", "age": 20},
    {"name": "王五", "age": 21},
    {"name": "赵六", "age": 21}
]

for age, group in itertools.groupby(data, key=itemgetter("age")):
    print(f"年龄 {age} 的人:")
    for person in group:
        print(f"  {person['name']}")
import itertools

# 1. 无限迭代器
# count: 从指定数字开始,无限递增
for i in itertools.islice(itertools.count(10, 2), 5):
    print(i)  # 10, 12, 14, 16, 18

# cycle: 无限循环迭代一个序列
for i, val in enumerate(itertools.islice(itertools.cycle(["A", "B", "C"]), 5)):
    print(f"{i}: {val}")  # 0:A, 1:B, 2:C, 3:A, 4:B

# repeat: 重复一个值指定次数
for val in itertools.repeat("Hello", 3):
    print(val)  # Hello, Hello, Hello

# 2. 组合迭代器
# product: 笛卡尔积
for combo in itertools.product([1, 2], ["a", "b"]):
    print(combo)  # (1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')

# permutations: 排列
for perm in itertools.permutations([1, 2, 3], 2):
    print(perm)  # (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)

# combinations: 组合
for comb in itertools.combinations([1, 2, 3], 2):
    print(comb)  # (1, 2), (1, 3), (2, 3)

# 3. 迭代器操作
# chain: 连接多个迭代器
for val in itertools.chain([1, 2], [3, 4], [5, 6]):
    print(val)  # 1, 2, 3, 4, 5, 6

# groupby: 分组
from operator import itemgetter

data = [
    {"name": "张三", "age": 20},
    {"name": "李四", "age": 20},
    {"name": "王五", "age": 21},
    {"name": "赵六", "age": 21}
]

for age, group in itertools.groupby(data, key=itemgetter("age")):
    print(f"年龄 {age} 的人:")
    for person in group:
        print(f"  {person['name']}")

推导式 ​

除了生成器表达式,Python还支持列表、字典和集合推导式。

python
# 列表推导式
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers if x % 2 == 0]
print(squares)  # [4, 16]

# 字典推导式
dict_squares = {x: x**2 for x in numbers if x % 2 != 0}
print(dict_squares)  # {1: 1, 3: 9, 5: 25}

# 集合推导式
set_squares = {x**2 for x in numbers}
print(set_squares)  # {1, 4, 9, 16, 25}
# 列表推导式
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers if x % 2 == 0]
print(squares)  # [4, 16]

# 字典推导式
dict_squares = {x: x**2 for x in numbers if x % 2 != 0}
print(dict_squares)  # {1: 1, 3: 9, 5: 25}

# 集合推导式
set_squares = {x**2 for x in numbers}
print(set_squares)  # {1, 4, 9, 16, 25}

上下文管理器 ​

上下文管理器的概念 ​

上下文管理器是一种用于管理资源的对象,它定义了在进入和退出代码块时应该执行的操作。上下文管理器通常与with语句一起使用,用于确保资源的正确获取和释放。

使用with语句 ​

python
# 文件操作中的上下文管理器
with open("file.txt", "w") as f:
    f.write("Hello, World!")
# 文件自动关闭,无需手动调用f.close()

# 数据库连接中的上下文管理器
import sqlite3

with sqlite3.connect(":memory:") as conn:
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE test (id INTEGER, name TEXT)")
    cursor.execute("INSERT INTO test VALUES (1, '张三')")
    conn.commit()
# 连接自动关闭
# 文件操作中的上下文管理器
with open("file.txt", "w") as f:
    f.write("Hello, World!")
# 文件自动关闭,无需手动调用f.close()

# 数据库连接中的上下文管理器
import sqlite3

with sqlite3.connect(":memory:") as conn:
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE test (id INTEGER, name TEXT)")
    cursor.execute("INSERT INTO test VALUES (1, '张三')")
    conn.commit()
# 连接自动关闭

自定义上下文管理器 ​

python
class MyContextManager:
    def __enter__(self):
        print("进入上下文管理器")
        return "上下文管理器返回值"
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("退出上下文管理器")
        # 如果发生异常,可以在这里处理
        if exc_type:
            print(f"发生异常: {exc_type}, {exc_val}")
        # 返回True表示异常已处理,不会向上传播
        return False

# 使用自定义上下文管理器
with MyContextManager() as cm:
    print(f"在with语句中,获取到的值: {cm}")
    # 可以在这里执行操作
class MyContextManager:
    def __enter__(self):
        print("进入上下文管理器")
        return "上下文管理器返回值"
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("退出上下文管理器")
        # 如果发生异常,可以在这里处理
        if exc_type:
            print(f"发生异常: {exc_type}, {exc_val}")
        # 返回True表示异常已处理,不会向上传播
        return False

# 使用自定义上下文管理器
with MyContextManager() as cm:
    print(f"在with语句中,获取到的值: {cm}")
    # 可以在这里执行操作

contextlib模块 ​

contextlib模块提供了创建上下文管理器的工具函数。

python
from contextlib import contextmanager

@contextmanager
def my_context_manager():
    print("进入上下文管理器")
    try:
        yield "上下文管理器返回值"
    except Exception as e:
        print(f"发生异常: {e}")
        # 可以选择重新抛出异常或处理
        raise
    finally:
        print("退出上下文管理器")

# 使用装饰器创建的上下文管理器
with my_context_manager() as cm:
    print(f"在with语句中,获取到的值: {cm}")
from contextlib import contextmanager

@contextmanager
def my_context_manager():
    print("进入上下文管理器")
    try:
        yield "上下文管理器返回值"
    except Exception as e:
        print(f"发生异常: {e}")
        # 可以选择重新抛出异常或处理
        raise
    finally:
        print("退出上下文管理器")

# 使用装饰器创建的上下文管理器
with my_context_manager() as cm:
    print(f"在with语句中,获取到的值: {cm}")

闭包 ​

闭包的概念 ​

闭包是指一个函数可以记住并访问其词法作用域,即使该函数在其词法作用域之外执行。闭包通常用于创建带有私有状态的函数。

闭包的示例 ​

python
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

# 创建闭包
add_five = outer_function(5)

# 调用闭包
print(add_five(3))  # 8
print(add_five(10))  # 15

# 创建另一个闭包
add_ten = outer_function(10)
print(add_ten(3))  # 13
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

# 创建闭包
add_five = outer_function(5)

# 调用闭包
print(add_five(3))  # 8
print(add_five(10))  # 15

# 创建另一个闭包
add_ten = outer_function(10)
print(add_ten(3))  # 13

闭包的应用场景 ​

  1. 创建私有变量
  2. 实现装饰器
  3. 延迟计算
  4. 实现回调函数
python
# 使用闭包创建计数器
def create_counter():
    count = 0
    
    def increment():
        nonlocal 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
# 使用闭包创建计数器
def create_counter():
    count = 0
    
    def increment():
        nonlocal 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

实用装饰器模式 ​

重试装饰器 ​

python
import functools
import time

def retry(max_attempts=3, delay=1):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(1, max_attempts + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts:
                        raise
                    print(f"第 {attempt} 次失败: {e},{delay}秒后重试...")
                    time.sleep(delay)
            return None
        return wrapper
    return decorator

@retry(max_attempts=3, delay=0.5)
def fetch_data(url: str) -> dict:
    # 模拟网络请求
    ...
import functools
import time

def retry(max_attempts=3, delay=1):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(1, max_attempts + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts:
                        raise
                    print(f"第 {attempt} 次失败: {e},{delay}秒后重试...")
                    time.sleep(delay)
            return None
        return wrapper
    return decorator

@retry(max_attempts=3, delay=0.5)
def fetch_data(url: str) -> dict:
    # 模拟网络请求
    ...

计时装饰器 ​

python
import functools
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"{func.__name__} 耗时: {elapsed:.4f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()  # 输出: slow_function 耗时: 1.0002s
import functools
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"{func.__name__} 耗时: {elapsed:.4f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()  # 输出: slow_function 耗时: 1.0002s

单例装饰器 ​

python
import functools

def singleton(cls):
    instances = {}
    @functools.wraps(cls)
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Database:
    def __init__(self):
        print("创建数据库连接")

db1 = Database()  # 打印: 创建数据库连接
db2 = Database()  # 不打印,返回已存在的实例
print(db1 is db2)  # True
import functools

def singleton(cls):
    instances = {}
    @functools.wraps(cls)
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Database:
    def __init__(self):
        print("创建数据库连接")

db1 = Database()  # 打印: 创建数据库连接
db2 = Database()  # 不打印,返回已存在的实例
print(db1 is db2)  # True

缓存装饰器(lru_cache) ​

python
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n: int) -> int:
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# fibonacci(100) 会非常快,结果被缓存
print(fibonacci(100))

# 查看缓存信息
print(fibonacci.cache_info())  # CacheInfo(hits=98, misses=101, maxsize=128, currsize=101)
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n: int) -> int:
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# fibonacci(100) 会非常快,结果被缓存
print(fibonacci(100))

# 查看缓存信息
print(fibonacci.cache_info())  # CacheInfo(hits=98, misses=101, maxsize=128, currsize=101)

总结 ​

Python的高级特性包括:

  1. 装饰器:增强函数功能,无需修改原代码
  2. 生成器:动态生成值,节省内存
  3. 迭代器:逐个访问容器元素,实现迭代器协议
  4. 上下文管理器:管理资源,确保正确获取和释放
  5. 闭包:记住并访问词法作用域

这些高级特性使Python代码更加简洁、高效和可维护,是Python编程中的重要工具。