Python學(xué)習(xí)之三大名器-裝飾器、迭代器、生成器

一、裝飾器

創(chuàng)新互聯(lián)主打移動(dòng)網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)站改版、網(wǎng)絡(luò)推廣、網(wǎng)站維護(hù)、域名注冊(cè)、等互聯(lián)網(wǎng)信息服務(wù),為各行業(yè)提供服務(wù)。在技術(shù)實(shí)力的保障下,我們?yōu)榭蛻舫兄Z穩(wěn)定,放心的服務(wù),根據(jù)網(wǎng)站的內(nèi)容與功能再?zèng)Q定采用什么樣的設(shè)計(jì)。最后,要實(shí)現(xiàn)符合網(wǎng)站需求的內(nèi)容、功能與設(shè)計(jì),我們還會(huì)規(guī)劃穩(wěn)定安全的技術(shù)方案做保障。

裝飾,顧名思義就是在原來(lái)的基礎(chǔ)上進(jìn)行美化及完善,器這里指函數(shù),所以說(shuō)裝飾器就是裝飾函數(shù),也就是在不改變?cè)瓉?lái)函數(shù)的代碼及調(diào)用方式的前提下對(duì)原函數(shù)進(jìn)行功能上的完善。其核心原理其實(shí)是利用閉包。

格式 @關(guān)鍵字+裝飾函數(shù)

被裝飾函數(shù)()

注意:@行必須頂頭寫(xiě)而且是在被裝飾函數(shù)的正上方

按照形式可以分為:無(wú)參裝飾器和有參裝飾器,有參裝飾器即給裝飾器加上參數(shù)

以下示例是一個(gè)無(wú)參裝飾器,為原函數(shù)添加了統(tǒng)計(jì)運(yùn)行時(shí)間的功能

import time
#定義裝飾器 
def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print("run time is %s" %(stop_time-start_time))
        return res
    return wrapper
#調(diào)用裝飾器
@timer
def index():
    l = []
    for i in range(10000000):
        l.append(i)
#調(diào)用階段 
index()

以下是一個(gè)有參裝飾器,實(shí)現(xiàn)簡(jiǎn)單的認(rèn)證功能,#數(shù)字表示程序依次執(zhí)行順序

def auth3(auth_type): #1 #3
    def auth(func): #4 #6
        def wrapper(*args,**kwargs): #7 #10
            if auth_type == 'file': #11
                name=input('username: ')
                password=input('password: ')
                if name == 'zhejiangF4' and password == '666':
                    print('auth successfull')
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('auth error')
            elif auth_type == 'sql': #12
                print('nothing!') #13
        return wrapper #8
    return auth #5
@auth3(auth_type='sql') #2
def index():
    print('welcome to inex page')
 index() #9

二、迭代器

迭代器(iterator)是一種對(duì)象,它能夠用來(lái)遍歷標(biāo)準(zhǔn)模板庫(kù)容器中的部分或全部元素,每個(gè)迭代器對(duì)象代表容器中的確定的地址**?!俣劝倏?*

可迭代的:只要對(duì)象本身有 iter方法,那它就是可迭代的

執(zhí)行對(duì)象下的 iter方法,得到的結(jié)果就是迭代器如果你依然在編程的世界里迷茫,不知道自己的未來(lái)規(guī)劃可以加入我們的Python秋秋裙去784掉758文214字看看前輩們?nèi)绾螌W(xué)習(xí)的!交流經(jīng)驗(yàn)!自己是一名高級(jí)python開(kāi)發(fā)工程師,從基礎(chǔ)的python腳本到web開(kāi)發(fā)、爬蟲(chóng)、django、數(shù)據(jù)挖掘等,零基礎(chǔ)到項(xiàng)目實(shí)戰(zhàn)的資料都有整理。送給每一位python的小伙伴!分享一些學(xué)習(xí)的方法和需要注意的小細(xì)節(jié)

為什么要用迭代器:
優(yōu)點(diǎn)
1:迭代器提供了一種不依賴(lài)于索引的取值方式,這樣就可以遍歷那些沒(méi)有索 引的可迭代對(duì)象了(字典,集合,文件)
2:迭代器與列表比較,迭代器是惰性計(jì)算的,更節(jié)省內(nèi)存

    **缺點(diǎn):
