namedtuple 是具有名称的元组, 与普通元组一样, namedtuple 也是不可变的序列, 除了支持整数索引访问, namedtuple 还支持点属性的方式访问元素
创建 namedtuple 数据类型
from collections import namedtuple
# 方式一
Book = namedtuple("Book", ["name", "author"])
# 方式二
Book = namedtuple("Book", "name author")
namedtuple 工厂函数
-
第一个参数是该数据类型的名称, 绑定到 Book.__name__
-
第二个参数指定了所有元素的属性名称, 可以简单地理解为字段名
创建新类型的同时会自动生成文档字符串以及 __repr__ 方法
# 该数据类型的名称
>>> Book.__name__
'Book'
# 该数据类型的文档
>>> Book.__doc__
'Book(name, author)'
Book 类型不仅包含全部普通元组的功能, 还能通过属性的方式访问
# 初始化
>>> r = Book("红楼梦", "曹雪芹 高鹗")
# 通过属性访问元素
>>> r.name
'红楼梦'
>>> r.author
'曹雪芹 高鹗'
# 通过索引访问元素
>>> r[0]
'红楼梦'
>>> r[1]
'曹雪芹 高鹗'
# Book 类型自动实现了 __repr__ (直接在交互式环境输出变量,调用的是 __repr__ 方法)
>>> r
Book(name='红楼梦', author='曹雪芹 高鹗')
# 解构赋值
>>> name, author = r
>>> name
'红楼梦'
>>> author
'曹雪芹 高鹗'
# 元组解包
>>> print(*r)
红楼梦 曹雪芹 高鹗
# Book 数据不可变, 试图修改会抛异常
>>> book.name = "西游记"
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [22], in <cell line: 1>()
----> 1 book.name = "西游记"
NameError: name 'book' is not defined
namedtuple 内置了一些以单下划线开头的属性和方法
# 获取所有字段
>>> r._fields
('name', 'author')
# 转为字典
>>> r._asdict()
{'name': '红楼梦', 'author': '曹雪芹 高鹗'}
# 替换字段的值, 生成新的数据, 注意这里使用的是浅拷贝
>>> r_2 = r._replace(author='曹雪芹')
>>> r_2
Book(name='红楼梦', author='曹雪芹')
# 另一种初始化方式
>>> w = Book._make(['西游记', '吴承恩'])
>>> w
Book(name='西游记', author='吴承恩')
Python 3.6 还提供一种全新的语法来定义命名元组(typing.NamedTuple)
from sys import getsizeof
from typing import NamedTuple
class Book(NamedTuple):
name: str
author: str
price: int
r = Book("红楼梦", "曹雪芹 高鹗", 35)
# Book 自动实现了 __repr__ 方法
print("r:", r)
# 属性访问
print("author:", r.author)
# 占用空间与普通元组一致
print("common tuple:", getsizeof(("红楼梦", "曹雪芹 高鹗", 35)))
print("named tuple:", getsizeof(r))
# 所有字段
print("fields:", r._fields)
# 转为字典
print("asdict:", r._asdict())
打印结果
r: Book(name='红楼梦', author='曹雪芹 高鹗', price=35)
author: 曹雪芹 高鹗
common tuple: 64
named tuple: 64
fields: ('name', 'author', 'price')
asdict: {'name': '红楼梦', 'author': '曹雪芹 高鹗', 'price': 35}