Python namedtuple使用实例

目录

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

Python中的tuples(元组)是经常用来表示简单的数据结构,但它只能通过下标来访问其中的数据,这导致代码难于阅读和维护。Python的collections模块包含一个namedtuple()函数,用来创建一个tuple的子类,其可以通过属性名称访问tuple中的元素。

下面的代码片段使用了namedtuple()函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> from collections import namedtuple
>>> NetworkAddress = namedtuple('NetworkAddress',['hostname','port'])
>>> a = NetworkAddress('www.python.org',80)
>>> a.hostname
'www.python.org'
>>> a.port
80
>>> host, port = a
>>> len(a)
2
>>> type(a)
<class '__main__.NetworkAddress'>
>>> isinstance(a, tuple)
True
>>>

虽然namedtuple看起来像一个普通的类实例(如type的输出所示),但它是普通的tuple的子类,支持所有普通tuple的操作,而且增加了通过使用属性名访问其中数据的功能。

  • 在定义一个只用作数据结构的类时,可以使用namedtuple替代,如:
    1
    2
    3
    4
    5
    class Stock(object):
    def __init__(self,name,shares,price):
    self.name = name
    self.shares = shares
    self.price = price

可以定义为:

1
2
import collections
Stock = collections.namedtuple('Stock','name shares price')

以上两个版本可以通过类似的方式访问其中的数据。然而使用namedtuple更加节省内存,同时也支持所有的元组操作,如unpacking等。但使用namedtuple访问属性值时,不如通过类那样高效。例如如果s是namedtuple实例而不是普通的类实例时,访问s.shares需要几乎两倍的时间。所以,如果你的目标是定义一个需要更新很多实例属性的高效数据结构,那么命名元组并不是你的最佳选择。

  • 命名元组另一个用途就是作为字典的替代,因为字典存储需要更多的内存空间。 如果你需要构建一个非常大的包含字典的数据结构,那么使用命名元组会更加高效。 但是需要注意的是,不像字典那样,一个命名元组是不可更改的。比如:
    1
    2
    3
    4
    5
    6
    7
    8
    >>> s = Stock('ACME', 100, 123.45)
    >>> s
    Stock(name='ACME', shares=100, price=123.45)
    >>> s.shares = 75
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AttributeError: can't set attribute
    >>>

如果你真的需要改变属性的值,那么可以使用命名元组实例的 _replace() 方法, 它会创建一个全新的命名元组并将对应的字段用新的值取代。比如:

1
2
3
4
>>> s = s._replace(shares=75)
>>> s
Stock(name='ACME', shares=75, price=123.45)
>>>