第五章 函數day2

来源:https://www.cnblogs.com/xuanxuan360/archive/2019/08/28/11425207.html
-Advertisement-
Play Games

5.2函數小高級 5.2.1 函數當參數 1 函數也可以當返回值 練習 函數其實也是一種數據類型,可以當變數存儲 面試題 5.2.2 閉包 閉包的意義: 返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域 閉包 就是在內層函 ...


5.2函數小高級

5.2.1 函數當參數

  • 1 函數也可以當返回值
def v(dar):
    v = dar()
def n ():
    print(444)
v(n)

# 實例2
def v():
    print(666)
def n():
    return v
m =n()
m()

# 實例3
def func():
    print(555)
    
def info():
    print(666)
    return func()
v = info()
print(v)
  • 練習

    # 實例1
    def v():
        print(666)
    def n():
        return v
    m =n()
    m()
    
    # 實例2
    def v():
        print(666)
    
    def n():
        print('alex')
        v()
    n()
    
    # 實例3
    name ='alex'
    def v():
    print(name)
    def v1():
        name = 'aicr'
        print(name)
        v()  # alex
    v1() # aicr
    
  • 函數其實也是一種數據類型,可以當變數存儲

# 實例1
def fucn():
    print('alex')
list = [fucn,fucn,fucn()]  #  加()直接執行了

list[0]()
list[1]()

# 實例2
def fucn():
    print('alex')

dic = {'k1':fucn,'k2':fucn()}

dic['k1']()
  • 面試題
'''用函數實現:
    用戶輸入 f1  話費查詢
            f2   餘額查詢
             f3   人工服務
             f4   寬頻業務  
    '''

# 方法1 
usee = input('請輸入業務 :')
if usee =='f1':
    print(話費查詢)
elif usee =='f2':
    xxxxx
else:
    xxxxxx
    
# 方法二  函數
def v1():
    print('話費')
def v2():
    print('餘額')
def v3():
    print('人工')
def v4():
    print('寬頻')

dic = {'f1':v1,'f2':v2,'f3':v3,'f4':v4}

usee = input('請輸入:')
dic[usee]()

5.2.2 閉包

  • 閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域
  • 閉包 就是在內層函數調用外層函數的變數
# 實例1 
def func():
    a = 2
    def info():
        print(a)  # 調用外層函數
     info()
 func()


# 實例 2
def get():
    name = 'alex'
    
    def info():
        print(name)
    return info # 返回info的記憶體id
v = get()
v() # 相當於調用info

# 實例 3

def get(arg):
    def func():
        return arg
    return func()

v = get(666)
print(v)
1 閉包的作用:
  • 1 保護變數,不受外部改變
作用 1  保護變數,不受外部改變

'''
a = 10
def func():
    global a
    a =2
    
def info():
    global a 
    a = 3
    
先 func()  再  info()   a =3
先 info()  再   func()   a= 2

全局變數不穩定,受影響
'''

# 閉包
def func():
    a = 10
    def info():
        print(a)
    info()
# 這樣保護了變數不受其他影響

    
作用 2 使變數常駐記憶體

def func():
    a = 10
    def info():
        print(a)
     return info
v = func()

v()
2 查看是不是閉包
def func():
    a = 10
    def info():
        print(a)

    info()
    print(info.__closure__)  # 不是閉包返回  None

func()
3 閉包應用
'''
    閉包 應用   簡易版爬蟲
'''
from urllib.request import urlopen

def func():
    get = urlopen('https://www.dytt8.net/').read()
    def info():
        print(get)
    return info
print('第一次,慢')
v = func()
v()

print('以後就在記憶體讀出')
v()
v()  # 閉包常駐記憶體 , 直接記憶體讀出

5.2.3 lambda 函數表達式

  • 三元運算

    print('ture') if v > 6 else print('flase')
  • lambda ( 匿名函數)

v = lambda x: x*3
print(v(3))
v = lambda x,y:x*y
print(v(4,6))

# 三元運算和lambda
n = lambda x:x if x<4 else x+1
print(n(14))
# 也可以當作參數
lst = [lambda x: x*3 ,lambda x: x*3,lambda x: x*3 ]
n = lst[0](3)
print(n)
print(lst[1](3))
  • map + lambda

    n = map(lambda x:x*5,[1,2,3,4])
    for line in n :
        print(line)

5.4 高級函數

  • map (多對一)

    # 實例1
    n = map(lambda x : x+2,[1,2,3,4])
    for i in n:
        print(i)
    
    # 實例2
    lst =[map(lambda x:x+1,[1,2,3]),map(lambda x:x+2,[1,2,3]),map(lambda x:x+3,[1,2,3])]
    print(lst)
    '''[<map object at 0x000002B3D40B17F0>, <map object at 0x000002B3D40B1940>, <map object at 0x000002B3D40B1C50>]'''
    
    #實例3
    lst =[map(lambda x:x+1,[1,2,3]),map(lambda x:x+2,[1,2,3]),map(lambda x:x+3,[1,2,3])]
    n = lst[0]
    for line in n :
        print(line)
    
    # 實例4
    
    lst =[map(lambda x:x+1,[1,2,3]),map(lambda x:x+2,[1,2,3]),map(lambda x:x+3,[1,2,3])]
    for i in lst:
        for line in  i:
            print(line)
  • filter 過濾掉不符合條件的數據

    # 實例1
    n = filter(lambda x :x>4,[1,22,33,4,5,])
    for line in n:
        print(line) # 22,33,5
    
    # 實例2
    n = filter(lambda x :x if x<4 else print('flase') ,[1,22,3,4,5,])
    for line in n:
        print(line)
    

