<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何更好的使用 Python 的類型提示?

          共 4764字,需瀏覽 10分鐘

           ·

          2022-10-15 14:47

          使用動態(tài)語言一時爽,代碼重構(gòu)火葬場。相信你一定聽過這句話,和單元測試一樣,雖然寫代碼的時候花費你少量的時間,但是從長遠來看,這是非常值得的。本文分享如何更好的理解和使用 Python 的類型提示。

          1、類型提示僅在語法層面有效

          類型提示(自 PEP 3107 開始引入)用于向變量、參數(shù)、函數(shù)參數(shù)以及它們的返回值、類屬性和方法添加類型。

          Python 的變量類型是動態(tài)的,可以在運行時修改,為代碼添加類型提示,僅在語法層面支持,對代碼的運行沒有任何影響,Python 解釋器在運行代碼的時候會忽略類型提示。

          因此類型提示一個直觀的作用就是提升代碼的可讀性,方便調(diào)用者傳入/傳出恰當類型的參數(shù),便于代碼重構(gòu)。

          Python 內(nèi)置的基本類型可以直接用于類型提示:

          變量的類型提示示例:

          a: int = 3
          b: float = 2.4
          c: bool = True
          d: list = ["A""B""C"]
          e: dict = {"x""y"}
          f: set = {"a""b""c"}
          g: tuple = ("name""age""job")

          函數(shù)的類型提示:

          def add_numbers(x: type_x, y: type_y, z: type_z= 100) -> type_return:
              return x + y + z

          這里的 type_x , type_y , type_z , type_return 可以是內(nèi)置的基本類型,也可以是自定義類型。

          類的類型提示:

          class Person:
              first_name: str = "John"
              last_name: str = "Does"
              age: int = 31

          2、用 mypy 檢查類型提示

          假如有這樣一段代碼:

          # script.py
          x: int = 2
          # ...
          x = 3.5

          用 Python 解釋器執(zhí)行是不會有任何錯誤的:

          借助于 mypy 就可以,先 pip install mypy 安裝一下,然后 mypy script.py 即可:

          更多 mypy 相關(guān)可以參考前文mypy 這個工具,讓Python的類型提示變得非常實用

          3、類型提示的好處

          如果解釋器沒有強制執(zhí)行類型提示,為什么還要編寫類型提示呢?確實,類型提示不會改變代碼的運行方式:Python 本質(zhì)上是動態(tài)類型的,這一點不太可能會改變。但是,從開發(fā)人員經(jīng)驗的角度來看,類型提示有很多好處。

          1、使用類型提示,尤其是在函數(shù)中,通過類型提示來明確參數(shù)類型和所產(chǎn)生結(jié)果的類型,非常便于閱讀和理解。

          2、類型提示消除了認知開銷,并使代碼更易于閱讀和調(diào)試。考慮到輸入和輸出的類型,你可以輕松推斷對象以及它們?nèi)绾握{(diào)用。

          3、類型提示可改善代碼編輯體驗。IDE 可以依靠類型檢測來靜態(tài)分析你的代碼并幫助檢測潛在的錯誤(例如,傳遞錯誤類型的參數(shù)、調(diào)用錯誤的方法等)。另外,還可以根據(jù)類型提示為每個變量提供自動補全。

          IDE 的類型檢查

          IDE 的類型檢查

          IDE 類型檢查后的自動補全

          4、List 用法

          假如你需要列表 list 內(nèi)部是 float 的類型提示,這樣做是不行的:

          def my_dummy_function(l: list[float]):
             return sum(l)

          標準庫 typing 考慮到了這個問題,你可以這樣:

          from typing import List

          def my_dummy_function(vector: List[float]):
             return sum(vector)

          5、Dict 用法

          假如要提示這樣的類型:

          my_dict = {"name""Somenzz""job""engineer"}

          借助于 Dict,你可以這樣定義類型:

          from typing import Dict
          my_dict_type = Dict[str, str]
          my_dict: my_dict_type = {"name""Somenzz""job""engineer"}

          6、TypedDict 用法

          假如你需要提示這樣的類型,那該怎么辦?

          d = {"name""Somenzz""interests": ["chess""tennis"]}

          借助于 TypedDict ,你可以這樣:

          TypedDict

          7、Union 用法

          從 Python 3.10 開始,Union 被替換為 | 這意味著 Union[X, Y] 現(xiàn)在等價于 X | Y。

          Union[X, Y](或 X | Y)表示 X 或 Y。

          假設(shè)你的函數(shù)需要從緩存目錄中讀取文件并加載 Torch 模型。此緩存目錄位置可以是字符串值(例如 /home/cache ),也可以是 Pathlib 庫的 Path 對象,在這種情況下,代碼如下:


          def load_model(filename: str, cache_folder: Union[str, Path]):
              if isinstance(cache_folder, Path):
                  cache_folder = str(cache_folder)

              model_path = os.join(filename, cache_folder)
              model = torch.load(model_path)
              return model

          8、Callable 用法

          當你需要傳入一個函數(shù)作為參數(shù)的時候,這個參數(shù)的類型提示可以為 Callable。

          from typing import Callable

          def sum_numbers(x: int, y: int) -> int:
              return x + y

          def foo(x: int, y: int, func: Callable) -> int:
              output = func(x, y)
              return output

          foo(12, sum_numbers)

          你還可以給這樣的函數(shù)參數(shù)指定參數(shù)列表,真的很強大:

          語法:

          Callable[[input_type_1, ...], return_type]

          示例:

          def foo(x: int, y: int, func: Callable[[int, int], int]) -> int:
              output = func(x, y)
              return output

          9、Any 用法

          當你傳入的參數(shù)可以為任何類型的時候,就可以使用 Any

          def bar(input: Any):
              ...

          10、Optional 用法

          如果你的函數(shù)使用可選參數(shù),具有默認值,那么你可以使用類型模塊中的 Optional 類型。

          from typing import Optional

          def foo(format_layout: Optional[bool] = True):
              ...

          11、Sequence 用法

          Sequence 類型的對象是可以被索引的任何東西:列表、元組、字符串、對象列表、元組列表的元組等。

          from typing import Sequence

          def print_sequence_elements(sequence: Sequence[str]):
              for i, s in enumerate(s):
                  print(f"item {i}{s}"

          12、Tuple 用法

          Tuple 類型的工作方式與 List 類型略有不同,Tuple 需要指定每一個位置的類型:

          from typing import Tuple
          t: Tuple[int, int, int] = (123)

          如果你不關(guān)心元組中每個元素的類型,你可以繼續(xù)使用內(nèi)置類型 tuple。

          t: tuple = (123, ["cat""dog"], {"name""John"})

          最后的話

          類型提示在代碼之上帶來了額外的抽象層:它們有助于記錄代碼,澄清關(guān)于輸入/輸出的假設(shè),并防止在頂部執(zhí)行靜態(tài)代碼分析 (mypy) 時出現(xiàn)的隱蔽和錯誤。接下來做的事情就是在你的項目中使用類型提示,從長期看,這是你最佳的選擇。如果有幫助,歡迎在看、關(guān)注、討論


          瀏覽 110
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰国产免费 | 国产精品主播视频 | 久久激情福利视频 | chaopeng超碰永久 | 青青草视频在线免费 |