python學習筆記 可變參數關鍵字參數**kw相關學習

在Python中可以定義可變參數,顧名思義,可變參數就是傳入參數是可變的。可以是任意個,以一個簡單的數學編程為例,計算

sum = a * a + b * b + .....z * z

函數定義可以如下:

def getsum(num) :sum = 0for n in num :sum = sum + n * nreturn sum

但是調用的時候必須定義一個元組或者列表。比如getsum([1,2,3])

如果利用可變參數調用函數的方式可以變成這樣的話就方便的多比如getsum(1,2,3)

可以這么修改

def getsum(*num) :sum = 0for n in num :sum = sum + n * nreturn sum

如果已經有一個list或者tuple,要調用一個可變參數怎么辦?可以這樣做:

>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
14

這種寫法當然是可行的,問題是太繁瑣,所以Python允許你在list或tuple前面加一個*號,把list或tuple的元素變成可變參數傳進去:

>>> nums = [1, 2, 3]
>>> calc(*nums)
14

函數的參數

閱讀: 171893

定義函數的時候,我們把參數的名字和位置確定下來,函數的接口定義就完成了。對于函數的調用者來說,只需要知道如何傳遞正確的參數,以及函數將返回什么樣的值就夠了,函數內部的復雜邏輯被封裝起來,調用者無需了解。

Python的函數定義非常簡單,但靈活度卻非常大。除了正常定義的必選參數外,還可以使用默認參數、可變參數和關鍵字參數,使得函數定義出來的接口,不但能處理復雜的參數,還可以簡化調用者的代碼。

位置參數

我們先寫一個計算x2的函數:

def power(x):return x * x 

對于power(x)函數,參數x就是一個位置參數。

當我們調用power函數時,必須傳入有且僅有的一個參數x

>>> power(5)
25
>>> power(15) 225 

現在,如果我們要計算x3怎么辦?可以再定義一個power3函數,但是如果要計算x4、x5……怎么辦?我們不可能定義無限多個函數。

你也許想到了,可以把power(x)修改為power(x, n),用來計算xn,說干就干:

def power(x, n):s = 1 while n > 0: n = n - 1 s = s * x return s 

對于這個修改后的power(x, n)函數,可以計算任意n次方:

>>> power(5, 2)
25
>>> power(5, 3) 125 

修改后的power(x, n)函數有兩個參數:xn,這兩個參數都是位置參數,調用函數時,傳入的兩個值按照位置順序依次賦給參數xn

默認參數

新的power(x, n)函數定義沒有問題,但是,舊的調用代碼失敗了,原因是我們增加了一個參數,導致舊的代碼因為缺少一個參數而無法正常調用:

>>> power(5)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'n'

Python的錯誤信息很明確:調用函數power()缺少了一個位置參數n

這個時候,默認參數就排上用場了。由于我們經常計算x2,所以,完全可以把第二個參數n的默認值設定為2:

def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s 

這樣,當我們調用power(5)時,相當于調用power(5, 2)

>>> power(5)
25
>>> power(5, 2) 25 

而對于n > 2的其他情況,就必須明確地傳入n,比如power(5, 3)

從上面的例子可以看出,默認參數可以簡化函數的調用。設置默認參數時,有幾點要注意:

一是必選參數在前,默認參數在后,否則Python的解釋器會報錯(思考一下為什么默認參數不能放在必選參數前面);

二是如何設置默認參數。

當函數有多個參數時,把變化大的參數放前面,變化小的參數放后面。變化小的參數就可以作為默認參數。

使用默認參數有什么好處?最大的好處是能降低調用函數的難度。

舉個例子,我們寫個一年級小學生注冊的函數,需要傳入namegender兩個參數:

def enroll(name, gender):print('name:', name) print('gender:', gender) 

這樣,調用enroll()函數只需要傳入兩個參數:

>>> enroll('Sarah', 'F')
name: Sarah
gender: F

如果要繼續傳入年齡、城市等信息怎么辦?這樣會使得調用函數的復雜度大大增加。

我們可以把年齡和城市設為默認參數:

def enroll(name, gender, age=6, city='Beijing'): print('name:', name) print('gender:', gender) print('age:', age) print('city:', city) 

這樣,大多數學生注冊時不需要提供年齡和城市,只提供必須的兩個參數:

>>> enroll('Sarah', 'F')
name: Sarah
gender: F
age: 6
city: Beijing

只有與默認參數不符的學生才需要提供額外的信息:

enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')

可見,默認參數降低了函數調用的難度,而一旦需要更復雜的調用時,又可以傳遞更多的參數來實現。無論是簡單調用還是復雜調用,函數只需要定義一個。

