namedtuple是Python中存儲數據類型,比較常見的數據類型還有有list和tuple數據類型。相比於list,tuple中的元素不可修改,在映射中可以當鍵使用。
namedtuple:
namedtuple類位於collections模塊,有了namedtuple後通過屬性訪問數據能夠讓我們的代碼更加的直觀更好維護。
namedtuple能夠用來創建類似於元祖的數據類型,除了能夠用索引來訪問數據,能夠迭代,還能夠方便的通過屬性名來訪問數據。
接下來通過本文給大家分享python namedtuple()的使用,一起看看吧!
基本定義
collections. namedtuple (typename, field_names, *, rename=False, defaults=None, module=None)
(1)返回一個名為typename的新元組子類
(2)新的子類用於創建類似元組的對象,這些對象具有可通過屬性查找訪問的字段以及可索引和可迭代的字段field_names
typename
(1)typename表示這個子類的名字,比如C++、python、Java中的類名
field_names
(1)field_names是一個字符串序列,例如['x','y']
(2)field_names可以是單個字符串,每個字段名都用空格或逗號分隔,例如'x y'或'x,y'
others
(1)其它的參數並不常用,這裡不再介紹啦
基本樣例
from collections import namedtuple # 基本例子 Point = namedtuple('Point',['x','y']) # 類名為Point,屬性有'x'和'y' p = Point(11, y=22) # 用位置或關鍵字參數實例化,因為'x'在'y'前,所以x=11,和函數參數賦值一樣的 print(p[0]+p[1]) # 我們也可以使用下標來訪問 # 33 x, y = p # 也可以像一個元組那樣解析 print(x,y) # (11, 22) print(p.x+p.y) # 也可以通過屬性名來訪問 # 33 print(p) # 通過內置的__repr__函數,顯示該對象的信息 # Point(x=11, y=22)
classmethod somenamedtuple. _make (iterable)
(1)從一個序列或者可迭代對象中直接對field_names中的屬性直接賦值,返回一個對象
t = [11, 22] # 列表 list p = Point._make(t) # 從列表中直接賦值,返回對象 print(Point(x=11, y=22)) # Point(x=11, y=22)
classmethod somenamedtuple._asdict ()
(1)之前也說過了,說它是元組,感覺更像一個帶名字的字典
(2)我們也可以直接使用_asdict()將它解析為一個字典dict
p = Point(x=11, y=22) # 新建一個對象 d = p._asdict() # 解析並返回一個字典對象 print(d) # {'x': 11, 'y': 22}
classmethod somenamedtuple._replace (**kwargs)
(1)這是對某些屬性的值,進行修改的,從replace這個單詞就可以看出來
(2)注意該函數返回的是一個新的對象,而不是對原始對象進行修改
p = Point(x=11, y=22) # x=11,y=22 print(p) # Point(x=11, y=22) d = p._replace(x=33) # x=33,y=22 新的對象 print(p) # Point(x=11, y=22) print(d) # Point(x=33, y=22)
classmethod somenamedtuple._fields
(1)該方法返回該對象的所有屬性名,以元組的形式
(2)因為是元組,因此支持加法操作
print(p._fields) # 查看屬性名 # ('x', 'y') Color = namedtuple('Color', 'red green blue') Pixel = namedtuple('Pixel', Point._fields + Color._fields) # 新建一個子類,使用多個屬性名 q = Pixel(11, 22, 128, 255, 0) print(q)
classmethod somenamedtuple._field_defaults
(1)該方法是python3.8新增的函數,因為我的版本是3.6,無法驗證其正確性
(2)下面給出官方的示例
Account = namedtuple('Account', ['type', 'balance'], defaults=[0]) print(Account._field_defaults) #{'balance': 0} print(Account('premium')) #Account(type='premium', balance=0)
getattr()函數
(1)用來獲得屬性的值
print(getattr(p, 'x')) # 11
字典創建namedtuple()
(1)從字典來構建namedtuple的對象
d = {'x': 11, 'y': 22} # 字典 p = Point(**d) # 雙星號是重點 print(p) # Point(x=11, y=22)
CSV OR Sqlite3
(1)同樣可以將從csv文件或者數據庫中讀取的文件存儲到namedtuple中
(2)這裡每次存的都是一行的內容
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade') import csv for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "r"))): # 這裡每行返回一個對象 注意! print(emp.name, emp.title) import sqlite3 conn = sqlite3.connect('/companydata') # 連接數據庫 cursor = conn.cursor() cursor.execute('SELECT name, age, title, department, paygrade FROM employees') for emp in map(EmployeeRecord._make, cursor.fetchall()): # 每行返回一個對象 注意! print(emp.name, emp.title)
類的繼承
(1)接下來用deepmind的開源項目graph_nets中的一段代碼來介紹
NODES = "nodes" EDGES = "edges" RECEIVERS = "receivers" SENDERS = "senders" GLOBALS = "globals" N_NODE = "n_node" N_EDGE = "n_edge" GRAPH_DATA_FIELDS = (NODES, EDGES, RECEIVERS, SENDERS, GLOBALS) GRAPH_NUMBER_FIELDS = (N_NODE, N_EDGE) class GraphsTuple( # 定義元組子類名 以及字典形式的鍵名(屬性名) collections.namedtuple("GraphsTuple", GRAPH_DATA_FIELDS + GRAPH_NUMBER_FIELDS)): # 這個函數用來判斷依賴是否滿足,和我們的namedtuple關係不大 def _validate_none_fields(self): """Asserts that the set of `None` fields in the instance is valid.""" if self.n_node is None: raise ValueError("Field `n_node` cannot be None") if self.n_edge is None: raise ValueError("Field `n_edge` cannot be None") if self.receivers is None and self.senders is not None: raise ValueError( "Field `senders` must be None as field `receivers` is None") if self.senders is None and self.receivers is not None: raise ValueError( "Field `receivers` must be None as field `senders` is None") if self.receivers is None and self.edges is not None: raise ValueError( "Field `edges` must be None as field `receivers` and `senders` are " "None") # 用來初始化一些參數 不是重點 def __init__(self, *args, **kwargs): del args, kwargs # The fields of a `namedtuple` are filled in the `__new__` method. # `__init__` does not accept parameters. super(GraphsTuple, self).__init__() self._validate_none_fields() # 這就用到了_replace()函數,注意只要修改了屬性值 # 那麼就返回一個新的對象 def replace(self, **kwargs): output = self._replace(**kwargs) # 返回一個新的實例 output._validate_none_fields() # pylint: disable=protected-access 驗證返回的新實例是否滿足要求 return output # 這是為了針對tensorflow1版本的函數 # 返回一個擁有相同屬性的對象,但是它的屬性值是輸入的大小和類型 def map(self, field_fn, fields=GRAPH_FEATURE_FIELDS): # 對每個鍵應用函數 """Applies `field_fn` to the fields `fields` of the instance. `field_fn` is applied exactly once per field in `fields`. The result must satisfy the `GraphsTuple` requirement w.r.t. `None` fields, i.e. the `SENDERS` cannot be `None` if the `EDGES` or `RECEIVERS` are not `None`, etc. Args: field_fn: A callable that take a single argument. fields: (iterable of `str`). An iterable of the fields to apply `field_fn` to. Returns: A copy of the instance, with the fields in `fields` replaced by the result of applying `field_fn` to them. """ return self.replace(**{k: field_fn(getattr(self, k)) for k in fields}) # getattr(self, k) 獲取的是鍵值對中的值, k表示鍵
[火星人 ] 詳解Python中namedtuple的使用已經有262次圍觀