Python從3.7開始各版本新增特性和示例

qiao39gs發表於2024-06-07

1. Python 3.7 新特性

1.1 PEP 563: 延遲的標註求值

Python 3.7 引入了 PEP 563,這允許型別註解的延遲求值,解決了型別提示中的兩個主要問題:啟動效能和前向引用。透過延遲求值,型別註解在定義時不會被立即計算,而是在需要時才解析,從而提升了程式啟動效能。此外,這使得開發者可以使用前向引用,即在類定義中引用尚未定義的型別。

1.2 PEP 538: 傳統 C 區域強制轉換

PEP 538 更新了 Python 直譯器的預設命令列介面,以自動將傳統的 C 區域強制轉換為基於 UTF-8 的區域。這意味著核心直譯器和能感知區域的 C 擴充套件都將假定 UTF-8 作為預設的文字編碼,而不是 ASCII。這一改變提高了 Python 在國際化環境中的文字處理能力。

1.3 PEP 540: 強制 UTF-8 執行時模式

Python 3.7 新增了 -X utf8 命令列選項和 PYTHONUTF8 環境變數,用於啟用 CPython 的 UTF-8 模式。在此模式下,CPython 忽略區域設定,預設使用 UTF-8 編碼,這簡化了在不同系統上的文字處理。

1.4 PEP 553: 內建的 breakpoint()

Python 3.7 包含了新的內建 breakpoint() 函式,提供了一種簡單方便地進入 Python 偵錯程式的方式。這個函式會呼叫 sys.breakpointhook(),在預設情況下會匯入 pdb 並呼叫 pdb.set_trace(),允許開發者在程式碼中快速設定斷點進行除錯。透過設定 PYTHONBREAKPOINT 環境變數,可以配置使用的偵錯程式或禁用 breakpoint() 函式。

2. Python 3.8 新特性

2.1 Walrus運算子 (:=)

Python 3.8 引入了 Walrus 運算子(:=),這是一個賦值表示式,允許在表示式內部進行變數賦值。這個特性極大地簡化了某些型別的程式碼,特別是那些需要從複雜表示式中提取結果並將其用於後續邏輯的情況。

例如,在使用 while 迴圈時,通常需要獲取某個資源並檢查其狀態,然後決定是否繼續迴圈。在沒有 Walrus 運算子的情況下,這可能需要多行程式碼來實現。現在,可以簡化為一行程式碼:

while (line := (yield from stream.readline())):
    if終止條件(line):
        break

2.2 f-strings改進

Python 3.8 對 f-strings 進行了改進,使得在格式化字串字面值中可以使用等號和括號。這意味著開發者可以在 f-string 中直接進行表示式計算和變數替換,而不需要額外的括號來包裹表示式。

改進之前的 f-string 需要使用額外的括號來確保表示式的計算順序,如下所示:

name = "Alice"
age = 30
# 需要額外的括號來保證計算順序
print("{name}'s age is {(age + 5)} years old".format(name=name, age=age))

改進之後,可以直接在 f-string 中使用表示式,無需額外括號:

name = "Alice"
age = 30
print(f"{name}'s age is {age + 5} years old")

2.3 非同步迭代器和非同步生成器改進

Python 3.8 對非同步迭代器和非同步生成器進行了改進,使得編寫和使用非同步迭代器和生成器變得更加簡潔和直觀。

在 Python 3.7 中,非同步迭代器需要定義一個 _anext() 方法,而在 Python 3.8 中,可以直接使用 async for 迴圈來消費非同步迭代器,無需顯式呼叫 _anext() 方法。這使得非同步迭代器的使用更加方便。

此外,Python 3.8 引入了 asyncio.run() 函式,這是一個高階介面,用於執行頂層的非同步程式碼。這使得從同步程式碼中啟動非同步程式變得更加簡單。

例如,使用 asyncio.run() 啟動一個非同步程式:

import asyncio

async def main():
    # 非同步操作
    print("Hello, world!")

asyncio.run(main())

這些改進使得 Python 的非同步程式設計更加易用和強大,為開發者提供了更好的工具來編寫高效的非同步程式碼。

3. Python 3.9 新特性

3.1 字典合併運算子 (|)

