一、闭包
闭包(Closure)是指一个函数可以访问并操作其外部作用域中的变量,即使在该函数被调用之后,仍能保持对这些变量的访问权限。
闭包的创建方式如下:
在外部函数中定义内部函数。
内部函数使用了外部函数的变量。
外部函数返回内部函数。
# 闭包代码实现
def outer_function(a):
def inner_function(b):
# 内部函数使用了外部函数的变量x和y
return a+b
# 外部函数返回内部函数
return inner_function
# 创建闭包
closure = outer_function(1)
# 调用闭包函数
print(closure(2)) # 输出 8
总结:
闭包是一种强大而灵活的编程概念,可以在Python中实现。通过使用闭包,我们可以创建具有特定功能和访问权限的函数,并且可以在不同的上下文中重复使用它们。闭包在编程中有一些有用的特性。例如,它们可以用来创建函数工厂、实现私有变量和缓存结果等。同时,闭包还允许函数保持对其作用域外部变量的引用,延长了这些变量的生命周期。
二、装饰器
装饰器可以用于修改、增强函数或类的功能的语法结构。可以使代码更加简洁、灵活,并提供了一种可重用的方式来扩展已有的功能。
它的本质是一个函数(或可调用对象),接收一个函数作为参数,并返回一个新的函数。
# 代码实现
def decorator_func(original_function):
def wrapper_func(*args, **kwargs):
print("在调用原始函数之前的操作")
result = original_function(*args, **kwargs) # 调用原始函数
print("在调用原始函数之后的操作")
return result
return wrapper_func
@decorator_func
def original_func():
print("原始函数")
original_func()
三、迭代器
迭代器(Iterator)是一种用于遍历可迭代对象(Iterable)的对象。可迭代对象是指实现了__iter__()方法的对象,而迭代器则是在可迭代对象的基础上实现了__iter__()和__next__()方法的对象。
迭代器提供了一个按需获取元素的接口,每次调用__next__()方法时都会返回下一个元素,直到没有更多元素可迭代时,抛出StopIteration异常。
# 代码实现迭代器
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):
raise StopIteration
result = self.data[self.index]
self.index += 1
return result
# 创建可迭代对象
my_list = [1, 2, 3, 4, 5]
my_iter = MyIterator(my_list)
# 使用迭代器遍历可迭代对象
for item in my_iter:
print(item)
迭代器的优点是节省内存空间,因为它不需要事先将所有元素加载到内存中。相反,它在每次迭代时按需提供一个元素。这在处理大型数据集或无限序列时非常有用。
内置的可迭代对象,例如列表、元组、字符串和字典。这些可迭代对象都可以通过调用 iter() 函数来获取对应的迭代器。
此外,还可使用 itertools 模块,其中包含了一系列用于快速生成迭代器的函数,如 count()、cycle() 和 zip() 等。
需要注意的是,一旦迭代器达到了最后一个元素,再次调用 next() 方法会引发 StopIteration 异常。为了避免这个问题,通常使用 for 循环来遍历可迭代对象,因为它会自动处理 StopIteration 异常。
四、生成器
生成器(Generator)是一种使用yield语句来定义的特殊函数,它可以在迭代时动态产生数据。
def my_generator():
yield 1
yield 2
yield 3
yield 4
yield 5
# 用for循环遍历生成器
for item in my_generator():
print(item)
# 获取生成器
gen = my_generator()
# 用next函数
print(f"第一次调用:{next(gen)}")
# 第一次调用:1
print(f"第二次调用:{next(gen)}")
# 第二次调用:2
print(f"第三次调用:{next(gen)}")
# 第三次调用:3
print(f"第四次调用:{next(gen)}")
# 第四次调用:4
print(f"第五次调用:{next(gen)}")
# 第五次调用:5
print(f"第六次调用:{next(gen)}")
# Traceback (most recent call last):
# File "D:\python\爬虫\test.py", line 27, in <module>
# print(f"第六次调用:{next(gen)}")
# StopIteration
与普通函数不同,生成器不会一次性返回所有结果,而是在每次迭代时,根据需要产生一个新的值,并暂停函数执行状态,等待下一次迭代再次执行。这种方式可以避免一次性加载所有数据到内存中,从而节省内存空间。
示例中,my_generator() 是一个生成器函数,它使用 yield 语句产生了五个连续的整数。当调用 my_generator() 函数时,它并不会立即执行函数体,而是返回一个生成器对象。使用 for 循环遍历生成器对象时,每次迭代时会执行生成器函数,并在每次调用 yield 语句时返回一个新的值。在遍历完所有元素后,生成器函数的执行状态被暂停,并且不会再产生任何新的值。除了使用 for 循环遍历生成器外,还可以使用 next() 函数来手动获取生成器的下一个值。每次调用 next() 函数时,生成器会从上一次暂停的位置继续执行,并返回下一个值。
内置的生成器,例如 range()、map() 和 filter() 等。这些生成器只需在需要时动态生成所需的值,而无需一次性生成所有元素。生成器是一种高效而强大的工具,可以用于处理大型数据集或无限序列等场景。使用生成器可以使代码更加简单、清晰,并节省内存空间。