程序代码篇---Python装饰器&迭代器&生成器



前言

本文就介绍了Python装饰器的组成、用法,以及用装饰器修饰日志的实例代码。


第一部分:Python装饰器

(1)装饰器的通俗理解

装饰器就是一个函数,他接受另外一个函数作为参数,并返回一个新的函数,这个函数在原来函数的基础上添加了一些额外功能。
当你使用**@装饰器名**的语法时,实际上是告诉Python:这个函数调用之前或者执行之后还需要执行一些其他代码。

(2)不带参数的装饰器

#定义装饰器
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper
    
#使用装饰器
@my_decorator
def say_hello():
    print("Hello!")

say_hello()

程序运行结果:(如下)

Something is happening before the function is called.
Hello!
Something is happening after the function is called.

(3)带参数的装饰器

#定义装饰器
def my_decorator_with_args(decorator_arg1, decorator_arg2):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"Decorator arguments: {decorator_arg1}, {decorator_arg2}")
            print("Something is happening before the function is called.")
            result = func(*args, **kwargs)
            print("Something is happening after the function is called.")
            return result
        return wrapper
    return decorator

#使用装饰器
@my_decorator_with_args("arg1", "arg2")
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

程序运行结果:(如下)

Decorator arguments: arg1, arg2
Something is happening before the function is called.
Hello, Alice!
Something is happening after the function is called.

(4)使用装饰器生成日志

import logging
import time
from functools import wraps

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def log_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        logging.info(f"Function {func.__name__} started")
        start_time = time.time()
        
        result = func(*args, **kwargs)
        
        end_time = time.time()
        logging.info(f"Function {func.__name__} finished - Execution time: {end_time - start_time:.2f}s")
        return result
    return wrapper

# 使用装饰器
@log_decorator
def example_function(x):
    """This is an example function that sleeps for x seconds."""
    time.sleep(x)
    return x

# 调用装饰过的函数
example_function(2)

程序运行结果:(如下)

2023-04-01 12:34:56,789 - INFO - Function example_function started
2023-04-01 12:34:58,790 - INFO - Function example_function finished - Execution time: 2.00s

实例代码简单介绍:
在这个例子中,我们首先配置了日志记录器,设置了日志级别和日志格式。log_decorator是一个装饰器,它记录了被装饰函数的开始和结束时间,以及函数的名称。

@wraps(func)是一个装饰器,它被用来更新wrapper函数的一些元信息,比如__name__和__doc__,这样装饰器就不会覆盖掉原始函数的信息。

当我们调用example_function(2)时,日志记录器会输出函数的开始和结束,以及函数执行的时间。

额外小知识点

  1. 如果一个函数被多个装饰器修饰,则装饰器由内到外依次按序应用到函数上
  2. def wrapper(*arg,**kwargs)中:*arg:代表位置参数,**kwargs:代表关键字参数

第二部分:Python迭代器

(1)可迭代对象

特点:必须实现魔术方法:iter()

dir(list) 列出对象的方法
goal = iter(list) 获得可迭代对象得迭代器
比如:列表、元组、字典等

(2)迭代器

特点:必须实现魔术方法:iter()、next()

(3)优点

1.内存效率高

内存效率:迭代器惰性加载,是逐个产生数据的,这意味着它们不需要在内存中一次性存储所有数据。这对于处理大量数据或无限数据集(如流数据)非常有用。

2.延迟计算

延迟计算:迭代器实现了惰性求值(lazy evaluation),即数据只在需要时才计算。这可以节省计算资源,并允许更高效的程序设计。

3.通用性

通用性:迭代器提供了一个通用的接口来遍历集合中的元素,而不需要关心集合的内部结构。这意味着任何实现了迭代器协议的对象都可以使用相同的迭代语法。

4.可扩展性

可扩展性:迭代器模式允许开发者轻松地添加新的迭代器,而不需要修改现有代码。这有助于保持代码的干净和模块化。

5.支持无限数据集

支持无限数据集:由于迭代器一次只产生一个元素,它们可以用来表示无限的数据集,如自然数序列。

6.与Python生态系统兼容

与Python生态系统兼容:Python的很多内置函数和语言结构都支持迭代器,如for循环、列表推导式、生成器表达式等。

7.简化代码

简化代码:使用迭代器可以使代码更加简洁和直观,尤其是当你需要遍历复杂的数据结构时。

第三部分:Python生成器

生成器是一种给特殊的迭代器,它们允许你在需要时惰性生成值,而不是一次性生成整个序列。生成器通过yield语句实现,可以在保持状态的同时暂停和恢复函数执行。

(1)生成器和迭代器的区别

生成器:主要用来生成元素的
迭代器:用来用访问元素的

(2)生成器的创建

1.生成器函数

通过在函数中使用yield语句来创建。当函数执行到yield时,它会返回一个值并暂停执行,直到下一次调用__next__()方法。

示例代码:

#定义生成器函数
def simple_generator():
    yield 1
    yield 2
    yield 3
#声明生成器函数
gen = simple_generator()
for value in gen:
    print(value)

2.生成器表达式

类似于列表推导式,但是使用圆括号而不是方括号。生成器表达式是惰性的,它们在迭代时生成值。

示例代码:

gen_expr = (x * x for x in range(10))
for value in gen_expr:
    print(value)

(3)生成器的特点

1.惰性求值

惰性求值:生成器只在需要时计算值,这意味着它们可以用于处理大量数据而不会耗尽内存。

2.状态保持

状态保持:生成器在每次yield之后会保持其状态,包括局部变量的值,直到下一次调用。

3.一次性

一次性的:生成器只能迭代一次,一旦耗尽,就不能再从中获取值。如果需要再次迭代,必须重新创建生成器。

(4)生成器使用实例

1.处理大型数据集

处理大型数据集:当数据集太大而无法一次性装入内存时,生成器可以逐个产生数据项。

2.流处理

流处理:处理来自文件或网络的数据流时,生成器可以逐行或逐块处理数据。

3.协同处理

协同程序:生成器可以用作协同程序,允许在函数之间传递数据而不需要使用全局变量或回调函数。

示例代码:(使用生成器读取大型文件)

def read_large_file(file_name):
    with open(file_name, 'r') as file:
        for line in file:
            yield line.strip()

# 使用生成器逐行读取文件
for line in read_large_file('large_file.txt'):
    print(line)

总结

以上就是今天要讲的内容,本文仅仅简单介绍了本文就介绍了Python装饰器的组成、用法,以及用装饰器修饰日志的实例代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值