没有备案号的网站,wordpress密码无效,外链seo推广,深圳设计公司深圳市广告公司文章目录 1 Python装饰器1.1 什么是装饰器#xff1f;1.1.1 参数化装饰器 1.2 装饰器的工作原理1.2.1 函数签名保持 1.3 装饰器的应用实例1.3.1 日志记录1.3.2 装饰器链1.3.3 自动注册装饰器 1.4 Summary 2 Python生成器2.1 生成器的定义和基本操作2.2 生成器的惰性求值和内存… 文章目录 1 Python装饰器1.1 什么是装饰器1.1.1 参数化装饰器 1.2 装饰器的工作原理1.2.1 函数签名保持 1.3 装饰器的应用实例1.3.1 日志记录1.3.2 装饰器链1.3.3 自动注册装饰器 1.4 Summary 2 Python生成器2.1 生成器的定义和基本操作2.2 生成器的惰性求值和内存优势2.3 生成器表达式2.4 生成器和协程2.5 Python标准库itertools2.6 Summary Reference 1 Python装饰器
1.1 什么是装饰器
在 Python 中装饰器提供了一种简洁的方式用来修改或增强函数和类的行为。装饰器在语法上表现为一个前置于函数或类定义之前的特殊标记
simple_decorator
def hello_world():print(Hello, world!)在这个例子中simple_decorator 是一个装饰器它作用于下方的 hello_world 函数。装饰器在概念上就像一个包装器它可以在被装饰的函数执行前后插入任意的代码进而改变被装饰函数的行为。
1.1.1 参数化装饰器
我们还可以进一步将装饰器参数化这让装饰器的行为更具灵活性。比如我们可以定义一个装饰器让它在函数执行前后打印自定义的消息
def message_decorator(before_message, after_message):def decorator(func):def wrapper(*args, **kwargs):print(before_message)result func(*args, **kwargs)print(after_message)return resultreturn wrapperreturn decoratormessage_decorator(Start, End)
def hello_world():print(Hello, world!)在这个例子中message_decorator 是一个参数化装饰器它接受两个参数分别代表函数执行前后要打印的消息。
1.2 装饰器的工作原理
在 Python 中函数是第一类对象。这意味着函数和其他对象一样可以作为变量进行赋值可以作为参数传给其他函数可以作为其他函数的返回值甚至可以在一个函数里面定义另一个函数。这个特性是实现装饰器的基础。
def decorator(func):def wrapper():print(Before function execution)func()print(After function execution)return wrapperdef hello_world():print(Hello, world!)decorated_hello decorator(hello_world)
decorated_hello()在这个例子中decorator 函数接收一个函数 hello_world 作为参数并返回了一个新的函数 wrapped_func。这个新函数在 hello_world 函数执行前后分别打印一条消息。我们可以看到装饰器实际上是一个返回函数的函数。
1.2.1 函数签名保持
默认情况下装饰器会“掩盖”掉原函数的名字和文档字符串。这是因为在装饰器内部我们返回了一个全新的函数。我们可以使用 functools.wraps 来解决这个问题
import functoolsdef decorator(func):functools.wraps(func)def wrapper():print(Before function execution)func()print(After function execution)return wrapperdecorator
def hello_world():Prints Hello, world!print(Hello, world!)print(hello_world.__name__)
print(hello_world.__doc__)这样使用装饰器后的函数名和文档字符串能够保持不变。
1.3 装饰器的应用实例
装饰器在实际的 Python 编程中有许多应用场景比如日志记录、性能测试、事务处理、缓存、权限校验等。
1.3.1 日志记录
一个常见的应用就是使用装饰器进行日志记录
import loggingdef log_decorator(func):logging.basicConfig(levellogging.INFO)def wrapper(*args, **kwargs):logging.info(fRunning {func.__name__} with arguments {args} and kwargs {kwargs})result func(*args, **kwargs)logging.info(fFinished {func.__name__} with result {result})return resultreturn wrapperlog_decorator
def add(x, y):return x y这个装饰器记录了函数的名称函数调用的参数以及函数返回的结果。
1.3.2 装饰器链
Python 允许我们将多个装饰器应用到一个函数上形成一个装饰器链。
例如我们可以同时应用日志装饰器和性能测试装饰器
import time
import logging
from functools import wrapsdef log_decorator(func):logging.basicConfig(levellogging.INFO)wraps(func)def wrapper(*args, **kwargs):logging.info(fRunning {func.__name__} with arguments {args} and kwargs {kwargs})result func(*args, **kwargs)logging.info(fFinished {func.__name__} with result {result})return resultreturn wrapperdef timer_decorator(func):wraps(func)def wrapper(*args, **kwargs):start_time time.time()result func(*args, **kwargs)end_time time.time()print(fFunction {func.__name__} took {end_time - start_time} seconds to run.)return resultreturn wrapperlog_decorator
timer_decorator
def add(x, y):time.sleep(2)return x y在这个例子中log_decorator 和 timer_decorator 两个装饰器被同时应用到 add 函数上它们分别负责记录日志和测量函数运行时间。
1.3.3 自动注册装饰器
一个有趣的装饰器应用是自动注册。这个装饰器会在装饰函数时自动将函数添加到一个列表或字典中这样我们就可以在程序的其他地方访问到这个列表或字典知道有哪些函数被装饰过。
# 装饰器将函数注册到一个列表中
def register_decorator(func_list):def decorator(func):func_list.append(func)return funcreturn decorator# 自动注册函数
registered_functions []
register_decorator(registered_functions)
def foo():passregister_decorator(registered_functions)
def bar():passprint(registered_functions) # 输出: [function foo at 0x10d38d160, function bar at 0x10d38d1f0]这个装饰器可以用于自动注册路由、插件系统、命令行参数处理等场景能够大大提高代码的灵活性和可扩展性。
1.4 Summary
Python 装饰器是一种强大的工具它可以让我们更有效地管理和组织代码从而在项目中更好地使用装饰器。
2 Python生成器 强大的数据处理管道 生成器是Python的一种核心特性允许我们在请求新元素时再生成这些元素而不是在开始时就生成所有元素。它在处理大规模数据集、实现节省内存的算法和构建复杂的迭代器模式等多种情况下都有着广泛的应用。在本篇文章中我们将从理论和实践两方面来探索Python生成器的深度用法。
2.1 生成器的定义和基本操作
生成器是一种特殊的迭代器它们的创建方式是在函数定义中包含yield关键字。当这个函数被调用时它返回一个生成器对象该对象可以使用next()函数或for循环来获取新的元素。
def simple_generator():yield Pythonyield isyield awesome# 创建生成器
gen simple_generator()# 使用next函数获取元素
print(next(gen)) # 输出: Python
print(next(gen)) # 输出: is
print(next(gen)) # 输出: awesome# 使用for循环获取元素
for word in simple_generator():print(word)# 输出:
# Python
# is
# awesome当生成器耗尽即没有更多元素产生时再次调用next()函数将引发StopIteration异常。这个异常可以由我们手动捕获或者由for循环自动处理。
2.2 生成器的惰性求值和内存优势
生成器的主要优势之一是它们的惰性求值特性。也就是说生成器只在需要时才计算和产生元素。这使得生成器在处理大规模数据时可以大大降低内存使用量。与传统的数据结构如列表相比生成器不需要在内存中存储所有元素而是在每次迭代时动态计算出新的元素。
这种特性使得生成器在处理大规模数据流、实现复杂的算法或构建动态的数据管道等场景中具有显著的优势。
# 无限序列生成器
def infinite_sequence():num 0while True:yield numnum 1# 创建生成器
seq infinite_sequence()# 输出前10个元素
for i in range(10):print(next(seq)) # 输出:
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9在这个例子中infinite_sequence是一个永不停止的生成器。尽管它可以产生无穷多的元素但由于生成器的惰性求值特性它并不会导致内存耗尽。
2.3 生成器表达式
生成器表达式是创建生成器的一种更简洁的方式。它们与列表推导式的语法相似但是生成的是一个生成器对象而不是一个完整的列表。这使得生成器表达式在处理大规模数据时可以节省大量的内存。
# 创建一个生成器表达式
gen_expr (x**2 for x in range(1000000))# 输出前10个元素
for i in range(10):print(next(gen_expr))# 输出:
# 0
# 1
# 4
# 9
# 16
# 25
# 36
# 49
# 64
# 81在这个例子中gen_expr是一个生成器表达式它可以生成10^6个元素的平方数。但是由于生成器表达式的惰性求值特性它并不会在内存中生成和存储所有这些元素。
2.4 生成器和协程
Python的生成器还可以作为协程使用。
协程是一种特殊类型的函数它可以在其执行过程中挂起和恢复从而在单个线程中实现多任务协作式并发。这使得我们可以使用生成器来实现复杂的控制流程如并发编程、异步IO等。
def coroutine_generator():print(Starting)while True:value (yield)print(fReceived: {value})# 创建生成器
gen coroutine_generator()# 启动生成器
next(gen) # 输出: Starting# 向生成器发送数据
gen.send(Hello) # 输出: Received: Hello
gen.send(Python) # 输出: Received: Python# 关闭生成器
gen.close()在这个例子中coroutine_generator是一个协程生成器。我们可以使用send()函数向它发送数据生成器在收到数据后将其打印出来。
2.5 Python标准库itertools
在Python的标准库itertools中有一个函数itertools.islice它可以用来对生成器进行切片操作就像我们对列表进行切片那样。这在处理大规模数据流时非常有用。
import itertools# 无限序列生成器
def infinite_sequence():num 0while True:yield numnum 1# 创建生成器
seq infinite_sequence()# 对生成器进行切片操作
sliced_seq itertools.islice(seq, 5, 10)# 输出切片后的元素
for num in sliced_seq:print(num)# 输出:
# 5
# 6
#7
# 8
# 9在这个例子中我们使用itertools.islice函数对无限序列生成器seq进行了切片操作获取了序列的第5个到第10个元素从0开始计数。这让我们能够在不消耗大量内存的情况下灵活地处理大规模的数据流。
2.6 Summary
生成器是Python中一种非常强大的工具它让我们能够以更高效和简洁的方式处理复杂的问题。熟练掌握生成器的使用将使你在Python编程中具有更高的自由度和更强的实力。
Reference
https://blog.csdn.net/magicyangjay111/article/details/131054330
https://blog.csdn.net/magicyangjay111/article/details/130965602