溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python中typing模塊怎么使用

發(fā)布時(shí)間:2022-05-17 09:14:42 來(lái)源:億速云 閱讀:150 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“Python中typing模塊怎么使用”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Python中typing模塊怎么使用”文章能幫助大家解決問(wèn)題。

typing庫(kù)

一、 簡(jiǎn)介

Python是一門(mén)弱類(lèi)型的語(yǔ)言,很多時(shí)候我們可能不清楚函數(shù)參數(shù)類(lèi)型或者返回值類(lèi)型,很有可能導(dǎo)致一些類(lèi)型沒(méi)有指定方法,在寫(xiě)完代碼一段時(shí)間后回過(guò)頭看代碼,很可能忘記了自己寫(xiě)的函數(shù)需要傳什么參數(shù),返回什么類(lèi)型的結(jié)果,就不得不去閱讀代碼的具體內(nèi)容,降低了閱讀的速度,typing模塊可以很好的解決這個(gè)問(wèn)題

Python 運(yùn)行時(shí)并不強(qiáng)制標(biāo)注函數(shù)和變量類(lèi)型。類(lèi)型標(biāo)注可被用于第三方工具,比如類(lèi)型檢查器、集成開(kāi)發(fā)環(huán)境、靜態(tài)檢查器等

typing的主要作用有:

  • 類(lèi)型檢查,防止運(yùn)行時(shí)出現(xiàn)參數(shù)、返回值類(lèi)型不符

  • 作為開(kāi)發(fā)文檔附加說(shuō)明,方便使用者調(diào)用時(shí)傳入和返回參數(shù)類(lèi)型

  • 模塊加入不會(huì)影響程序的運(yùn)行不會(huì)報(bào)正式的錯(cuò)誤,pycharm支持typing檢查錯(cuò)誤時(shí)會(huì)出現(xiàn)黃色警告

語(yǔ)法:

def 函數(shù)名(參數(shù): 數(shù)據(jù)類(lèi)型) -> 返回值類(lèi)型:
    pass

變量名: 數(shù)據(jù)類(lèi)型 = 值

二、 別名

1、 類(lèi)型別名

要定義一個(gè)類(lèi)型別名,可以將一個(gè)類(lèi)型賦給別名。類(lèi)型別名可用于簡(jiǎn)化復(fù)雜類(lèi)型簽名,同時(shí)類(lèi)型別名適用于簡(jiǎn)化復(fù)雜的類(lèi)型簽名

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file : test.py
# @time : 2022/5/13 16:54
from typing import Sequence

ConnectionOptions = dict[str, int]  # 表示字典中的鍵為字符串類(lèi)型,值為整型
Address = tuple[str, int, ...]  # 表示元組的第一個(gè)數(shù)據(jù)為字符串,第二個(gè)數(shù)據(jù)為整型,里面只能存儲(chǔ)兩個(gè)數(shù)據(jù),有省略號(hào)表示里面可以添加n個(gè)整型數(shù)據(jù)
Server = tuple[Address, ConnectionOptions]


def broadcast_message(message: str,
                      servers: Sequence[Server]  # 表示一個(gè)序列對(duì)象里面存儲(chǔ)了[tuple[tuple[str, int], dict[str, int]]]
                      ) -> None:  # 返回值為空
    ...

broadcast_message("a", [(("a", 1, 2), {"a": 1})])

2、 NewType

