Python中namedtuple的使用

引言

在Python中,有時需要自定義簡單但是有名字的記錄類型,如果使用字典或普通元組,通常會顯得有點笨重。此時,namedtuple就成為了一個很好的選擇。namedtuple是Python標準庫collections中的一個函數,用於創建和實例化類似於元組的對象,但這些對象有名稱,可以像字典一樣通過名稱來訪問字段。namedtuple相當於一個輕量級的類定義器,它本質上是一個Python類,可以像其他類一樣繼承、實例化、序列化和擴展。

正文

一、namedtuple的使用方法

namedtuple的使用方法與普通元組非常相似。首先需要導入collections庫,然後使用namedtuple函數來定義一個命名元組。定義時需要提供兩個參數:元組名稱和元素名稱列表。下面是一個簡單的例子:

from collections import namedtuple
#定義一個命名元組
Person = namedtuple("Person", ["name", "age"])
#使用命名元組
person = Person(name="Tom", age=18)
print(person.name)  # Tom

在上面的例子中,定義了一個Person命名元組,包含name和age兩個字段。在實例化時,使用關鍵字參數來指定字段的值,可以像普通元組一樣通過索引或名稱來訪問元素。但不同的是,通過名稱訪問元素時更直觀和安全。

二、namedtuple與普通元組的比較

在使用namedtuple之前,可以先看一下普通元組的缺陷。

  • 元組和其它序列一樣是有序的。當元素需要賦予語義時,就需要藉助位置來訪問元素。這會降低程序的可讀性,並讓代碼更加脆弱(如果代碼依賴於元組中的位置,那麼當元組結構發生變化時,很容易出錯)。
  • 在表達簡單的對象時,元組常常是有用的——如果需要將其作為函數的參數,並且只有少數幾個值是有意義的。但是,當元組變得更大,或者需要添加一些方法或屬性來擴展元組時,這時候使用類會更好。
  • 元組是不可變的,因此如果想在元素被賦值後修改它們是不可能的。這樣如果需要在修改後返回相似但是不同的對象時,就需要使用其他的數據類型(如列表)來存儲數據。
  • 在元組中添加、刪除或修改元素會非常困難。當元組項數變得非常龐大時,元組會變得笨重,在這種情況下,盡量使用更合適的數據結構。

三、namedtuple的高級用法

namedtuple本身是可以繼承的,這意味着其可以和其他的類一樣進行擴展,添加自己的方法和屬性:

from collections import namedtuple
#定義一個命名元組
Animal = namedtuple("Animal", ["name", "age"])
#定義一個Cat類,並繼承Animal類
class Cat(Animal):
    def __str__(self):
        return "cat: {name}, {age}".format(name=self.name, age=self.age)

cat = Cat(name="Tom", age=3)
print(cat)  # cat: Tom, 3

此外,namedtuple還支持各種繼承和多重繼承的方式,可以方便地與需要繼承的類和對象進行交互。

四、namedtuple的性能測試

對於一個類定義器來說,其性能是一個非常重要的因素,下面從創建、訪問和執行效率三個方面對namedtuple進行性能測試,和普通元組進行比較。

1.創建效率

使用timeit模塊測試一個10000000個元素的元組和namedtuple的創建效率:

from collections import namedtuple
import timeit

def test_normal_tuple():
    t = tuple(range(10000000))

def test_named_tuple():
    Person = namedtuple("Person", list(range(10000000)))
    tuple = Person(*range(10000000))

if __name__ == "__main__":
    normal_time = timeit.timeit("test_normal_tuple()", setup="from __main__ import test_normal_tuple", number=1000)
    named_time = timeit.timeit("test_named_tuple()", setup="from __main__ import test_named_tuple", number=1000)
    print("normal tuple :", normal_time)
    print("named tuple  :", named_time)

得到結果如下:

normal tuple : 1.4164350395202637
named tuple  : 8.236930131912231

可以看到,namedtuple創建的速度比普通元組慢,因為它需要額外的計算來生成所需要的類定義,但這種差異在實際應用中並不會影響太多。

2.訪問效率

使用timeit模塊測試一個10000000個元素的元組和namedtuple的訪問效率:

from collections import namedtuple
import timeit

Person = namedtuple("Person", list(range(10000000)))
tuple = Person(*range(10000000))

def test_normal_tuple():
    t = tuple(range(10000000))
    for i in range(len(t)):
        a = t[i]

def test_named_tuple():
    for i in range(10000000):
        a = tuple[i]

if __name__ == "__main__":
    normal_time = timeit.timeit("test_normal_tuple()", setup="from __main__ import test_normal_tuple", number=1000)
    named_time = timeit.timeit("test_named_tuple()", setup="from __main__ import test_named_tuple", number=1000)
    print("normal tuple :", normal_time)
    print("named tuple  :", named_time)

得到結果如下:

normal tuple : 5.558712959289551
named tuple  : 6.515319109916687

可以看到,namedtuple與元組在訪問效率上並無明顯區別。

3.執行效率

使用timeit模塊測試一個空操作的元組和namedtuple的執行效率:

from collections import namedtuple
import timeit

Person = namedtuple("Person", ["name", "age"])
tuple = Person(name="Tom", age=3)

def test_normal_tuple():
    pass

def test_named_tuple():
    pass

if __name__ == "__main__":
    normal_time = timeit.timeit("test_normal_tuple()", setup="from __main__ import test_normal_tuple", number=1000)
    named_time = timeit.timeit("test_named_tuple()", setup="from __main__ import test_named_tuple", number=1000)
    print("normal tuple :", normal_time)
    print("named tuple  :", named_time)

得到結果如下:

normal tuple : 0.0016641616821289062
named tuple  : 0.0016469955444335938

可以看到,namedtuple與元組在執行效率上幾乎無差別。

結論

總體來說,namedtuple相比普通元組來說有更好的可讀性,同時它本身也具備擴展性和繼承性。儘管在創建方面不如普通元組快,但巨大的拓展性和易用性彌補了這一點缺陷。在實際項目中,使用namedtuple可以提高代碼的可讀性和可維護性,減少由於人為疏忽帶來的錯誤。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/219980.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-09 11:02
下一篇 2024-12-09 11:02

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • Python編程二級證書考試相關現已可以上網購買

    計算機二級Python考試是一項重要的國家級認證考試,也是Python編程的入門考試。與其他考試一樣,Python編程二級證書的考生需要進入正式考試,而為了備考,這篇文章將詳細介紹…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29

發表回復

登錄後才能評論