# Argue of Arguments and Keyword-arguments
整理一下 Python 中的技巧:`*args` 和 `**kwargs`。
`*args` 是處理「函數中不定數量的位置引數」,而 `**kwargs` 是處理「關鍵字引數」的語法。因為還不太熟悉這些語法,於是就想寫這篇來釐清一下。要注意的是沒有 `*kwargs` ,因為 `*kwargs` 就是 `*args`。
### About Parameter and Argument
- 定義函數叫做引數(Parameter)
- 傳遞函數叫做參數(Argument)
# `*args`
首先我們先來介紹當用在引數時的 `*args`
### Example
```python
def func(*arg1, arg2):
print(arg1, arg2)
func(1, 2, 3, 4, 5, arg2=300)
```
```shell
$ python3 main.py
(1, 2, 3, 4, 5) 300
```
在這裡我們可以看到呼叫 `func()` 時帶入的參數為一串整數,一直到最後一個 `arg2` 時才完整打上 `arg2=300` 告訴函數位於 `arg2` 的參數為多少,這個寫法能讓 Python 正確解析跑出數值,所以此程式是沒有錯誤的。
### Summary
使用者在輸入 `*args` 引數時,能於該參數傳遞不只一項數值。當某情況需要傳遞多數值時就可以用 `*args` 來打包一狗票東西到一個 Tuple 裡,而不用預先將資料打包在容器裡後傳入。當使用者輸入完 `*args` 欄位時,則需要特別打上下一個參數名稱來提醒直譯器 `*args` 欄位輸入完畢。
總結一下,上面程式中我到底輸入了什麼、函數拿到了什麼?
我們可以改寫一下程式:
```python
def func(*arg1, arg2):
print(arg1)
print(arg2)
func(1, 2, 3, 4, 5, arg2=300)
```
```shell
$ python3 main.py
(1, 2, 3, 4, 5)
300
```
就能知道 `(1, 2, 3, 4, 5)` 為 `*arg1` 的引數、`300` 為 `arg2` 的引數。
# `**kwargs`
Python 中有 Keyword 用法的結構只有 Dictionary,那在這邊的 `**kwargs` 是以 Key-Value pair 的結構出現。但這裡的用法稍微特殊,當使用 `**kwargs` 時,傳遞的引數會是 Variable-Value pair。
### Example
```python
def func(**kwargs):
print(kwargs)
func(a=1, b=2, c=3, d=4)
```
```shell
$ python3 main.py
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
```
### Summary
也就是像上面範例一樣,傳遞的是一組一組的 Variable 與 Value。這種就是 `**kwargs` 的基本用法。再來我們可以看到,經過 `**kwargs` 後的 Variable-Value paie 被轉換成了 Key-Value pair,也就是說,透過傳遞給 `**kwargs` 後我們會得到一個字典回傳值。
# `*args` and `**kwargs`
從前面認識了 `*args` 與 `**kwargs`,也發現到 `**kwargs` 有包裝的特性外,也具備 `*args` 傳遞多筆參數的性質。所以現在想知道如何同時使用 `*args` 和 `**kwargs` 。
其實很簡單,只要將 `*args` 與 `**kwargs` 的兩個性質放在一起就可以了。最終,在呼叫函數時的引數會是這樣:
### Example
```python
def func(*args, **kwargs):
print(args)
print(kwargs)
func(1, 2, 3, a=1, b=2, c=3)
```
```shell
$ python3 main.py
(1, 2, 3)
{'a': 1, 'b': 2, 'c': 3}
```
### Summary
當同時使用 `*args` 與 `**kwargs` 時,只需要把在 `*args` 段落中其他的參數全部想像成 `**kwargs`。只要依照這個思路去記,就能無痛將 `*args` 與 `**kwargs` 全部記下來!
# `*args` and `*args` or `**kwargs` and `**kwargs`
直譯器會報錯 `SyntaxError: * argument may appear only once` 或 `SyntaxError: arguments cannot follow var-keyword argument`。
# Reference
- [Glossary - Python 3.11.0 documentation](https://docs.python.org/3/glossary.html#term-parameter)