5.5 推導式

  • 列表

    lst = [i for i in range(10)]
    
    lst1 = [1 for i in range(10)]
    
    lst2 = [ i for i in range(10) if i <6]
    # [迭代的變數 for i in 可迭代的對象 判斷 ]
    
    lst3 =[ i if i < 5 else 777 for i in range(10)   ]
    print(lst5)
    # 加if 在for後 , 加 if ....else 在for前
    
    
    lst4 = [lambda : i for i in range(10)]
    '''
    v =[]
    for i in range(10):
        v.append(lambda :i)
    
    n = v[1]()
    print(n)'''
    
    lst5 = [ lambda x : x if x+i >10 for i in range(10)]
    
    def func():
        pass
    lst6 = [func for i in range(10)]
    
    # 面試題
    def func():
        return [lambda x : x+i for i in range(10)]
    lst7 = [ i  for i in func() ]
    print(lst7[1](7))
    
    
    

    上面這個題。 不要死磕。 能明白多少就明白多少。 這個題對小白很不友好

  • 元祖(集合)

    # 元祖和集合都要循壞列印
    set1 =(i for i  in range(18 ))
    for i in set1:
        print(i)
    
    
    set1 ={lambda  : i for i  in range(18 )}
    for i in set1:
        print(i())
    
    def func():
        print(222)
    set3 = (func for i in range(10))
    for i in set3:
        i()
  • 字典

dic ={ 'k%d'%i:i for i in range(10)}
print(dic)
#同列表

5.6 遞歸

  • 函數內部調用自己 (不建議,占記憶體)
  • python 為了不爆記憶體 ,限制了遞歸次數1000次
# 實例1
def func(a):
    print(a)
    a = a +1
    func(a)
func(1)

# 實例2
def func(a):
    print(a)
    if a < 5:
        func( a + 1)

func(1)  # 1,2,3,4,5

# 實例3
def func(a):
    if a < 5:
        func( a + 1)
    print(a)

func(1)  # 5,4,3,2,1  
'''
函數在每進入下一層的時候,當前層的函數並未結束,它必須等它調用的下一層函數執行結束返回後才能繼續往下走。 所以最下麵的那句print(n)會等最裡層的函數執行時才會執行,然後不斷往外退層,所以會出現 5,4,3,2,1的效果
'''
 
# 實例 4 

def func(a):
    if a ==5:
        return a
    info = func(a + 1) + 10
    return info
v = func(1)
print(v)  # 34 

5.7 裝飾器

1. 什麼是裝飾器
  • 裝飾器就是在不改變原函數的情況下,調用函數前後增加代碼

    def func(arg):
        def info():
            print('aaaaaaaaaaaaaaaaaaa')
            arg()
        return  info
    
    def v():
        xxxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxxx
    
        print(1111111111111)
        return 3333
    
    data = func(v)
    data()
    
    def v1():
        xxxxxxxxxxxxxxxxxxx
        print('alex')
        xxxxxxxxxxxxxxxxxxx
    lst = func(v1)
    lst()
    
    
    '''
      如果在 函數v 和函數v1 加上百行代碼, 你要一個一個加
      函數如果不只有 v v1 很多
        怎麼辦  -------------裝飾器--------------
    '''
    
    # 實例1 
    def func(arg):
        def info():
            print('alrx sb')  # 在調用函數前列印 alx sb
            arg()
            print('aaaaaaaaaaa')  #在調用函數後列印  aaaaaaaaa
    
        return  info
    
    def v():
        print(1111111111111)
    
    data = func(v)  # func的參數傳入v函數  此時data = info 函數
    data()  # 執行data = 執行 info()
    
    # 實例2
    def func(arg):
        def info():
            print('aaaaaaaaaaaaa')
            v = arg()
            return v
        return  info
    
    def v():
        print(1111111111111)
        return 3333
    
    data = func(v)
    print(data())  
    
2. 裝飾器基本格式
'''
    上面的裝飾器很low  因為  如果裝飾上百個函數的話
    要重覆  賦值操作
'''
def func(arg):
    def info():
        print('alex sb')
        arg()
        print('aaaaaaaaaa')
    return info

@func
 #  @func 簡化 func函數的賦值 
 #  @ 函數  第一步,調用func 把下麵的函數名當做func函數的參數   # arg = v
 #      第二步 , func 的return info,賦值給下麵函數  v = info
 # 但是 func中 arg還是指向 v函數id   而 v 重新的賦值
def v():
    print(666)

v()
3.關於參數裝飾
# 實例1
'''
如果裝飾的函數需要傳參數
'''
def func(arg):
    def info(a):
        arg(a)
    return info
