首先要知道的是python3中有typing模块含有类NamedTuple,collections模块含有函数namedtuple(该函数返回一个tuple的子类),这是官方文档传送门。
collections.namedtuple
namedtuple将创建一个和tuple类似的object,其中的元素可通过属性名访问,也可通过像tuple一样的下标来访问。其好处是通过名称访问数据能够让我们的代码更加的直观、规范,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | from collections import namedtuple # 定义一个namedtuple类型User,并包含name,sex和age属性。 User = namedtuple('User', ['name', 'sex', 'age']) # 创建一个User对象 user = User(name='kongxx', sex='male', age=21) # 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法 user = User._make(['kongxx', 'male', 21]) print(user) # User(name='user', sex='male', age=21) # 获取用户的属性 print(user.name) print(user.sex) print(user.age) # 修改对象属性,注意要使用"_replace"方法 user = user._replace(age=22) print(user) # User(name='user', sex='male', age=22) # 将User对象转换成字典,注意要使用"_asdict" print(user._asdict()) # OrderedDict([('name', 'kongxx'), ('sex', 'male'), ('age', 22)]) |
在python中,传统的tuple类似于数组,只能通过下标来访问各个元素,我们还需要注释每个下标代表什么数据。通过使用namedtuple,每个元素有了自己的名字,类似于C语言中的struct,这样数据的意义就可以一目了然了。当然,声明namedtuple是非常简单方便的。
代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | from collections import namedtuple Friend=namedtuple("Friend",['name','age','email']) f1=Friend('xiaowang',33,'[email protected]') print(f1) print(f1.age) print(f1.email) f2=Friend(name='xiaozhang',email='[email protected]',age=30) print(f2) name,age,email=f2 print(name,age,email) |
类似于tuple,它的属性也是不可变的:
1 2 3 4 | >>> big_yellow.age += 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute |
能够方便的转换成OrderedDict:
1 2 | >>> big_yellow._asdict() OrderedDict([('name', 'big_yellow'), ('age', 3), ('type', 'dog')]) |
方法返回多个值的时候,其实更好的是返回namedtuple的结果,这样程序的逻辑会更加的清晰和好维护:
1 2 3 4 5 6 7 8 | >>> from collections import namedtuple >>> def get_name(): ... name = namedtuple("name", ["first", "middle", "last"]) ... return name("John", "You know nothing", "Snow") ... >>> name = get_name() >>> print name.first, name.middle, name.last John You know nothing Snow |
typing.NamedTuple
官方文档中认为下面这两段代码是等价的:
1 2 3 | class Employee(NamedTuple): name: str id: int |
1 | Employee = collections.namedtuple('Employee', ['name', 'id']) |
NamedTuple几乎等同于namedtuple,但NamedTuple拥有一个额外的属性
值得注意 的是:继承自NamedTuple的类将是tuple的子类,但不会是NamedTuple的子类:
而其实例将像往常一样成为元组的实例,且不是NamedTuple的实例:
1 2 3 4 5 6 7 8 | >>> class Employee(NamedTuple): ... name: str ... id: int ... >>> issubclass(Employee, NamedTuple) False >>> isinstance(Employee(name='guido', id=1), NamedTuple) False |
如果想了解为何如此,请参看下方参考中的第二个链接。
参考自:
https://blog.csdn.net/qq_39173907/article/details/80023694
http://www.cocoachina.com/articles/46911