函數

函數

函數是Python中 組織代碼的最小單元。javascript

1、函數的定義

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]:

2、函數的調用

只有調用函數的時候,纔算執行函數。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

3、參數

一、參數的默認值

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]:

可變參數有兩重:數組

  • 位置可變參數(*args)
  • 關鍵字可變參數(**kwargs)

可變參數的區別: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]:

四、keyword-only 參數

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]:
相關文章
相關標籤/搜索