@func
def data(n):
    print(n)
data()
# 第一步 執行func(data)
# data = info函數
#執行data(參數)

########如果被裝飾的函數n個參數,需要改裝飾器

# 優化

def func(arg):
    def info(*args,**kwargs):
        arg(*args,**kwargs) # 加上*args **keargs 不用管被裝飾的函數需要幾個參數都能傳
    return info

@func
def data(n1,n2,n3):
    print(n1,n2,n3)

data(1,2,n3=3)

@func
def inner(a1,a2,a3,a4):
    print(a1,a2,a3,a4)
inner('alex',1,2,3)  # alex 1 2 3
  • 裝飾器標準格式

    def func(arg):
        def info(*args,**kwargs):
            data = arg()
            return data
        return info
    @func
4.關於返回值
# 實例1 

def func(arg):
    def info(*args,**kwargs):
        data = arg(*args,**kwargs)
        return data
    return info

@func
def inner():
    print('alex')
v = inner()
print(v)  # none

# 實例2

def func(arg):
    def info(*args,**kwargs):
        data = arg(*args,**kwargs)
        return data
    return info

@func
def inner():
    print('alex')
    return 666
v = inner()
print(v)  # 666
# 練習題

# 1 判斷文件是否存在
'''
imprt os
os.path.exists()
True or flase
'''
import os
def func(arg):
    def info(*args,**kwargs):
        # 檢查文件的路徑是否存在

        lst= args[0]
        if not os.path.exists(lst):
            print('路徑不存在')
            return None

        data = arg(*args,**kwargs)
        return data
    return info

@func
def inner(path):
    f1 = open(path,mode='r',encoding='utf-8')
    v = f1.read()
    print(v)
    f1.close()
    return True
v = inner("E:\代碼庫\電影下載地址.txt")
print(v)

5. 帶參數的裝飾器
# 實例1 

def inner(a):   # 在閉包外再嵌套一層,即帶參數的裝飾器
    print(a)
    def func(arg):
        def info(*args,**kwargs):
            data = arg(*args,**kwargs)
            return data
        return info
    return func

@inner('alex')
# 執行 inner
# inner 返回的值func   @func
# 執行ear = func(ear) = info
# 執行info函數
def ear(v):
    print(v)

n = ear(111)
print(n)
          
# 實例2

def inner(a):
    print(a)
    def func(arg):
        def info(*args,**kwargs):
            data = arg(*args,**kwargs)
            return data
        return info
    return func

@inner('alex')
def ear(v):
    print(v)
    return 666

n = ear(111)
print(n)

帶參數的裝飾器的執行過程其實是這樣的。 先inner(xxx) 然後inner函數返回值再和前面的@組合成裝飾器


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

-Advertisement-
Play Games
更多相關文章
  • 場景 zxing.dll下載 https://download.csdn.net/download/badao_liumang_qizhi/11623214 效果 實現 根據上面文章中將簡單的二維碼生成後,現在要調整其佈局。 拖拽一個按鈕,雙擊進入其點擊事件。 這裡新建了一個工具類ZxingHelp ...
  • 1 private static dynamic GetSorObject (Object obj) 2 { 3 if (obj is JArray) 4 { 5 var list = new List<dynamic> (); 6 foreach (var item in (obj as JArr... ...
  • 場景 zxing.dll下載 https://download.csdn.net/download/badao_liumang_qizhi/11623214 效果 實現 新建Winform程式,將上面下載的zxing.dll添加到引用。 拖拽一個按鈕,雙擊進入其點擊事件。 然後在頁面上拖拽一個pic ...
  • in 修飾符記錄: 新版C# 新增加的 in 修飾符:保證發送到方法當中的數據不被更改(值類型),當in 修飾符用於引用類型時,可以改變變數的內容,單不能更改變數本身。 個人理解:in 修飾符傳遞的數據,在方法里就是只讀的 ,不能進行任何更改。 ...
  • 從註冊而來的這麼多天,不對,是這麼多月以來,還沒有正經地寫過一篇博客,不對,連不正經的博客也沒有,正好有人邀請我一起搭建網站,看了下視頻覺得還可以,就開始動手了。 以前覺得搭網站,說難不難,可是說簡單又不簡單。 百度了一下,先自行總結了這麼幾步。 哦對,先把自己的網站放上來。 smallblog.x ...
  • [TOC] 首先我要說明,我失敗了~ 我把我的進度和經驗放出來,希望能夠幫助別人完成編譯工作~ 背景:最近接手一個華為某型號的嵌入式設備,需要在上面搭建 .NET Core 環境。 設備是 Armel 架構的,Linux 內核 3.10;.NET Core ARM 只有 Armhf。 因此編譯出來的 ...
  • 我們知道MVC請求進來,然後路由匹配,然後找到控制器和Action,最後會調用Action方法,但是大家想想控制器是個普通的類,Action是個普通的實例方法,要想調用Action必須先實例化控制器,那麼MVC中如何實例化控制器的呢? 1、MVC請求進來會先進入到UrlRoutingHandler里 ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...