python-函數(shù)的簡(jiǎn)單介紹

1切省、函數(shù)的基本概念

函數(shù): 是一段可以重復(fù)多次調(diào)用的代碼辩块,通過輸入的參數(shù)值蛔六,返回需要的結(jié)果。通俗地說(shuō)庆捺,函數(shù)就是完成特定功能的一個(gè)語(yǔ)句組古今,這組語(yǔ)句可以作為一個(gè)單位使用,并且給它取一個(gè)名字滔以,這樣捉腥,我們就可以通過函數(shù)名在程序的不同地方多次執(zhí)行(這通常叫做函數(shù)調(diào)用),卻不需要在所有地方都重復(fù)編寫這些語(yǔ)句你画。另外抵碟,每次使用函數(shù)時(shí)可以提供不同的參數(shù)作為輸入,以便對(duì)不同的數(shù)據(jù)進(jìn)行處理坏匪;函數(shù)處理后拟逮,還可以將相應(yīng)的結(jié)果反饋給我們。

2适滓、定義函數(shù):

2.1敦迄、函數(shù)定義的語(yǔ)法:

def function_name(argument1[=default_value1], argument2[=default_value2]...):
    ''' docString '''
    pass
    return expression
  • def 關(guān)鍵字:definition 的縮寫,表示后面定義的是一個(gè)函數(shù)或方法。
  • 函數(shù)名:以字母罚屋、數(shù)字或下劃線組成的字符串苦囱,但是不能以數(shù)字開頭。推薦全部使用小寫字母脾猛,單詞之間以下劃線隔開
  • 文檔字符串:是包, 模塊, 類或函數(shù)里的第一個(gè)語(yǔ)句撕彤。 這些字符串可以通過對(duì)象的 __doc__ 成員被自動(dòng)提取, 并且被 pydoc 所用。
  • 函數(shù)的參數(shù):放在一對(duì)圓括號(hào)中猛拴,參數(shù)的個(gè)數(shù)可以有零個(gè)羹铅、一個(gè)或多個(gè),參數(shù)之間用逗號(hào)隔開愉昆。
    • 形參职员、實(shí)參:在定義函數(shù)時(shí),函數(shù)名后面圓括號(hào)中的變量名稱叫做“形式參數(shù)”撼唾,或簡(jiǎn)稱為“形參”廉邑;在調(diào)用函數(shù)時(shí),函數(shù)名后面圓括號(hào)中的變量名稱叫做“實(shí)際參數(shù)”倒谷,或簡(jiǎn)稱為“實(shí)參”。
    • 缺省參數(shù):在定義函數(shù)時(shí)糙箍,我們可以用賦值符號(hào)給某些形參指定默認(rèn)值渤愁,這樣當(dāng)調(diào)用該函數(shù)的時(shí)候,如果調(diào)用方?jīng)]有為該參數(shù)提供值的話深夯,則使用默認(rèn)值抖格;如果調(diào)用該函數(shù)的時(shí)候?yàn)樵搮?shù)提供了值的話,則使用調(diào)用方提供的值 -- 像這樣的參數(shù)我們稱之為缺省參數(shù)咕晋。
  • return 語(yǔ)句:return 語(yǔ)句的作用是結(jié)束函數(shù)調(diào)用雹拄,并將結(jié)果返回給調(diào)用者。不過掌呜,對(duì)于函數(shù)來(lái)說(shuō)滓玖,該語(yǔ)句是可選的,并且可以出現(xiàn)在函數(shù)體的任意位置质蕉;對(duì)于沒有使用 return 語(yǔ)句的函數(shù)势篡,它實(shí)際上也向調(diào)用者返回一個(gè)值,那就是 None模暗。

2.2禁悠、定義一個(gè)空函數(shù):

def function_name(argument1[=default_value1], argument2[=default_value2]...):
    pass

pass 語(yǔ)句什么都不做,只是用來(lái)作為占位符兑宇,比如:現(xiàn)在還沒想好怎么寫函數(shù)的代碼碍侦,就可以先放一個(gè)pass,讓代碼能運(yùn)行起來(lái)。

3瓷产、函數(shù)調(diào)用:

3.1比规、函數(shù)調(diào)用語(yǔ)法:

function_name(argument1, argument2...)

在交互式命令行,比如說(shuō)想要獲得 print 函數(shù)的幫助信息拦英,可以執(zhí)行如下命令

>>> help('print')