有多個默認參數時,調用的時候,既可以按順序提供默認參數,比如調用enroll('Bob', 'M', 7),意思是,除了namegender這兩個參數外,最后1個參數應用在參數age上,city參數由于沒有提供,仍然使用默認值。

也可以不按順序提供部分默認參數。當不按順序提供部分默認參數時,需要把參數名寫上。比如調用enroll('Adam', 'M', city='Tianjin'),意思是,city參數用傳進去的值,其他默認參數繼續使用默認值。

默認參數很有用,但使用不當,也會掉坑里。默認參數有個最大的坑,演示如下:

先定義一個函數,傳入一個list,添加一個END再返回:

def add_end(L=[]):L.append('END') return L 

當你正常調用時,結果似乎不錯:

>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z']) ['x', 'y', 'z', 'END'] 

當你使用默認參數調用時,一開始結果也是對的:

>>> add_end()
['END']

但是,再次調用add_end()時,結果就不對了:

>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

很多初學者很疑惑,默認參數是[],但是函數似乎每次都“記住了”上次添加了'END'后的list。

原因解釋如下:

Python函數在定義的時候,默認參數L的值就被計算出來了,即[],因為默認參數L也是一個變量,它指向對象[],每次調用該函數,如果改變了L的內容,則下次調用時,默認參數的內容就變了,不再是函數定義時的[]了。

所以,定義默認參數要牢記一點:默認參數必須指向不變對象!

要修改上面的例子,我們可以用None這個不變對象來實現:

def add_end(L=None):if L is None: L = [] L.append('END') return L 

現在,無論調用多少次,都不會有問題:

>>> add_end()
['END']
>>> add_end()
['END']

為什么要設計strNone這樣的不變對象呢?因為不變對象一旦創建,對象內部的數據就不能修改,這樣就減少了由于修改數據導致的錯誤。此外,由于對象不變,多任務環境下同時讀取對象不需要加鎖,同時讀一點問題都沒有。我們在編寫程序時,如果可以設計一個不變對象,那就盡量設計成不變對象。

可變參數

在Python函數中,還可以定義可變參數。顧名思義,可變參數就是傳入的參數個數是可變的,可以是1個、2個到任意個,還可以是0個。

我們以數學題為例子,給定一組數字a,b,c……,請計算a2 + b2 + c2 + ……。

要定義出這個函數,我們必須確定輸入的參數。由于參數個數不確定,我們首先想到可以把a,b,c……作為一個list或tuple傳進來,這樣,函數可以定義如下:

def calc(numbers):sum = 0 for n in numbers: sum = sum + n * n return sum 

但是調用的時候,需要先組裝出一個list或tuple:

>>> calc([1, 2, 3])
14 >>> calc((1, 3, 5, 7)) 84 

如果利用可變參數,調用函數的方式可以簡化成這樣:

>>> calc(1, 2, 3)
14 >>> calc(1, 3, 5, 7) 84 

所以,我們把函數的參數改為可變參數:

def calc(*numbers):sum = 0 for n in numbers: sum = sum + n * n return sum 

定義可變參數和定義一個list或tuple參數相比,僅僅在參數前面加了一個*號。在函數內部,參數numbers接收到的是一個tuple,因此,函數代碼完全不變。但是,調用該函數時,可以傳入任意個參數,包括0個參數:

>>> calc(1, 2)
5
>>> calc() 0 

如果已經有一個list或者tuple,要調用一個可變參數怎么辦?可以這樣做:

>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2]) 14 

這種寫法當然是可行的,問題是太繁瑣,所以Python允許你在list或tuple前面加一個*號,把list或tuple的元素變成可變參數傳進去:

>>> nums = [1, 2, 3]
>>> calc(*nums) 14 

*nums表示把nums這個list的所有元素作為可變參數傳進去。這種寫法相當有用,而且很常見。

關鍵字參數

可變參數允許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝為一個tuple。而關鍵字參數允許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝為一個dict。請看示例:

def person(name, age, **kw):print('name:', name, 'age:', age, 'other:', kw)

?

函數person除了必選參數name和age外,還接受關鍵字參數kw。調用該函數時可以只傳入必選參數

>>> person('Michael', 30)
name: Michael age: 30 other: {}

?

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

關鍵字參數有什么用?它可以擴展函數的功能,比如在person函數里,我們保證能接收到必選參數,但是如果調用者愿意提供更多的參數,我們也能收到,

試想你正在做一個用戶注冊的功能,除了用戶名和年齡是必須的以外,其他的都是可選項目,利用關鍵字參數就可以完成這個要求。

和可變參數類似可以先組裝出一個字典dict,然后把dict傳進去。

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'

