百萬年薪python之路 -- day10 -- 函數的動態參數

来源:https://www.cnblogs.com/zhangchaoyin/archive/2019/07/17/11203935.html
-Advertisement-
Play Games

1.函數的動態參數 1.1 動態接收位置參數 在參數位置用 表示接受任意參數 動態接收參數的時候要註意: 動態參數必須在位置參數後面 args 是 萬能(接受任意多個)的位置參數, 在函數定義的時候叫做 聚合 動態接收參數的時候要註意:動態參數必須在位置參數後面 優先順序:位置參數 動態位置參數 1. ...


1.函數的動態參數

1.1 動態接收位置參數

在參數位置用*表示接受任意參數

def eat(*args):
    print('我想吃',args)
eat('蒸羊羔','蒸熊掌','蒸鹿尾兒','燒花鴨','燒雛雞','燒子鵝','滷豬','滷鴨','醬雞','腊肉','松花小肚兒','晾肉','香腸兒') # 收到的結果是一個tuple元祖

動態接收參數的時候要註意: 動態參數必須在位置參數後面

def eat(*args):
    print('我想吃',args,a,b)
eat('蒸羊羔','蒸熊掌','蒸鹿尾兒','燒花鴨','燒雛雞','燒子鵝','滷豬','滷鴨','醬雞','腊肉','松花小肚兒','晾肉','香腸兒')

結果:

TypeError: eat() missing 2 required keyword-only arguments: 'a' and 'b'
# eat函數在調用的時候發現缺少倆個位置參數沒有進行傳遞
# 把所有的位置參數都給接受了,a和b接收不到值,所有會報錯.
def eat(a,b,*args):
    print('我想吃',args,a,b)
eat('蒸羊羔','蒸熊掌','蒸鹿尾兒','燒花鴨','燒雛雞','燒子鵝','滷豬','滷鴨','醬雞','腊肉','松花小肚兒','晾肉','香腸兒')

結果:
我想吃 ('蒸鹿尾兒', '燒花鴨', '燒雛雞', '燒子鵝', '滷豬', '滷鴨', '醬雞', '腊肉', '松花小肚兒', '晾肉', '香腸兒') 蒸羊羔 蒸熊掌
def func(a,b,*args):
    print(a,b,args)     #*args 是 萬能(接受任意多個)的位置參數, *在函數定義的時候叫做聚合
    print(*args)        #  在這一行 *args作用是 打散

args 是 萬能(接受任意多個)的位置參數, 在函數定義的時候叫做聚合

動態接收參數的時候要註意:動態參數必須在位置參數後面

優先順序:位置參數 > 動態位置參數

1.2 動態接收關鍵字參數

在python中可以動態的位置參數,但是*這種情況只能接收位置參數無法接收關鍵字參數,在python中使用**來接收動態關鍵字參數

def func(**kwargs):
    print(kwargs)     
func(a=1, b=2, c=3)

結果:
{'a': 1, 'b': 2, 'c': 3}    #dict字典形式

動態關鍵字參數最後獲取的是一個dict字典形式

位置參數必須在關鍵字參數前面.動態接收關鍵字參數也要在後面

倆個動態參數:

def trans_para(*args,**kwargs):
    print(args,type(args))      # args是元祖形式
    print(kwargs,type(kwargs))  # kwargs接收的只是鍵值對的參數,並保存在字典中。
trans_para("jinxin",12,[1,2,3,4],[3,4,],(1,4,7),{"a":"123","c":456},country="china")

結果:
('jinxin', 12, [1, 2, 3, 4], [3, 4], (1, 4, 7), {'c': 456, 'a': '123'}) <class 'tuple'>
{'country': 'china'} <class 'dict'>

動態參數,也叫不定長傳參,就是你需要傳給函數的參數很多,不定個數,那這種情況下,你就用*args,**kwargs接收,args是元祖形式,接收除去鍵值對以外的所有參數,kwargs接收的只是鍵值對的參數,並保存在字典中。

*args和 **kwargs

args是元祖形式,kwargs是字典形式

最終順序:

位置參數 > *args(動態位置參數) > 預設值參數 > **kwargs(動態預設參數)

如果想接收所有的參數:

def func(*args,**kwargs):
    print(args,kwargs)
    print(*args,*kwargs)    #*args為把元組打散,*kwargs為字典的keys

func(1,23,5,a=1,b=6)

結果:
(1, 23, 5) {'a': 1, 'b': 6}
1 23 5 a b

動態參數還可以這樣傳參:

lst = [1,4,7]
# 方法一
def func(*args):
    print(args)

func(lst[0],lst[1],lst[2])  # (1, 4, 7)


# 方法二
def func(*args):
    print(args)

func(*lst)      # (1, 4, 7)
# 在實參的位置上用*將lst(可迭代對象)按照順序打散

# 在形參的位置上用*把收到的參數組合成一個元祖

字典也可以進行打散,不過需要**

dic = {'a':1,'b':2}
lst = [1,2,3,4,5,6,7,81]
def func(*args,**kwargs):
    print(args)
    print(kwargs)
func(*lst,**dic)

結果:
(1, 2, 3, 4, 5, 6, 7, 81)
{'a': 1, 'b': 2}

2.函數的註釋

# 函數的註釋

def func(*args,**kwargs):
    '''
    #很重要 寫函數一定要寫註釋
    :param args:   要標識的內容
    :param kwargs: 要標識的內容
    :return: 要標識的內容
    '''

    pass

# 函數名.__doc__   查看函數的註釋
# 函數名.__name__  查看函數名(在學反射的時候使用)

3.名稱空間

在python解釋器開始執行之後, 就會在記憶體中開闢一個空間, 每當遇到一個變量的時候, 就把變量名和值之間的關係記錄下來, 但是當遇到函數定義的時候, 解釋器只是把函數名讀入記憶體, 表示這個函數存在了, 至於函數內部的變量和邏輯, 解釋器是不關心的. 也就是說一開始的時候函數只是載入進來, 僅此而已, 只有當函數被調用和訪問的時候, 解釋器才會根據函數內部聲明的變量來進行開闢變量的內部空間. 隨著函數執行完畢, 這些函數內部變量占用的空間也會隨著函數執行完畢而被清空.

def fun():   
    a = 10   
    print(a)
fun()
print(a)    # a不存在了已經..

我們給存放名字和值的關係的空間起一個名字叫: 命名空間. 我們的變量在存儲的時候就 是存儲在這片空間中的.

命名空間分類:

  1. 全局命名空間--> 我們直接在py文件中, 函數外聲明的變量都屬於全局命名空間
  2. 局部命名空間--> 在函數中聲明的變量會放在局部命名空間
  3. 內置命名空間--> 存放python解釋器為我們提供的名字, list, tuple, str, int這些都是內置命名空間  

載入順序:

  1. 內置命名空間
  2. 全局命名空間
  3. 局部命名空間(函數被執行的時候)

取值順序:

  1. 局部命名空間
  2. 全局命名空間
  3. 內置命名空間
a = 10
def func():  
    a = 20   
    print(a)

func()  # 20

作用域: 作用域就是作用範圍, 按照生效範圍來看分為 全局作用域 和 局部作用域

   全局作用域: 包含內置命名空間和全局命名空間. 在整個文件的任何位置都可以使用(遵循 從上到下逐⾏執行).

   局部作用域: 在函數內部可以使用.

作⽤域命名空間:

  1. 全局作用域: 全局命名空間 + 內置命名空間
  2. 局部作用域: 局部命名空間

我們可以通過globals()函數來查看全局作⽤用域中的內容,也可以通過locals()來查看局部作 ⽤用域中的變數量和函數信息

a = 10
def func():   
    a = 40   
    b = 20   
    print("哈哈")   
    print(a, b)        
    print(globals())    # 列印全局作用域中的內容   
    print(locals())     # 列印當前作用域中的內容
func()

4.函數嵌套

  1. 只要遇見了()就是函數的調用. 如果沒有()就不是函數的調用
  2. 函數的執行順序
def fun1():   
    print(111)  
def fun2():   
    print(222)   
    fun1()   
fun2()
print(111)

1548388589142

def fun2():   
    print(222)   
    def fun3():       
        print(666)   
    print(444)   
    fun3()   
    print(888)
print(33)
fun2()
print(555)

1548388743478

5.global nonlocal (很重要)

首先我們寫這樣一個代碼, 首先在全局聲明一個變量, 然後再局部調用這個變量, 並改變這 個變量的值

a = 100
def func():   
    global a    # 加了個global表示不再局部創建這個變量了. 而是直接使用全局的a   
    a = 28   
print(a)
func()
print(a)

結果:
100
28

global表示不再使用局部作用域中的內容了. 而改用全局作用域中的變量

2.1global 宗旨

在函數內部修改全局的變數,如果全局中不存在就創建一個變數

lst = ["周道鎔", "章超印", "楊紅興"]
def func():   
    lst.append("朱凡宇")   
    # 對於可變數據類型可以直接進行訪問
   print(lst)
func()
print(lst)

2.2 nonlocal宗旨

nonlocal 只修改上一層變數,如果上一層中沒有變數就往上找一層,只會找到函數的最外層,不會找到全局進行修改

a = 10
def func1():   
    a = 20   
    def func2():
        nonlocal a       
        a = 30       
        print(a)  
    func2()   
    print(a)
func1()


結果:
加了nonlocal
30
30

不加nonlocal
30
20

再看, 如果嵌套了很多層, 會是一種什麼效果:

a = 1
def fun_1():   
    a = 2   
    def fun_2():       
        nonlocal a       
        a = 3       
        def fun_3():           
            a = 4           
            print(a)       
        print(a)       
        fun_3()       
        print(a)   
    print(a)   
    fun_2()   
    print(a)
print(a)
fun_1()
print(a)
# 這樣的程式如果能分析明白. 那麼作用域, global, nonlocal就沒問題了

6.其他