Python 3.9 引入了字典合併運算子 |,它允許開發者使用簡潔的語法來合併兩個字典。這個特性特別適用於組合來自不同資料來源的字典,例如配置檔案的合併。

# 合併兩個字典
config = {"host": "localhost", "port": 8080}
defaults = {"port": 80, "timeout": 30}
combined_config = config | defaults
print(combined_config)  # 輸出:{'host': 'localhost', 'port': 8080, 'timeout': 30}

在這個例子中,combined_config 包含了 configdefaults 中的所有鍵值對,如果有相同的鍵,則 config 中的值會覆蓋 defaults 中的值。

3.2 型別提示改進

Python 3.9 對型別提示進行了改進,支援更多的型別註解語法和型別推斷。這包括對 typing 模組的更新,以及對內建集合型別的型別提示支援。

from typing import TypedDict, List

# 使用 TypedDict 定義字典結構
class User(TypedDict):
    name: str
    age: int

# 列表的型別提示
users: List[User] = [
    {"name": "Alice", "age": 30},
    {"name": "Bob", "age": 25},
]

# 現在可以更準確地標註函式返回值的型別
def get_users() -> List[User]:
    return users

這些改進使得型別提示更加靈活和強大,有助於開發者編寫更清晰和可維護的程式碼。

3.3 新標準庫模組

Python 3.9 引入了一些新的標準庫模組,其中包括 zoneinfo 模組用於處理時區資訊,以及 graphlib 模組用於處理圖形資料結構。

  • zoneinfo 模組提供了對 IANA 時區資料庫的支援,允許開發者在處理日期和時間時考慮時區。
from zoneinfo import ZoneInfo

# 建立時區物件
tz = ZoneInfo("America/New_York")
from datetime import datetime, timedelta

# 考慮時區的日期和時間
dt = datetime(2023, 1, 1, 12, 0, tzinfo=tz)
print(dt)  # 輸出考慮時區的日期和時間
  • graphlib 模組提供了圖資料結構和演算法,使得處理圖相關的問題變得更加方便。
from graphlib import TopologicalSorter

# 建立圖並新增節點和依賴關係
ts = TopologicalSorter()
ts.add('A', 'B')  # A 依賴於 B
ts.add('B', 'C')  # B 依賴於 C
ts.add('A', 'C')  # A 也依賴於 C

# 執行拓撲排序
for node in ts.static_order():
    print(node)

這些新模組的加入,進一步擴充套件了 Python 標準庫的功能,為特定領域的程式設計提供了更多的便利。

4. Python 3.10 新特性

4.1 匹配模式(match statement)

Python 3.10 引入了一種新的結構——匹配模式(match statement),這是一種類似於其他程式語言中的模式匹配或 switch-case 語句的特性。它允許開發者基於不同的情況來執行不同的程式碼塊。

def greet(name):
    match name:
        case "Alice":
            return "Hello, Alice!"
        case "Bob":
            return "Hello, Bob!"
        case _:
            return "Hello, stranger!"

在這個例子中,match 語句檢查 name 的值,並根據其與 case 子句的匹配情況來選擇執行的程式碼塊。如果沒有任何 case 子句匹配成功,那麼執行帶有 _(表示預設情況)的程式碼塊。

4.2 結構化的異常上下文

Python 3.10 對異常處理進行了改進,引入了結構化的異常上下文,使得異常資訊更加豐富和有用。現在,異常物件包含更多的屬性,比如 .__cause__.__context__,這些屬性提供了異常鏈的詳細資訊。

try:
    # 嘗試執行可能引發異常的操作
    risky_operation()
except Exception as e:
    # 列印異常的上下文資訊
    print(f"An error occurred: {e}")
    print(f"Caused by: {e.__cause__}")
    print(f"Context: {e.__context__}")

在這個例子中,如果 risky_operation() 引發異常,異常物件 e 會包含關於異常原因和上下文的詳細資訊,這有助於開發者更好地理解異常發生的環境和原因。

4.3 zoneinfo模組改進

Python 3.10 對 zoneinfo 模組進行了改進,使其更加易用和強大。現在,zoneinfo 模組提供了更簡單的方式來建立時區物件,並且可以直接使用時區名稱作為引數。

