函數是Python中 組織代碼的最小單元。javascript
def fn 函數名,後面用圓括號,裏面放參數java
In [1]: def add(x, y): ...: print(x + y) ...: return x + y ...: In [2]: add(1, 2) 3 Out[2]: 3 In [3]:
只有調用函數的時候,纔算執行函數。python
In [11]: def add(x, y): # 位置參數 ...: ret = x + y ...: print('{} + {}'.format(x, y, ret)) ...: return ret ...: In [12]: add(3, 5) 3 + 5 Out[12]: 8 In [13]: add(y = 5, x = 3) # 關鍵字參數 3 + 5 Out[13]: 8 In [14]: add(z = 4, x = 2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-14-6b37cddfa8aa> in <module>() ----> 1 add(z = 4, x = 2) TypeError: add() got an unexpected keyword argument 'z' In [15]: add(3, y = 5) 3 + 5 Out[15]: 8 In [16]: add(3 = 3, 5) File "<ipython-input-16-63efc42b67b1>", line 1 add(3 = 3, 5) ^ SyntaxError: keyword can't be an expression In [17]:
位置參數必須在關鍵字參數的前面express
In [41]: def inc(base, x): ...: return base + x ...: In [42]: inc(3, 1) Out[42]: 4 In [43]: inc(5, 1) Out[43]: 6 In [44]: def inc(base, x=1): ...: return base + x ...: In [45]: inc(3,) Out[45]: 4 In [46]: inc(3, 6) Out[46]: 9 In [47]: In [47]: def add(x=0, y): # 在定義的時候, 默認值參數, 必須在位置參數的後面。 ...: return x + y File "<ipython-input-47-1543c5d4b45d>", line 1 def add(x=0, y): ^ SyntaxError: non-default argument follows default argument In [48]:
In [49]: '{} {} {} {}'.format(1, 2, 3, 4) Out[49]: '1 2 3 4' In [50]: def sum(x, y, z): ...: return x + y + z ...: In [51]: sum(1, 2, 3) Out[51]: 6 In [52]: In [52]: def sum(lst): ...: ret = 0 ...: for x in lst: ...: ret += x ...: return ret ...: In [53]: sum([1, 2]) Out[53]: 3 In [54]: sum([1, 2, 3]) Out[54]: 6 In [55]: In [55]: def sum(*args): # 位置可變參數,能夠接受 任意多個參數, 參數將構成一個 元組 ...: print(args, type(args)) ...: ret = 0 ...: for x in args: ...: ret += x ...: return ret ...: In [56]: sum(1, 2, 3) (1, 2, 3) <class 'tuple'> Out[56]: 6 In [57]: sum(1, 2) (1, 2) <class 'tuple'> Out[57]: 3 In [58]:
In [58]: def connect(**kwargs): # 可以接受任意多個參數, 這些參數組成一個字典,且只能經過關鍵字參數傳遞 ...: print(kwargs) ...: In [59]: connect(host='127.0.0.1', port=3306) {'host': '127.0.0.1', 'port': 3306} In [60]: In [60]: def connect(**kwargs): # 關鍵字可變參數 ...: print(kwargs) ...: for k, v in kwargs.items(): ...: print('{} => {})'.format(k, v)) ...: In [61]: connect(host='127.0.0.1', port=3306) {'host': '127.0.0.1', 'port': 3306} host => 127.0.0.1) port => 3306) In [62]: connect('127.0.0.1') --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-62-e35c0d82773d> in <module>() ----> 1 connect('127.0.0.1') TypeError: connect() takes 0 positional arguments but 1 was given In [63]:
可變參數有兩重:數組
可變參數的區別:bash
In [64]: def fn(*args, **kwargs): ...: print(args, kwargs) ...: In [65]: fn(1, 2, c=3, d=4) (1, 2) {'c': 3, 'd': 4} In [66]: fn(c=5, 2, a=1) # 當位置可變參數 和 關鍵字可變參數一塊兒使用時, 可變位置參數必須在前面 File "<ipython-input-66-b9d80d780fb7>", line 1 fn(c=5, 2, a=1) ^ SyntaxError: positional argument follows keyword argument In [67]:
In [67]: def fn(*args, x): ...: print(args) ...: print(x) ...: In [68]: fn(2, 3, 4) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-68-058123dd4a01> in <module>() ----> 1 fn(2, 3, 4) TypeError: fn() missing 1 required keyword-only argument: 'x' In [69]: fn(2, 3, x=4) # 位置參數能夠在 普通參數以前,可是在位置參數以後的普通參數就變成了 keyword-only參數。 (2, 3) # keyword-only 參數,必需要用關鍵字參數方式傳遞。 4 In [70]: def fn(**kwargs, x): # 關鍵字可變參數不容許在普通參數以前。 File "<ipython-input-70-db752afe6c1a>", line 1 def fn(**kwargs, x): ^ SyntaxError: invalid syntax
# ssl In [76]: def connect(host='127.0.0.1', port=3306, user='root', password='', db='test', **kwargs): ...: pass ...: In [77]: def connect(**kwargs): ...: host = kwargs.pop('host', '1270.0.1') ...: port = kwargs.pop('port', 3306) ...: In [78]: connect(host='192.168.1.246') In [79]: d = {'host': '127.0.0.1'} In [80]: d.get('port', 3306) Out[80]: 3306 In [81]:
In [82]: def add(x, y): # 位置參數 ...: ret = x + y ...: print('{} + {}'.format(x, y, ret)) ...: return ret ...: In [83]: add(1, y=2) 1 + 2 Out[83]: 3 In [84]: add(x=1, y=2) 1 + 2 Out[84]: 3 In [85]: lst = [1, 2] In [86]: add(lst[0], lst[1]) 1 + 2 Out[86]: 3 In [87]: add(*lst) # 加一個 星號, 把一個可迭代對象 解構成 位置參數 1 + 2 Out[87]: 3 In [88]: add(*range(10)) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-88-979391e2ced2> in <module>() ----> 1 add(*range(10)) TypeError: add() takes 2 positional arguments but 10 were given In [89]: add(*range(2)) 0 + 1 Out[89]: 1 In [90]:
參數解構 是發生在函數調用的時候, 可變參數 是發生在 函數定義的 時候函數
In [90]: d = {'x': 1, 'y': 2} In [91]: add(**d) # 加兩個 星號, 把字典解構出來 1 + 2 Out[91]: 3 In [92]:
參數解構有兩種形式:ui
In [93]: def sum(*args): ...: ret = 0 ...: for x in args: ...: ret += x ...: return ret ...: In [94]: sum(*range(10)) Out[94]: 45 In [95]: def fn(**kwargs): ...: print(kwargs) ...: In [96]: fn(**{1: 2}) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-96-248217b02acb> in <module>() ----> 1 fn(**{1: 2}) TypeError: fn() keywords must be strings In [97]: fn(**{'1': 2}) {'1': 2} In [98]:
In [99]: def fn(*, x): # 第一個參數是一個星號,表示星號以後的參數只能經過關鍵字參數傳遞,叫作 keyword-onlyc參數 ...: print(x) ...: In [100]: fn(x=3) 3 In [101]: fn(3) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-101-a2cf1d578950> in <module>() ----> 1 fn(3) TypeError: fn() takes 0 positional arguments but 1 was given In [102]:
In [103]: def fn(x, *, y): ...: print(x) ...: print(y) ...: In [104]: fn(1, y=2) 1 2 In [105]: In [105]: def fn(x, *, y=5): ...: print(x) ...: print(y) ...: In [106]: fn(1, 2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-106-f2b75686a58b> in <module>() ----> 1 fn(1, 2) TypeError: fn() takes 1 positional argument but 2 were given In [107]: fn(1, y=2) 1 2 In [108]: fn(1) 1 5 In [109]: In [109]: def fn(*, x=1, y=5): ...: print(x) ...: print(y) ...: In [110]: fn(x=11, y=2) 11 2 In [111]: def fn(*args): ...: print(args) ...: In [112]: fn(*{1, 2, 3}) (1, 2, 3) In [113]: