24 型別標注
24.1 Python中的資料型別
? ? 在Python中有很多資料型別,比較常見如下所示:
| 整型 | 浮點型 | 字串 | 串列 | 元組 | 字典 | 集合 | 布爾 |
|---|---|---|---|---|---|---|---|
| int | float | str | list | tuple | dict | set | bool |
? ? 因Python是弱型別語言,所以在實際寫代碼時,一般不去宣告和定義引數的型別,示例如下:
def welcome(city):
print(f"welcome to {city}")
? ? 以上代碼非常簡單,就是輸出一行歡迎標語,而在大家看到這個代碼,也都默認了city是一個字串型別(str),
? ? 現在我們來改造一下代碼,將傳入的city引數全部變為大寫,代碼如下所示:
def welcome(city):
print(f"welcome to {city.upper()}")
以上代碼在傳入的city為字串型別時,一切正常,但如果傳入的是非字串型別就會報錯,例如傳入123,便會出現如下所示的報錯
AttributeError: 'int' object has no attribute 'upper'
24.2 指定型別
24.2.1 指定變數型別
24.2.1.1 指定變數型別
? ? 針對以上問題,Python 3.5中引入了typing包,推薦使用型別標注,并且IDE會檢查型別,讓Python看起來有點像靜態語言的感覺,
? ? 那如何指定變數型別呢?只需要在變數名后 :型別 即可,如下所示:
def welcome(city:str):
print(f"welcome to {city.upper()}")
24.2.1.2 變數型別宣告的好與壞
? ? 變數型別宣告,對于之前有使用過強型別語言的人來講,可能習以為常,但卻對弱型別的語言,可能不太習慣,但確實還是有一些好處的,
- 以上面代碼為例,如果定義為str型別,而實際傳入為int時,PyCharm會進行相應的提示,不能這樣做,如下所示:

- PyCharm會有更多提示
? ? 在Python中,str型別的資料會有很多方法,而在指定資料型別后,PyCharm則會有更多提示,如下所示:

- 閱讀代碼方便,可以更快的知道需要傳入什么型別的資料及回傳的資料型別
? ? 在指定變數的資料型別時,也是有一些壞處的,如下所示:
- 在撰寫代碼,需要多寫一些代碼,看起來沒有那么流暢
- 雖然指定的資料型別,但也僅僅是方便查看,并沒有規定死變數型別,如指定為str型別,但傳入int,依然可以運行代碼,沒有在運行層面進行檢查
24.2.2 指定回傳值型別
? ? 在Python里面,方法/函式都是有回傳值的,那么使用型別標的話,可以直接方法/函式末尾冒號之前添加 ->型別,示例如下所示:
def welcome(city:str)->str:
return city.upper()
? ? 這樣做的好處跟之前示例一樣,IDE可以更加智能提示,防止撰寫代碼出錯,如下所示:

? ? 指定型別并不會影響編譯結果,但也有很多好處,如下所示:
- 提高開發效率
- 降低出錯率
- 閱讀代碼更友好
24.3 typing包
24.3.1 typing作用
? ? 主要作用如下所示:
- 型別檢查,防止運行時出現引數和回傳值型別不符合
- 做為開發檔案附加說明,方便呼叫者快速查看傳入和回傳資料型別
- 加入該模塊后,不影響程式運行,僅有提醒
typing模塊只有在Python 3.5 以上版本中才可以使用,PyCharm支持typing檢查
24.3.2 typing包常見資料型別
| 型別 | 備注 |
|---|---|
| int | int |
| str | str |
| List | 串列,也可以使用list |
| List[型別] | 指定串列中存放的資料型別 |
| Tuple | 元組,也可以使用tuple |
| Tuple[型別] | 指定元組中存放的資料型別 |
| Set | 集合,也可以使用set |
| Set[型別] | 指定集合中存放的資料型別 |
| Dict | 字典,也可以使用dict |
| Dict[型別1,型別2] | key為型別1,value為型別2的字典 |
| Sequence[型別] | 指定序列中存放的資料型別 |
| NoReturn | 表示無回傳型別 |
| Any | 任意型別 |
| TypeVar | 自定義兼容特定型別的變數 |
| Union[型別1,型別2] | 聯合型別,可以接受型別1或型別2 |
| Optional[型別] | 引數可以為慷訓已經宣告的型別 |
常見的型別如上表格表示,如果需要使用List,Set,Dict,Union則需要匯入typing
from typing import List,Set,Dict
24.3.3 typing包常見資料型別用法
- List
? ? List:串列,是list的泛型,基本等同于list,其后緊跟一個方括號,里面代表了構成這個串列的元素型別,示例如下所示:
from typing import List
# 基本宣告
listSample:List[int or str]=[1,"Surpass"]
# 嵌套宣告
listSample:List[List[int]]=[[1,2],[3,4]]
- Tuple
? ? Tuple:元組,是 tuple 的泛型,其后緊跟一個方括號,方括號中按照順序宣告了構成本元組的元素型別,如 Tuple[X, Y] 代表了構成元組的第一個元素是 X 型別,第二個元素是 Y 型別,示例如下所示:
from typing import Tuple
personInfo:Tuple[str,int,float,str]=("Surpass",28,62.33,"Shanghai")
- Set/AbstractSet
? ? Set(集合)是set 的泛型,AbstractSet是 collections.abc.Set 的泛型,根據官方檔案,Set 推薦用于注解回傳型別,AbstractSet 用于注解引數,使用方法是后面跟一個中括號,里面宣告集合中元素的型別,示例如下所示:
from typing import Set,AbstractSet
def SetSample(s:AbstractSet[int]) -> Set[int]:
return set(s)
- Dict/Mapping
? ? Dict(字典)是 dict 的泛型,Mapping(映射)是 collections.abc.Mapping 的泛型,根據官方檔案,Dict推薦用于注解回傳型別,Mapping 推薦用于注解引數,使用方法都是其后跟一個中括號,中括號內分別宣告鍵名、鍵值的型別,示例如下所示:
from typing import Dict,Mapping
def DictSample(personInfo:Mapping[str,str])->Dict[str,str]:
return {"name":personInfo["name"],"location":personInfo["location"]}
- Sequence
? ? Sequence是 collections.abc.Sequence 的泛型,在某些情況下,我們可能并不需要嚴格區分一個變數或引數到底是串列型別還是元組型別,則可以使用一個更為泛化的型別,叫做 Sequence,其用法類似于List,示例如下所示:
from typing import Sequence,List
def Square(ele:Sequence[int])->List[int]:
return [i**2 for i in ele]
- NoReturn
? ? 當一個方法沒有回傳結果時,為了注解它的回傳型別,我們可以將其注解為 NoReturn,示例如下所示:
from typing import NoReturn
def hello(word:str)->NoReturn:
print(word.title())
- Any
? ? Any是一種特殊的型別,它可以代表所有任意型別,靜態型別檢查器的所有型別都與 Any 型別兼容,所有的無引數型別注解和回傳型別注解的都會默認使用 Any 型別,以下示例兩種是完全等價相同的
from typing import Any
def hello(word):
return word.title()
def hello(word:Any)->Any:
return word.title()
- TypeVar
? ? TypeVar可以用來自定義兼容特定型別的變數,比如有的變數宣告為int、float、str都是符合要求的,實際就是代表任意的數字或者字串都是可以的,其他的型別則不可以,例如一個人的身高,便可以使用 int 或 float 或 None 來表示,但不能用 dict 來表示,所以可以這么宣告:
from typing import TypeVar
Height=TypeVar(int,float,None)
def getHeight(height)->Height:
return height
- NewType
? ? NewType,我們可以借助于其來宣告一些具有特殊含義的型別,如前面Tuple示例,需要用來定義一個Person資訊,但從表面上宣告為Tuple不太直觀,因此可以借助NewType來進行宣告,示例如下所示:
from typing import NewType,Tuple
personInfo=NewType("PersonInfo",Tuple[str,int,float,str])
person=personInfo(("Surpass",28,62.33,"Shanghai"))
示例中person就是一個tuple型別,跟其他tuple型別一樣進行操作
- Union
? ? Union(聯合型別),Union[型別1,型別2] 代表要么是型別1型別,要么是型別2 型別,聯合型別的聯合型別等價于展平后的型別:
Union[Union[int, str], float] == Union[int, str, float]
? ? 僅有一個引數的聯合型別等同于引數自身,示例如下:
Union[int] == int
? ? 如果存在相同型別的時候,則會進行去重處理,示例如下:
Union[int, str, int] == Union[int, str]
? ? 在比較聯合型別的時候,引數順序會被忽略,示例如下:
Union[int, str] == Union[str, int]
from typing import Union
def getType(params:Union[int,str,float])->str:
if isinstance(params,int):
return f"{params} type is int"
elif isinstance(params,float):
return f"{params} type is float"
elif isinstance(params,str):
return f"{params} type is str"
else:
return f"{params} type is unknown"
- Optional
? ? Optional意思是說這個引數可以為慷訓已經宣告的型別,即 Optional[型別1] 等價于 Union[型別1, None]
需要注意的是這個并不等價于可選引數,當它作為引數型別注解的時候,不代表這個引數可以不傳遞了,而是說這個引數可以傳為 None,
from typing import Optional
def getInfo(data:Optional[int])->Optional[str]:
if isinstance(data,int):
return f"INFO - {data} type is int"
elif data is None:
return f"WARNING - {data} type is None"
else:
return f"ERROR - {data} type is not int,"
原文地址:https://www.jianshu.com/p/5b135f8dec0d
本文同步在微信訂閱號上發布,如各位小伙伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

作者: Surpassme
來源: http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
宣告:本文著作權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出 原文鏈接 ,否則保留追究法律責任的權利,如有問題,可發送郵件 聯系,讓我們尊重原創者著作權,共同營造良好的IT朋友圈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500745.html
標籤:Python
