在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 函數參數
基礎
itertools
HTTP 服務
hashlib
閉包
文件和目錄
單元測試
使用 @property
標準模塊
陌生的 metaclass
Base64
進程、線程和協程
讀寫二進制文件
匿名函數
輸入和輸出
Click
元組
字符編碼
partial 函數
參考資料
collections
協程
類和實例
Python 之旅
定制類和魔法方法
常用數據類型
繼承和多態(tài)
ThreadLocal
HTTP 協議簡介
Requests 庫的使用
讀寫文本文件
列表
os 模塊
迭代器 (Iterator)
正則表達式
集合
上下文管理器
異常處理
你不知道的 super
定義函數
datetime
資源推薦
字典
slots 魔法
hmac
第三方模塊
進程
類方法和靜態(tài)方法
函數參數
高階函數
函數
re 模塊
高級特性
線程
argparse
生成器
結束語
字符串
map/reduce/filter
函數式編程
Celery
裝飾器

函數參數

在 Python 中,定義函數和調用函數都很簡單,但如何定義函數參數和傳遞函數參數,則涉及到一些套路了??偟膩碚f,Python 的函數參數主要分為以下幾種:

  • 必選參數
  • 默認參數
  • 可變參數
  • 關鍵字參數

必選參數

必選參數可以說是最常見的了,顧名思義,必選參數就是在調用函數的時候要傳入數量一致的參數,比如:

>>> def add(x, y):        # x, y 是必選參數
...     print x + y
...
>>> add()                 # 啥都沒傳,不行
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (0 given)
>>> add(1)                # 只傳了一個,也不行
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(1, 2)             # 數量一致,通過
3

默認參數

默認參數是指在定義函數的時候提供一些默認值,如果在調用函數的時候沒有傳遞該參數,則自動使用默認值,否則使用傳遞時該參數的值。

看看例子就明白了:

>>> def add(x, y, z=1):     # x, y 是必選參數,z 是默認參數,默認值是 1
...     print x + y + z
...
>>> add(1, 2, 3)            # 1+2+3
6
>>> add(1, 2)               # 沒有傳遞 z,自動使用 z=1,即 1+2+1
4

可以看到,默認參數使用起來也很簡單,但有兩點需要注意的是:

  • 默認參數要放在所有必選參數的后面
  • 默認參數應該使用不可變對象

比如,下面對默認參數的使用是錯誤的:

>>> def add(x=1, y, z):      # x 是默認參數,必須放在所有必選參數的后面
...     return x + y + z
...
  File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
>>>
>>> def add(x, y=1, z):      # y 是默認參數,必須放在所有必選參數的后面
...     return x + y + z
...
  File "<stdin>", line 1
SyntaxError: non-default argument follows default argument

再來看看為什么默認參數應該使用不可變對象。

我們看一個例子:

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

在上面的函數中,L 是一個默認參數,默認值是 [],表示空列表。

我們來看看使用:

>>> add_to_list([1, 2, 3])          # 沒啥問題
[1, 2, 3, 'END']
>>> add_to_list(['a', 'b', 'c'])    # 沒啥問題
['a', 'b', 'c', 'END']
>>> add_to_list()                   # 沒有傳遞參數,使用默認值,也沒啥問題
['END']
>>> add_to_list()                   # 沒有傳遞參數,使用默認值,竟出現兩個 'END'
['END', 'END']
>>> add_to_list()                   # 糟糕了,三個 'END'
['END', 'END', 'END']

為啥呢?我們在調用函數的時候沒有傳遞參數,那么就默認使用 L=[],經過處理,L 應該只有一個元素,怎么會出現調用函數兩次,L 就有兩個元素呢?

原來,L 指向了可變對象 [],當你調用函數時,L 的內容發(fā)生了改變,默認參數的內容也會跟著變,也就是,當你第一次調用時,L 的初始值是 [],當你第二次調用時,L 的初始值是 ['END'],等等。

所以,為了避免不必要的錯誤,我們應該使用不可變對象作為函數的默認參數。

可變參數

在某些情況下,我們在定義函數的時候,無法預估函數應該制定多少個參數,這時我們就可以使用可變參數了,也就是,函數的參數個數是不確定的。

看看例子:

>>> def add(*numbers):
...     sum = 0
...     for i in numbers:
...         sum += i
...     print 'numbers:', numbers
...     return sum

在上面的代碼中,numbers 就是一個可變參數,參數前面有一個 * 號,表示是可變的。在函數內部,參數 numbers 接收到的是一個 tuple。

在調用函數時,我們可以給該函數傳遞任意個參數,包括 0 個參數:

>>> add()           # 傳遞 0 個參數
numbers: ()
0
>>> add(1)          # 傳遞 1 個參數
numbers: (1,)
1
>>> add(1, 2)       # 傳遞 2 個參數
numbers: (1, 2)
3
>>> add(1, 2, 3)    # 傳遞 3 個參數
numbers: (1, 2, 3)
6

