1.18 映射名称到序列元素

    函数通过使用一个普通的元组对象来帮你解决这个问题。这个函数实际上是一个返回 Python 中标准元组类型子类的一个工厂方法。你需要传递一个类型名和你需要的字段给它,然后它就会返回一个类,你可以初始化这个类,为你定义的字段传递值等。代码示例:

    尽管 namedtuple 的实例看起来像一个普通的类实例,但是它跟元组类型是可交换的,支持所有的普通元组操作,比如索引和解压。比如:

    1. >>> len(sub)
    2. 2
    3. >>> addr, joined = sub
    4. >>> addr
    5. 'jonesy@example.com'
    6. >>> joined
    7. >>>

    命名元组的一个主要用途是将你的代码从下标操作中解脱出来。因此,如果你从数据库调用中返回了一个很大的元组列表,通过下标去操作其中的元素,当你在表中添加了新的列的时候你的代码可能就会出错了。但是如果你使用了命名元组,那么就不会有这样的顾虑。

    下标操作通常会让代码表意不清晰,并且非常依赖记录的结构。下面是使用命名元组的版本:

    1. from collections import namedtuple
    2.  
    3. Stock = namedtuple('Stock', ['name', 'shares', 'price'])
    4. def compute_cost(records):
    5. total = 0.0
    6. for rec in records:
    7. s = Stock(*rec)
    8. total += s.shares * s.price

    命名元组另一个用途就是作为字典的替代,因为字典存储需要更多的内存空间。如果你需要构建一个非常大的包含字典的数据结构,那么使用命名元组会更加高效。但是需要注意的是,不像字典那样,一个命名元组是不可更改的。比如:

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

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

    下面是它的使用方法:

    1. >>> a = {'name': 'ACME', 'shares': 100, 'price': 123.45}
    2. >>> dict_to_stock(a)
    3. Stock(name='ACME', shares=100, price=123.45, date=None, time=None)
    4. >>> b = {'name': 'ACME', 'shares': 100, 'price': 123.45, 'date': '12/17/2012'}
    5. >>> dict_to_stock(b)
    6. >>>

    最后要说的是,如果你的目标是定义一个需要更新很多实例属性的高效数据结构,那么命名元组并不是你的最佳选择。这时候你应该考虑定义一个包含 slots 方法的类(参考8.4小节)。

    原文: