## DEV Community

codemee

Posted on • Updated on

# 可以用欄位名稱取用元素的序組 (tuple)

``````>>> import time
>>> t1 = time.localtime()
>>> t1
time.struct_time(tm_year=2023, tm_mon=1, tm_mday=28, tm_hour=17, tm_min=26, tm_sec=48, tm_wday=5, tm_yday=28, tm_isdst=0)

>>> type(t1)
<class 'time.struct_time'>
``````

``````>>> t1[0]
2023
``````

``````>>> t1.tm_year
2023
``````

## 自製具名序組

namedtuple() 是所謂的工廠 (factory) 函式, 這種函式的功用就是幫你依據需求製造出新的物件, 而 namedtuple() 會製造的是一種新的類別, 可以用來產生具名序組。

``````>>> import collections
>>> P = collections.namedtuple(
...     'Point',
...     ['X', 'Y']
... )
``````

``````>>> p1 = P(1,2)
>>> p2 = P(Y=3,X=5)
>>> p1
Point(X=1, Y=2)

>>> p2
Point(X=5, Y=3)

>>> type(p1)
<class '__main__.Point'>
``````

``````>>> p1[0]
1

>>> p2.Y
3
``````

``````>>> getattr(p1, 'X')
1
``````

## 具名序組元素的預設值

``````>>> P = collections.namedtuple(
...     'Point',
...     ['X', 'Y'],
...     defaults=[1,1]
... )
>>> p3 = P()
>>> p3
Point(X=1, Y=1)
``````

defaults 參數必須是一個可走訪物件, 由他依序提供個別元素的預設值。如果 defaults 內的資料數量少於元素個數, 就必須依循位置參數要出現在套用預設值的參數前的規則, 把 defaults 提供的預設值套用在序組中排在後面的元素, 前面的元素仍需要在建立物件時指定內容, 例如：

``````>>> P = collections.namedtuple(
...     'Point',
...     ['X', 'Y'],
...     defaults=[1]
... )
>>> p4 = P()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Point.__new__() missing 1 required positional argument: 'X'

Point.__new__() missing 1 required positional argumen'
``````

``````>>> p4 = P(3)
>>> p4
Point(X=3, Y=1)
``````

## 具名序組的特殊成員

``````>>> P._fields
('X', 'Y')

>>> P._field_defaults
{'Y': 1}
``````

_fields 會以序組傳回欄位名稱清單, 而 _field_defaults 則是以字典傳回個別欄位的預設值。要特別留意的是這些成員的名稱都是以 '_' 開頭。

``````>>> p5 = P(*[5,6])
>>> p6 = P._make([7,8])
>>> p5
Point(X=5, Y=6)

>>> p6
Point(X=7, Y=8)
``````

``````>>> p7 = P(**{'X':10, 'Y':11})
>>> p7
Point(X=10, Y=11)
``````

``````>>> p7._asdict()
{'X': 10, 'Y': 11}
``````

``````>>> p7
Point(X=10, Y=11)
>>> p8 = p7._replace(X=100)
>>> p8
Point(X=100, Y=11)
``````