上面的 * 表示任意參數,實際上,它還有另外一個用法:用來給函數傳遞參數。

看看例子:

>>> def add(x, y, z):        # 有 3 個必選參數
...     return x + y + z
...
>>> a = [1, 2, 3]
>>> add(a[0], a[1], a[2])    # 這樣傳遞參數很累贅
6
>>> add(*a)                  # 使用 *a,相當于上面的做法
6
>>> b = (4, 5, 6)
>>> add(*b)                  # 對元組一樣適用
15

再看一個例子:

>>> def add(*numbers):       # 函數參數是可變參數
...     sum = 0
...     for i in numbers:
...         sum += i
...     return sum
...
>>> a = [1, 2]
>>> add(*a)                  # 使用 *a 給函數傳遞參數
3
>>> a = [1, 2, 3, 4]
>>> add(*a)
10

關鍵字參數

可變參數允許你將不定數量的參數傳遞給函數,而關鍵字參數則允許你將不定長度的鍵值對, 作為參數傳遞給一個函數。

讓我們看看例子:

>>> def add(**kwargs):
    return kwargs
>>> add()            # 沒有參數,kwargs 為空字典
{}
>>> add(x=1)         # x=1 => kwargs={'x': 1}
{'x': 1}
>>> add(x=1, y=2)    # x=1, y=2 => kwargs={'y': 2, 'x': 1}
{'y': 2, 'x': 1}

在上面的代碼中,kwargs 就是一個關鍵字參數,它前面有兩個 * 號。kwargs 可以接收不定長度的鍵值對,在函數內部,它會表示成一個 dict。

和可變參數類似,我們也可以使用 **kwargs 的形式來調用函數,比如:

>>> def add(x, y, z):
...     return x + y + z
...
>>> dict1 = {'z': 3, 'x': 1, 'y': 6}
>>> add(dict1['x'], dict1['y'], dict1['z'])    # 這樣傳參很累贅
10
>>> add(**dict1)        # 使用 **dict1 來傳參,等價于上面的做法
10

再看一個例子:

>>> def sum(**kwargs):               # 函數參數是關鍵字參數
...     sum = 0
...     for k, v in kwargs.items():
...         sum += v
...     return sum
>>> sum()                            # 沒有參數
0
>>> dict1 = {'x': 1}
>>> sum(**dict1)                     # 相當于 sum(x=1)
1
>>> dict2 = {'x': 2, 'y': 6} 
>>> sum(**dict2)                     # 相當于 sum(x=2, y=6)
8

參數組合

在實際的使用中,我們經常會同時用到必選參數、默認參數、可變參數和關鍵字參數或其中的某些。但是,需要注意的是,它們在使用的時候是有順序的,依次是必選參數、默認參數、可變參數和關鍵字參數。

比如,定義一個包含上述四種參數的函數:

>>> def func(x, y, z=0, *args, **kwargs):
    print 'x =', x
    print 'y =', y
    print 'z =', z
    print 'args =', args
    print 'kwargs =', kwargs

在調用函數的時候,Python 會自動按照參數位置和參數名把對應的參數傳進去。讓我們看看:

>>> func(1, 2)                     # 至少提供兩個參數,因為 x, y 是必選參數
x = 1
y = 2
z = 0
args = ()
kwargs = {}
>>> func(1, 2, 3)                  # x=1, y=2, z=3
x = 1
y = 2
z = 3
args = ()
kwargs = {}
>>> func(1, 2, 3, 4, 5, 6)         # x=1, y=2, z=3, args=(4, 5, 6), kwargs={}
x = 1
y = 2
z = 3
args = (4, 5, 6)
kwargs = {}
>>> func(1, 2, 4, u=6, v=7)        # args = (), kwargs = {'u': 6, 'v': 7}
x = 1
y = 2
z = 4
args = ()
kwargs = {'u': 6, 'v': 7}
>>> func(1, 2, 3, 4, 5, u=6, v=7)   # args = (4, 5), kwargs = {'u': 6, 'v': 7}
x = 1
y = 2
z = 3
args = (4, 5)
kwargs = {'u': 6, 'v': 7}

我們還可以通過下面的形式來傳遞參數:

>>> a = (1, 2, 3)
>>> b = {'u': 6, 'v': 7}
>>> func(*a, **b)
x = 1
y = 2
z = 3
args = ()
kwargs = {'u': 6, 'v': 7}

小結

  • 默認參數要放在所有必選參數的后面。
  • 應該使用不可變對象作為函數的默認參數。
  • *args 表示可變參數,**kwargs 表示關鍵字參數。
  • 參數組合在使用的時候是有順序的,依次是必選參數、默認參數、可變參數和關鍵字參數。
  • *args**kwargs 是 Python 的慣用寫法。

參考資料

上一篇:第三方模塊下一篇:元組