活动地址:优快云21天学习挑战赛
python高级语法学习(一)
在一种语言中,很难客观判断哪些语法元素属于高级语法。对于本章会讲到的高级语法元素,我们会讲到这样的元素,它们不与任何特定的内置类型直接相关,而且在刚开始学习时相对难以掌握。对于Python中难以理解的特性,其中最常见的是:
- 迭代器(iterator)
- 生成器(generator)
- 装饰器(decorator)
- 上下文管理器(context manager)
迭代器(类比for循环)
只不过是一个实现了迭代器协议的容器对象。它基于以下两个方法。
-
__ next __
:返回容器的下一个元素。 -
__ iter __
:返回迭代器本身。
迭代器可以利用内置的iter
函数和一个序列来创建。看下面这个例子:
>>> i = iter('abc')
>>> next(i)
'a'
>>> next(i)
'b'
>>> next(i)
'c'
循环完成
当遍历完序列时,会引发一个异常。这样迭代器就可以与循环兼容,因为可以捕获这个异常并停止循环。要创建自定义的迭代器,可以编写一个具有方法的类,只要这个类提供返回迭代器实例的特殊方法:
class CountDown:
def __init__(self, step):
self.step = step
def __next__(self):
"""Return the next element."""
if self.step < = 0:
raise StopIteration
self.step -= 1
return self.step
def __iter__(self):
"""Return the iterator itself."""
return self
下面是这个迭代器的用法示例:
>>> for element in CountDown(4):
... print(element)
...
3
2
1
0
迭代器本身是一个底层的特性和概念,在程序中可以不用它。但它为生成器这一更有趣的特性提供了基础。
生成器(yield语句)
生成器提供了一种优雅的方法,可以让编写返回元素序列的函数所需的代码变得简单、高效。基于语句,生成器可以暂停函数并返回一个中间结果。该函数会保存执行上下文,稍后在必要时可以恢复。
举个例子,斐波纳契(Fibonacci)数列可以用生成器语法来实现。下列代码是来自于**PEP 255(简单生成器)**文档中的例子:
def fibonacci():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
你可以用next()函数或for循环从生成器中获取新的元素,就像迭代器一样:
>>> fib = fibonacci()
>>> next(fib)
1
>>> next(fib)
1
>>> next(fib)
2
>>> [next(fib) for i in range(10)]
[3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
以下内容很重要请仔细阅读
这个函数返回一个对象,是特殊的迭代器,它知道如何保存执行上下文。它可以被无限次调用,每次都会生成序列的下一个元素。这种语法很简洁,算法可无限调用的性质并没有影响代码的可读性。不必提供使函数停止的方法。实际上,它看上去就像用伪代码设计的数列一样。
在社区中,生成器并不常用,因为开发人员还不习惯这种思考方式。多年来,开发人员已经习惯于使用直截了当的函数。每次你需要返回一个序列的函数或在循环中运行的函数时,都应该考虑使用生成器。当序列元素被传递到另一个函数中以进行后续处理时,一次返回一个元素可以提高整体性能。
在这种情况下,用于处理一个元素的资源通常不如用于整个过程的资源重要。因此,它们可以保持位于底层,使程序更加高效。举个例子,斐波那契数列是无穷的,但用来生成它的生成器每次提供一个值,并不需要无限大的内存。一个常见的应用场景是使用生成器的数据流缓冲区。使用这些数据的第三方代码可以暂停、恢复和停止生成器,在开始这一过程之前无需导入所有数据。