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
相關文章
相關標籤/搜索