Python函數參數與參數解構

来源:https://www.cnblogs.com/dabric/archive/2019/10/14/11670997.html
-Advertisement-
Play Games

1 Python中的函數 函數,從數學的角度來講是,輸入一個參數,經過一個表達式的處理後得到一個結果的輸出,即就是x-->y的一個映射。同樣,在Python或者任何編程語言中,函數其實就是實現一種功能,也可以稱其為介面,通過使用定義的函數,以此來達到某種功能的實現。 1.1 Python中函數的定義 ...


1 Python中的函數

  函數,從數學的角度來講是,輸入一個參數,經過一個表達式的處理後得到一個結果的輸出,即就是x-->y的一個映射。同樣,在Python或者任何編程語言中,函數其實就是實現一種功能,也可以稱其為介面,通過使用定義的函數,以此來達到某種功能的實現。

1.1 Python中函數的定義

  使用def語句可定義函數: 

1 def 函數名(參數列表)
2     函數體(代碼塊)
3     [return 返回值]

  函數名就是一個函數的名字,也是一種標識符,命名的要求為:只能以字母或下劃線開頭的除   Python的關鍵字外的任意字元串,註意Python是大小寫敏感的;

  Python中利用縮進的形式來表示語句塊,約定4個空格;

  返回語句,在一個函數中可以沒有返回值,如果沒有返回值,隱式會返回一個None值;

  定義中的參數列表為形式參數,只是一種符號表達,簡稱形參;

  比如下麵的add函數:

1 def add(x, y):
2     return x + y

 

1.2 函數的調用

  函數的定義過程,只是聲明瞭一個函數,函數不會被執行,需調用。對於1.1中定義的函數,通過a = add(3, 4)來調用,其中調用時寫的參數是實際參數,是實實在在傳入的值,簡稱實參。

  函數可調用的對象,可以通過callable()函數來檢測一個變數是否可以調用。

2 函數參數

  在Python中函數的參數有以下幾種類型:

  •   位置參數
  •   關鍵字參數
  •   可變參數
  •   keyword-only參數

2.1 位置參數

  在1.1中定義的add(x, y)函數,其中x和y為位置參數。在調用函數的時候,實參的順序和數量必須與函數定義中的形參匹配,否則會引發TypeError異常。

  比如定義函數def f(x, y, z),調用時為f(1, 2, 3).

2.2 關鍵字參數

  函數調用的過程當中,實參利用函數形參的名字進行賦值傳參,那麼該實參就為關鍵字參數。如果函數調用時的實參使用了形參名字,那麼傳參順序就可和定義參數的順序不同。

  同樣對函數的f有以下調用方式:

1 f(1, 2, 4)
2 f(z=None, x=6, y=4) # 關鍵字參數調用
3 f(y=5, 2, 6)  # 該調用方式是否可行

  註:要求位置參數必須在關鍵字參數之前傳入,位置參數是按位置對應的。

2.3 可變參數

  有時候在調用函數時,可能會給函數傳多個參數,我們不可能在定義函數時將函數的參數的個數固定死,那麼這個函數的靈活性就不存在。於是就有了可變參數,即一個形參可匹配任意個參數。可變參數分為:位置參數的可變參數和關鍵字參數的可變參數。

2.3.1 位置參數的可變參數

  在形參前使用*標識該形參是可變參數,可以接收多個實參。如下例子:

1 def add(*nums):
2     sum = 0
3     print(type(nums))
4     for x in nums:
5         sum += x
6     print(sum)
7 add(3, 6, 9) # 調用            

  調用add函數時的實參為多個,這時形參中的*num會將多個實參收集為一個tuple。

2.3.2 關鍵字參數的可變參數

  在形參前使用**符號,可以接收多個關鍵字參數。如下示例:

1 def showconfig(**kwargs):
2     for k,v in kwargs.items():
3         print('{} = {}'.format(k, v))
4 showconfig(host='127.0.0.1',port='8080',username='viktor',password='123456')    

  調用showconfig時使用了關鍵字參數,這時函數中的形參**kwargs會將多個關鍵字參數收集為一個字典(dict)。

