Python3的高級用法之類型提示
是不是曾經看到過類似這樣的代碼
def greeting(name: str) -> str:
return 'Hello ' + name
感覺很高大上。
這其實是Python3.5版本開始的一個新功能,類型提示。這個代碼的意思就是,提示你輸入參數name的值是str類型,返回值也是str類型。
以下參考官方文檔。
類型別名
from typing import List
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# typechecks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
把list里面放float類型,並且取個新名字叫Vector
取別名在限定復雜的參數類型的時候很有用,比如以下代碼
from typing import Dict, Tuple, List
ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: List[Server]) -> None:
...
# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
message: str,
servers: List[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
...
自己定義類型
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
自己定義了一個UserId類型
這個有啥用呢?繼續看一個代碼
def get_user_name(user_id: UserId) -> str:
...
# 正常
user_a = get_user_name(UserId(42351))
# 直接傳-1也沒事,不進行類型檢查。
user_b = get_user_name(-1)
-1雖說是int類型,但是,不是UserId類型,直接傳-1也不會報錯,靜態檢查器會把新類型看成為原始類型的子類,這樣有助於處理邏輯錯誤。
新定義的UserId類型也能執行int類型的運算
# 'output' 是int類型,而不是UserId類型
output = UserId(23413) + UserId(54341)
注意:這里為啥最后output是int類型,官方解釋是,自己定義的類型僅由靜態類型檢查器強制執行,但是運行時會立馬返回原始類型(也就是int類型),這也就意味着不能直接創建UserId的子類型,因為他是運行時的標識函數,而不是實際類型
看一下這個小例子
def test(name: str) -> str:
return (1,2)
test([1,2,3])
看這里,要求輸入是str類型,我強行輸入的是一個list,要求返回的是str,我強行返回的是一個tuple,但是這個代碼並不報錯,而且返回的類型是tuple而不是指定的str
我的理解是,這個只是一個標注作用,目前來說就是提示別人調用我的函數的人,我的參數類型是什么,返回值的類型是什么。就是一個提示作用,並不會對這些類型進行匹配檢查。后期我覺得官方可能會強制要求類型必須匹配,也許不會(不然有點像java的感覺了)。