使用NewType輔助函數(shù)創(chuàng)建不同的類(lèi)型,靜態(tài)類(lèi)型檢查器會(huì)將新類(lèi)型視為它是原始數(shù)據(jù)的子類(lèi),相當(dāng)于C++里面的`typedef

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file : test.py
# @time : 2022/5/13 16:54
from typing import NewType

UserId = NewType('UserId', int)  # 其不會(huì)創(chuàng)建一個(gè)新的類(lèi)或引入其他內(nèi)存,只是做一個(gè)約束作用


def name_by_id(user_id: UserId) -> str:
    ...


name_by_id(42)  # Fails type check
name_by_id(UserId(42))  # OK

num = UserId(5) + 1  # type: int,可以進(jìn)行對(duì)應(yīng)數(shù)據(jù)類(lèi)型的操作

同時(shí),可以嵌套創(chuàng)建,即可以基于NewType創(chuàng)建NewType

3、 可調(diào)用對(duì)象

Callable[[Arg1Type, Arg2Type], ReturnType]

如,實(shí)現(xiàn)一個(gè)互斥鎖的裝飾器

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file : test.py
# @time : 2022/5/13 16:54
from collections.abc import Callable  # 注意要使用Concatenate和ParamSpec就必須使用這個(gè)模塊里面的Callable
from threading import Lock
from typing import TypeVar
from pip._vendor.typing_extensions import Concatenate, ParamSpec  # 導(dǎo)入typing的擴(kuò)展

P = ParamSpec('P')  # 里面有args和kwargs參數(shù)
R = TypeVar('R')  # 自定義數(shù)據(jù)類(lèi)型

my_lock = Lock()  # 創(chuàng)建一個(gè)互斥鎖


def with_lock(f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]:
    '''一個(gè)提供互斥鎖,使得線程安全的裝飾器'''
    def inner(*args: P.args, **kwargs: P.kwargs) -> R:
        return f(my_lock, *args, **kwargs)
    return inner


@with_lock
def sum_threadsafe(lock: Lock, numbers: list[float]) -> float:
    '''Add a list of numbers together in a thread-safe manner.'''
    with lock:
        return sum(numbers)


# We don't need to pass in the lock ourselves thanks to the decorator.
print(sum_threadsafe([1.1, 2.2, 3.3]))

無(wú)需指定調(diào)用簽名,用省略號(hào)字面量替換類(lèi)型提示里的參數(shù)列表: Callable[..., ReturnType],就可以聲明可調(diào)對(duì)象的返回類(lèi)型

與 Callable 和 ParamSpec 一起使用,對(duì)一個(gè)高階可調(diào)用對(duì)象進(jìn)行類(lèi)型注釋?zhuān)搶?duì)象可以增加、刪除或轉(zhuǎn)換另一個(gè)可調(diào)用對(duì)象的參數(shù)。 使用形式為Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]。 Concatenate 目前只在作為 Callable 的第一個(gè)參數(shù)時(shí)有效。Concatenate 的最后一個(gè)參數(shù)必須是一個(gè) ParamSpec

三、 泛型支持

typing模快最基本的支持有Any ,Tuple,Callable,TypeVar 和 Generic類(lèi)型組成

1、集合類(lèi)型

from typing import (
    List,  # list的泛型版本。用于注釋返回類(lèi)型。要注釋參數(shù),最好使用抽象集合類(lèi)型,如Sequence或Iterable
    Set,  # set的泛型版本
    Dict  # dict 的泛型版本。對(duì)標(biāo)注返回類(lèi)型比較有用。如果要標(biāo)注參數(shù)的話,使用如 Mapping 的抽象容器類(lèi)型是更好的選擇
    )

2、 抽象基類(lèi)

from typing import (
    Mapping,  # 要注釋函數(shù)參數(shù)中的Key-Value類(lèi)型時(shí),推薦使用的抽象集合類(lèi)型
    Sequence,  # 要注釋函數(shù)參數(shù)中的序列例如列表類(lèi)型時(shí),推薦使用的抽象集合類(lèi)型
    Iterable  # 要注釋函數(shù)參數(shù)中的迭代類(lèi)型時(shí),推薦使用的抽象集合類(lèi)型
    )

3、 泛型

TypeVar:其就像C++里面的template一樣

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file : test.py
# @time : 2022/5/13 16:54
from typing import (
    Sequence,
    TypeVar  # 限制多個(gè)變量為同一個(gè)數(shù)據(jù)類(lèi)型
)

T = TypeVar('T')  # Can be anything 
A = TypeVar('A', str, bytes)  # Must be str or bytes 

def repeat(x: T, n: int) -> Sequence[T]:
    """Return a list containing n references to x."""
    return [x] * n

def longest(x: A, y: A) -> A:
    """Return the longest of two strings."""
    return x if len(x) >= len(y) else y

AnyStr

AnyStr是一個(gè)字符串和字節(jié)類(lèi)型的特殊類(lèi)型變量AnyStr = TypeVar('AnyStr', str, bytes),它用于可以接受任何類(lèi)型的字符串而不允許不同類(lèi)型的字符串混合的函數(shù)

4、 Any

特殊類(lèi)型,表明類(lèi)型沒(méi)有任何限制

  • 每一個(gè)類(lèi)型都對(duì) Any 兼容

  • Any 對(duì)每一個(gè)類(lèi)型都兼容

Any 是一種特殊的類(lèi)型。靜態(tài)類(lèi)型檢查器將所有類(lèi)型視為與Any兼容,反之亦然, Any也與所有類(lèi)型相兼容。

這意味著可對(duì)類(lèi)型為 Any 的值執(zhí)行任何操作或者方法調(diào)用并將其賦值給任意變量

如下所示,將 Any 類(lèi)型的值賦值給另一個(gè)更具體的類(lèi)型時(shí),Python不會(huì)執(zhí)行類(lèi)型檢查。例如,當(dāng)把 a 賦值給 s 時(shí),即使 s 被聲明為 str類(lèi)型,在運(yùn)行時(shí)接收到的是 int 值,靜態(tài)類(lèi)型檢查器也不會(huì)報(bào)錯(cuò)

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file : test.py
# @time : 2022/5/13 16:54
from typing import (
    Any,
    NoReturn,  # 表示函數(shù)沒(méi)有返回值
)

def test(s: Any) -> NoReturn:
    s.item()  # 不會(huì)檢測(cè)s里面是否有item()屬性

def test_(s: object) -> NoReturn:
    s.item()  # 會(huì)檢測(cè)s里面是否有item屬性

當(dāng)參數(shù)無(wú)類(lèi)型是,默認(rèn)為Any類(lèi)型

5、 特殊形式

5.1 Type

一個(gè)注解為 C 的變量可以接受一個(gè)類(lèi)型為 C 的值。相對(duì)地,一個(gè)注解為 Type[C] 的變量可以接受本身為類(lèi)的值 。 更精確地說(shuō)它接受 C的 類(lèi)對(duì)象

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file : test.py
# @time : 2022/5/13 16:54
from typing import (
    Type,
)


class User:
    ...


class BasicUser(User):
    ...

# Accepts User, BasicUser, ...

def make_new_user(user_class: Type[User]) -> User:
    return user_class()


print(make_new_user(User))
5.2 Union

聯(lián)合類(lèi)型;Union[X, Y]意味著:要么是 X,要么就是 Y。定義一個(gè)聯(lián)合類(lèi)型,需要注意的有:

  • 參數(shù)必須是類(lèi)型,而且必須至少有一個(gè)參數(shù)。

  • 能繼承或者實(shí)例化一個(gè)聯(lián)合類(lèi)型。

  • Union[X, Y]不能寫(xiě)成 Union[X][Y] 。

  • 可以使用 Optional[X] 作為Union[X, None]的縮寫(xiě)- 聯(lián)合類(lèi)型的聯(lián)合類(lèi)型會(huì)被展開(kāi)打平

  • 僅有一個(gè)參數(shù)的聯(lián)合類(lèi)型會(huì)坍縮成參數(shù)自身,比如:

Union[int] == int  # The constructor actually returns int

多余的參數(shù)會(huì)被跳過(guò),比如:

Union[int, str, int] == Union[int, str]

在比較聯(lián)合類(lèi)型的時(shí)候,參數(shù)順序會(huì)被忽略,比如:

Union[int, str] == Union[str, int]
5.3 Optional

可選類(lèi)型,Optional[X] 等價(jià)于Union[X, None]

5.4 Tuple

元組類(lèi)型,Tuple[X, Y] 標(biāo)注了一個(gè)二元組類(lèi)型,其第一個(gè)元素的類(lèi)型為 X 且第二個(gè)元素的類(lèi)型為Y??赵M的類(lèi)型可寫(xiě)作 Tuple[()]

為表達(dá)一個(gè)同類(lèi)型元素的變長(zhǎng)元組,使用省略號(hào)字面量,如Tuple[int, ...]。單獨(dú)的一個(gè) Tuple 等價(jià)于 Tuple[Any, ...],進(jìn)而等價(jià)于tuple

示例: Tuple[int, float, str]表示一個(gè)由整數(shù)、浮點(diǎn)數(shù)和字符串組成的三元組

5.5 Callable

可調(diào)用類(lèi)型;Callable[[int], str]是一個(gè)函數(shù),接受一個(gè) int 參數(shù),返回一個(gè)str。下標(biāo)值的語(yǔ)法必須恰為兩個(gè)值:參數(shù)列表和返回類(lèi)型。參數(shù)列表必須是一個(gè)類(lèi)型和省略號(hào)組成的列表;返回值必須是單一一個(gè)類(lèi)型

不存在語(yǔ)法來(lái)表示可選的或關(guān)鍵詞參數(shù),這類(lèi)函數(shù)類(lèi)型罕見(jiàn)用于回調(diào)函數(shù)。Callable[..., ReturnType](使用字面省略號(hào))能被用于提示一個(gè)可調(diào)用對(duì)象,接受任意數(shù)量的參數(shù)并且返回 ReturnType。單獨(dú)的 Callable 等價(jià)于Callable[..., Any],并且進(jìn)而等價(jià)于 collections.abc.Callable

關(guān)于“Python中typing模塊怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI