百萬年薪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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...