惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
P
Palo Alto Networks Blog
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
Last Week in AI
Last Week in AI
Blog — PlanetScale
Blog — PlanetScale
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
The Cloudflare Blog
I
Intezer
P
Privacy International News Feed
C
Check Point Blog
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
H
Hackread – Cybersecurity News, Data Breaches, AI and More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
B
Blog
Latest news
Latest news
小众软件
小众软件
Engineering at Meta
Engineering at Meta
Cyberwarzone
Cyberwarzone
Project Zero
Project Zero
P
Proofpoint News Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Schneier on Security
美团技术团队
G
GRAHAM CLULEY
博客园 - 司徒正美
T
Threatpost
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 叶小钗
C
Cisco Blogs
MongoDB | Blog
MongoDB | Blog
人人都是产品经理
人人都是产品经理
博客园 - 三生石上(FineUI控件)
H
Help Net Security
Simon Willison's Weblog
Simon Willison's Weblog
Cisco Talos Blog
Cisco Talos Blog
K
Kaspersky official blog
NISL@THU
NISL@THU
AWS News Blog
AWS News Blog
T
Threat Research - Cisco Blogs
月光博客
月光博客
Security Latest
Security Latest
Scott Helme
Scott Helme
T
Tenable Blog

晚花行乐

马克卡尼在2026年达沃斯论坛上的讲话(阅读材料) | 晚花行乐 鸡娃如何用力才是恰到好处 | 晚花行乐 读万卷书,行万里路的辩证关系 | 晚花行乐 反对培训机构掐尖招生 | 晚花行乐 小泽和建国会谈最后10分钟全文(阅读材料) | 晚花行乐 来看看 DeepSeek 怎么鸡娃 | 晚花行乐 谈谈基本功 | 晚花行乐 惠普 ProDesk SFF PC 各系列参数对比 | 晚花行乐 解决瘦客户机上安装 Debian 12 启动失败问题 | 晚花行乐 意拾喻言:老外写的文言文 | 晚花行乐 笠翁对韵中的典故(十三元) | 晚花行乐 谈谈中考取消四小门 | 晚花行乐 亚马逊云科技产品免费试用攻略(3) - 对象存储服务 | 晚花行乐 在 Windows 10 LTSC 版本上安装 WSL2 | 晚花行乐 Debian 12 的常用配置项 | 晚花行乐 在 Debian 12 上安装 Nvidia 显卡驱动程序 | 晚花行乐 解决 Debian 12 关机失败问题 | 晚花行乐 解决 VS Code 自动更新版本后卡在连接界面 | 晚花行乐 观看巴黎奥运会有感 | 晚花行乐 在 Windows10 上安装惠普旧打印机驱动程序 | 晚花行乐 欢迎关注公众号:晚花行乐 | 晚花行乐 如何编写拼写检查器 | 晚花行乐 亚马逊云科技产品免费试用攻略(2) - 云服务器 | 晚花行乐 Pandas 中 axis 参数的理解(附实例) | 晚花行乐 我打算命个名,叫什么什么 Manager | 晚花行乐 上海武康路历史建筑一览 | 晚花行乐 Python 实现简单的数学表达式解析并处理 | 晚花行乐 观看马拉松的感悟 | 晚花行乐 Python 保存 Cookies 到文件并再次读取 | 晚花行乐 如何为 Hugo 静态网站添加评论功能 | 晚花行乐 Linux 共享打印服务 CUPS | 晚花行乐 如何为 Hugo 静态网站添加搜索功能 | 晚花行乐 解决 CSV 文件的第一列不能解析 | 晚花行乐 亚马逊云科技产品免费试用攻略(1) - 注册账户 | 晚花行乐 第二幕 Atma 的闲聊 | 晚花行乐 第二幕野蛮人的语音 | 晚花行乐 古入声和普通话平声对照 | 晚花行乐 第一幕的背景音乐 | 晚花行乐 第二幕亚马逊的语音 | 晚花行乐 第一幕的亚马逊的语音 | 晚花行乐 第一幕的野蛮人的语音 | 晚花行乐 MacOS 的彩蛋:Here's to the crazy ones | 晚花行乐 笠翁对韵的基本知识 | 晚花行乐 笠翁对韵中的典故(十二文) | 晚花行乐 笠翁对韵中的典故(十一真) | 晚花行乐 笠翁对韵中的典故(十灰) | 晚花行乐 杭州景点的楹联 | 晚花行乐 adb keycode 大全 | 晚花行乐 Scikit-learn 学习笔记(0)名词术语 | 晚花行乐 Scikit-learn 学习笔记(3)监督学习的例子 | 晚花行乐 SQLite 文档的学习笔记(1)长期支持计划 | 晚花行乐 SQLite 文档的学习笔记(2)测试方法 | 晚花行乐 笠翁对韵中的典故(九佳) | 晚花行乐 Ansible 如何检查一个程序的版本 | 晚花行乐 Ansible 如何检查一个文件夹是否存在 | 晚花行乐 pip 配置文件详解 | 晚花行乐 Ansible 如何检查一个URL是否正常 | 晚花行乐 Ansible 如何修改 iptables 规则 | 晚花行乐 Ansible 指定 playbook 运行的主机 | 晚花行乐 Ansible 如何清空文件夹 | 晚花行乐 Ansible 如何在本机执行命令 | 晚花行乐 笠翁对韵中的典故(八齐) | 晚花行乐 Python 中 Defaultdict 的理解 | 晚花行乐 《伊索寓言》电子书 | 晚花行乐 菲伯尔钢琴伴奏:第二册 | 晚花行乐 Python 的 Keyword-Only Arguments 理解 | 晚花行乐 Python 的 函数参数处理机制 | 晚花行乐 瓦瑞夫在第一幕的闲聊 | 晚花行乐 瓦瑞夫在第一幕的任务提示 | 晚花行乐 第一幕的女巫语音 | 晚花行乐 《Fluent Python》 读书笔记:文本和字节序列 | 晚花行乐 第一幕的罗格语音 | 晚花行乐 第一幕的圣骑士语音 | 晚花行乐 第一幕的男巫语音 | 晚花行乐 第一幕的旁白 | 晚花行乐 第一幕的恶魔 | 晚花行乐 Python 中 Element Tree 的理解 | 晚花行乐 笠翁对韵中的典故(七虞) | 晚花行乐 笠翁对韵中的典故(五微) | 晚花行乐 笠翁对韵中的典故(六鱼) | 晚花行乐 笠翁对韵中的典故(一东) | 晚花行乐 笠翁对韵中的典故(二冬) | 晚花行乐 笠翁对韵中的典故(三江) | 晚花行乐 笠翁对韵中的典故(四支) | 晚花行乐 姜太公钓鱼 | 晚花行乐 武王建立周朝 | 晚花行乐 大禹治水 | 晚花行乐 尧舜让位 | 晚花行乐 黄帝战蚩尤 | 晚花行乐 上下五千年-精简版 | 晚花行乐 成功修复鼠标按键 | 晚花行乐 横向的Word文档怎么加页眉页脚 | 晚花行乐 商标通用化的故事:商标代替商品名 | 晚花行乐 搜索空文件夹的批处理程序 | 晚花行乐 Sn0wbreeze不能运行? | 晚花行乐 天线的驻波比 | 晚花行乐 天线参数:增益Gain | 晚花行乐 天线参数:方向图Radiation pattern | 晚花行乐 本拉登别墅的Google Earth坐标 | 晚花行乐 宜家帕克斯(PAX)衣柜的拼装过程 | 晚花行乐
Python 中 NamedTuple 的理解 | 晚花行乐
2021-12-04 · via 晚花行乐