上面復雜的調用可以用簡化的寫法

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

**extra表示把extra這個dict的所有key-value用關鍵字參數傳入到函數的**kw參數,**kw將獲得一個dict,注意kw獲得的dict是extra的一個拷貝,對kw的改動不會影響到函數外的extra

?

命名關鍵字參數:

對于關鍵字參數,函數的調用者可以傳入任意不受限制的關鍵字參數。至于到底傳入了哪些,需要在函數內部對kw進行檢查

仍然以上述函數為例,我們需要檢查是否有city和job參數

def person(name, age, **kw):if 'city' in kw:# 有city參數passif 'job' in kw:# 有job參數passprint('name:', name, 'age:', age, 'other:', kw)

但是調用者仍可以傳入不受限制的關鍵字參數:

>>> person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)

?

如果要限制關鍵字參數的名字,就可以用命名關鍵字參數,例如,只接收cityjob作為關鍵字參數。這種方式定義的函數如下:

def person(name, age, *, city, job):print(name, age, city, job)

和關鍵字參數**kw不同,命名關鍵字參數需要一個特殊分隔符**后面的參數被視為命名關鍵字參數。

?

?

?

轉載于:https://www.cnblogs.com/Commence/p/5578215.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372818.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372818.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372818.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Struts2之環境配置

在學習struts2之前&#xff0c;首先我們要明白使用struts2的目的是什么&#xff1f;它能給我們帶來什么樣的好處&#xff1f; 設計目標 Struts設計的第一目標就是使MVC模式應用于web程序設計。在這兒MVC模式的好處就不在提了。 技術優勢 Struts2有兩方面的技術優勢&#xff0c;…

mysql數據庫備份shell_mysql數據庫備份shell腳本分享

#!/bin/bash#2020年04月27日15:56:21#auto backup mysql db#by author www.cnbugs.com########################SQL_DB"$*"SQL_USR"backup"SQL_PWD"123456"SQL_CMD"/usr/bin/mysqldump"SQL_DIR"/data/backup/date %F"if [ $…

懶惰的JSF Primefaces數據表分頁–第1部分

今天&#xff0c;我們將使用帶有視圖范圍的托管bean的惰性列表進行JSF數據表分頁。 這些單詞/表達式是什么意思&#xff1f; 如今&#xff0c;有幾個JSF框架為數據表提供現成的分頁&#xff0c;列排序器和其他功能。 今天&#xff0c;我們將使用Primefaces數據表。 通常&#…

java 動態增加定時任務

直接上代碼 import org.apache.tools.ant.util.DateUtils; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory;import java.util.Calendar; import…

基于JavaFX的SimpleDateFormat演示程序

對于使用Java Date進行格式化的新手甚至對于使用Java Date進行格式化的有經驗的Java開發人員而言&#xff0c;可能有些棘手的事情是使用SimpleDateFormat規范日期/時間格式。 SimpleDateFormat的基于類級別的Javadoc的文檔非常詳盡&#xff0c;涵蓋了表示日期/時間的各個組成部…

mysql中預定義常量_PHP預定義常量

這些常量在 PHP 的內核中定義。它包含 PHP、Zend 引擎和 SAPI 模塊。PHP_VERSION (string)PHP_OS (string)PHP_EOL (string)自 PHP 4.3.10 和 PHP 5.0.2 起可用PHP_INT_MAX (integer)自 PHP 4.4.0 和 PHP 5.0.5 起可用PHP_INT_SIZE (integer)自 PHP 4.4.0 和 PHP 5.0.5 起可用D…

iOS與H5交互

前提&#xff1a;在iOS控制器中加載UIWebView&#xff0c;設置代理&#xff0c;遵守UIWebViewDelegate協議。 一、iOS調用JS方法 通過iOS調用JS代碼實現起來比較方便直接調用UIWebView的方法- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script…

cocos2dx 3.x 蒙板 遮罩 點擊圓功能

//注冊觸摸EventListenerTouchOneByOne *listener EventListenerTouchOneByOne::create();listener->onTouchBegan CC_CALLBACK_2(HelloWorld::onTouchBegan,this);listener->onTouchMoved CC_CALLBACK_2(HelloWorld::onTouchMoved,this);listener->onTouchEnded …

markdownTest

MARKDOWNTEST 11111111111111有一種神奇的語言&#xff0c;它比html還簡單&#xff0c;它巧妙地將內容與格式整合在一起——它就是Markdown有一種神奇的語言&#xff0c;它比html還簡單&#xff0c;它巧妙地將內容與格式整合在一起——它就是Markdown 111111111111111222222222…

python模擬密碼有效性檢測功能_檢查密碼有效性(Django/Python)

