題圖:Photo by Paulo Jacobe on Unsplash
大家好,我是軍哥
今天開始,開一個冷門模塊的系列更新。
collections模塊算得上是最冷門的模塊之一,用得人少,但是功能很強大。
collections提供了4個重要的數據類型,在實際開發中或多或少會接觸到,通過使用這些數據類型,可以讓你的代碼變得更優雅、更地道。
今天先來介紹 namedtuple 這個類型
namedtuple 是 元組(tuple)類型的子類,所以本質上它還是一個元組類型,繼承了元組所有的的特性,namedtuple 特別之處在於你可以通過名字來訪問元組中的元素,類似字典,通過key來訪問value。
以前訪問元組中的元素必須通過索引訪問
>>> x, y = 1,2
>>> point = (x, y)
>>> point[0]
1
>>> point[1]
2
現在你可以通過屬性名來訪問,先看如何定義一個 namedtuple
定義from collections import namedtuple
# 首先定義一個namedtuple類
# 類的名字是 "Point"
# 它有兩個屬性 x 和 y
>>> Point = namedtuple('Point', ['x', 'y'])
# namedtuple初始化
>>> p = Point(x=11, y=22)
# 和tuple類型一樣,通過下標索引訪問,等價於 p = (11, 22)
>>> p[0] + p[1]
33
# 通過欄位屬性來訪問,這是namedtuple獨有的特性
>>> p.x + p.y
33
咋看起來,要使用 namedtuple還是挺麻煩的,不像tuple一樣,直接 p = (11, 22) 就定義了一個元組對象,那什麼場景下會用到 namedtuple呢?
答案是在使用tuple可讀性不強,但是又不希望用class來自定義類的時候。
比如有這樣一組數據
bob = ('Bob', 30, 'male')
看值其實你是不知道這裡面的3個元素分別表示什麼意思的,也許你能猜出來,但也僅僅是靠猜,那怎麼樣可讀性更好一點呢?其實,我們可以自定義一個類來抽象化這組數據
class Person:
def __init__(name, age, gender):
self.name = name
self.age = age
self.gender = gender
bob = Person('Bob', 30, 'male')
通過Person類,你可以一目了然,知道Bob對應的就是name,30對應的是 age,male 對應的gender欄位。
可是這樣做,雖然可讀性更強一點了,但是代碼更麻煩,更重要的是創建一個這樣的對象消耗的成本會比純粹的元組高很多。
而 namedtuple 正好可以解決這種問題,它即繼承了tuple良好的性能,又有可讀性的特點。
from collections import namedtuple
Person = namedtuple("Person", "name age gender")
bob = Person(name='Bob', age=30, gender='male')
>>> bob[0]
'Bob'
>>> bob.name
'Bob'
>>> bob.age
30
>>> bob[1]
30
你有沒有注意到,namedtuple可認為是一種簡單的自定義類,可以指定屬性,但是不能像class定義的類一樣定義方法。因此,在考慮到如果定義一個類,類裡面不需要定義方法時,其實就可以用namedtuple來代替。
這就是namedtuple的作用,你了解了嗎?
臥槽!python這個內置模塊可以開發遊戲
哈工程和哈工大被 MathWorks 禁止使用 MATLAB