目錄python
函數在編程語言中就是完成特定功能的一個詞句組(代碼塊),這組語句能夠做爲一個單位使用,而且給它取一個名字。能夠經過函數名在程序的不一樣地方屢次執行(這叫函數的調用
)。函數在編程語言中有基本分爲:預約義函數,自定義函數。預約義函數能夠直接使用,而自定義函數顧名思義須要咱們本身定義函數。編程
在數學中的定義,這裏就不介紹了。由於沒卵用。哈哈編程語言
在編程中使用函數主要有兩個優勢:函數
在Python中,函數由若干語句組成代碼塊
、函數名稱
、參數列表
構成,它是組織代碼的最小單元,使用函數能夠完成必定的功能,在Python中函數主要分爲三類:內置函數
、第三方函數庫
、自定義函數
。經常使用的內置函數在前面已經介紹,第三方函數庫須要先引入模塊,經過模塊調用,在模塊學習中進行介紹,這裏主要說的是如何自定義一個函數。學習
在Python中,定義一個函數要使用def語句,依次寫出函數名
、括號
、括號中的參數和冒號:
,而後,在縮進塊中編寫函數體,函數的返回值用return語句
返回。下面是一個函數的基本結構ui
def 函數名(參數列表): 函數體(代碼塊) [return 返回值] # 函數能夠無返回值
注意:3d
函數名
就是標識符
,命名要求同樣語句塊
必須縮進,約定4個空格
隱式會返回一個None
形參
定義: def abs(x): if x >= 0: return x else: return -x 調用: abs(-10)
上面只是一個函數的定義,j具體來看一下各個部分的解釋:code
可調用對象
,函數名加括號
就表示調用。直接打印函數名,不會觸發函數的執行,反而會打印函數的內存地址。orm
咱們自定義的函數abs,因爲與內置函數重名,那麼將會覆蓋掉內置函數,因此請謹慎命名。對象
函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,並將結果返回。所以,函數內部經過條件判斷和循環能夠實現很是複雜的邏輯。若是沒有return語句,函數執行完畢後會隱士的返回None
。若是咱們確實要return None
能夠簡寫爲return
,或者不寫return語句(會讓人看不懂,建議只寫return)。
調用函數,那麼只須要使用函數名加括號,就能執行,但若是函數定義了參數,那麼必須在執行的時候傳遞參數給函授,不然會報異常!關於調用咱們還須要瞭解:
調用時寫的參數是實際參數,是實實在在傳入的值,簡稱實參
函數是可調用對象,可使用callable()進行判斷
In [1]: def abs(x): ...: if x >= 1: ...: return x ...: else: ...: return -x In [2]: callable(abs) # 函數是可調用的,注意這裏不能對函數加括號,那麼callable判斷的就是函數的返回值是否能夠執行了 Out[2]: True In [3]: a = '123' In [4]: callable(a) # 字符串是不可調用的 Out[4]: False
定義函數的時候,括號中指定的就是函數的參數(形式參數),當咱們調用函數時,須要將數據進行傳遞,這種傳遞參數的方式就叫作傳參,嚴格來講函數只可使用兩種方式:位置傳參
和關鍵字傳參
。
關鍵字傳參:使用形參的名字來傳入實參的方式
須要注意的時:參數傳遞時若是
使用
了形參的名字
,那麼傳入參數的順序就能夠
和定義的順序不一樣
,當位置傳參和關鍵字傳參混用時,位置傳參必須放在關鍵字傳參前面傳入
。
定義函數function: In [1]: def function(x,y): ...: result = x + y ...: return result ...: 位置傳參: In [2]: function(1,2) # 1對應x,2對應y。 Out[2]: 3 關鍵字傳參: In [3]: function(y=1, x=2) # 使用關鍵字時,參數能夠不用按照位置順序。 Out[3]: 3 混合傳參: In [8]: function(1, y = 3) # 混用時,關鍵字參數必需要再位置參數右邊 Out[8]: 4
在定義形式參數時,爲參數指定對應的值,就叫作參數的默認值,當定義了參數的默認值之後,咱們傳參時能夠選擇傳遞該參數的值,也能夠選擇不傳遞,當不傳遞
此參數的值時,該參數就使用指定的默認值
,不然
將會使用傳遞的值
。
參數默認值也屬於位置參數,只不過是給位置參數定義了默認值。
In [9]: def function(x = 10, y = 20): ...: return x + y ...: In [10]: function(2) # 2會以位置參數的形式傳遞給x,y沒有傳遞,會使用默認值 Out[10]: 22 In [11]: function(y=100) # x沒有傳遞,會使用默認值 Out[11]: 110 In [12]: function(x=100) # y沒有傳遞,會使用默認值 Out[12]: 120 In [13]: function(20, y=500) # 20以位置參數的形式傳遞給x,500以關鍵字參數的形式傳遞給了y Out[13]: 520
當定義參數的默認值時,注意
默認值參數
必需要放在位置參數的右邊
In [1]: def functions(x=1, y): # 必須把x=1,放在y的右邊,不然沒法完成函數定義 ...: print(x+y) File "<ipython-input-1-ea496fa7fc81>", line 1 def functions(x=1, y): ^ SyntaxError: non-default argument follows default argument
使用默認值參數的好處是:
可變參數顧名思義表示參數的數量是可變的,而且可使用一個形參匹配任意個實參。針對傳遞參數方式的不一樣又分爲可變位置傳參
和可變關鍵字傳參
。
在形參前使用*
號,表示該形參是可變參數,能夠接受多個實參,在函數內部,可變參數會封裝成元祖(即使是沒有傳遞)
In [15]: def function(*nums): ...: print(nums) ...: In [16]: function(1,2,3,4) # 多個參數會被nums收集 (1, 2, 3, 4) In [18]: function([1,2,3,4]) # 會把list收集成元祖類型 ([1, 2, 3, 4],)
在函數定義時,通常的規範是使用
*args
, 表示收集多個位置傳參。
在形參前使用**
號,表示該形參是可變關鍵字參數,能夠接受多個關鍵字參數,在函數內部,可變關鍵字參數會封裝成字典(即使是沒有傳遞)
In [20]: def function(**kwargs): ...: print(kwargs) ...: In [21]: function(a=1,b=2) {'a': 1, 'b': 2} # 參數的默認值和位置參數同時使用 In [5]: def function(x=1,y=2,**kwargs): ...: print('x = {}'.format(x)) ...: print('y = {}'.format(y)) ...: print(kwargs) ...: In [6]: function(a=10,b=20) # 參數沒有a,b形參,則被kwargs接收 x = 1 y = 2 {'a': 10, 'b': 20} In [7]: function(x=100,y=200,z=300) # z沒有被匹配,被kwargs接收 x = 100 y = 200 {'z': 300} In [8]: function(1000,2000,z=300) # 前面的按照位置參數賦值,z一樣被字典kwargs收集 x = 1000 y = 2000 {'z': 300} In [9]:
前面說的各類參數是能夠混合使用的,當混合使用時遵循必定的順序,簡單總結一下,按照從左至右的順序來講:位置參數,默認值參數,可變位置參數,可變關鍵字參數:def function(位置參數,默認值參數,可變位置參數,可變關鍵字參數)
。
不管如何,
順序不能顛倒
。
In [9]: def function(x,y,z=1,*args,**kwargs): # x,y,z都爲位置參數,z的默認值爲1,*args收集額外的位置傳參,kwargs收集額外的關鍵字傳參 ...: print(x,y,z) ...: print(args) ...: print(kwargs) ...: In [10]: function(1,2,3,4,5,a=1,b=2) 1 2 3 (4, 5) {'a': 1, 'b': 2}
針對可變參數以及不一樣的混用方式能夠有以下結論:
位置可變參數
和關鍵字可變參數
一個星號*
兩個星號**
可變位置參數
收集造成一個tuple
,可變關鍵字參數
收集造成一個dict
混合使用參數的時候,在定義階段要遵循以下順序:位置參數
,默認值參數
,可變位置參數
,可變關鍵字參數
當位置傳參和關鍵字傳參同時使用時,
不能夠重複賦值!
,這一點使用的時候很重要。
Python3的函數參數中,新增了keyword-only參數,什麼叫keyword-only參數?咱們說當在一個星號參數(可變位置參數)後,出現的普通參數,咱們稱它爲keyword-only參數,由於多餘的位置參數都會被*args收集,只能經過keyword的方式對這些形參進行賦值
,因此它們只能使用'關鍵字傳參'。
In [11]: def function(a,b,c=1,*args,x,y=2,**kwargs): # x,y是keyword-only參數,其中y存在默認值,能夠不用傳遞,x必須使用關鍵字的方式進行傳遞 ...: print(a,b,c) ...: print(args) ...: print(x,y) ...: print(kwargs) ...: In [12]: function(100,200,300,400,d=100,e=200) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-12-cf60009e3d1f> in <module> ----> 1 function(100,200,300,400,d=100,e=200) TypeError: function() missing 1 required keyword-only argument: 'x' In [13]: function(100,200,300,400,d=100,e=200,x=500) 100 200 300 (400,) 500 2 {'d': 100, 'e': 200}
特殊形式:
In [17]: def function(*,x,y): ...: print(x,y) ...: In [18]: function(1,2,3,x=100,y=200) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-18-7d07ae79c088> in <module> ----> 1 function(1,2,3,x=100,y=200) TypeError: function() takes 0 positional arguments but 3 positional arguments (and 2 keyword-only arguments) were given In [20]: function(x=100,y=200) 100 200
這裏*表示不接受位置傳參,只能使用關鍵字對參數進行賦值
注意:使用了keyword-only參數,那麼在定義形參的時的順序就有所改變了,它們是:位置參數,默認值參數,可變位置參數,keyword-only參數,可變關鍵字參數
前面咱們說過Python的封裝與結構,這裏的參數也能夠利用這種思想進行結構,現有以下函數:
In [21]: def add(x=1,y=2): ...: print(x+y) ...: In [22]: t = (10,20) In [23]: add(t[0],t[1]) # 將元祖的元素1和元素2分別傳給X,y 30 In [24]: add(*t) 30 In [25]: d = {'x':100, 'y':200} In [30]: add(**d) 300
10,20
,做爲位置傳參
傳遞給add函數x=100,y=200
,做爲關鍵字傳參
傳遞給函數如今再來回頭看一下,什麼時參數解構?
*解構成位置參數
**解構成關鍵字參數
In [31]: def add(a,b,*args,m,n,**kwargs): ...: print(a+b+m+n) ...: In [32]: dic = {'a':100,'b':200} In [33]: add(**dic,m=300,n=400,x=1000) 1000
咱們一般編寫函數除了代碼能夠複用,更多的時候須要的是知道函數的運算結果,那麼函數把運算的結果返回給咱們,這個結果就叫做作函數的返回值。使用return
關鍵字進行返回。
# 返回1個數據 In [34]: def add(x,y): ...: result = x + y ...: return result ...: In [35]: a = add(10,20) In [36]: print(a) 30 # 返回多個數據 In [37]: def add(x,y): ...: result = x + y ...: test = x * y ...: return result,test ...: In [38]: a = add(10,20) In [39]: print(a) (30, 200) # 多個return語句 In [40]: def add(x,y): ...: if x > 10: ...: return y ...: else: ...: return x ...: In [41]: a = add(10,20) In [42]: print(a) 10
總結:
return能夠理解爲,結束當前函數計算,返回值!
多個返回值會被包裝成一個tuple進行返回,因此函數永遠只能返回一個數據。