Python中的函數(shù)---函數(shù)的定義和參數(shù)

本文是廖雪峰教程的筆記。

函數(shù)的定義

  • 定義函數(shù)時(shí)衙四,需要確定函數(shù)名和參數(shù)個(gè)數(shù) def fun(x1,x2,x3):剔氏;

  • 如果有必要,可以先對參數(shù)的數(shù)據(jù)類型做檢查积仗;

  • 函數(shù)體內(nèi)部可以用return隨時(shí)返回函數(shù)結(jié)果;

  • 函數(shù)執(zhí)行完畢也沒有return語句時(shí)蜕猫,自動(dòng)return None寂曹。

  • 函數(shù)可以同時(shí)返回多個(gè)值,但其實(shí)就是一個(gè)tuple回右。


函數(shù)的參數(shù)

Python的函數(shù)具有非常靈活的參數(shù)形態(tài)隆圆,既可以實(shí)現(xiàn)簡單的調(diào)用,又可以傳入非常復(fù)雜的參數(shù)翔烁。

默認(rèn)參數(shù)

默認(rèn)參數(shù)可以簡化函數(shù)的調(diào)用渺氧。設(shè)置默認(rèn)參數(shù)時(shí),有幾點(diǎn)要注意:

  1. 必選參數(shù)在前蹬屹,默認(rèn)參數(shù)在后侣背,否則Python的解釋器會(huì)報(bào)錯(cuò);
  2. 默認(rèn)參數(shù)降低了函數(shù)調(diào)用的難度慨默,而一旦需要更復(fù)雜的調(diào)用時(shí)贩耐,又可以傳遞更多的參數(shù)來實(shí)現(xiàn)。
  3. 默認(rèn)參數(shù)一定要用不可變對象厦取,如果是可變對象潮太,程序運(yùn)行時(shí)會(huì)有邏輯錯(cuò)誤!例如:
def add_end(L=[]):
    L.append('END')
    return L

默認(rèn)參數(shù)L是一個(gè)空list虾攻,是一個(gè)可變對象铡买。當(dāng)使用默認(rèn)參數(shù)調(diào)用時(shí),會(huì)發(fā)現(xiàn)

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

這顯然是有問題的台谢,要修改上面的例子寻狂,我們可以用None這個(gè)不變對象來實(shí)現(xiàn):

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

此時(shí)調(diào)用結(jié)果為

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

所以,我們在編寫程序時(shí)朋沮,如果可以設(shè)計(jì)一個(gè)不變對象,那就盡量設(shè)計(jì)成不變對象。

可變參數(shù)

  • 可變參數(shù)就是傳入的參數(shù)個(gè)數(shù)是可變的樊拓,可以是1個(gè)纠亚、2個(gè)到任意個(gè),還可以是0個(gè)筋夏。
  • 定義可變參數(shù)和定義一個(gè)list或tuple參數(shù)相比蒂胞,僅僅在參數(shù)前面加了一個(gè)*號。在函數(shù)內(nèi)部条篷,參數(shù)numbers接收到的是一個(gè)tuple骗随,因此,函數(shù)代碼完全不變赴叹。但是鸿染,調(diào)用該函數(shù)時(shí),可以傳入任意個(gè)參數(shù)乞巧,包括0個(gè)參數(shù):
  • 可變參數(shù)允許你傳入0個(gè)或任意個(gè)參數(shù)涨椒,這些可變參數(shù)在函數(shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)tuple。 例如:
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

運(yùn)行結(jié)果

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

如果已經(jīng)有一個(gè)list或者tuple绽媒,可以這么調(diào)用可變參數(shù):

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

*nums表示把nums這個(gè)list的所有元素作為可變參數(shù)傳進(jìn)去蚕冬。這種寫法相當(dāng)有用,而且很常見是辕。

