# Python
###### tags: `MCL Notebook` `language` `python`
# 基礎功能
## string
python 有很多種 string 輸出的方式,也演進的愈來愈強、方便,可以參考[教學](https://blog.louie.lu/2017/08/08/outdate-python-string-format-and-fstring/)有介紹與舉例
# 進階功能
## args kwargs
python 的函數參數常見有 **tuple** 和 **dict** 兩種做法(可以併存),如:
``` python
def func(a, b, c = 1, d = 'min'):
pass
func(1, 2, c = 3, d = 'max')
```
而 a、b 可以想成 tuple,c、d 可以想成 dict,而可以改寫成
``` python
def func(args, kwargs):
pass
func(1, 2, c = 3, d = 'max')
```
args 和 kwargs 分別是
``` python
>>> args
(1, 2)
>>> kwargs
{'c' = 3, 'd' = 'max'}
```
也就是常看到的 * 和 ** 詳細內容請參考[^args_kwargs]
## warpper(decorator)
### 概念
可以對函數、class 修式(修改)的函數,如
``` python
@abc
def A():
pass
```
可以自己定義 @abc,做到在執行 A() 之前有預處理或後處理,更多請參考[^warpper]
### 進階
#### 對 class wrapper
對 Class 裡的所有 method 做 wrapper
- [元生問題](https://stackoverflow.com/questions/6780907/python-wrap-class-method)
- [解法1](http://code.activestate.com/recipes/198078-wrapping-method-calls-meta-class-example/)
- [解法2](https://stackoverflow.com/questions/11349183/how-to-wrap-every-method-of-a-class)
# 物件
## 封裝
也就是 @property 和 @變數名.setter 的 wrapper[^warpper]
1. @property 封裝的函數寫 getter
2. @變數名.setter 的函數寫 setter
詳細內容請參考[^property]
# Library(套件)
## 概述
python 強大的功能,很大一部份在於有很方便的套件可以使用,內建的就很多了,另外可以使用套件管理工具獲得更多強大的套件
## 套件管理工具
常見的是 pip,搭配 venv 可以在非管理員權限下安裝套件,也有兩者(pip、venv) 的混合[pipenv](https://medium.com/@chihsuan/pipenv-更簡單-更快速的-python-套件管理工具-135a47e504f4)
### setuptools (從 source code 獲得套件)
有些套件只有提供 source code,沒有放到官方的資源庫中,所以不能使用 pip 的方式安裝,但一般 source code 中都會提供 setuptools 的設定,就可以使用簡單的指令安裝到系統上
#### 教學文件
[講概念](https://medium.com/@dboyliao/python-相依管理-f7d89dfe917b)
[安裝與使用](http://blog.luoyuanhang.com/2016/03/23/Python-分发工具初探之-setuptools/)
## logging
### 概述
log 的工具,可以自己定義 log 到的輸出介面,和輸出格式,可以先了解一下[基礎](http://yu-liang.logdown.com/posts/195882/python-logging-module),進一步可以可以藉由 `__class__.__name__` 達到不同 class 使用不同的定義,或 `__name__` 達到不同 file 使用不同的定義
### 參考教學
#### 進階
[在 class、module 中使用](https://www.patricksoftwareblog.com/python-logging-tutorial/)
## re
使用正規表示法搜尋想要的字串
### (?P<name>...)
可以把想要的字直接用 `name` 定義,也就可以使用 `.group('name')` 的方式取得 match 的字串。如
``` python
>>> match = re.find('((?P<key>[a-zA-Z]+) = (?P<value>[0-9]+)', 'a = 1')
>>> match.group('key')
'a'
>>> match.group('value')
'1'
```
但這樣的方式卻無法在 `re.findall` 使用,出來的內容不會有名詞的對應,而只會保留順序性變成 tuple,所以需要改用 `re.finditer` 在使用 `.groupdict()` 轉成 dict 的格式,name 的部分就會變成 key 保留出來,詳細可以參考[^re.finditer]
## [click](https://github.com/pallets/click)
### 概述
做 command line 的工具,優勢:
- 支援 python2 與 python3 的相容
- 支援跨平台(widows、linux)
- 支援 shell 相關的 autocomplete 功能
- 使用 wrapper 傳遞參數,設計直覺
### 參考教學
- [不錯的入門教學](https://myapollo.com.tw/2018/12/14/python-click/)
## 進階定義條件
- 基本用法 `logging.basicConfig`
- 設定 config file 並輸入
- dict 的方式輸入
更多請參考[^logging_dict]
# Link
[^args_kwargs]:
1. [args kwargs](https://github.com/dokelung/Python-QA/blob/master/questions/star/%E9%97%9C%E6%96%BCpython*%E5%92%8C**%E7%9A%84%E5%95%8F%E9%A1%8C.md)
2. [更多用法](https://www.linuxnix.com/5-useful-value-unpacking-star-operator-idioms-python/)
[^property]:
3. [@property](https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386820062641f3bcc60a4b164f8d91df476445697b9e000)
[^warpper]:
[warpper](https://foofish.net/python-decorator.html)
[^logging_dict]:
[logging](https://juejin.im/post/5bc2bd3a5188255c94465d31)
[^re.finditer]:
[stack overflow](https://stackoverflow.com/questions/11103856/re-findall-which-returns-a-dict-of-named-capturing-groups)
[metaclass](https://kuanyui.github.io/2016/07/03/python-metaclass/)