3.2蜒什、參數(shù)傳遞的方法

  • 標(biāo)準(zhǔn)調(diào)用:標(biāo)準(zhǔn)調(diào)用方式,傳遞的值按照形參定義的順序相應(yīng)地賦給它們疤估。
  • 關(guān)鍵字調(diào)用:即在調(diào)用函數(shù)時(shí)同時(shí)給出形式參數(shù)和實(shí)際參數(shù)灾常。解釋器能通過給出的關(guān)鍵字來(lái)匹配參數(shù)的值,所以這樣就允許參數(shù)缺失或者不按定義函數(shù)時(shí)的形式參數(shù)的順序提供實(shí)際參數(shù)铃拇。
  • 默認(rèn)值參數(shù):只有在形參表末尾的那些參數(shù)可以有默認(rèn)參數(shù)值钞瀑,也就是說(shuō)你不能在聲明函數(shù)形參的時(shí)候,先聲明有默認(rèn)值的形參而后聲明沒有默認(rèn)值的形參慷荔。這是因?yàn)橘x給形參的值是根據(jù)位置而賦值的雕什。例如,def func(a, b=1) 是有效的显晶,但是 def func(a=1, b) 是無(wú)效的贷岸。

注:

默認(rèn)參數(shù)的值是不可變的對(duì)象,比如 None磷雇、True偿警、False、數(shù)字或字符串

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

def print_info( a , b = [] ):
    print("value: %s, id: %d" %(b, id(b)))
    return b

if __name__ == '__main__':
    result = print_info(1)

    result.append('error')

    print_info(2)

執(zhí)行結(jié)果:

value: [], id: 42733832
value: ['error'], id: 42733832

3.2唯笙、參數(shù)檢查:

  • 個(gè)數(shù)檢查:調(diào)用函數(shù)時(shí)螟蒸,如果參數(shù)個(gè)數(shù)不對(duì),Python 解釋器會(huì)自動(dòng)檢查出來(lái)崩掘,并拋出 TypeError

  • 類型檢查:內(nèi)置函數(shù) isinstance 可以用來(lái)判斷對(duì)象的類型七嫌,基本語(yǔ)法如下:

isinstance(object, class-or-type-or-tuple) -> bool

第二個(gè)參數(shù)可以是一個(gè)類型名或一個(gè)元組,如果是元組的話苞慢,對(duì)象類型與元組中類型名之一相同即返回True诵原。

判斷一個(gè)對(duì)象是否是字符串

>>> s = 'abc'
>>> isinstance(s,basestring)
True
 
>>> s = 3
>>> isinstance(s,basestring)
False

檢查到錯(cuò)誤之后,我們可以通過 raise 自己觸發(fā)一個(gè)異常

3.4枉疼、變量的作用域

在 Python 中的任何變量都有其特定的作用域皮假,比如在一個(gè)函數(shù)中定義的變量一般只能在該函數(shù)內(nèi)部使用,這些只能在程序的特定部分使用的變量我們稱之為局部變量骂维;比如在一個(gè)文件頂部定義的變量可以供該文件中的任何函數(shù)調(diào)用惹资,這些可以為整個(gè)程序所使用的變量稱為全局變量。

上面是從空間的角度來(lái)考察變量的局部性和全局性航闺,如果從時(shí)間的角度來(lái)看褪测,不妨簡(jiǎn)單地認(rèn)為在程序運(yùn)行的整個(gè)過程中猴誊,全局變量一直占據(jù)著內(nèi)存,并且它的值可以供所有函數(shù)訪問侮措;而局部變量則是只有在其所在函數(shù)被調(diào)用時(shí)才給它分配內(nèi)存懈叹,當(dāng)函數(shù)返回時(shí),其所占內(nèi)存就會(huì)被釋放分扎,所以它只能供其所在的函數(shù)所訪問——換句話說(shuō)澄成,當(dāng)某個(gè)函數(shù)退出時(shí),其局部變量原先所占的內(nèi)存將被分配給其它函數(shù)的局部變量畏吓。打個(gè)不太貼切的比方墨状,全局變量就好比您自己買的房子,通常一家人要在那里住上好幾十年菲饼,如果我要找您要債肾砂,我會(huì)老往您家里跑;而局部變量好像旅館宏悦,今天您租住這件房間镐确,我可以到這個(gè)房間來(lái)找您,但是到明天再來(lái)這間房間的話饼煞,找到的可能就是別人了源葫。

在同一個(gè)源文件中,全局變量和局部變量同名時(shí)派哲,在局部變量的作用范圍內(nèi)臼氨,全局變量不起作用。像下面這個(gè)例子芭届,在函數(shù) func 外部定義的變量 x ,和在函數(shù)內(nèi)部定義的 x 互不影響

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

def func(x):
    print("x 在函數(shù)內(nèi)感耙,改變前:%d, x is %d" %(id(x), x))
    x = 2
    print("x 在函數(shù)內(nèi)褂乍,改變后:%d, x is %d" %(id(x), x))

if __name__ == '__main__':
    
    x = 50  
    print("x 在函數(shù)外:%d, x is %d" %(id(x), x))
    func(x)
    print('x 在函數(shù)外:%d, x is still %d' %(id(x), x))

輸出:

