亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python / mypy 中 NamedTuple 和 TypedDict 的主要區別是什么

Python / mypy 中 NamedTuple 和 TypedDict 的主要區別是什么

素胚勾勒不出你 2021-08-24 15:14:51
在我看來,NamedTuple和TypedDict非常相似,Python 開發人員自己也認識到了這一點。關于 PEP,我寧愿添加一個關于 NamedTuple 和 TypedDict 的公共部分,它們非常相似,后者在結構上已經表現得很好。你怎么看? 但是Guido似乎對此不太確定。我不太確定 NamedTuple 和 TypedDict 是否真的那么相似(除了它們都試圖在靜態類型的世界中處理過時的模式)。所以,這是我懶惰的嘗試,讓其他人在官方文檔似乎缺乏的情況下提出清晰的比較。
查看完整描述

2 回答

?
慕慕森

TA貢獻1856條經驗 獲得超17個贊

Python 及其社區正在努力解決“結構”問題:如何最好地將相關值分組到復合數據對象中,以允許邏輯/輕松訪問組件(通常按名稱)。有許多相互競爭的方法:

  • collections.namedtuple 實例

  • 字典(帶有一組固定/已知的鍵)

  • 屬性可訪問的字典(如stuf

  • ATTRS

  • PEP 557數據類

  • 為每種結構類型手工制作的普通舊定制對象

  • 每個位置/插槽的類似tuplelist隱含含義的序列(過時但非常常見)

  • 等。

“應該有一種——最好只有一種——明顯的方法來做到這一點?!?/p>

無論是typing圖書館和Mypy,像在大的Python社區,同時與如何更有效地定義類型/模式,包括復合對象掙扎。您鏈接到的討論是努力尋找前進道路的一部分。

NamedTuplecollections.namedtuple工廠產生的結構化對象的類型超類;TypedDicta Mypy 嘗試定義使用固定模式字典時出現的鍵和相應類型的值。如果您只是考慮“我有一組固定的鍵應該映射到一組固定的鍵入值”,那么它們是相似的。但是由此產生的實現和約束是非常不同的。袋子和盒子一樣嗎?也許。也許不是。取決于您的觀點以及您想如何使用它們。倒酒,開始討論!

NamedTuple順便說一下,現在是 Python 的正式組成部分。

from typing import NamedTuple


class Employee(NamedTuple):

    name: str

    id: int

TypedDict開始作為一個實驗性的 Mypy 功能開始生活,將打字與字典的異構、面向結構的使用進行斗爭。然而,從 Python 3.8 開始,它被納入標準庫。


try:

    from typing import TypedDict  # >=3.8

except ImportError:

    from mypy_extensions import TypedDict  # <=3.7


Movie = TypedDict('Movie', {'name': str, 'year': int})

還可以使用基于類的類型構造函數:


class Movie(TypedDict):

    name: str

    year: int

盡管存在分歧,兩者NamedTuple并TypedDict鎖定特定的鍵被使用,并且該類型的對應于每個鍵的值。因此,它們的目標基本相同:成為復合/結構類型的有用類型機制。


Python 的標準typing.Dict側重于更同質的并行映射,定義鍵/值類型,而不是鍵本身。因此,它在定義碰巧存儲在字典中的復合對象時不是很有用。


ConnectionOptions = Dict[str, str] 


查看完整回答
反對 回復 2021-08-24
?
喵喵時光機

TA貢獻1846條經驗 獲得超7個贊

NamedTuple如果可能的話,如果我想凍結這些值,我會去。否則我會使用數據類。

from dataclasses import dataclass

from typing import NamedTuple, TypedDict

from enum import Enum



class Gender(Enum):

? ? MALE = "male"

? ? FEMALE = "female"



## Class definition: Almost the same

@dataclass

class UserDataC:

? ? name: str

? ? gender: Gender



class UserTuple(NamedTuple):

? ? name: str

? ? gender: Gender



class UserNDict(TypedDict):

? ? name: str

? ? gender: Gender



## Object Creation: Looks the same

anna_datac = UserDataC(name="Anna", gender=Gender.FEMALE)

anna_tuple = UserTuple(name="Anna", gender=Gender.FEMALE)

anna_ndict = UserNDict(name="Anna", gender=Gender.FEMALE)


## Mutable values vs frozen values

anna_datac.gender = Gender.MALE

# anna_tuple.gender = Gender.MALE? # AttributeError: can't set attribute

anna_ndict["gender"] = Gender.MALE

# AttributeError: 'dict' object has no attribute 'gender'

# anna_ndict.gender = Gender.MALE


## New attribute

# Note that you can add new attributes like this.

# Python will not complain. But mypy will.

anna_datac.password = "secret"? # Dataclasses are extensible

# anna_tuple.password = "secret"? # AttributeError - named tuples not

# anna_ndict.password = "secret"? # AttributeError - TypedDict not

anna_ndict["password"] = "secret"


## isinstance

assert isinstance(anna_tuple, tuple)

assert isinstance(anna_ndict, dict)

為什么我更喜歡 NamedTuple 而不是 namedtuple

我認為寫和讀更直觀。另外,您可以為 mypy 提供更多檢查的可能性:


class UserTuple(NamedTuple):

? ? name: str

? ? gender: Gender


# vs


UserTuple = namedtuple("UserTuple", ["name", "gender"])

為什么我更喜歡元組而不是字典

如果我不需要事物可變,我喜歡它們不是可變的。這樣我可以防止意外的副作用


查看完整回答
反對 回復 2021-08-24
  • 2 回答
  • 0 關注
  • 394 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號