關(guān)鍵字參數(shù)

  • 關(guān)鍵字參數(shù)和可變參數(shù)類似囤热,關(guān)鍵字參數(shù)允許你傳入0個(gè)或任意個(gè)含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)dict获三,而可變參數(shù)中自動(dòng)組成一個(gè)tuple旁蔼。
  • 關(guān)鍵字參數(shù)可以擴(kuò)展函數(shù)的功能。試想你正在做一個(gè)用戶注冊的功能石窑,除了用戶名和年齡是必填項(xiàng)外牌芋,其他都是可選項(xiàng),利用關(guān)鍵字參數(shù)來定義這個(gè)函數(shù)就能滿足注冊的需求松逊。例如:
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

運(yùn)行

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

**extra表示把extra這個(gè)dict的所有key-value用關(guān)鍵字參數(shù)傳入到函數(shù)的**kw參數(shù)躺屁,kw將獲得一個(gè)dict,注意kw獲得的dictextra的一份拷貝经宏,對kw的改動(dòng)不會(huì)影響到函數(shù)外的extra犀暑。

命名關(guān)鍵字參數(shù)

  • 如果要限制關(guān)鍵字參數(shù)的名字,就可以用命名關(guān)鍵字參數(shù)烁兰,例如:
def person(name, age, *, city, job):
    print(name, age, city, job)

和位置參數(shù)不同耐亏,命名關(guān)鍵字參數(shù)必須傳入?yún)?shù)名。調(diào)用方式如下:

>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

和關(guān)鍵字參數(shù)**kw不同沪斟,命名關(guān)鍵字參數(shù)需要一個(gè)特殊分隔符*广辰,*后面的參數(shù)被視為命名關(guān)鍵字參數(shù),前面的參數(shù)是普通的位置參數(shù)。上面定義的函數(shù)就只接收city和job作為關(guān)鍵字參數(shù)择吊。

  • 如果函數(shù)定義中已經(jīng)有了一個(gè)可變參數(shù)李根,后面跟著的命名關(guān)鍵字參數(shù)就不再需要一個(gè)特殊分隔符*了:
def person(name, age, *args, city, job):
    print(name, age, args, city, job)

上面的函數(shù)定義中,*args代表可變參數(shù)几睛,跟著的city房轿,job是命名關(guān)鍵字參數(shù)。

  • 命名關(guān)鍵字參數(shù)可以有缺省值所森,從而簡化調(diào)用:
def person(name, age, *, city='Beijing', job):
    print(name, age, city, job)

調(diào)用結(jié)果:

>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer

參數(shù)組合

  • 在Python中定義函數(shù)囱持,可以用必選參數(shù)、默認(rèn)參數(shù)焕济、可變參數(shù)纷妆、關(guān)鍵字參數(shù)和命名關(guān)鍵字參數(shù),這5種參數(shù)都可以組合使用吼蚁。但是請注意凭需,參數(shù)定義的順序必須是:必選參數(shù)、默認(rèn)參數(shù)肝匆、可變參數(shù)粒蜈、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

在f1中旗国,a枯怖,b是必選參數(shù)(位置參數(shù)),c=0是默認(rèn)參數(shù)能曾,*args是可變參數(shù)度硝,**kw是關(guān)鍵字參數(shù);
在f2中,d是命名關(guān)鍵字參數(shù)寿冕。

  • 對于任意函數(shù)蕊程,都可以通過類似func(*args, **kw)的形式調(diào)用它,無論它的參數(shù)是如何定義的驼唱。例如:
>>> args = (1, 2, 3, 4) #這是一個(gè)tuple
>>> kw = {'d': 99, 'x': '#'} #這是一個(gè)dict
>>> f1(*args, **kw)  #*args可以將args中的元素作為可選參數(shù)傳入藻茂,**kw可以將kw中的元素作為key-value形式傳入。
a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}

上面的函數(shù)中玫恳,f1(*args, **kw)可以看作是f1(args[1],args[2],args[3],args[4], d=kw['d'],x=kw['x'])
f2(*args, **kw)可以看作f2(args[1],args[2],args[3], d=kw['d'],x=kw['x'])辨赐。


注意事項(xiàng)總結(jié)

要注意定義可變參數(shù)和關(guān)鍵字參數(shù)的語法:

  • *args是可變參數(shù),args接收的是一個(gè)tuple京办;
  • **kw是關(guān)鍵字參數(shù)掀序,kw接收的是一個(gè)dict。

