天天看點

python進階(21)typing子產品--類型提示支援

typing介紹

  Python是一門弱類型的語言,很多時候我們可能不清楚函數參數的類型或者傳回值的類型,這樣會導緻我們在寫完代碼一段時間後回過頭再看代碼,忘記了自己寫的函數需要傳什麼類型的參數,傳回什麼類型的結果,這樣就不得不去閱讀代碼的具體内容,降低了閱讀的速度,

typing

子產品可以很好的解決這個問題

注意:

typing

子產品隻有在python3.5以上的版本中才可以使用,pycharm目前支援typing檢查

typing的作用

  • 類型檢查,防止運作時出現參數和傳回值類型不符合。
  • 作為開發文檔附加說明,友善使用者調用時傳入和傳回參數類型。
  • 該子產品加入後并不會影響程式的運作,不會報正式的錯誤,隻有提醒pycharm目前支援typing檢查,參數類型錯誤會黃色提示

常用類型

  • int,long,float: 整型,長整形,浮點型;
  • bool,str: 布爾型,字元串類型;
  • List, Tuple, Dict, Set:清單,元組,字典, 集合;
  • Iterable,Iterator:可疊代類型,疊代器類型;
  • Generator:生成器類型;

除了以上常用的類型,還支援

Any

Union

Tuple

Callable

TypeVar

Generic

類型組成。有關完整的規範,請參閱 PEP 484。有關類型提示的簡單介紹,請參閱 PEP 483

代碼示例

python進階(21)typing子產品--類型提示支援

我們可以發現,func函數要求傳入的第2個參數為

str

類型,而我們調用時傳入的參數是

int

類型,此時Pycharm就會用黃色來警告你,我們将光标放到黃色的地方,會出現下面的提示

python進階(21)typing子產品--類型提示支援

寫着期望類型是

str

,而現在是

int

,但是

typing

的作用僅僅是提示,并不會影響代碼執行,我們執行看看

執行結果如下:

[2, 3]
           

我們會發現并沒有報錯,因為

typing

僅僅是起到了提醒的作用

typing子產品的其他用法

  • 類型别名
  • NewType
  • Callable
  • TypeVar泛型
  • Any類型
  • Union類型

類型别名,就是給複雜的類型取個别名

# 給List[float]類型取個别名為Vector
Vector = List[float]


def scale(scalar: float, vector: Vector) -> Vector:
    return [scalar * num for num in vector]

new_vector = scale(2.0, [1.0, -4.2, 5.4])
           

當然,類型别名我們完全可以不用,用以下寫法也一樣,看個人喜好

def scale(scalar: float, vector: List[float]) -> List[float]:
    return [scalar * num for num in vector]
           

官網看了下,個人覺得這個沒啥用,就不細寫了

期望特定簽名的回調函數的架構可以将類型标注為

Callable[[Arg1Type, Arg2Type], ReturnType]

  • [Arg1Type, Arg2Type]:代表參數類型
  • ReturnType:代表傳回值類型
from typing import Callable


def get_next_item(name: str):
    print(name)

# Callable 作為函數參數使用,其實隻是做一個類型檢查的作用,檢查傳入的參數值 get_next_item 是否為可調用對象
def feeder(get_next_item: Callable[[str], None]) -> (str):
    return get_next_item


v1 = feeder(get_next_item)
v1('hello')

# 結果
hello
           

可以自定義一個任意類型,也可以自定義指定類型

自定義一個任意類型

# 自定義一個任意類型
T = TypeVar('T')


def func(user: T) -> T:
    print(user)
    return user


func('1')
func(1)
func([1])
func((1, 2))
func({"status": 200})

# 結果
1
1
[1]
(1, 2)
{'status': 200}
           

自定義指定類型

# 指定為int或者str
a = TypeVar('a', int, str)

s1: a = 1
s2: a = 'aaa'
s3: a = []  # 這裡定義了清單,pycharm會出現黃色警告

print(s1, s2, s3)

# 結果
1 aaa []
           

Any

Any

是一種特殊的類型。靜态類型檢查器認為所有類型均與

Any

相容,同樣,

Any

也與所有類型相容。

也就是說,可對

Any

類型的值執行任何操作或方法調用,并指派給任意變量:

from typing import Any

a = None    # type: Any
a = []      # OK
a = 2       # OK

s = ''      # type: str
s = a       # OK

def foo(item: Any) -> int:
    # Typechecks; 'item' could be any type,
    # and that type might have a 'bar' method
    item.bar()
    ...
           

此外,未指定傳回值與參數類型的函數,都隐式地預設使用

Any

def legacy_parser(text):
    ...
    return data

# 兩種寫法效果是一樣的
def legacy_parser(text: Any) -> Any:
    ...
    return data
           

Union

Union類型文法格式:

Union[X, Y]

,相當于

X | Y

,意思是類型是X或者Y

如果我們想定義

Union

類型,就要寫成如下的eg:

Union[X, Y]

,或者也可以使用縮寫X | Y(此寫法python3.10版本才支援)

from typing import Union

# 指定變量a的類型為int或者str
a: Union[int, str]
a = 1
print(a)

a = []  # 定義了一個清單,pycharm會有黃色警告提示