x 在函數(shù)外:500593664, x is 50
x 在函數(shù)內(nèi),改變前:500593664, x is 50
x 在函數(shù)內(nèi)即硼,改變后:500592128, x is 2
x 在函數(shù)外:500593664, x is still 50

這個(gè)過程逃片,用文字描述如下:

  • “x = 50”:新建了一個(gè)整形對(duì)象 50,分配了內(nèi)存地址為:500593664只酥,并且將函數(shù)外變量 x 綁定到了這個(gè)對(duì)象上褥实。
  • “func(x)”:新建了一個(gè)函數(shù)內(nèi)變量 x,并且將 x 綁定到這個(gè)對(duì)象上裂允,所以此時(shí)损离,對(duì)象內(nèi)存地址未變
  • “x = 2”:新建了一個(gè)整型對(duì)象 2,分配了內(nèi)存地址:500592128绝编,并將函數(shù)內(nèi)變量 x 重新綁定到了這個(gè)對(duì)象上

如果你想要為一個(gè)定義在函數(shù)外的變量賦值僻澎,那么你就得告訴 Python 這個(gè)變量名不是局部的貌踏,而是全局的。我們使用 global 語(yǔ)句完成這一功能窟勃。
global 語(yǔ)句的作用是將某些變量聲明為全局變量祖乳,變量名可以是一個(gè),也可以是多個(gè)秉氧。當(dāng)關(guān)鍵詞 global 后面跟隨多個(gè)變量名稱時(shí)眷昆,各名稱之間要用逗號(hào)分隔開來(lái)。

#!/usr/bin/python
# Filename: func_global.py

def func():
    global x

    print 'x is', x
    x = 2
    print 'Changed local x to', x

x = 50
func()
print 'Value of x is', x

輸出

]# python func_global.py
x is 50
Changed global x to 2
Value of x is 2

注1:

在 Python 中汁咏,字符串亚斋,整形,浮點(diǎn)型梆暖,tuple 是不可更改的對(duì)象伞访,而 list , dict 等是可以更改的對(duì)象轰驳。

  • 不可更改的類型:類似 c++ 的值傳遞厚掷,如:整數(shù)、字符串级解、元組冒黑。如fun(a),傳遞的只是 a 的值勤哗,沒有影響 a 對(duì)象本身抡爹。比如在 fun(a) 內(nèi)部修改 a 的值,只是修改另一個(gè)復(fù)制的對(duì)象芒划,不會(huì)影響 a 本身冬竟。
  • 可更改的類型:類似 c++ 的引用傳遞,如:列表民逼,字典泵殴。如 fun(a),則是將 a 真正的傳過去拼苍,修改后 fun 外部的 a 也會(huì)受影響
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

def chagne_list( b ):
    print('函數(shù)中一開始 b 的值:{}, id 值為:%d' .format( b ) %id(b))
    b.append(1000)
    print('函數(shù)中 b 賦值后的值:{}, id 值為:%d' .format( b ) %id(b))

if __name__ == '__main__':
    b = [1, 2, 3, 4, 5]
    chagne_list(b)
    print('最后輸出 b 的值:{}, id 值為:%d'.format(b) %id(b))

執(zhí)行結(jié)果為:

函數(shù)中一開始 b 的值:[1, 2, 3, 4, 5], id 值為:42799368
函數(shù)中 b 賦值后的值:[1, 2, 3, 4, 5, 1000], id 值為:42799368
最后輸出 b 的值:[1, 2, 3, 4, 5, 1000], id 值為:42799368

注2:

如果要避免上面這種情況發(fā)生笑诅,可以向函數(shù)傳遞一個(gè)字典或列表的副本,而不是它本身

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

import copy
def chagne_list( b ):
    print('函數(shù)中一開始 b 的值:{}, id 值為:%d' .format( b ) %id(b))
    b.append(1000)
    print('函數(shù)中 b 賦值后的值:{}, id 值為:%d' .format( b ) %id(b))

if __name__ == '__main__':
    b = [1, 2, 3, 4, 5]
    print('函數(shù)外一開始 b 的值:{}, id 值為:%d'.format(b) % id(b))
    chagne_list(copy.deepcopy(b))

執(zhí)行結(jié)果為:

函數(shù)外一開始 b 的值:[1, 2, 3, 4, 5], id 值為:43472904
函數(shù)中一開始 b 的值:[1, 2, 3, 4, 5], id 值為:43473096
函數(shù)中 b 賦值后的值:[1, 2, 3, 4, 5, 1000], id 值為:43473096

注3:

上面這個(gè)例子疮鲫,又涉及到了 python 的淺拷貝和深拷貝吆你,再舉一個(gè)例子來(lái)說(shuō)明一下:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

import copy