from zoneinfo import ZoneInfo

# 直接使用時區名稱建立時區物件
tz = ZoneInfo("America/New_York")

# 使用時區物件處理時間
dt = datetime(2023, 1, 1, 12, 0, tzinfo=tz)
print(dt)  # 輸出考慮時區的日期和時間

此外,zoneinfo 模組現在支援從作業系統的時區資料庫載入時區資訊,這意味著開發者可以更容易地獲取和使用最新的時區資料。這些改進使得 zoneinfo 模組成為處理時區相關問題的首選工具。

5. 示例程式碼

5.1 Python 3.7 型別標註示例

Python 3.7 引入了對型別標註的改進,使得程式碼更加清晰和易於維護。以下是使用型別標註的示例:

from typing import List

def greet(names: List[str]) -> None:
    for name in names:
        print(f"Hello, {name}!")

# 使用型別標註的函式
greet(["Alice", "Bob", "Charlie"])

5.2 Python 3.8 Walrus運算子示例

Walrus 運算子 (:=) 允許在表示式內部進行變數賦值,這使得某些程式碼更加簡潔。以下是 Walrus 運算子的示例:

def find_first_even(numbers):
    for number in numbers:
        if (even := number % 2 == 0):
            return number
    return None

# 使用 Walrus 運算子簡化 if 語句
print(find_first_even([1, 3, 5, 8]))

5.3 Python 3.9 字典合併運算子示例

字典合併運算子 | 使得合併字典變得非常簡單。以下是使用字典合併運算子的示例:

# 使用字典合併運算子合並字典
personal_info = {"name": "Alice", "age": 30}
contact_info = {"email": "alice@example.com", "phone": "123-456-7890"}

full_info = personal_info | contact_info
print(full_info)

5.4 Python 3.10 匹配模式示例

匹配模式(match statement)提供了一種新的方式來執行基於模式的程式碼分支。以下是使用匹配模式的示例:

def get_greeting(name: str) -> str:
    match name.lower():
        case "alice":
            return "Hello, Alice!"
        case "bob":
            return "Hello, Bob!"
        case _:
            return "Hello, there!"

# 使用匹配模式根據不同的名字返回不同的問候語
print(get_greeting("Alice"))
print(get_greeting("Bob"))
print(get_greeting("Charlie"))

6. 總結

Python自3.7版本以來,引入了一系列新特性,這些特性不僅提升了語言的表達能力,也增強了效能和易用性。從型別註解的改進、字串格式化的增強,到非同步程式設計的簡化,再到模式匹配的引入,Python持續在為開發者提供更加強大和靈活的工具。

6.1 型別系統和效能的提升

型別註解的增強,包括延遲求值和更豐富的型別提示,使得Python程式碼的可讀性和可維護性得到了顯著提升。同時,透過改進型別系統的實現,提高了程式的啟動效能。

6.2 國際化和本地化的支援

透過PEP 538和PEP 540,Python加強了對國際化和本地化的支援,使得Python程式能夠更好地處理多語言文字,簡化了在不同區域設定下的文字處理。

6.3 非同步程式設計的進步

Python 3.8和3.9版本對非同步迭代器和生成器的改進,以及asyncio.run()的引入,使得Python在非同步程式設計領域更加成熟,為編寫高效的非同步程式碼提供了更好的支援。

6.4 語言結構的增強

Walrus運算子的引入,以及字典合併運算子的出現,進一步豐富了Python的語言結構,使得某些型別的程式碼編寫變得更加簡潔和直觀。

6.5 模式匹配的引入

Python 3.10版本引入的匹配模式,為Python增添了一種新的程式碼分支結構,使得基於資料的程式碼執行更加靈活和強大。

6.6 新標準庫模組的加入

新加入的zoneinfographlib模組,擴充套件了Python標準庫的功能,為處理時區和圖資料結構提供了原生支援。

這些新特性的引入,不僅反映了Python社群對語言發展的持續貢獻,也顯示了Python作為一種現代程式語言,其活躍的生態系統和強大的生命力。隨著Python的不斷進步,我們可以期待它在未來的軟體開發中扮演更加重要的角色。

相關文章