2.3.4 可變參數總結

  可變參數可以接收任意個參數,其中位置可變參數將收集的參數形成一個元組,關鍵字參數將收集的參數形成一個字典。當然這些參數都可以在函數定義時混合使用,混合使用參數的時候要註意:可變參數要放到參數列表的最後,位置參數放到參數列表的前面,位置可變參數需要放在關鍵字可變參數之前。如下例子:

 1 def fn(x, y, *args, **kwargs):
 2     print(x)
 3     print(y)
 4     print(args)
 5     print(kwargs)
 6 fn(3,5,7,9,10,a=1,b='python')
 7 fn(3,5)
 8 fn(3,5,7)
 9 fn(3,5,a=1,b='python')
10 fn(7,9,y=5,x=3,a=1,b='python') # 錯誤,7和9分別賦給了x,y,又y=5、x=3,重覆了
11 
12 def fn(*args, x, y, **kwargs):  
13     print(x)
14     print(y)
15     print(args)
16     print(kwargs)
17 fn(3,5)   # 執行出現TypeError
18 fn(3,5,7)  # 執行出現TypeError
19 fn(3,5,a=1,b='python')  # 執行出現TypeError
20 fn(7,9,y=5,x=3,a=1,b='python')
View Code

2.4 keyword-only參數

  keyword-only參數是在Python3中加入的。如果在一個星號參數後,或者一個位置可變參數後,出現普通參數,那麼這個參數就為keyword-only參數。示例如下:

1 def fn(*args, x):
2     print(x)
3     print(args)
4 fn(3,5)
5 fn(3,5,7)
6 fn(3,5,x=7)

  可以看出,在函數調用的過程中,args參數將所有的位置參數截獲,x不使用關鍵字參數就不可能接收到實參的傳遞。那麼,關鍵字的可變參數後是否能跟一個普通的位置參數呢?看如下示例:

1 def(**kwargs, x):
2     print(x)
3     print(kwargs)

  運行後直接報語法錯誤,可以理解為kwargs會截獲所有的關鍵字參數,就算在調用函數時的形參中有類似x = 5形式的傳參,形參x也不能得到該值,而這個位置參數上的值又必須在函數調用時提供,所以就會出現語法錯誤。

  keyword-only參數另一種形式:*號之後跟普通形參,示例如下:

1 def fn(*, x,y):
2     print(x,y)
3 fn(x=5,y=6)

  *號之後,普通參數都會變成必須給出的keyword-only參數。

2.5 可變參數和參數預設值

  函數的定義中,將參數的預設值和可變參數混合在一起使用,那麼函數的調用過程中是如何傳參呢?看下麵幾個示例:

1 def fn(y, *args, x=5):
2     print('x={}, y={}'.format(x, y))
3     print(args)
4 fn()  # 出錯,因為fn函數中的位置參數y在調用fn時必須得給出;
5 fn(5)  # 可以執行,此時形參y接收5,args參數為空,x參數使用預設值;
6 fn(x=6)  # 錯誤,形參y必須接收一個實參;
7 fn(1,2,3,x=10)  # 可以執行,此時y=1,args=(2, 3),x=10;
8 fn(y=17,2,3,x=10)  # 出現語法錯誤,調用函數時,必須得將關鍵字參數放到參數列表的後面
9 fn(1,2,y=3,x=10)  # 出錯,形參y已經接收到實參1,之後又利用關鍵字參數給y進行傳參,肯定會出錯
1 def fn(x=5, **kwargs):
2     print('x={}'.format(x))
3     print(kwargs)
4 fn()  # 可以執行,x使用預設值5,kwargs為空
5 fn(5) # 可以執行,x=5,kwargs為空
6 fn(x=6)  # 可以執行,此時x=6,kwargs為空
7 fn(y=3,x=10)  # x=10,字典中存入'y':3
8 fn(3,y=10)  # x=3,字典中存入'y':10

