<p>命名元组基本上是易于创建的轻量级对象类型。命名元组实例可以使用类似对象的变量解引用或标准元组语法来引用。它们可以类似于<code>struct</code>或其他常见的记录类型,只是它们是不可变的。它们是在Python2.6和Python3.0中添加的,尽管有一个<a href="http://code.activestate.com/recipes/500261/" rel="noreferrer">recipe for implementation in Python 2.4</a>。</p>
<p>例如,通常将点表示为元组<code>(x, y)</code>。这将导致如下代码:</p>
<pre><code>pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)
from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
</code></pre>
<p>使用命名元组,它变得更可读:</p>
<pre><code>from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
</code></pre>
<p>但是,命名元组仍然与普通元组向后兼容,因此以下操作仍然有效:</p>
<pre><code>Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
# use tuple unpacking
x1, y1 = pt1
</code></pre>
<p>因此,<strong>您应该使用命名元组而不是元组,只要您认为对象表示法将使您的代码更具python性,并且更易于阅读。我个人已经开始使用它们来表示非常简单的值类型,特别是当将它们作为参数传递给函数时。它使函数更具可读性,而不必查看元组打包的上下文。</p>
<p>此外,<strong>您还可以替换普通的<em>不可变的</em>类,这些类没有函数</strong>,只有字段。甚至可以将命名元组类型用作基类:</p>
<pre><code>class Point(namedtuple('Point', 'x y')):
[...]
</code></pre>
<p>但是,与元组一样,命名元组中的属性是不可变的:</p>
<pre><code>>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute
</code></pre>
<p>如果希望能够更改值,则需要其他类型。有一个方便的<a href="http://code.activestate.com/recipes/576555/" rel="noreferrer">mutable recordtypes</a>配方,允许您为属性设置新值。</p>
<pre><code>>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
2.0
</code></pre>
<p>但是,我不知道任何形式的“命名列表”允许您添加新字段。你可能只想在这种情况下用字典。命名元组可以使用返回<code>{'x': 1.0, 'y': 5.0}</code>的<code>pt1._asdict()</code>转换为字典,并且可以使用所有常用的字典函数进行操作。</p>
<p>如前所述,您应该<a href="http://docs.python.org/py3k/library/collections.html?highlight=namedtuple#collections.namedtuple" rel="noreferrer">check the documentation</a>获取构造这些示例的更多信息。</p>