# 《Python 精粹》書摘分享
---
### 本次分享受眾:一般軟體工程師
* 預設受眾不熟悉 Python,不會介紹過於細節的內容
* 從「Python 語言特性」中挑選有趣或重要部分
* 共 3 項內容
---
## 第一項,else 特殊用法
---
最常見的else
```PYTHON
score = int(input("請輸入成績"))
if score >= 60:
print("成績及格!")
else:
print("成績不及格!")
```
下面來看看 Python 特有的 else 用法:
迴圈 + else
---
網路上的例子與優點講解
```
nums = [60, 70, 30, 110, 90]
found = False
for n in nums:
if n > 100:
found = True
print "There is a number bigger than 100"
break
if not found:
print "Not found!"
```
```
nums = [60, 70, 30, 110, 90]
for n in nums:
if n > 100:
print "There is a number bigger than 100"
break
else:
print "Not found!"
```
如此一來,透過使用 else 可以節省一些 flag 的使用
---
### 與迴圈併用的 else
for 迴圈與 while 皆適用,在此以 for 迴圈為例:
```
scores = [60, 80, 50, 40, 30]
for score in scores:
if score < 60:
print("有人不及格!")
else:
print("全部都及格!")
```
光上面這樣寫是不正常的
---
### 為什麼?
請看輸出結果
```
有人不及格!
有人不及格!
全部都及格!
```
自相矛盾
---
### 通常的`for else`寫法:有`break`
```PYTHON
scores = [60, 80, 50, 40]
for score in scores:
if score < 60:
print("有人不及格!")
break
else:
print("全部都及格!")
```
輸出
```
有人不及格!
```
---
### 良葛格:原則上不推薦使用迴圈else
舉例:當輸入(scores)為空
```PYTHON
scores = []
for score in scores:
if score < 60:
print("有人不及格!")
break
else:
print("全部都及格!")
```
輸出會是如何?
---
輸出:
```
全部都及格!
```
---
### 原因
只要for部分沒有被「打斷(break)」
else就一定會執行
---
### 缺點與不推薦使用的理由
- 行為不直觀,容易讓人誤解
- 許多 Python Clean Code 書也不推薦使用
- 只適合在非常「經典」的場合使用
- 或乾脆不要用
---
### try/except/else/finally
較無爭議的方便用法
```python
response = requsets.get('www.hello-world.com')
try:
crawled_data = response.data
except:
crawled_data = 'No data'
else:
print('資料爬取成功')
finally:
logger.write(crawled_data)
print("全部完成")
```
else/finally 皆為「可選」項
---
## 第二項:海象運算符 :=

---
## 正式名稱:賦值表達式(運算式)
- Assignment Expressions
- 起源與定案:[PEP 572](https://peps.python.org/pep-0572/)
- 實裝:Python 3.8
- 可謂 3.8 最具代表性的一項更新
- 運算符:`:=`,故又稱為「海象運算符(子)」
- 特色:極具爭議
---
### Syntax(語法)
海象運算子的語法格式是:
```
(variable_name := expression or value)
```
例子
```python=
walrus = False
print(walrus)
# False
print(walrus := True)
# True
```
---
### 一個典型使用場景
尚在發展中,先只關注在它的優點與使用場景,常見場景有三:
- if/else 條件式
- while 迴圈
- 生成式(Comprehension)取值
在此舉其中一個最有代表性的「while 迴圈」
主要的優點都在於「**減少重覆取值**」
---
### while 迴圈場景:命令列互動程式
傳統寫法
```python=
while True:
command = input("> ");
if command == "quit":
break
print("You entered:", command)'
# 開始執行本互動程式的主要邏輯,下略100行
```
---
### 賦值表達式寫法
```python
while (command := input("> ")) != "quit":
print("You entered:", command)
# 開始執行本互動程式的主要邏輯,下略100行
```
---
### 賦值表示式的反對看法
- 可讀性的取捨
- 變數 scope 相關議題
---
### 個人對賦值表達式看法
- 利大於弊,持「正面」觀點
- 有時候某些重覆取值確實「很不優雅」
- 尤其是這個取值行為很「耗能」之際
- 需要慎重考慮需求場景使用、切勿濫用
- 判斷標準:**有感**
---
## 第三項、Python Docstring
---
### 程式碼中的「文件」——Docstring
- 來源:[PEP 257](https://peps.python.org/pep-0257/)
- 定義:在模組、類別、函式(主要)中的說明文件,為程式碼的一部分,可使用物件的`__doc__`方法取得其內容
- 功能:提升程式可讀性與提高協作效率
---
### 語法:使用三引號「`"""`」或「`'''`」
- 慣例上會使用3個雙引號——PEP 257。
- 位置在模組、類別、函式的開頭,說明該元件的功能與用途
- 形式上有「單行」與「多行」
---
### 「單行」docstring
僅僅一行「主旨」,就能帶來大量資訊
```python=
def get_gateway_connection_string(request, device_id):
"""取得gateway所屬的連接字串"""
...
```
使用場景:函式需要說明,但不用太詳細,說明主旨已足
---
### 「多行」docstring
```python
def manage_gateway(request, gateway_id):
"""
取得單一gateway資訊
PATCH: 修改單一gateway資訊
DELETE: 刪除單一gateway
"""
context = {}
...
```
---
### 「多行」docstring
標準 Docstring 風格之一:google style
```python=
def function_with_types_in_docstring(param1, param2):
"""Example function with types documented
in the docstring.
Args:
param1 (int): The first parameter.
param2 (str): The second parameter.
Returns:
bool: The return value.
```
目前cloud team採:單行 + google style
---
### 實例演示
模組與類別的 docstring
`config.py`內容:
```python=
"""專案內程式碼自訂的設定
主要用來區別第三方套件的設定以及 Django settings.py 設定內容
"""
class HostType:
"""
Host類型與代號對照
"""
CLOUD = 0
TENANT = 1
PROJECT = 2
GATEWAY = 3
```
---
複雜函式的 docstring
```python=
def write_ew50_data_into_redis(slaves, ew50_data, gateway_id, received_time):
for slave in slaves:
prefix = slave['rule_name']
registers = slave['registers']
for index, register in enumerate(registers):
data_id = uuid.UUID(register['_id']).hex
save_serial_to_redis(data_id, gateway_id, received_time / 1000,
ew50_data[prefix + str(index + 1)])
```
---

---
### IDE 整合
藉由呼叫物件的「`__doc__`」方法

---
## Thank You 😚
{"metaMigratedAt":"2023-06-17T11:52:26.934Z","metaMigratedFrom":"Content","title":"《Python 精粹》書摘分享","breaks":true,"contributors":"[{\"id\":\"a43222ff-e8b4-4263-9ff7-5fc01611a8f8\",\"add\":5855,\"del\":1132}]"}