2.6 函數參數定義規則

  參數列表中的參數的一般順序是:普通參數、預設參數、可變位置參數、keyword-only參數(可帶預設值)、可變關鍵字參數。如下:

1 def fn(x, y, z=3, *arg, m=4, n, **kwargs):
2     print(x,y,z,m,n)
3     print(args)
4     print(kwargs)

 3 函數參數解構

  給函數提供實參時,可以在集合類型的實參前使用*或者**,把集合類型的結構解開,提取出所有元素作為函數的實參。如下示例:

 1 def add(x, y):
 2     return x+y
 3  
 4 add(4, 5)
 5 add((4,5))
 6 t = (4, 5)
 7 add(t[0], t[1])
 8 add(*t) 
 9 add(*(4,5)) 
10 add(*[4,5]) 
11 add(*{4,6})
12 add(*range(1,3))
13 
14 d = {'x': 5, 'y': 6}
15 add(**d)
16 add(**{'a': 5, 'b': 6}) 
17 add(*{'a': 5, 'b': 6})
18 
19 def add(*iterable):
20     result = 0
21     for x in iterable:
22         result += x
23     return result
24 add(1,2,3)
25 add(*[1,2,3])
26 add(*range(10))        
View Code

  參數解構時,非字典類型的實參使用*解構成位置參數;字典類型使用**解構成關鍵字參數。註意:提取出來的元素數目要和參數的要求匹配,也要和參數的類型匹配。

  


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

-Advertisement-
Play Games
更多相關文章
  • URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL與要為該URL調用的視圖函數之間的映射表;你就是以這種方式告訴Django,對於客戶端發來的某個URL調用哪一段邏輯代碼對應執行。 簡單的路由配置 註意: 1、使用URL,必須先將應用程式中的視圖函數導入到urls.py ...
  • Thymeleaf表達式語法之常量分為字元串常量、數字常量、布爾值常量、空值常量; 運算符分為算術運算符、關係運算符、條件運算符、無操作符。 ...
  • 只要你在 resources 目錄下放置名為 banner.txt、banner.gif 、banner.jpg 或 banner.png 的文件,Spring Boot 會自動載入,將其作為啟動時列印的 logo。 ...
  • Spring Boot 二十個註解 占據無力擁有的東西是一種悲哀。 Cold on the outside passionate on the insede. 背景:Spring Boot 註解的強大毋庸置疑,使用其註解可以大量減少XML 等複雜的配置文件,令Java 代碼更純,開發更簡單高效,記下 ...
  • 摘要 Guava Cache是Google開源的Java工具集庫Guava里的一款緩存工具,一直覺得使用起來比較簡單,沒想到這次居然還踩了一個坑 背景 功能需求抽象出來很簡單,就是將資料庫的查詢 的結果緩存起來。但同時還有批量請求,為了提高效率,肯定要批量查詢資料庫, 對於的guava cache ...
  • Python多任務之進程,內容包括 Process多進程,使用進程池完成多任務;其中 Process多進程 包括 進程的概念,使用Process完成多任務,進程和線程對比,通過隊列完成進程間通信,進程的狀態,獲取進程id;使用進程池完成多任務 包括 進程池的概念和語法,進程池拷貝文件夾等內容 ...
  • 需求點 在很多場景中信息是不能輕易被修改的,修改時要麼需要具備許可權,要麼需要審批,但是無論是哪種方式,修改前後的數據都是需要留有“案底”的,也就是說關鍵的信息被修改後是有修改記錄的,一般修改記錄會記錄修改人、修改日期和修改的數據欄位。 比如,修改一個人的姓名從“張三”變為了“李四”,那麼在進行記錄的 ...
  • 為什麼使用Lombok? 當我們創建一個javaBean的時候,往往會做一些重覆性的事情,比如:getter和setter方法,toString方法,構造函數等等,如果只是有一兩個類的話我們大可使用IDE來自動生成,但是如果類有很多的話我們不可能來手動生成,這樣很浪費時間,並且會造成很多冗餘的代碼。 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...