1. 程式人生 > >Python 3.7.1 中 namedtuple 具名元組基本用法詳解

Python 3.7.1 中 namedtuple 具名元組基本用法詳解

Python 3.7.1 中 namedtuple 具名元組基本用法詳解

轉載請註明出處:https://blog.csdn.net/jpch89/article/details/84645251


文章目錄


0. 參考資料


1. 概述

namedtuple 大多數翻譯作具名元組命名元組,個人喜歡前者的譯法。
具名元組可以理解為元組的增強版本,它適用於任何普通元組的應用範圍。
具名元組為元組中的每個元素都賦予了含義,從而增強程式碼可讀性,能夠讓程式設計師寫出自文件化 self-documenting 的程式碼。


2. namedtuple() 定義與引數

namedtuple() 工廠函式返回一個具名元組類,該函式位於 collections 模組下,具體定義形式如下:

namedtuple(typename, field_names, *, rename=False, defaults=
None, module=None)

2.1 typename 引數

namedtuple 返回一個元組的子類(即具名元組類),類名為 typename
通過具名元組類創建出來的具名元組物件,其內部元素支援屬性查詢(點號語法)、索引操作(方括號語法),並且是可迭代的
具名元組物件還有自動生成的文件字串,和一個 __repr__() 方法,把具名元組物件展示為 name=value 的格式。
下面是一小段示例程式碼:

from collections import namedtuple

Student = namedtuple('Student', 'name, gender')
s = Student('小花', '女')

# 屬性訪問
print(s.name)
print(s.gender)
"""
小花
女
"""

# 索引取值
print(s[0])
print(s[1])
"""
小花
女
"""

# 可迭代
for i in s:
    print(i)
"""
小花
女
"""

# docstring
print(s.__doc__)
"""
Student(name, gender)
"""

# repr
print(repr(s))
"""
Student(name='小花', gender='女')
"""

2.2 field_names 引數

field_names 是具名元組的欄位名。
它可以通過兩種形式指定:

  • 字串組成的序列
    比如 ['x', 'y']('x', 'y')

  • 一個長字串,各個欄位名之間用空格或逗號分隔
    比如 'x y' 或者 'x, y'

欄位名必須符合以下規則:

  • 以字母開頭
  • 由字母、數字、下劃線組成
  • 不能與關鍵字重名
  • 不能以下劃線開頭

2.3 rename 引數

rename 預設為 False,它是隻能以關鍵字形式指定的引數,或者叫做強制關鍵字引數 keyword-only argument
如果 rename=True,那麼無效的欄位名會被替換為 '_索引值'
比如 ['abc', 'def', 'ghi', 'abc'] 會被轉換成 ['abc', '_1', 'ghi', '_3']。其中與關鍵字重名的 'def' 和重複的 'abc' 都被替換成了 '_索引值'


2.4 defaults 引數

defaults 引數預設為 None,是強制關鍵字引數。
它可以被設定為可迭代物件。
由於預設值引數必須在非預設值引數之後,所以 defaults 引數會被設定給最右邊的欄位名。
比如欄位名為 'x, y, z'defaults 引數為 (1, 2) 時,y 預設為 1z 預設為 2x 則沒有預設值。


2.5 module 引數

如果定義了 __module__ 的值,那麼具名元組類的 __module__ 屬性就會被設定為該值。

補充
__module__ 屬性記錄類定義的位置,如果定義的位置正好是主程式,那麼該值為 '__main__',否則是類所屬模組的名字。


2.6 補充和歷代版本變化

具名元組物件是輕量級的,它們消耗的記憶體與普通元組一樣,因為它們不會對每個例項都維護一個屬性字典。

3.1:增加了 rename 引數
3.6verboserename 引數變成強制關鍵字引數
3.6:增加了 module 引數
3.7:去除了 verbose 引數和 _source 屬性
3.7:加入了 defaults 引數和 _field_defaults 屬性


3. 具名元組的方法和屬性

3.1 簡單示例

from collections import namedtuple

# 簡單示例
Point = namedtuple('Point', ['x', 'y'])

# 通過位置引數或者關鍵字引數例項化
p = Point(11, y=22)

# 索引取值
print(p[0] + p[1])
"""
33
"""

# 像普通元組一樣解包
x, y = p
print(x, y)
"""
11 22
"""

# 通過名字訪問欄位
print(p.x + p.y)
"""
33
"""

# __repr__ 展現為 name=value
print(repr(p))
"""
Point(x=11, y=22)
"""

3.2 _make 方法

除了從元組繼承來的方法和屬性,具名元組自己還有三個方法兩個屬性
為了避免與欄位名重名,這些方法和屬性都以一個下劃線開頭,這也是為什麼欄位名不能以下劃線開頭的原因。

classmethod somenamedtuple._make(iterable)

  • 從序列或者可迭代物件例項化一個具名元組
t = [11, 22]
print(Point._make(t))
"""
Point(x=11, y=22)
"""

3.3 _asdict 方法

somenamedtuple._asdict()
返回一個 OrderedDict 有序字典物件,把欄位名對映到相應的值。

p = Point(11, 22)
print(p._asdict())
"""
OrderedDict([('x', 11), ('y', 22)])
"""

3.1 版本開始返回 OrderedDict 物件而不是普通字典物件。


3.4 _replace 方法

somenamedtuple._replace(**kwargs)

  • _replace 接收關鍵字引數,給指定的欄位重新賦值
  • 不改變原來的具名元組,而是會返回一個新的具名元組
p = Point(11, 22)
# _replace 不改變原具名元組!
new_p = p._replace(x=33)
print(p)
print(new_p)
"""
Point(x=11, y=22)
Point(x=33, y=22)
"""

3.5 _fields 屬性

somenamedtuple._fields
該屬性是由欄位名組成的元組。
在內省 introspection 時和從現有的欄位名建立新的具名元組型別時很好用。

# 檢視具名元組的欄位
print(p._fields)
"""
('x', 'y')
"""

Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields + Color._fields)
p = Pixel(11, 22, 128, 255, 0)
print(p)
"""
Pixel(x=11, y=22, red=128, green=255, blue=0)
"""

3.7 _fields_defaults 屬性

somenamedtuple._fields_defaults
返回一個字典,是欄位名和預設值的對映。

Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
print(Account._fields_defaults)
"""
{'balance': 0}
"""
print(Account('premium'))
"""
Account(type='premium', balance=0)
"""

3.8 補充用法

  • 使用 getattr 獲取屬性
# 使用 getattr 獲取屬性
print(getattr(p, 'x'))
"""
11
"""
  • 用字典生成具名元組
# 解包字典作為引數生成具名元組
# 相當於以關鍵字形式指定的引數
d = {'x': 11, 'y': 22}
p = Point(**d)
print(p)
"""
Point(x=11, y=22)
"""

其它用法比如子類化具名元組另行記述。


完成於 2018.11.30