# Python - namedtuple

## 1. 用tuple表示点，从例子可见计算两个点的距离非常麻烦且可读性差

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)
print(line_length)


## 2. 用namedtuple表示点，可读性更强，类似与struct结构体，只是元素不可变

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)
print(line_length)


## 3. namedtuple兼容tuple

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
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
# use tuple unpacking
x1, y1 = pt1

print(line_length)
print(x1)
print(y1)


## 4. 缺点：在namedtuple的属性值不可变

>>> 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


## 5. 基本用法

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)


## 6. 一个特别的用法，可以替换那些没有函数的普通不可变类

from collections import namedtuple
class Point(namedtuple('Poin2t', 'x y')):
pass

Point = namedtuple('Point', 'x y z')
pt1 = Point(1,2,3)
print(Point.__dict__)
print(pt1)
print(pt1.x, pt1.y, pt1.z)


# 总结：

1. 使用namedtuple更pythonic和更加易读。
2. namedtuple是一个生产tuple类的工厂函数。通过这个类，我们可以创建可调用的元组
3. 一般情况下用namedtuple代替tuple, 表示一些简单的类型。特别地，可以作为参数传递给函数，原因参考总结的第一点。
posted @ 2018-04-10 23:28  Rocin  阅读(313)  评论(0编辑  收藏  举报