最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python類(lèi)型標(biāo)注里Optional的實(shí)現(xiàn)

 更新時(shí)間:2026年02月04日 09:34:31   作者:Kevin666  
本文主要介紹了Python類(lèi)型標(biāo)注里Optional的實(shí)現(xiàn),包括與默認(rèn)參數(shù)/可選參數(shù)的關(guān)系,以及在靜態(tài)類(lèi)型檢查中的注意事項(xiàng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在 Python 的類(lèi)型標(biāo)注(type hints)體系中,Optional 是一個(gè)非常常用、也非常容易被誤解的工具。很多人以為 Optional[T] 的意思是“這個(gè)參數(shù)可選、可以不傳”,但實(shí)際上它表達(dá)的是:值可能是 T,也可能是 None。

這篇文章會(huì)把 Optional 的語(yǔ)義、典型用法、與默認(rèn)參數(shù)/可選參數(shù)的關(guān)系,以及靜態(tài)類(lèi)型檢查中的注意事項(xiàng)講清楚。

1. Optional 是什么?

Optional[T] 定義在 typing 模塊中:

from typing import Optional

它的含義是:

Optional[T] 等價(jià)于 T | None(或舊寫(xiě)法 Union[T, None])

也就是說(shuō):

  • Optional[int] 表示 int 或 None
  • Optional[str] 表示 str 或 None

2. Optional 的等價(jià)寫(xiě)法(Python 版本差異)

Python 3.10+ 推薦寫(xiě)法:T | None

def parse_age(s: str) -> int | None:
    ...

Python 3.9 及更早:Optional[T]/Union[T, None]

from typing import Optional, Union

def parse_age(s: str) -> Optional[int]:
    ...

def parse_age2(s: str) -> Union[int, None]:
    ...

在語(yǔ)義上這三種寫(xiě)法完全等價(jià)。團(tuán)隊(duì)如果有兼容性要求(例如要支持 3.9),通常用 Optional[T] 更穩(wěn)妥。

3. Optional ≠ “參數(shù)可選(可以不傳)”

這是最常見(jiàn)誤解。

3.1 “可以不傳”的關(guān)鍵是:是否有默認(rèn)值

from typing import Optional

def f(x: Optional[int]):  # 沒(méi)默認(rèn)值
    ...

這里 x 必須傳,只是傳入的值允許是 intNone

f(1)       # OK
f(None)    # OK
f()        # TypeError:缺少參數(shù)

3.2 “可以不傳”應(yīng)該寫(xiě)成:有默認(rèn)值

def f(x: Optional[int] = None):
    ...

這時(shí)才是“可不傳”,并且值也允許為 None。

4. 什么時(shí)候應(yīng)該用 Optional?

場(chǎng)景 A:函數(shù)可能返回 None

例如查找失敗返回 None

def find_user_name(user_id: int) -> Optional[str]:
    if user_id == 1:
        return "Alice"
    return None

調(diào)用方就需要處理 None 分支:

name = find_user_name(2)
if name is None:
    print("not found")
else:
    print(name.upper())

場(chǎng)景 B:參數(shù)允許為 None 表示“缺省/未知/不處理”

例如可選過(guò)濾條件:

from typing import Optional

def query_users(country: Optional[str] = None) -> list[str]:
    if country is None:
        return ["Alice", "Bob"]
    return ["Alice"]

場(chǎng)景 C:對(duì)象屬性可能為空

from dataclasses import dataclass
from typing import Optional

@dataclass
class User:
    id: int
    email: Optional[str]  # 有些用戶可能沒(méi)有郵箱

5. Optional 與靜態(tài)類(lèi)型檢查:必須做 None 處理(narrowing)

Optional[str] 意味著變量可能是 None,因此你不能直接當(dāng) str 用,否則類(lèi)型檢查器(mypy/pyright)會(huì)報(bào)錯(cuò)。

5.1 錯(cuò)誤示例

from typing import Optional

def shout(name: Optional[str]) -> str:
    return name.upper()  # 類(lèi)型檢查會(huì)報(bào):name 可能是 None

5.2 正確做法:顯式判斷

def shout(name: Optional[str]) -> str:
    if name is None:
        return "UNKNOWN"
    return name.upper()

這種 if name is None 會(huì)觸發(fā)類(lèi)型收窄(narrowing):

  • if 分支里:nameNone
  • else 分支里:namestr

5.3 常見(jiàn)變體:提前返回(guard clause)

def shout(name: Optional[str]) -> str:
    if name is None:
        raise ValueError("name required")
    return name.upper()

6. Optional 與 “truthy” 判斷的坑

很多人寫(xiě):

if name:
    ...

這會(huì)把以下值都當(dāng)成“空”:

  • None
  • ""(空字符串)
  • "0" 是 truthy,但 0 是 falsy
  • 00.0、False、空容器等

如果你的意圖是只判斷 None,要寫(xiě):

if name is None:
    ...

這是 Optional 場(chǎng)景里非常推薦的寫(xiě)法。

7. Optional 容器類(lèi)型:Optional[list[int]]vslist[Optional[int]]

這兩個(gè)差別極大:

7.1Optional[list[int]]

列表本身可能不存在:

xs: Optional[list[int]] = None  # OK
xs = [1, 2, 3]                  # OK

7.2list[Optional[int]]

列表一定存在,但元素可能是 None:

xs: list[Optional[int]] = [1, None, 3]

實(shí)際項(xiàng)目里兩者經(jīng)常寫(xiě)反,建議寫(xiě)之前先問(wèn)自己一句:

“可能為 None 的是容器本身,還是容器里的元素?”

8. Optional 與默認(rèn)參數(shù):避免可變默認(rèn)值的經(jīng)典模式

Python 里可變默認(rèn)值是大坑:

def add_item(x, items=[]):  # 不推薦
    items.append(x)
    return items

正確做法常用 Optional[list[T]] = None 作為哨兵(sentinel):

from typing import Optional

def add_item(x: int, items: Optional[list[int]] = None) -> list[int]:
    if items is None:
        items = []
    items.append(x)
    return items

這里 None 的意義是“沒(méi)傳就新建”。

9. Optional 與 “缺失值” 的設(shè)計(jì):None 還是 sentinel?

有些場(chǎng)景 None 既可能表示“缺失”,也可能是“合法值”(例如某字段允許顯式為 None)。這時(shí)可以用自定義 sentinel 區(qū)分:

_MISSING = object()

def set_value(x=_MISSING):
    if x is _MISSING:
        print("not provided")
    else:
        print(f"provided: {x!r}")

類(lèi)型標(biāo)注上更嚴(yán)格的寫(xiě)法會(huì)更復(fù)雜(涉及 object、Literal、overload 等),但思想很重要:當(dāng) None 的語(yǔ)義不夠用時(shí),考慮 sentinel。

10. 最佳實(shí)踐總結(jié)(速記)

  1. Optional[T] 表示 T 或 None,不是“參數(shù)可不傳”
  2. “可不傳”必須配合默認(rèn)值:x: Optional[T] = None
  3. 遇到 Optional,調(diào)用前/使用前要做 is None 判斷
  4. 只想判斷 None 不要用 if x:,用 if x is None:
  5. 分清 Optional[list[T]](容器可無(wú))和 list[Optional[T]](元素可無(wú))
  6. Optional[...] = None 常用于避免可變默認(rèn)值問(wèn)題

到此這篇關(guān)于Python類(lèi)型標(biāo)注里Optional的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Optional內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Django 生成登陸驗(yàn)證碼代碼分享

    Django 生成登陸驗(yàn)證碼代碼分享

    這篇文章主要介紹了Django 生成登陸驗(yàn)證碼代碼分享,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • python單鏈表實(shí)現(xiàn)代碼實(shí)例

    python單鏈表實(shí)現(xiàn)代碼實(shí)例

    這篇文章主要介紹了python單鏈表實(shí)現(xiàn)代碼,大家參考使用吧
    2013-11-11
  • Python實(shí)現(xiàn)簡(jiǎn)單的Rust風(fēng)格類(lèi)型檢查

    Python實(shí)現(xiàn)簡(jiǎn)單的Rust風(fēng)格類(lèi)型檢查

    本文主要介紹了Python實(shí)現(xiàn)簡(jiǎn)單的Rust風(fēng)格類(lèi)型檢查,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-04-04
  • 學(xué)生信息管理系統(tǒng)python版

    學(xué)生信息管理系統(tǒng)python版

    這篇文章主要為大家詳細(xì)介紹了學(xué)生信息管理系統(tǒng)python版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Python執(zhí)行Shell命令的六種方法

    Python執(zhí)行Shell命令的六種方法

    在 Python 編程中,有時(shí)我們需要執(zhí)行一些 shell 命令來(lái)完成特定的任務(wù),比如文件操作、系統(tǒng)調(diào)用等,Python 提供了多種內(nèi)建的方法來(lái)執(zhí)行這些命令,每種方法都有其適用場(chǎng)景和特點(diǎn),本文給大家介紹了Python執(zhí)行Shell命令的六種方法,需要的朋友可以參考下
    2024-09-09
  • Python群發(fā)郵件實(shí)例代碼

    Python群發(fā)郵件實(shí)例代碼

    今天試了試Python發(fā)郵件,突然想到能不能群發(fā)郵件呢?群發(fā)郵件是smtplib的一個(gè)bug,不過(guò)最終還是解決了
    2014-01-01
  • 在Python中操作PDF的常見(jiàn)方法小結(jié)

    在Python中操作PDF的常見(jiàn)方法小結(jié)

    當(dāng)在Python中操作PDF時(shí),有幾種常見(jiàn)的方法,每種方法都有其獨(dú)特的優(yōu)點(diǎn)和用例,在本文中,我們將深入探討這些方法,并提供豐富的示例代碼,以幫助大家更好地理解如何使用這些技術(shù),需要的朋友可以參考下
    2024-01-01
  • python如何獲取服務(wù)器硬件信息

    python如何獲取服務(wù)器硬件信息

    這篇文章主要為大家詳細(xì)介紹了python獲取服務(wù)器硬件信息的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Python自動(dòng)化運(yùn)維之Ansible定義主機(jī)與組規(guī)則操作詳解

    Python自動(dòng)化運(yùn)維之Ansible定義主機(jī)與組規(guī)則操作詳解

    這篇文章主要介紹了Python自動(dòng)化運(yùn)維之Ansible定義主機(jī)與組規(guī)則操作,結(jié)合實(shí)例形式分析了自動(dòng)化運(yùn)維工具Ansible定義主機(jī)與組規(guī)則相關(guān)配置操作與注意事項(xiàng),需要的朋友可以參考下
    2019-06-06
  • 解決Pycharm在Debug的時(shí)候一直“Connected”沒(méi)有下一步動(dòng)作問(wèn)題

    解決Pycharm在Debug的時(shí)候一直“Connected”沒(méi)有下一步動(dòng)作問(wèn)題

    這篇文章主要介紹了解決Pycharm在Debug的時(shí)候一直“Connected”沒(méi)有下一步動(dòng)作問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評(píng)論

奉节县| 波密县| 元江| 翁牛特旗| 集安市| 泸定县| 娄底市| 崇州市| 淄博市| 得荣县| 崇左市| 丹巴县| 策勒县| 湟源县| 鄄城县| 岳西县| 泰和县| 永泰县| 田林县| 鹰潭市| 云梦县| 商水县| 溧阳市| 漾濞| 西乌| 苏尼特左旗| 栾城县| 太白县| 新津县| 乌审旗| 毕节市| 五寨县| 景洪市| 开鲁县| 开阳县| 青田县| 织金县| 石家庄市| 新龙县| 乐亭县| 安丘市|