namedtuple(具名元组)和与 tuple 通过坐标位置辨认属性相比,可读性更好。

namedtuple(具名元组)自带属性名称,对比下面两个:

t1 = ('Alice', 12500, 2)
t2 = Employee(name='Alice', salary=12500, grade=2)

namedtuple 可以使用在 tuple 的任何地方。

你可以这么理解:namedtuple 之于 tuple 就像 dict 之于 list,为每个元素起了名字,使用名字操作元素,更加方便、好记。

使用场景

当你打算抽象出一个类,而你设计的这个类只有属性而没有方法,仅仅为了保存数据,而且不做进一步修改。那么你可以考虑使用 namedtuple,将大大减少你的代码量。

简单示例

下面的几行代码简单展示了 namedtuple 的基本用法:

t 变量指向一个新生成的类,类名叫做 T

>>> t=collections.namedtuple('T',["a","b","c","d"])

实例化出 T 的对象,叫 t1

>>> t1=t(a=1,b=2,c=3,d=4)
>>> print(t1)
T(a=1, b=2, c=3, d=4)

参数不够就报错

>>> t1=t(a=1, b=2, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'd'

如何访问实例的成员

>>> t1.a   # 点号表示法
1
>>> t1[1]  # 可索引
2
>>> for item in t1: print(item)  # 可遍历
...
1
2
3
4
>>> A,B,C,D = t1   # 可拆包
>>> A
1
>>>

因为 namedtuple 从 tuple 派生而来,所以继承了 tuple ,乃至 sequence 的特性。

上面例子里的点号表示法,十分方便,因为 dict 类型并不支持这种访问成员的方法。

工厂函数 namedtuple()

之所以叫工厂函数,是因为它不返回具体的实例,而是动态生成一个新的类,可以用这个新类来创建实例。

为什么要使用工厂函数而不是直接提供一个类?因为 namedtuple 要让用户自定义类型的名称,这个名称不能预先定义,所以要先动态生成一个类,再用这个类生成自定义类型的tuple实例。

与之相比,其他数据类型都从同一个类,实例化而来:

>>> d = dict(a=1, b=2)
>>> d
{'a': 1, 'b': 2}

namedtuple() 的参数列表

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

下面逐个解释参数(单独星号 * 的含义,见 这篇文章)。

类名 typename

必选参数。定义了生产出的类的名称,也就是新生成 tuple 的 type,所以叫 typename. 看下面的例子:

>>> import collections
>>> new_class = collections.namedtuple('aa',['a'])
>>> new_class.__class__
<class 'type'>           # 从type派生出来的
>>> new_class.__name__   # 类的名称
'aa'

这里创建了 aa 这个新类,但是这个新类被 new_class 变量所引用。就像

x=2

在使用 x 这个变量时,就在指代 2 这个字面量。当我使用 new_class 变量时,实际上在指代 aa 这个新类。下面我们用这个新类来创建对象。

>>> aa_object = new_class(a=1)
>>> aa_object.__class__
<class '__main__.aa'>      # 从 aa 实例化
>>> type(aa_object)
<class '__main__.aa'>      # aa 类型
>>> isinstance(aa_object,new_class)
True
>>>

很多关于 namedtuple 的教程里,喜欢把工厂函数 namedtuple()返回的类赋给同名的变量,比如

Card = collections.namedtuple('Card', ['rank', 'suit'])

或者

Employee = collections.namedtuple('Employee', ['name', 'city', 'salary'])

这样会引起误解,会以为对变量名又什么要求。其实并没有, 只是指向新类的一个变量而已。比如下面的例子中,更换了变量名称。

>>> new_2_class = new_class
>>> new_2_class(a=1).__class__
<class '__main__.aa'>
>>>

我们用新的变量指代,仍然指向同一个类。对于 Python 变量的赋值,可以参考 这篇文章

字段列表 field_names

定义 tuple 的字段名称,字段列表有序列和字符串两种形式:

字符串的序列

sequence of string 即可,比如

namedtuple('T',["a","b","c","d"])
namedtuple('T',("a","b","c","d"))

都可以

空格或逗号分隔

为了方便,还可以将所有字段名称放在同一个长的字符串里,用空格或者逗号分隔。比如:

namedtuple('T',"a b c d"])
namedtuple('T',"a,b,c,d")

