第四周 day4 python學習筆記,day4python

來源:互聯網
上載者:User

第四周 day4 python學習筆記,day4python

  關於裝飾器的更多資訊可以參考http://egon09.blog.51cto.com/9161406/1836763

  1.裝飾器Decorator

裝飾器:本質上是函數,(裝飾其他函數),就是為其他函數添加附加功能
原則:不能修改被裝飾函數的原始碼;不能修改被裝飾函數的調用方式
#實現裝飾器的知識儲備:
1.函數即變數
2.高階函數,有兩種方式:
(1)把一個函數名當做實參傳遞給另一個函數(在不修改被裝飾函數原始碼的情況下為其添加功能)
(2)傳回值中包含函數名(不修改函數調用的方式)
3.嵌套函數
高階函數+嵌套函數==》裝飾器
import time#計算一個函數的已耗用時間的裝飾器def timer(func):    def wrapper(*kargs,**kwargs):        start_time=time.time()        func()        end_time=time.time()        print("the func runtime is %s"%(end_time-start_time))    return wrapper@timerdef test1():    time.sleep(3)    print("in the test1....")test1()
#高階函數def bar():    print("in the bar...")def test(func):    print(func)#列印出該函數變數的地址    func()test(bar)

# 把一個函數名當做實參傳遞給另一個函數import timedef bar():    time.sleep(2)    print("in the bar...")def test(func):    start_time=time.time()    func()  #run bar()    end_time=time.time()    print(" the func runtime is %s"%(end_time-start_time))test(bar)
# 傳回值中包含函數名import timedef bar():    time.sleep(2)    print("in the bar...")def test2(func):   print(func)   return funcbar2=test2(bar)bar2()
#嵌套函數#局部範圍和全域範圍的訪問順序x=0def grandpa():    x=1    print("grandpa:",x)    def dad():        x=2        print("dad:",x)        def son():            x=3            print("son:",x)        son()    dad()grandpa()

#匿名函數:沒有定義函數名字的函數calc=lambda x,y:x+yprint(calc(13,15))
import timedef timer(func):    def deco(*kargs,**kwargs):        start_time=time.time()        func(*kargs,**kwargs)        end_time=time.time()        print(" the func runtime is %s"%(end_time-start_time))    return deco@timer  # test1=timer(test1)def test1():    time.sleep(2)    print("in the test1.....")# test1=timer(test1)test1()@timerdef test2(name,age):    time.sleep(3)    print("in the test2:",name,age)test2("Jean_V",20)

#裝飾器進階版#對各個頁面添加使用者認證username,password="admin","123"def auth(auth_type):    print("auth_type:",auth_type)    def out_wrapper(func):        def wrapper(*args,**kwargs):            if auth_type=="local":                uname=input("請輸入使用者名稱:").strip()                passwd=input("請輸入密碼:").strip()                if uname==username and passwd==password:                    print("\033[32;1m User has passed authentication\033[0m")                    res=func(*args,**kwargs)                    print("************after authentication")                    print(res)                else:                    exit("\033[31;1m Invalid username or password\033[0m")            elif auth_type=="LADP":                print("我不會LADP認證,咋辦?。。。")        return wrapper    return out_wrapperdef index():    print("index page......")@auth(auth_type="local")#home 頁採用本地驗證def home():    print("home page.....")    return "from home page....."@auth(auth_type="LADP")#bbs 頁採用LADP驗證def bbs():    print("bbs page....")index()print(home())home()bbs()
2.列表產生式














#列表產生式:一句代碼更加簡潔a=[i*2 for i in range(10)]print(a)b=[i*i for i in range(20)]print(b)#上面的列表產生式等同於res=[]for i in range(10):    res.append(i*2)print(res)#列表產生式的更加進階的用法:#[funv(i) for i in range(10)]def fun(n):#定義一個求階乘的函數    if n>1:        return n*fun(n-1)    else:        return 1#利用函數產生10以內的階乘c=[fun(i) for i in range(10)]print(c)

3.迭代器與產生器

參考資訊:http://www.cnblogs.com/alex3714/articles/5765046.html