1:無(wú)法獲取迭代器的長(zhǎng)度,使用不如列表索引取值靈活
2**:**一次性的,只能往后取值,不能倒著取值**

查看s對(duì)象是否是迭代器:print(isinstance(s,Iterator)) 返回True就是迭代器

from collections import Iterable,Iterator
s='hello'
l=[1,2,3]
t=(1,2,3)
d={'a':1}
set1={1,2,3,4}
f=open('a.txt')
s.__iter__()
l.__iter__() 
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__()
print(isinstance(s,Iterable))
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable))
print(isinstance(s,Iterator))
print(isinstance(l,Iterator))
print(isinstance(t,Iterator))
print(isinstance(d,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))

運(yùn)行結(jié)果如下:

Python學(xué)習(xí)之三大名器-裝飾器、迭代器、生成器

可以看出,字符串、列表、字典、集合、元組、文件都是可迭代的,但是只有文件是迭代器

三、生成器

通過(guò)列表生成式,我們可以直接創(chuàng)建一個(gè)列表。但是,受到內(nèi)存限制,列表容量肯定是有限的。而且,創(chuàng)建一個(gè)包含100萬(wàn)個(gè)元素的列表,不僅占用很大的存儲(chǔ)空間,如果我們僅僅需要訪問(wèn)前面幾個(gè)元素,那后面絕大多數(shù)元素占用的空間都白白浪費(fèi)了。

所以,如果列表元素可以按照某種算法推算出來(lái),那我們是否可以在循環(huán)的過(guò)程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。在Python中,這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱(chēng)為生成器:generator。

函數(shù)中包含yield語(yǔ)句的我們稱(chēng)其為生成器函數(shù)

yield與return有何區(qū)別?
return只能返回一次函數(shù)就徹底結(jié)束了,而yield能返回多次值
yield到底干了什么事情:
yield把函數(shù)變成生成器(生成器就是迭代器)
函數(shù)在暫停以及繼續(xù)下一次運(yùn)行時(shí)的狀態(tài)是由yield保存

下例是兩個(gè)生成器的應(yīng)用,一個(gè)用來(lái)不斷的輸入url,不斷的解析,另外一個(gè)則模仿Linux中的管道命令(實(shí)質(zhì)是將一個(gè)函數(shù)的運(yùn)行結(jié)果傳給下一個(gè)函數(shù)做處理,實(shí)現(xiàn)的比較簡(jiǎn)單粗暴,多包涵,哈哈)

例1:

from urllib.request import urlopen
def get(url):
    while True:
        def index():
            return urlopen(url).read()
        url = yield index()
g = get('http://www.baidu.com')
next(g)
def run():
    while True:
        url = input("請(qǐng)輸入U(xiǎn)RL:")
        if 'http://' not in url:
            print(g.send('http://'+url))
        else:
            print(g.send(url))
run()

例2:

def cat(filename):
    with open(filename,'r') as f:
        while True:
            line = f.readline()
            if not line:
                break
            else:
                yield line
def grep(string,lines):
    for line in lines:
        if string in line:
            yield line
g1 = cat('a.txt')
g2 = grep('mac',g1)
if __name__ == '__main__':
    m = input("請(qǐng)輸入命令:").strip()
    if m == "cat a.txt |grep mac":
        for i in g2:
            print(i)

補(bǔ)充:協(xié)程

如果在一個(gè)函數(shù)內(nèi)部yield的使用方式是表達(dá)式形式的話,如x=yield,那么該函數(shù)成為協(xié)程函數(shù)

直接看例子吧

def hello(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        next(res)
        return res
    return wrapper
@hello
def eater(name):
    print('%s start to eat food' %name)
    food_list=[]
    while True:
        food=yield food_list
        print('%s get %s ,to start eat' %(name,food))
        food_list.append(food)
    print('done')
e=eater("somebody")
print(e.send('巧克力'))
print(e.send("香蕉"))

分享題目:Python學(xué)習(xí)之三大名器-裝飾器、迭代器、生成器
分享網(wǎng)址:http://muchs.cn/article26/jojdcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站建站公司、品牌網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航網(wǎng)站設(shè)計(jì)公司、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)