我有一個非常小的Django應用程序&#xff0c;主要是為了學習。我使用的是Django提供的內置用戶模型。為了學習這個功能&#xff0c;我創建了一些頁面&#xff0c;這些頁面允許我創建和編輯用戶&#xff0c;而不必進入管理面板。在register頁面允許我非常容易地檢查密碼和電子郵…

教程:Hibernate,JPA –第1部分

這是關于使用Hibernate和JPA的教程的第一部分。 這部分是對JPA和Hibernate的介紹。 第二部分將研究使用Spring ORM組合Spring MVC應用程序以減少創建CRUD應用程序所需的代碼量。 為此&#xff0c;您需要熟悉Maven&#xff0c;JUnit&#xff0c;SQL和關系數據庫。 依存關系 首…

TCP、UDP套接字的數據傳輸

tcp發送數據&#xff1a; 1 #include <sys/types.h> 2 #include <socket.h> 3 ssize_t send(int sockfd,const void *msg,size_t len,int flags); 函數send只能對面向連接的套接字使用。參數sockfd為已經建立好連接的套接字描述符。參數msg指向待發送數據的緩沖區&…

Windows下用PIP安裝scipy出現no lapack/blas resources found

Windows下升級了pandas&#xff0c;但是發現scipy包隨后引用出錯&#xff0c;后來確認需重新安裝scipy&#xff0c; 在用PIP安裝scipy出現no lapack/blas resources found的錯誤&#xff0c;具體原因可參考 這里。 后來找到一種簡便的解決方案&#xff0c;只要在網站 Unofficia…

Aleri –復雜事件處理

Sybase的Aleri流媒體平臺是CEP市場中最受歡迎的產品之一。 它在Sybase的交易平臺RAP版本中使用&#xff0c;該版本在資本市場中廣泛用于管理投資組合中的頭寸。 今天&#xff0c;在這個由多個部分組成的系列文章的第一個部分中&#xff0c;我希望提供Aleri平臺的概述&#xff0…

python版本回退_Python爬蟲之BeautifulSoup解析之路

上一篇分享了正則表達式的使用&#xff0c;相信大家對正則也已經有了一定的了解。它可以針對任意字符串做任何的匹配并提取所需信息。但是我們爬蟲基本上解析的都是html或者xml結構的內容&#xff0c;而非任意字符串。正則表達式雖然很強大靈活&#xff0c;但是對于html這樣結構…

0615 團隊第二階段貢獻

0615 團隊第二階段貢獻 列志華http://www.cnblogs.com/liezhihua/ 26% 組長 黃柏堂 http://www.cnblogs.com/huang123/ 22% 團隊 韓麒麟 http://www.cnblogs.com/hanqilin/ 26% 團隊 王俊杰 http://www.cnblogs.com/wangjunjie123/ 28%團隊posted on 2016…

WebStorm 運行Rect Native 項目

今天教大家如何直接使用WebStorm這個IDE直接完成編碼運行項目工作.這樣就可以不用打開Xcode了. 1.首先點擊WebStorm右上方的下拉箭頭彈出的Edit Configurations.... 2.然后會進入一個配置頁面.點擊左上方的.在彈出的列表中選中npm.如圖. 3.在右邊的配置框中,先選擇Command為hel…

python編程比賽_用Python編程分析4W場球賽后,2018世界杯冠軍竟是…

比賽已經開始&#xff0c;我們不妨用 Python 來對參賽隊伍的實力情況進行分析&#xff0c;并大膽的預測下本屆世界杯的奪冠熱門球隊吧&#xff01;通過數據分析&#xff0c;可以發現很多有趣的結果&#xff0c;比如&#xff1a;找出哪些隊伍是首次進入世界杯的黑馬隊伍找出2018…

GlassFish 3.1.2充滿了MOXy(EclipseLink JAXB)

我非常高興地宣布&#xff0c; EclipseLink JAXB&#xff08;MOXy&#xff09;現在是GlassFish 3.1.2中的JAXB&#xff08; JSR-222 &#xff09;提供程序。 我要感謝EclipseLink和GlassFish提交者為實現這一目標付出的??辛勤工作。 在本文中&#xff0c;我將介紹如何利用MOX…

夢斷代碼閱讀筆記03

讀完《夢斷代碼(Dream In Code)》樣書&#xff0c;我感覺心情有點沉重&#xff0c;Chandler項目的結局&#xff0c;它失敗了&#xff0c;它成了眾多失敗軟件項目中的一個。這個結局讓那個我感受到軟件實在是太難了&#xff0c;我覺得當初選這個專業可能到最后只是一個碼農。但是…