文章目录
前言
本文就介绍了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)时,日志记录器会输出函数的开始和结束,以及函数执行的时间。
额外小知识点
- 如果一个函数被多个装饰器修饰,则装饰器由内到外依次按序应用到函数上
-
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装饰器的组成、用法,以及用装饰器修饰日志的实例代码。