非法的字段名称

python 的预留关键字不能用作字段名称:

>>> collections.namedtuple('T',"for,b,c,d")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "xx.py", line 393, in namedtuple
    raise ValueError('Type names and field names cannot be a '
ValueError: Type names and field names cannot be a keyword: 'for'

字段名称不能以下划线开头 (_),因为下划线有其他预留的用途。

rename

非必选参数,布尔值。True 表示允许自动重命名,(上节)[#invalid] 中非法字段名会被自动改成下划线开头的字段名(原因在 这一节 中有解释)。还是用 (上节)[#invalid] 的例子:

>>> collections.namedtuple('T',"for,b,c,d",rename=True)._fields
('_0', 'b', 'c', 'd')

# for 被自动更名为 _0

defaults

注意末尾有个"s",非必选参数,各字段的默认值。接受的取值是可迭代对象(iterable)。比如

>>> t=collections.namedtuple('T',"a,b,c,d")   # 没有定义默认值
>>> t()       #报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 4 required positional arguments: 'a', 'b', 'c', and 'd'
>>> t=collections.namedtuple('T',"a,b,c,d",defaults=[1,2,3,4])  # 定义了默认值
>>> t()    #自动赋值
T(a=1, b=2, c=3, d=4)
>>>

如果 defaults 提供了 dict 类型,那么默认值取自 key :

>>> t=collections.namedtuple('T',"a b c d",defaults={"a":4,"b":3,"c":2,"d":1})
>>> t()
T(a='a', b='b', c='c', d='d')
>>>

如果 defaults 提供了 str 类型,是每个字母分别赋值:

>>> t=collections.namedtuple('T',"a b c d",defaults="1234")
>>> t()
T(a='1', b='2', c='3', d='4')

对不上的情况

如果 defaults 提供的数量和前面 fields 的数量对不上,那么一定有些字段是需要在实例化的时候靠位置定义的,比如说:

>>> t=collections.namedtuple('T',"a b c d",defaults="34")

default 提供的数值少两个,那么实例化的时候,必然有两个参数需要用位置来赋值、

又因为位置参数必须先于关键字参数,所以 defaults 值是从右往左一一赋值。

>>> t=collections.namedtuple('T',"a b c d",defaults="34")
>>> t(1,2)
T(a=1, b=2, c='3', d='4')
>>>

自带函数

namedtuple 是派生自 tuple 的子类,除了继承了 tuple 的所有特性外,还自带了一些特有的方法方便使用。

为了避免和用户自定义的属性冲突,自带的方法名都以下划线开头,这也是为什么 fields 字段不能使用下划线开头的字段名的原因。

_make()

输入一个可迭代对象,可以实例化一个对象。我觉得没什么用,直接用类名实例化即可。如果数据保存在序列里,那么用星号 unpack 即可。

>>> t=collections.namedtuple('T',"a b c d")
>>> t(*[1,2,3,4])
T(a=1, b=2, c=3, d=4)
>>>

_asdict()

输出一个 dict 形式:

>>> t1
T(a=1, b=2, c=3, d=4)
>>> t1._asdict()
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>>

各位读后有什么想法,请在下方留言吧!如果对本文有疑问或者寻求合作,欢迎 联系邮箱邮箱已到剪贴板

精彩评论