以及調(diào)用函數(shù)時(shí)如何傳入可變參數(shù)和關(guān)鍵字參數(shù)的語法:

  1. 可變參數(shù)既可以直接傳入:func(1, 2, 3)惭婿,又可以先組裝list或tuple不恭,再通過*args傳入:func(*(1, 2, 3))叶雹;
  2. 關(guān)鍵字參數(shù)既可以直接傳入:func(a=1, b=2),又可以先組裝dict县袱,再通過**kw傳入:func(**{'a': 1, 'b': 2})浑娜。
  1. 使用*args**kw是Python的習(xí)慣寫法佑力,當(dāng)然也可以用其他參數(shù)名式散,但最好使用習(xí)慣用法。
  2. 命名的關(guān)鍵字參數(shù)是為了限制調(diào)用者可以傳入的參數(shù)名打颤,同時(shí)可以提供默認(rèn)值暴拄。
  3. 定義命名的關(guān)鍵字參數(shù)在沒有可變參數(shù)的情況下不要忘了寫分隔符*,否則定義的將是位置參數(shù)编饺。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乖篷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子透且,更是在濱河造成了極大的恐慌撕蔼,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秽誊,死亡現(xiàn)場離奇詭異鲸沮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锅论,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門讼溺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人最易,你說我怎么就攤上這事怒坯。” “怎么了藻懒?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵剔猿,是天一觀的道長。 經(jīng)常有香客問我嬉荆,道長归敬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任员寇,我火速辦了婚禮弄慰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蝶锋。我一直安慰自己陆爽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布扳缕。 她就那樣靜靜地躺著慌闭,像睡著了一般别威。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上驴剔,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天省古,我揣著相機(jī)與錄音,去河邊找鬼丧失。 笑死豺妓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的布讹。 我是一名探鬼主播琳拭,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼描验!你這毒婦竟也來了白嘁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤膘流,失蹤者是張志新(化名)和其女友劉穎絮缅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呼股,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耕魄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卖怜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屎开。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖马靠,靈堂內(nèi)的尸體忽然破棺而出奄抽,到底是詐尸還是另有隱情,我是刑警寧澤甩鳄,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布逞度,位于F島的核電站,受9級特大地震影響妙啃,放射性物質(zhì)發(fā)生泄漏档泽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一揖赴、第九天 我趴在偏房一處隱蔽的房頂上張望馆匿。 院中可真熱鬧,春花似錦燥滑、人聲如沸渐北。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赃蛛。三九已至恃锉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呕臂,已是汗流浹背破托。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留歧蒋,地道東北人土砂。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像疏尿,于是被迫代替她去往敵國和親瘟芝。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第5章 函數(shù)和函數(shù)式編程 5.1 引言函數(shù)是組織好的褥琐,可重復(fù)使用的,用來實(shí)現(xiàn)單一晤郑,或相關(guān)聯(lián)功能的代碼段敌呈。函數(shù)...
    VIVAFT閱讀 959評論 0 5
  • 一、位置參數(shù) 例如我們寫一個(gè)計(jì)算x2的函數(shù): 對于power(x)函數(shù)造寝,參數(shù)x就是一個(gè)位置參數(shù)磕洪。當(dāng)我們調(diào)用powe...
    劉光軍_MVP閱讀 273評論 0 1
  • 1.函數(shù)參數(shù) 1.1 位置參數(shù) 我們先寫一個(gè)計(jì)算x2的函數(shù): 對于power(x)函數(shù),參數(shù)x就是一個(gè)位置參數(shù)诫龙。當(dāng)...
    時(shí)間之友閱讀 372評論 0 2
  • Python的函數(shù)定義非常簡單析显,但靈活度卻非常大。除了正常定義的必選參數(shù)外签赃,還可以使用默認(rèn)參數(shù)谷异、可變參數(shù)和關(guān)鍵字參...
    luckybabying閱讀 234評論 0 0
  • 定義函數(shù)的時(shí)候,我們把參數(shù)的名字和位置確定下來锦聊,函數(shù)的接口定義就完成了歹嘹。對于函數(shù)的調(diào)用者來說,只需要知道如何傳遞正...
    Aedda閱讀 283評論 0 1