Python -型別提示 Type Hints

小菠蘿測試筆記發表於2021-08-16

為什麼會有型別提示

  • Python是一種動態型別語言,這意味著我們在編寫程式碼的時候更為自由,執行時不需要指定變數型別
  • 但是與此同時 IDE 無法像靜態型別語言那樣分析程式碼,及時給我們相應的提示,比如字串的 split 方法
def split_str(s):
    strs = s.split(",")

由於不知道引數 s 是什麼型別,所以當你敲  s.  的時候不會出現 split 的語法提示

 

解決上述問題,型別提示

Python 3.6 新增了兩個特性 PEP 484 和 PEP 526

幫助 IDE 為我們提供更智慧的提示

這些新特性不會影響語言本身,只是增加一點提示

 

型別提示分類

主要分兩個

  • 變數提示:PEP 526 特性加的
  • 函式引數提示:PEP 484 特性加的

 

變數型別提示

沒有使用型別提示

想說明變數的資料型別只能通過註釋

# 'primes' is a list of integers
primes = []  # type: List[int]

# 'captain' is a string (Note: initial value is a problem)
captain = ...  # type: str


class Starship:
    # 'stats' is a class variable
    stats = {}  # type: Dict[str, int]

 

使用了型別提示

from typing import List, ClassVar, Dict

# int 變數,預設值為 0
num: int = 0

# bool 變數,預設值為 True
bool_var: bool = True

# 字典變數,預設為空
dict_var: Dict = {}

# 列表變數,且列表元素為 int
primes: List[int] = []


class Starship:
    # 類變數,字典型別,鍵-字串,值-整型
    stats: ClassVar[Dict[str, int]] = {}

    # 例項變數,標註了是一個整型
    num: int

這裡會用到 typing 模組,後面會再展開詳解

 

假設變數標註了型別,傳錯了會報錯嗎?

from typing import List

# int 變數,預設值為 0
num: int = 0

# bool 變數,預設值為 True
bool_var: bool = True

# 字典變數,預設為空
dict_var: Dict = {}

# 列表變數,且列表元素為 int
primes: List[int] = []


num = "123"
bool_var = 123
dict_var = []
primes = ["1", "2"]

print(num, bool_var, dict_var, primes)


# 輸出結果
123 123 [] ['1', '2']

它並不會報錯,但是會有 warning,是 IDE 的智慧語法提示

所以,這個型別提示更像是一個規範約束,並不是一個語法限制

 

變數型別提示-元組打包

# 正常的元組打包
a = 1, 2, 3

# 加上型別提示的元組打包
t: Tuple[int, ...] = (1, 2, 3)
print(t)

t = 1, 2, 3
print(t)

# py3.8+ 才有的寫法
t: Tuple[int, ...] = 1, 2, 3
print(t)

t = 1, 2, 3
print(t)


# 輸出結果
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)

 

為什麼要加 ...

不加的話,元組打包的時候,會有一個 warning 提示

 

變數型別提示-元組解包

# 正常元組解包
message = (1, 2, 3)
a, b, c = message
print(a, b, c)  # 輸出 1 2 3

# 加上型別提示的元組解包
header: str
kind: int
body: Optional[List[str]]

# 不會 warning 的栗子
header, kind, body = ("str", 123, ["1", "2", "3"])

# 會提示 warning 的栗子
header, kind, body = (123, 123, ["1", "2", "3"])

Optional 會在後面講 typing 的時候詳解

 

在類裡面使用

class BasicStarship:
    captain: str = 'Picard'               # 例項變數,有預設值
    damage: int                           # 例項變數,沒有預設值
    stats: ClassVar[Dict[str, int]] = {}  # 類變數,有預設值

 

ClassVar

  • 是 typing 模組的一個特殊類
  • 它向靜態型別檢查器指示不應在類例項上設定此變數

 

函式引數型別提示

不僅提供了函式引數列表的型別提示,也提供了函式返回的型別提示

栗子一

# 引數 name 型別提示 str,而函式返回值型別提示也是 str
def greeting(name: str) -> str:
    return 'Hello ' + name

 

栗子二

 def greeting(name: str, obj: Dict[str, List[int]]) -> None:
    print(name, obj)

 

相關文章