Python笔记6---闭包,装饰器,迭代器,生成器

闭包

  • 嵌套函数
# 定义一个外层函数
def foo():
    # 定义了一个内部函数
    def bar():
        print("hello world")
    bar()
  • 函数bar是一个定义在foo函数内部的函数。Python中的函数是支持嵌套的,也就是可以在一个函数内部再定义一个函数。然后,我们还知道函数是可以当作变量的,于是我们就可以在foo函数中把定义的这个bar函数返回。就像下面这样:
# 定义一个外层函数
def foo():
    # 定义了一个内层函数
    def bar():
        print("hello world")
    return bar

func = foo()
func()  # func --> bar,这里执行func其实就相当于执行了在foo函数内部定义的bar函数
  • 闭包
def foo():
    name = "Andy"  # 外部函数的局部变量,同样也可以作为参数传入
    # 定义了一个内部函数
    def bar():
        print(name)  # 虽然bar函数中没有定义name变量,但是它可以访问外部函数的局部变量name
    return bar

func = foo()
func()  # func --> bar --> 除了是一个函数,还包含一个值(它外层函数的局部变量)的引用

装饰器

  • 装饰器通常是一个命名的对象(不允许使用 lambda 表达式),在被装饰函数调用时接受单一参数,并返回另一个可调用对象。
  • 事实上,任何函数都可以用作装饰器,因为Python并没有规定装饰器的返回类型。

示例:

import time
import random


# 注意返回的是内部函数不是传入的参数
def f1(func):
    def f2():
        t1 = time.time()
        func()
        t2 = time.time()
        print('用时 %s 秒' % (t2-t1))
    return f2


@f1
def f():
    t = random.random()
    time.sleep(t)
    print('t = %s' % t)


# f()
"""
等价于
x = f1(f)
x()
"""

迭代器

  • 迭代器(Iterators)的使用非常普遍并使得 Python 成为一个统一的整体。 在幕后,for 语句会调用容器对象中的 iter()。 该函数返回一个定义了 __next__() 方法的迭代器对象,该方法将逐一访问容器中的元素。 当元素用尽时,__next__() 将引发 StopIteration 异常来通知终止 for 循环。 你可以使用 next() 内置函数来调用 __next__() 方法;这个例子显示了它的运作方式:

示例:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

image

生成器

  • 生成器 Generator 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。 显示如何非常容易地创建生成器的示例如下:
def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]
        
>>> for char in reverse('golf'):
...     print(char)
...
f
l
o
g

生成器表达式

  • 某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,将外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

例如:

>>> sum(i*i for i in range(10))                 # sum of squares
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
260
  • 总结

image

猜你喜欢

转载自www.cnblogs.com/bmxm/p/11918488.html