產生器:按照某種演算法可以進行推算,不必建立完整的List,節省大量空間,在迭代過程中一邊迴圈一邊計算的機制,稱之為產生器generator

建立Lg的區別僅在於最外層的[]()L是一個list,而g是一個generator。

針對generator可以使用for迴圈輸出;因為generator也是可迭代對象

for j in g:
print(j)

如果要一個一個列印出來,可以通過__next__()函數獲得generator的下一個傳回值:

著名的斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契數列用列表產生式寫不出來,但是,用函數把它列印出來卻很容易:

#斐波那契數列#輸出斐波那契數列的前m個數def fibnacci(m):    n,a,b=0,0,1    while n<m:         print(b)         a,b=b,a+b #這一句相當於:t=(b,a+b)  a=t[0]  b=t[1]         n+=1    return 'done'fibnacci(10)
上面的函數和generator僅一步之遙。要把fib函數變成generator,只需要把print(b)改為yield b就可以了:
#斐波那契數列#輸出斐波那契數列的前m個數def fibnacci(m):    n,a,b=0,0,1    while n<m:         yield b #這一句很關鍵         a,b=b,a+b #這一句相當於:t=(b,a+b)  a=t[0]  b=t[1]         n+=1    return ' well done'#異常的時候顯示的資訊f=fibnacci(10)for i in f:    print(i)g=fibnacci(6)#捕獲異常並處理while True:    try:        x=next(g)        print("g:",x)    except StopIteration as e:        print("Generator return value :",e.value)        break

在上面fib的例子,我們在迴圈過程中不斷調用yield,就會不斷中斷。當然要給迴圈設定一個條件來退出迴圈,不然就會產生一個無限數列出來。

同樣的,把函數改成generator後,我們基本上從來不會用next()來擷取下一個傳回值,而是直接使用for迴圈來迭代:

但是用for迴圈調用generator時,發現拿不到generator的return語句的傳回值。如果想要拿到傳回值,必須捕獲StopIteration錯誤,傳回值包含在StopIterationvalue中:

還可通過yield實現在單線程的情況下實現並發運算的效果

生產者消費者問題 (通過產生器實現協程並行運算)

#生產者消費者問題import timedef consumer(name):    print("%s,準備好吃漢堡包了"%name)    while True:        hamburg=yield        print("第[%s]個漢堡包來了,被[%s]吃了"%(hamburg+1,name))def producer(name):    c1=consumer('Alice')    c2=consumer('Bob')    #生產者生產的時候需要通知消費者前來吃    c1.__next__()    c2.__next__()    print("%s,開始做漢堡包了"%name)    for i in range(10):        time.sleep(1.5)        print("做好了1個漢堡包,可以吃了")        c1.send(i)        c2.send(i)producer("Jean")

迭代器

可以直接作用於for迴圈的資料類型有以下幾種:

   一類是集合資料類型,如listtupledictsetstr、bytes等;

   一類是generator,包括產生器和帶yield的generator function。

這些可以直接作用於for迴圈的對象統稱為可迭代對象:Iterable

可以使用isinstance()判斷一個對象是否是Iterable對象:

而產生器不但可以作用於for迴圈,還可以被__next__()函數不斷調用並返回下一個值,直到最後拋出StopIteration錯誤表示無法繼續返回下一個值了。

*可以被next()函數調用並不斷返回下一個值的對象稱為迭代器:Iterator

可以使用isinstance()判斷一個對象是否是Iterator對象:

產生器都是Iterator對象,但listdictstr雖然是Iterable,卻不是Iterator

listdictstrIterable變成Iterator可以使用iter()函數:

Iterator對象表示的是一個資料流,Iterator對象可以被next()函數調用並不斷返回下一個資料,直到沒有資料時拋出StopIteration錯誤。可以把這個資料流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個資料,所以Iterator的計算是惰性的,只有在需要返回下一個資料時它才會計算。

Iterator甚至可以表示一個無限大的資料流,例如全體自然數。而使用list是永遠不可能儲存全體自然數的。

小結:

凡是可作用於for迴圈的對象都是Iterable類型;

凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;

集合資料類型如listdictstr等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。

Python的for迴圈本質上就是通過不斷調用next()函數實現的,例如:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.