Python資料結構:一個被低估的Namedtuple(二)
python影片教學專欄繼續帶大家了解Python資料結構的Namedtuple。
上篇Python資料結構:一個被低估的Namedtuple(一)講了namedtuple的一些基本用法,這篇繼續。
namedtuples和資料類別(Data Class)之間有什麼差別?
功能
在Python 3.7之前,可使用下列任一方法建立一個簡單的資料容器:
- namedtuple
- 常規類別
- 第三方函式庫,
attrs
如果您想使用常規類,那意味著您將必須實作幾個方法。例如,常規類別將需要一種__init__
方法來在類別實例化期間設定屬性。如果您希望該類別是可雜湊的,則表示自己實作一個__hash__
方法。為了比較不同的對象,還需要__eq__
實作一個方法。最後,為了簡化偵錯,您需要一種__repr__
方法。
讓我們使用常規類別來實作下我們的顏色用例。
class Color: """A regular class that represents a color.""" def __init__(self, r, g, b, alpha=0.0): self.r = r self.g = g self.b = b self.alpha = alpha def __hash__(self): return hash((self.r, self.g, self.b, self.alpha)) def __repr__(self): return "{0}({1}, {2}, {3}, {4})".format( self.__class__.__name__, self.r, self.g, self.b, self.alpha ) def __eq__(self, other): if not isinstance(other, Color): return False return ( self.r == other.r and self.g == other.g and self.b == other.b and self.alpha == other.alpha )复制代码
如上,你需要實作好多方法。您只需要一個容器來為您保存數據,而不必擔心分散注意力的細節。同樣,人們偏好實作類別的一個關鍵區別是常規類別是可變的。
實際上,引入資料類別(Data Class)
的PEP將它們稱為「具有預設值的可變namedtuple」(譯者註:Data Class python 3.7引入,參考: docs.python.org/zh-cn/3/lib…
現在,讓我們看看如何用資料類別
來實作。
from dataclasses import dataclass ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: float复制代码
哇!就是這麼簡單。由於沒有__init__
,您只需在docstring後面定義屬性即可。此外,必須使用類型提示對其進行註釋。
除了可變之外,資料類別還可以開箱即用提供可選字段。假設我們的Color類別不需要alpha字段。然後我們可以設定為可選。
from dataclasses import dataclassfrom typing import Optional ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: Optional[float]复制代码
我們可以像這樣實例化它:
>>> blue = Color(r=0, g=0, b=255)复制代码
由於它們是可變的,因此我們可以更改所需的任何字段。我們可以像這樣實例化它:
>>> blue = Color(r=0, g=0, b=255) >>> blue.r = 1 >>> # 可以设置更多的属性字段 >>> blue.e = 10复制代码
相比之下,namedtuple
預設情況下沒有可選字段。要添加它們,我們需要一點技巧和一些元編程。
提示:要添加__hash__
方法,您需要通過將設置unsafe_hash
為使其不可變True
:
@dataclass(unsafe_hash=True)class Color: ...复制代码
另一個區別是,拆箱(unpacking)是namedtuples的自帶的功能(first-class citizen)。如果希望資料類別
具有相同的行為,則必須實現自己。
from dataclasses import dataclass, astuple ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: float def __iter__(self): yield from dataclasses.astuple(self)复制代码
效能比較
僅比較功能是不夠的,namedtuple和資料類別在效能上也有所不同。資料類別基於純Python實作dict。這使得它們在訪問字段時更快。另一方面,namedtuples只是常規的擴展tuple。這意味著它們的實現基於更快的C代碼並具有較小的內存佔用量。
為了證明這一點,請考慮在Python 3.8.5上進行此實驗。
In [6]: import sys In [7]: ColorTuple = namedtuple("Color", "r g b alpha") In [8]: @dataclass ...: class ColorClass: ...: """A regular class that represents a color.""" ...: r: float ...: g: float ...: b: float ...: alpha: float ...: In [9]: color_tup = ColorTuple(r=50, g=205, b=50, alpha=1.0) In [10]: color_cls = ColorClass(r=50, g=205, b=50, alpha=1.0) In [11]: %timeit color_tup.r36.8 ns ± 0.109 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [12]: %timeit color_cls.r38.4 ns ± 0.112 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [15]: sys.getsizeof(color_tup) Out[15]: 72In [16]: sys.getsizeof(color_cls) + sys.getsizeof(vars(color_cls)) Out[16]: 152复制代码
如上,資料類別在中存取欄位的速度稍快一些,但是它們比nametuple佔用更多的記憶體空間。
如何將類型提示新增至namedtuple
資料類別預設使用類型提示。我們也可以將它們放在namedtuples上。透過匯入Namedtuple註解類型並從中繼承,我們可以對Color元組進行註釋。
from typing import NamedTuple ...class Color(NamedTuple): """A namedtuple that represents a color.""" r: float g: float b: float alpha: float复制代码
另一個可能未引起注意的細節是,這種方式也允許我們使用docstring。如果輸入,help(Color)我們將能夠看到它們。
Help on class Color in module __main__:class Color(builtins.tuple) | Color(r: float, g: float, b: float, alpha: Union[float, NoneType]) | | A namedtuple that represents a color. | | Method resolution order: | Color | builtins.tuple | builtins.object | | Methods defined here: | | __getnewargs__(self) | Return self as a plain tuple. Used by copy and pickle. | | __repr__(self) | Return a nicely formatted representation string | | _asdict(self) | Return a new dict which maps field names to their values.复制代码
如何將可選的預設值新增至 namedtuple
在上一節中,我們了解了資料類別可以具有可選值。另外,我提到要模仿上的相同行為,namedtuple
需要進行一些技巧修改操作。事實證明,我們可以使用繼承,如下例所示。
from collections import namedtupleclass Color(namedtuple("Color", "r g b alpha")): __slots__ = () def __new__(cls, r, g, b, alpha=None): return super().__new__(cls, r, g, b, alpha)>>> c = Color(r=0, g=0, b=0)>>> c Color(r=0, g=0, b=0, alpha=None)复制代码
結論
元組是一個非常強大的資料結構。它們使我們的程式碼更清潔,更可靠。儘管與新的資料類別
競爭激烈,但他們仍有大量的場景可用。在本教程中,我們學習了使用namedtuples
的幾種方法,希望您可以使用它們。
相關免費學習推薦:python影片教學
以上是Python資料結構:一個被低估的Namedtuple(二)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。
