第四周 day4 python學習筆記

来源:http://www.cnblogs.com/jean925/archive/2017/10/06/7631797.html
-Advertisement-
Play Games

關於裝飾器的更多信息可以參考http://egon09.blog.51cto.com/9161406/1836763 1.裝飾器Decorator裝飾器:本質上是函數,(裝飾其他函數),就是為其他函數添加附加功能 原則:不能修改被裝飾函數的源代碼;不能修改被裝飾函數的調用方式#實現裝飾器的知識儲備:... ...


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

  1.裝飾器Decorator

Open-mouthed smile裝飾器:本質上是函數,(裝飾其他函數),就是為其他函數添加附加功能
原則:不能修改被裝飾函數的源代碼;不能修改被裝飾函數的調用方式
#實現裝飾器的知識儲備:
1.函數即變數
2.高階函數,有兩種方式:
(1)把一個函數名當做實參傳遞給另一個函數(在不修改被裝飾函數源代碼的情況下為其添加功能)
(2)返回值中包含函數名(不修改函數調用的方式)
3.嵌套函數
高階函數+嵌套函數==》裝飾器
Dog faceimport 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

@timer
def test1():
    time.sleep(3)
    print("in the test1....")

test1()
Dog face#高階函數
def bar():
    print("in the bar...")

def test(func):
    print(func)#列印出該函數變數的地址
    func()

test(bar)

Dog face# 把一個函數名當做實參傳遞給另一個函數
import time
def 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)
Dog face# 返回值中包含函數名
import time
def bar():
    time.sleep(2)
    print("in the bar...")

def test2(func):
   print(func)
   return func

bar2=test2(bar)
bar2()
Winking smile#嵌套函數
#局部作用域和全局作用域的訪問順序
x=0
def 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+y
print(calc(13,15))
Hot smileimport time
def 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()

@timer
def test2(name,age):
    time.sleep(3)
    print("in the test2:",name,age)

test2("Jean_V",20)

Sun#裝飾器進階版
#對各個頁面添加用戶認證
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_wrapper

def 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

image

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

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

for j in g:
print(j)

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

image

Left hug著名的斐波拉契數列(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中:

image

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

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

#生產者消費者問題
import time
def 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對象:

image

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

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

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

image

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

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

image

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

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

Nyah-Nyah小結:

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

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

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

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、創建自定義標簽基本步驟 1、步驟 標簽處理類(標簽也是一個對象,那麼就需要先有類!) tld文件,它是一個xml 頁面中使用<%@taglib%>來指定tld文件的位置 2、標簽處理類 SimpleTag介面 void doTag():每次執行標簽時都會調用這個方法; JspTag getPar ...
  • Python 協程爬取妹子圖~~~ async aiohttp scrapy ...
  • 首先分析一下集合與數組的區別:1.java中的數組一般用於存儲基本數據類型,而且是靜態的,即長度固定不變,這就不適用於元素個數未知的情況;2.集合只能用於存儲引用類型,並且長度可變,適用於大多數情況,可用toArray()方法轉換成數組。 java語言提供了多種集合類的介面,如List、Set、Ma ...
  • 方法一: Toolkit.getDefaultToolkit().beep(); 方法二: System.out.println('\007');//八進位數 ...
  • package com.swift;//可以不要這句 import java.io.IOException; public class Shutdown100 { public static void main(String[] args) { try { Runtime.getRuntime().... ...
  • Doing Homework HDU - 1074 題意: 有n個作業,每個作業有一個截止時間和完成所需時間,如果完成某個作業的時間超出了截止時間就扣完成時間-截止時間的分。求按怎樣的順序完成作業扣分最少。 方法:狀壓dp。ans[S]表示完成集合S的作業最少的扣分(集合S用一個數字表示)。pre[ ...
  • 一、JSTL的概述 1、Apache開發與維護,依賴EL表達式 2、Apache Tomcat安裝JSTL 庫步驟如下: 從Apache的標準標簽庫中下載的二進包(jakarta-taglibs-standard-current.zip)。 官方下載地址:http://archive.apache. ...
  • Buy Tickets Problem Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queu ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...