詳解python3類型注釋annotations實用案例
1、類型注解簡介
Python是一種動態(tài)類型化的語言,不會強制使用類型提示,但為了更明確形參類型,自python3.5開始,PEP484為python引入了類型注解(type hints)
示例如下:
2、常見的數(shù)據類型
- int,long,float: 整型,長整形,浮點型
- bool,str: 布爾型,字符串類型
- List, Tuple, Dict, Set: 列表,元組,字典, 集合
- Iterable,Iterator: 可迭代類型,迭代器類型
- Generator:生成器類型
- Sequence: 序列
3、基本的類型指定
def test(a: int, b: str) -> str: print(a, b) return 200 if __name__ == '__main__': test('test', 'abc')
函數(shù)test,a:int 指定了輸入參數(shù)a為int類型,b:str b為str類型,-> str 返回值為srt類型。可以看到,在方法中,我們最終返回了一個int,此時pycharm就會有警告;
當調用這個方法時,參數(shù)a 輸入的是字符串,此時也會有警告;
but…,pycharm這玩意兒 只是
提出了警告
,但實際上運行是不會報錯,畢竟python的本質還是動態(tài)語言
。
4、復雜的類型指定
指定列表
from typing import List Vector = List[float] def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector] # type checks; a list of floats qualifies as a Vector. new_vector = scale(2.0, [1.0, -4.2, 5.4]) print(new_vector)
指定 字典、元組 類型
from typing import Dict, Tuple, Sequence ConnectionOptions = Dict[str, str] Address = Tuple[str, int] Server = Tuple[Address, ConnectionOptions] def broadcast_message(message: str, servers: Sequence[Server]) -> None: print(message) print(servers) # The static type checker will treat the previous type signature as # being exactly equivalent to this one. if __name__ == '__main__': broadcast_message('OK', [(('127.0.0.1', 8080), {"method": "GET"})])
這里需要注意,元組這個類型是比較特殊的,因為它是不可變的。
所以,當我們指定Tuple[str, str]時,就只能傳入長度為2
,并且元組中的所有元素
都是str類型
5、創(chuàng)建變量時的類型指定
對于常量或者變量添加注釋
from typing import NamedTuple class Employee(NamedTuple): name: str id: int = 3 employee = Employee('Guido') # assert employee.id == 3 # 當類型一致時,不會輸出內容,反之報錯 assert employee.id == '3' # 當類型一致時,不會輸出內容,反之報錯 # AssertionError
指定一個變量odd,顯式的聲明了它應該是整數(shù)列表。如果使用mypy來執(zhí)行這個腳本,將不會收到任何提示輸出,因為已經正確地傳遞了期望的參數(shù)去執(zhí)行所有操作。
from typing import List def odd_numbers(numbers: List) -> List: odd: List[int] = [] for number in numbers: if number % 2: odd.append(number) return odd if __name__ == '__main__': numbers = list(range(10)) print(odd_numbers(numbers))
mypy 安裝
pip install mypy
執(zhí)行 mypy file,正常情況下不會報錯
C:\Users\Sunny_Future\AppData\Roaming\Python\Python36\Scripts\mypy.exe tests.py
# 指定 環(huán)境變量或者 linux 下可以直接執(zhí)行 mypy
# mypy tests.py
Success: no issues found in 1 source file
接下來,嘗試更改一下代碼,試圖去添加整形之外的其他類型內容!那么執(zhí)行則會檢查報錯
from typing import List def odd_numbers(numbers: List) -> List: odd: List[int] = [] for number in numbers: if number % 2: odd.append(number) odd.append('foo') return odd if __name__ == '__main__': numbers = list(range(10)) print(odd_numbers(numbers))
代碼中添加一個行新代碼,將一個字符串foo
附加到整數(shù)列表中?,F(xiàn)在,如果我們針對這個版本的代碼來運行mypy
C:\Users\Sunny_Future\AppData\Roaming\Python\Python36\Scripts\mypy.exe tests.py
tests.py:114: error: Argument 1 to “append” of “l(fā)ist” has incompatible type “str”; expected “int”
Found 1 error in 1 file (checked 1 source file)
6、 泛型指定
from typing import Sequence, TypeVar, Union T = TypeVar('T') # Declare type variable def first(l: Sequence[T]) -> T: # Generic function return l[0] T = TypeVar('T') # Can be anything A = TypeVar('A', str, bytes) # Must be str or bytes A = Union[str, None] # Must be str or None
7、再次重申
在Python 3.5中,你需要做變量聲明,但是必須將聲明放在注釋中:
# Python 3.6 odd: List[int] = [] # Python 3.5 odd = [] # type: List[int]
如果使用Python 3.5的變量注釋語法,mypy仍將正確標記該錯誤。你必須在
#
井號之后指定type:。如果你刪除它,那么它就不再是變量注釋了?;旧螾EP 526增加的所有內容都為了使語言更加統(tǒng)一。
8、不足之處
雖然指定了 List[int] 即由 int 組成的列表,但是,實際中,只要這個列表中存在 int(其他的可以為任何類型),pycharm就不會出現(xiàn)警告,使用 mypy 才能檢測出警告!
from typing import List def test(b: List[int]) -> str: print(b) return 'test' if __name__ == '__main__': test([1, 'a'])
pycharm 并沒有檢測出類型錯誤,沒有告警
mypy
工具 檢測到 類型異常,并進行了報錯
9、demo
# py2 引用 from__future__import annotations
class Starship: captain: str = 'Picard' damage: int stats: ClassVar[Dict[str, int]] = {} def __init__(self, damage: int, captain: str = None): self.damage = damage if captain: self.captain = captain # Else keep the default def hit(self): Starship.stats['hits'] = Starship.stats.get('hits', 0) + 1 enterprise_d = Starship(3000) enterprise_d.stats = {} # Flagged as error by a type checker Starship.stats = {} # This is OK
from typing import Dict class Player: ... players: Dict[str, Player] __points: int print(__annotations__) # prints: {'players': typing.Dict[str, __main__.Player], # '_Player__points': <class 'int'>}
class C: __annotations__ = 42 x: int = 5 # raises TypeError
到此這篇關于詳解python3類型注釋annotations實用案例的文章就介紹到這了,更多相關python3類型注釋annotations內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
修復Python?Pandas數(shù)據標記錯誤的幾種方法總結
用于分析數(shù)據的?Python?庫稱為?Pandas,在?Pandas?中讀取數(shù)據最常見的方式是通過?CSV?文件,但?CSV?文件的限制是它應該采用特定的格式,否則在標記數(shù)據時會拋出錯誤,在本文中,我們將討論修復?Python?Pandas?錯誤標記數(shù)據的各種方法2023-10-10Python3+django2.0+apache2+ubuntu14部署網站上線的方法
這篇文章主要介紹了Python3+django2.0+apache2+ubuntu14部署網站上線的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07python+selenium實現(xiàn)登錄賬戶后自動點擊的示例
本篇文章主要介紹了python+selenium實現(xiàn)登錄賬戶后自動點擊的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12python科學計算之numpy——ufunc函數(shù)用法
今天小編就為大家分享一篇python科學計算之numpy——ufunc函數(shù)用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11Python中torch.load()加載模型以及其map_location參數(shù)詳解
torch.load()作用用來加載torch.save()保存的模型文件,下面這篇文章主要給大家介紹了關于Python中torch.load()加載模型以及其map_location參數(shù)的相關資料,需要的朋友可以參考下2022-09-09