阅读Python 3.1中的更改后 ,我发现了一些意外…… html
sys.version_info元组如今是一个命名的元组 : python
我之前从未据说过命名元组,而且我认为元素能够经过数字(例如在元组和列表中)或经过键(例如在字典中)进行索引。 我从未想到它们能够同时被索引。 函数
所以,个人问题是: spa
namedtuple是用于建立元组类的工厂函数 。 经过该类,咱们能够建立可经过名称调用的元组。 code
import collections #Create a namedtuple class with names "a" "b" "c" Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False) row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created print row #Prints: Row(a=1, b=2, c=3) print row.a #Prints: 1 print row[0] #Prints: 1 row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values print row #Prints: Row(a=2, b=3, c=4)
在Python内部,有一个很好使用的容器,称为命名元组,它可用于建立类的定义,并具备原始元组的全部功能。 htm
使用命名元组将直接应用于默认的类模板以生成一个简单的类,此方法容许使用大量代码来提升可读性,而且在定义类时也很是方便。 对象
命名元组容许向后兼容检查此类版本的代码 索引
>>> sys.version_info[0:2] (3, 1)
同时经过使用此语法使未来的代码更明确 ip
>>> sys.version_info.major 3 >>> sys.version_info.minor 1
命名元组基本上是易于建立的轻量级对象类型。 可使用类对象变量解引用或标准元组语法来引用已命名的元组实例。 除了它们是不可变的,它们能够相似地用于struct
或其余常见记录类型。 它们是在Python 2.6和Python 3.0中添加的,尽管在Python 2.4中有实现的秘诀 。 ci
例如,一般将点表示为元组(x, y)
。 这致使以下代码:
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)
使用命名元组,它变得更具可读性:
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)
可是,命名元组仍然与普通元组向后兼容,所以如下内容仍然有效:
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
所以, 在您认为对象表示法将使您的代码更具pythonic性且更易于阅读的任何地方 , 都应使用命名元组代替元组 。 我我的已经开始使用它们来表示很是简单的值类型,尤为是在将它们做为参数传递给函数时。 它使函数更具可读性,而看不到元组包装的上下文。
此外, 您还能够替换没有功能的普通不可变类 ,仅将它们替换为字段。 您甚至能够将命名的元组类型用做基类:
class Point(namedtuple('Point', 'x y')): [...]
可是,与元组同样,命名元组中的属性是不可变的:
>>> Point = namedtuple('Point', 'x y') >>> pt1 = Point(1.0, 5.0) >>> pt1.x = 2.0 AttributeError: can't set attribute
若是要可以更改值,则须要另外一种类型。 对于可变记录类型 ,有一个方便的用法 ,可以让您为属性设置新值。
>>> 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
可是,我不知道有任何形式的“命名列表”可以让您添加新字段。 在这种状况下,您可能只想使用字典。 可使用pt1._asdict()
将命名的元组转换为字典,该pt1._asdict()
返回{'x': 1.0, 'y': 5.0}
而且可使用全部经常使用的字典功能进行操做。
如前所述,您应该查看文档以获取构成这些示例的更多信息。
namedtuple是一个很棒的功能,它们是数据的完美容器。 当您必须“存储”数据时,可使用元组或字典,例如:
user = dict(name="John", age=20)
要么:
user = ("John", 20)
字典方法是压倒性的,由于字典比元组易变且慢。 另外一方面,元组是不可变的且轻量级的,可是对于数据字段中的大量条目却缺少可读性。
namedtuple是这两种方法的完美折衷,它们具备出色的可读性,轻巧性和不变性(并且它们是多态的!)。