第四周 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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...