python的重重之器(產生器、迭代器、裝飾器)

來源:互聯網
上載者:User

標籤:auth   建立   tuple   consumer   元組   空間   預設   use   寫法   

一、裝飾器

1、定義:本質是函數,裝飾其他函數就是為其他函數添加附件功能。

2、原則:

  a.不能修改被裝飾的函數的原始碼;

  b.不能修改被裝飾的函數的調用方式;

 執行個體:

  #!/usr/bin/env python
  # -*- coding:utf-8 -*-
  #Author:ye

  import time

  #裝飾器
  def time_cha(func):#func等於test
   time_start = time.time()
   func()#此時func()相當於test()
   time.sleep(2)
   time_stop = time.time()
   print("the time cha is :%s" % (time_stop - time_start))

  #主函數
  def test():
   print("*")
   time.sleep(1)
   print("*")
   time.sleep(1)
   print("in the test")

  #單獨調用主函數
  test()

  #將裝飾器套用在主函數上
  time_cha(test)#此方式改變了主函數的調用方式

3、實現裝飾器的知識儲備:

  a.函數即“變數”

  b.高階函數

    b1.把一個函數名當做實參傳遞給另外一個函數(在不修改被裝飾函數的前提下,增加其功能)

      執行個體:      

        def test1():#此函數時原始碼
        print("in the test1")

        def test2(func):#此函數時裝飾器
        print("in the test2")
        print(func)#列印test1的記憶體位址
        func()#這裡相當於test1()

        test1()
        test2(test1)#將test1這個函數名作為實參傳遞給test2,這樣實現了高階函數

    b2.傳回值中包含函數名(不改變函數(原始碼)的調用方式)

      執行個體:

        def test1():#原始碼
        print("in the test1")

        def test2(func):#裝飾器
        print("in the test2")
        func()
        return test1#通過return,把函數名作為傳回值

        test1 = test2(test1)#此處是test1函數名的記憶體位址
        test1()#執行test1函數

  c.嵌套函數

    def test1():#第一層函數
      print("in the test1")

      def test2():#第二層函數
        print("in the test2")

      test2()#第一層函數執行時,調用第二層函數

    test1()#執行第一層函數

4、裝飾器的案例分析:

 案例背景:首先定義兩個模組,歐美專區和河南專區,兩個專區的使用前提是需要登入。

      步驟一:首先實現兩個專區的免登入訪問;

      步驟二:定義登入模組,然後以登入模組做為裝飾器,裝飾在歐美專區和河南專區上

      步驟三:當調用到兩個專區模組時,再進行登入驗證,不能調用之前就進行驗證(此處涉及到了嵌套函數的使用) 

      status = False            #初始化登入狀態,false表示未登入,true表示已登入

      def login(func):           #定義登入模組(裝飾器函數)
      def inner():           #定義嵌套函數
      _uername = "zhangye"    #定義使用者資料
      global status        #將函數內變數全域化

      if status ==False:     #根據狀態判斷是否需要登入
      username = input("請輸入使用者名稱:")
      if username == _uername:
      print("welcome...")
      status = True   #登入成功後,將預設狀態由false轉化為true
      if status == True:
      print(func)
      func()
      return inner           #未調用時,不進行驗證,只返回一個第二層的函數名(驗證函式的函數名)

      @login                 #還未到真正調用函數的地方,所以此處不需要進行登入驗證,只返回第二層的函數名即可。
      def america():
      print("*****歐美專區*****")

      @login                 #還未到真正調用驗證函式的地方,所以此處不需要進行登入驗證,只返回第二層函數名即可。
      def henan():
      print("*****河南專區*****")

      america()               #調用時,執行第二層函數。因為上面已經拿到了第二層的函數名
      henan()                #調用時,執行第二層函數。因為上面已經拿到了第二層的函數名

 

二、產生器

通過列表產生式,我們可以直接建立一個列表。但是,受到記憶體限制,列表容量肯定是有限的。而且,建立一個包含100萬個元素的列表,不僅佔用很大的儲存空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。

所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?這樣就不必建立完整的list,從而節省大量的空間。在Python中,這種一邊迴圈一邊計算的機制,稱為產生器:generator。

要建立一個generator,有很多種方法。第一種方法很簡單,只要把一個列表產生式的[]改成(),就建立了一個generator:

  執行個體一:

 data = [1,2,3,4,5,6,7,8,9,]

#列表產生式(裝逼的寫法)
data = [i*2 if i > 4 else i for i in data]
print(data)
==》[1, 2, 3, 4, 10, 12, 14, 16, 18]

#清單產生器(資料用到的時候才產生)
data2 = (i*2 if i > 4 else i for i in data)
print(data2)
==》<generator object <genexpr> at 0x000002797C151DB0>

小結:產生器只有在調用時,才會產生相應的資料。

  執行個體二、
  
import time

#定義消費者模型函數

def consumer(name): print("%s 準備吃包子啦!" %name)
    while True:
baozi = yield
print("包子[%s]來了,被[%s]吃了!" % (baozi,name))

#定義生產者模型函數
def producer(name):
c_a = consumer("A")
c_b = consumer("B")
c_a.__next__()
c_b.__next__()
print("老子開始準備做包子了!")
for i in range(10):
time.sleep(1)
print("做了2個包子!")
c_a.send(i)
c_b.send(i)

producer("alex")


三、迭代器
我們知道,可以直接作用於for迴圈的資料類型有以下幾種:
一類是集合資料類型:如list,tuple,dict,set,str等;
一類是 generator,包括產生器和帶yield的generator函數。
這些可以直接作用於for迴圈的對象統稱為可迭代對象,Iterable
可以使用isinstance()判斷一個對象是否是
Iterable對象:

from collections import Iterable

#判斷字串是否可迭代
data = "abc"
print(isinstance(data,Iterable)) #===》True

#判斷列表是否可迭代
data = [1,2,3]
print(isinstance(data,Iterable)) #===》True

#判斷字典是否可迭代
data = {1:"ye",2:"zhang",3:"alex"}
print(isinstance(data,Iterable)) #===》True

#判斷元組是否可迭代
data = (1,2,3)
print(isinstance(data,Iterable)) #===》True

注1:可以被next()函數調用並不斷返回下一個值的對象稱為迭代器:Iterator。
注2:字典、集合、元組、字串等都是可迭代對象,但是不是迭代器。但是可以通過iter()函數獲得一個迭代器。

 

  


 

    

 

python的重重之器(產生器、迭代器、裝飾器)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.