if __name__ == '__main__':

    original = [[1], "test"]
    shallow_copy = copy.copy(original)
    deep_copy = copy.deepcopy(original)

    print("改變前:")
    print("original 值為:{}, id 為:{}".format(original, id(original)))
    print("shallow_copy 值為:{}, id 為:{}".format(shallow_copy, id(shallow_copy)))
    print("deep_copy 值為:{}, id 為:{}".format(deep_copy, id(deep_copy)))

    original[0].append(2)

    print ("改變后:")
    print("original 值為:{}, id 為:{}".format(original, id(original)))
    print("shallow_copy 值為:{}, id 為:{}".format(shallow_copy, id(shallow_copy)))
    print("deep_copy 值為:{}, id 為:{}".format(deep_copy, id(deep_copy)))

執(zhí)行結(jié)果:

改變前:
original 值為:[[1], 'test'], id 為:43338056
shallow_copy 值為:[[1], 'test'], id 為:43339336
deep_copy 值為:[[1], 'test'], id 為:43339272
改變后:
original 值為:[[1, 2], 'test'], id 為:43338056
shallow_copy 值為:[[1, 2], 'test'], id 為:43339336
deep_copy 值為:[[1], 'test'], id 為:43339272

3.5、傳遞長(zhǎng)度可變的參數(shù):

預(yù)先并不知道, 函數(shù)使用者會(huì)傳遞多少個(gè)參數(shù)給你, 所以在這個(gè)場(chǎng)景下使用如下兩個(gè)關(guān)鍵字俊犯。

  • 在函數(shù)的參數(shù)前使用標(biāo)識(shí)符 *:通常的寫法 *args妇多,可以將數(shù)量不定的,以位置參數(shù)方式傳入的參數(shù)打包一個(gè)元組中瘫析。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

def print_everything(*args):
    for count, thing in enumerate(args):
        print('{0}. {1}'.format(count, thing))

if __name__ == '__main__':
    print_everything('apple', 'banana', 'cabbage')

輸出:

0. apple
1. banana
2. cabbage
  • 在函數(shù)的參數(shù)前使用標(biāo)識(shí)符 **:通常的寫法 **kwargs砌梆,可以將數(shù)量不定的默责,以關(guān)鍵字方式傳入的參數(shù)打包到一個(gè)字典中。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# environment:python3.6.4

def greet_me(**kwargs):
    for key, value in kwargs.items():
        print("{0} == {1}".format(key, value))

if __name__ == '__main__':
    greet_me(name="yasoob",age=15)

輸出

name == yasoob
age == 15

4咸包、函數(shù)的返回

python 函數(shù)返回值有兩種形式:

  1. 返回一個(gè)值

現(xiàn)看看返回一個(gè)值的吧桃序。

def firstvalue(a,b):
    c = a + b
    return c

print firstvalue(1,2)

結(jié)果:

3
  1. 返回多個(gè)值。

再看看返回多個(gè)值的:

def secondvalue(a,b):
    c = a + b
    return (a,b,c)
   
x,y,z = secondvalue(1,2)
print 'x:',x,'y:',y,'z:',z

結(jié)果:

x: 1 y: 2 z: 3
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烂瘫,一起剝皮案震驚了整個(gè)濱河市媒熊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坟比,老刑警劉巖芦鳍,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異葛账,居然都是意外死亡柠衅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門籍琳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)菲宴,“玉大人,你說(shuō)我怎么就攤上這事趋急『嚷停” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵呜达,是天一觀的道長(zhǎng)谣蠢。 經(jīng)常有香客問我,道長(zhǎng)查近,這世上最難降的妖魔是什么眉踱? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮霜威,結(jié)果婚禮上勋锤,老公的妹妹穿的比我還像新娘。我一直安慰自己侥祭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布茄厘。 她就那樣靜靜地躺著矮冬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪次哈。 梳的紋絲不亂的頭發(fā)上胎署,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音窑滞,去河邊找鬼琼牧。 笑死恢筝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的巨坊。 我是一名探鬼主播撬槽,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼趾撵!你這毒婦竟也來(lái)了侄柔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤占调,失蹤者是張志新(化名)和其女友劉穎暂题,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體究珊,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薪者,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剿涮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片言津。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幔虏,靈堂內(nèi)的尸體忽然破棺而出纺念,到底是詐尸還是另有隱情,我是刑警寧澤想括,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布陷谱,位于F島的核電站,受9級(jí)特大地震影響瑟蜈,放射性物質(zhì)發(fā)生泄漏烟逊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一铺根、第九天 我趴在偏房一處隱蔽的房頂上張望宪躯。 院中可真熱鬧,春花似錦位迂、人聲如沸访雪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)臣缀。三九已至,卻和暖如春泻帮,著一層夾襖步出監(jiān)牢的瞬間精置,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工锣杂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脂倦,地道東北人番宁。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像赖阻,于是被迫代替她去往敵國(guó)和親蝶押。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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