python 迭代器 生成器 装饰器

迭代器

定义

python里面迭代器指的是遵循迭代器协议的对象。迭代器协议指要实现对象的__iter()____next__()(python3)的方法,其中,__iter()__方法返回迭代器对象本身,__next__()方法返回容器的下一个元素,在没有后续元素会抛出StopIteration异常。

注意一点的是python里面的listsetdict并不是迭代器,它们是可迭代对象,但是它们并不是迭代器。一个实现了iter方法的对象是可迭代的,一个实现了next方法并且可迭代的对象时迭代器。这个在一次技术讨论中,我误以为list等可迭代对象为迭代器,这是不对的。
在这里插入图片描述
什么是迭代?迭代指的是用循环(for或者while等)遍历容器中的元素的过程;什么是可迭代对象?可迭代对象指的是能够用for循环进行迭代的对象,含有__iter____next__方法的对象成为可迭代对象。

在这里插入图片描述

例子

实现斐波那契数列迭代器:

from collections import Iterator

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    # 返回迭代器对象本身
    def __iter__(self):
        return self

    # 返回容器下一个元素
    def next(self):
        self.a, self.b = self.b, self.a + self.b
        return self.a

def main():
    fib = Fib()    # fib 是一个迭代器
    print 'isinstance(fib, Iterator): ', isinstance(fib, Iterator)

    for i in fib:
        if i > 10:
            break
        print i

if __name__ == '__main__':
    main()

优势

迭代器与列表的区别在于,构建迭代器的时候不像列表把所有元素一次性加载到内存,而是以一种延迟计算方式返回元素。在加载大数据的时候使用迭代器更有优势。

生成器

定义

生成器是一种特殊的迭代器,可以被用作控制循环的迭代行为,使用yield返回值函数。每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。生成器类似于返回值数组的一个函数,这个函数可以接受参数,可以被调用。不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗内存数量将大大减少,而且允许调用函数可以很快处理前几个返回值,因此生成器看起来像个函数,但是表现得像迭代器。
注意: 生成器只能遍历一次。

生成器函数

常规函数定义,使用yield语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起一个函数的状态,以便下次在它离开的地方继续执行。
在这里插入图片描述
在这里插入图片描述

生成器表达式

类似于列表推导,但是生长期返回按需产生结果的一个对象,而不是全部结果的列表
在这里插入图片描述

装饰器

定义

装饰器是Python的一个重要部分。装饰器是修改其它函数的功能的函数,能够有助于使得代码更简短,也更加Pythonic
以下例子是一个简单的装饰器:

def a_new_decorator(a_func):
 
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")
 
        a_func()
 
        print("I am doing some boring work after executing a_func()")
 
    return wrapTheFunction
 
def a_function_requiring_decoration():
    print("I am the function which needs some decoration to remove my foul smell")
 
a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell"
 
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()
 
a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
#        I am the function which needs some decoration to remove my foul smell
#        I am doing some boring work after executing a_func()

真正应用中的装饰器的写法:

from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated
 
@decorator_name
def func():
    return("Function is running")
 
can_run = True
print(func())
# Output: Function is running
 
can_run = False
print(func())
# Output: Function will not run

注意@wraps接受一个函数来进行修饰,并加入了复制函数名称、注释文档、参数列表等功能。

应用场景

授权

授权的应用可以参考我的github上的Flask-HTTPAuth

日志

from functools import wraps
 
def logit(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging
 
@logit
def addition_func(x):
   """Do some math."""
   return x + x
 
 
result = addition_func(4)
# Output: addition_func was called

带参数的装饰器

在函数中嵌入装饰器

from functools import wraps
 
def logit(logfile='out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile,并写入内容
            with open(logfile, 'a') as opened_file:
                # 现在将日志打到指定的logfile
                opened_file.write(log_string + '\n')
            return func(*args, **kwargs)
        return wrapped_function
    return logging_decorator
 
@logit()
def myfunc1():
    pass
 
myfunc1()
# Output: myfunc1 was called
# 现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串
 
@logit(logfile='func2.log')
def myfunc2():
    pass
 
myfunc2()
# Output: myfunc2 was called
# 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串

装饰器类

from functools import wraps
 
class logit(object):
    def __init__(self, logfile='out.log'):
        self.logfile = logfile
 
    def __call__(self, func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile并写入
            with open(self.logfile, 'a') as opened_file:
                # 现在将日志打到指定的文件
                opened_file.write(log_string + '\n')
            # 现在,发送一个通知
            self.notify()
            return func(*args, **kwargs)
        return wrapped_function
 
    def notify(self):
        # logit只打日志,不做别的
        pass

调用:

@logit()
def myfunc1():
    pass

参考

  1. itertools库的学习地址:https://pymotw.com/2/itertools/
  2. itertools库的官网地址:https://docs.python.org/2/library/itertools.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的迭代器生成器装饰器都是非常重要的编程概念,下面分别介绍一下: 1. 迭代器 Python中的迭代器是一种可以遍历集合中元素的对象,可以使用for循环遍历集合中的元素。迭代器实现了两个方法:__iter__()和__next__()。__iter__()方法返回迭代器对象自身,__next__()方法返回集合中的下一个元素。 下面是一个简单的使用迭代器遍历列表的示例: ``` my_list = [1, 2, 3] my_iterator = iter(my_list) for i in my_iterator: print(i) ``` 2. 生成器 生成器是一种特殊的函数,可以在执行过程中多次返回值,而不是只返回一次。生成器使用yield语句返回值,可以暂停函数的执行,并在需要时继续执行。 下面是一个简单的生成器示例: ``` def my_generator(): yield 1 yield 2 yield 3 for i in my_generator(): print(i) ``` 3. 装饰器 装饰器是一种可以修改函数或类的行为的函数,可以在不修改原始代码的情况下添加额外的功能。装饰器本质上是一个可以接受函数或类作为参数的函数,可以在不修改原始函数或类的情况下修改其行为。 下面是一个简单的装饰器示例: ``` def my_decorator(func): def wrapper(): print("Before the function is called.") func() print("After the function is called.") return wrapper @my_decorator def my_function(): print("Inside the function.") my_function() ``` 在上面的代码中,我们定义了一个装饰器函数my_decorator,它接受一个函数作为参数,并返回一个新的函数wrapper。这个新函数在调用原始函数之前和之后打印一些文本。我们使用@符号将装饰器应用到my_function函数上,这样my_function函数的行为就被修改了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值