Python中的迭代器、生成式、生成器及装饰器

1.迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到全部的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,由于人们不多在迭代途中日后退。另外,迭代器的一大优势是不要求事先准备好整个迭代过程当中全部的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这以前或以后,元素能够不存在或者被销毁。这个特色使得它特别适合用于遍历一些巨大的或是无限的集合,好比几个G的文件python

特色:缓存

  1. 访问者不须要关心迭代器内部的结构,仅需经过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头至尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存

生成一个迭代器:函数

 

>>> a = iter([1,2,3,4,5])
>>> a
<list_iterator object at 0x101402630>
>>> a.__next__()
1
>>> a.__next__()
2
>>> a.__next__()
3
>>> a.__next__()
4
>>> a.__next__()
5
>>> a.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

 

2.生成式和生成器

列表生成式格式:

[exp for val in collection if condition]

[x*x for x in xrange(10) if x*x%2 == 0]

生成器(generator):

方法一:工具

(exp for val in collection if condition)

方法二:
使用yield关键字,包含yield语句的函数会被特意编译成生成器。
yield能够理解力成return,可是并不退出,只是挂起,恢复的时候从yield下面开始执行。性能

生成式和生成器的区别:

列表显示生成式直接返回了表达式的结果列表,面生成器是一个对象,该对象包含了对表达式结果的计算引用,经过结果循环能够直接选举输出
生成器不会一次性列出全部的数据,固然你用到的时候,在列出来,更加节约内存的使用率。
相似 range(1,10) xrange(1,10)的区别,可是类型却不一样。测试

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @time   :2018/1/28 22:34
# @Author :FengXiaoqing
# @file   :production.py

a = [x*x for x in range(1,11) if x%2 ==0]
print (a)
print(type(a))

b = (x*x for x in range(1,11) if x%2 ==0)
print (b)
print(type(b))
for i in b:
    print(i)
print('#'*20)

def test(l):
    for i in l:
        yield i
        print("OK i = {0}".format(i))

m = test([1,2,3,4,5,6])
for i in m:
    print(i)
结果:
[4, 16, 36, 64, 100]
<class 'list'>
<generator object <genexpr> at 0x0000000002160D00>
<class 'generator'>
4
16
36
64
100
####################
1
OK i = 1
2
OK i = 2
3
OK i = 3
4
OK i = 4
5
OK i = 5
6
OK i = 6

3. 装饰器

装饰器的做用:

装饰器本质上是一个python函数,它可让其余工具函数在不须要作任何代码变更的前提下增长额外功能 ,装饰器的返回值也是一个函数对象。它常常用于有切面需求的场景,好比:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,咱们就能够抽离出大量与函数功能 自己无关的雷同代码并继续重用。
装饰器的做用简单点说:就是不改变 原来函数自己,在函数的前面或后面增长一些额外的功能 。
场景:京东购物,放入购物车后在结算前弹出的让你登陆用户的窗口。this

装饰器:

在了解装饰器以前 ,咱们先来了解一个callable函数
说明:
1.方法用来检测对象是否可被调用 ,可被调用 批量的是对象测否使用()括号的方法调用 。
def a():
pass
callable(a)
2.可调用 对象,在实际调用 也可测调用 失败;可是不可调用 对象,调用 确定不成功。
3.类对象都 是可被调用 对象,类的实例对象是否可调用 对象,取决于类是否认义了call方法spa

装饰器例子:

#!/usr/bin/env python
import datetime

def hellow(fun):
    def preHello():
        print("########start##########“)
        fun()
        print("########end###########“)
    return preHello

原有方法:设计

def startend(func):
    def start():
        print("#########start#############")
        func()
        print("#########end#############")
    return start
def hello():
    print("hello world!")
hello = startend(hello)
hello()

改进后的使用方法:日志

def startend(func):
    def start():
        print("#########start#############")
        func()
        print("#########end#############")
    return start

@startend
def hello():
    print("hello world!")
hello()

另外一个实例 :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/4/18 23:32
# @Author  : Feng Xiaoqing
# @File    : test.py
# @Function: -----------


def startEnd(author):
    def a(fun):
        def b(name):
            print("this author is {0}".format(author))
            print("start")
            fun(name)
            print("end")
        return b
    return a

@startEnd("fengxiaoqing")
def hello(name):
    print("hello {0}".format(name))

hello("fxq")

 结果:

this author is fengxiaoqing
start
hello fxq
end
相关文章
相关标签/搜索