三元運算符
a = 10
b = 30
c = a if a > b else b
print(c)

結果:
30

enumerate() #枚舉
lst = [11,22,33,44,55,66]
for i,j in enumerate(lst):
    print(i,j)
    
結果:
0 11
1 22
2 33
3 44
4 55
5 66



元組和字典打散:
tu = (1,2,3,4,5,6)
dic = {1:2,2:4}
print(*tu)
print(*dic)

結果:
1 2 3 4 5 6
1 2

一日總結:

# 1.函數的動態參數
# *args,**kwargs (能夠接受動態的位置參數和動態的關鍵字參數)
# 定義階段(*args,**kwargs) 聚合
#     *args -  tuple
#     **kwargs -- dict
# 使用階段*args,*kwargs 打散
#     *args - 源數據類型
#     *kwargs - 打散是字典的鍵
# 優先順序: 位置 > 動態位置> 預設 > 動態關鍵字

# lst = [12,23,3,4,5,6]
# def func(*args):
#     print(*args)
# func(lst[0],lst[1]) # 笨的辦法
# func(*lst)

# dic = {"key":1,"key1":34}
# def func(**kwargs):
#     print(kwargs)
# func(**dic)

# 2.函數的註釋
"""
每次寫函數的時候需要寫註釋
函數名.__doc__
函數名.__name__
"""

# 3.名稱空間
# 內置空間: python解釋器自帶的
# 全局空間:當前文件(.py文件)
# 局部空間:函數體開闢的空間

# 載入順序: 內置 > 全局> 局部
# 取值順序: 局部 > 全局 > 內置

# 作用域:
# 全局作用域 內置 + 全局
# 局部作用域: 局部

# 4.函數嵌套
# 函數中套函數
# 函數嵌套調用
# 函數嵌套參數的傳遞
# 函數嵌套返回值的傳遞

# 5.global nonlocal
# global : 修改全局空間的變數對應的值
# nonlocal :在外層的函數中,修改局部空間的變數值.完全不涉及全局變數,
# 只修改離它最近的一層,最近的一層沒有變數繼續向上找,直到找到最外層函數

# 6.三元運算符
# a = 10
# b = 20
# c = a if a> b else b
# 變數名 = 條件成立的結果 條件 條件不成立的結果

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

-Advertisement-
Play Games
更多相關文章
  • 閱讀目錄 一、三大編程範式 編程範式即編程的方法論,標識一種編程風格: 大家學習了基本的python語法後,大家可以寫python代碼了,然後每個人寫代碼的風格不同,這些不同的風格就代表了不同的流派; 如果把python的基本語法比作武術的基本功,那麼不同的編程風格就好比不同的武林門派。 雖然大家風 ...
  • 前面介紹瞭如何使用畫筆工具Graphics繪製各種圖案,然而Graphics並不完美,它的遺憾之處包括但不限於:1、不能設置背景顏色;2、雖然提供了平移功能,卻未提供旋轉功能與縮放功能;3、只能在控制項上作畫,無法將整幅畫保存為圖片;有鑒於此,AWT提供了Graphics的升級版名叫Graphics2 ...
  • 11-3 雇員:編寫一個名為Employee的類,其方法__init__() 接受名、姓和年薪,並將它們都存儲在屬性中。編寫一個名為give_raise()的方法,它預設將年薪增加5000美元,但也能夠接受其他的年薪增加量。 為Employee編寫一個測試用例,其包含兩個測試方法:test_give ...
  • a=1 聲明變數 a 變數的名字 = 賦值 1 值 變數定義的規則: 1. 變數由數字,字母,下劃線組成(不能加空格): a a_1 a1 2. 不能以數字開頭 3. 不能使用python中的關鍵字(寫的時候變藍了) 4. 不能使用中文和拼音 5. 區分大小寫 6. 變數名要具有描述性 7. 推薦寫 ...
  • SpringBoot快速入門--環境搭建 1、創建web工程 1.1 創建新的工程。 1.2 選擇maven工程,點擊下一步。 1.3 填寫groupid(maven的項目名稱)和artifactid(項目模塊)。點擊下一步 1.4 確認自己的項目路徑後,點擊finish。 2、添加springbo ...
  • github: 主頁: 使用手冊: LMDIF使用說明 官方英文介紹: 包括函數名 ,` lmdif1_` 最小化非線性函數平方和 函數概要 詳細描述 的目的是最小化m個n元非線性方程的平方和,使用的方法是LM演算法的改進。用戶需要提供計算方程的子程式。Jacobian矩陣會通過一個前向差分(forw ...
  • 這是一張簡單的service的繼承圖。可以看到我們的執行類,即XxxServiceImpl的繼承關係。 從上到下,ServiceImpl和BaseMapper是一個依賴關係,ServiceImpl和Iservice是一個實現關係。即ServiceImpl實現了IService中定義的方法,這裡為什麼 ...
  • 分享學習Python數據結構的一些理解,主要包含序列(如列表和元組),映射(如字典)以及集合3中基本的數據結構,以及可變和不可變數據類型。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...