流畅的python
1.namedtuple方法
参考文献地址:
1、https://www.cnblogs.com/jiangbingyang/p/7455853.html
2、https://blog.csdn.net/helei001/article/details/52692128/
1、定义:
是一个工厂方法,它可以动态的创建一个继承tuple的子类。跟tuple相比,返回的子类可以使用名称来访问元素。
2、参数:
nametuple方法支持4个参数:def namedtuple(typename, field_names, verbose=False, rename=False)
typename=>类名称(字符串)例如:
>>> from collections import namedtuple
>>> Account = namedtuple("Account", ["name","pwd"])
>>> account = Account(*("bingyang", "123456"))
>>> account.name
'bingyang'
>>> account.pwd
'123456'
field_names=>字段名称(可以接受可遍历对象或者是逗号链接起来的字符串)例如:
>>> Account = namedtuple("Account", ("name", "pwd"))
>>> Account = namedtuple("Account", "name,pwd")
verbose
设置为True生成子类时会打印出类定义代码
rename
正常情况下设置字段名称如果不符合规范是会直接报错,如果设置rename为True会对不符合规范的名称前面加,即$d。
例如:
>>> Account = namedtuple("Account", ['1','2'], rename=True)
>>> account = Account('bingyang', '123456')
>>> account._0
'bingyang'
>>> account._1
'123456'
3、总结
namedtuple的主要作用是将代码与它所控制的元素位置解耦。所以在一些比较大的元组列表中,我们可以将元祖转为namedtuple使用,这样就算元祖增加了新的列,代码也不会崩溃。而且使用名称来访问数据,代码可读性也比较高。
4、作用域
Python中存储系列数据,比较常见的数据类型有list,除此之外,还有tuple数据类型。相比与list,tuple有序但是tuple中的元素不可修改,在映射中可以当键使用。tuple元组的item只能通过index访问,collections模块的namedtuple子类不仅可以使用item的index访问item,还可以通过item的name进行访问和修改。
5、简单例子
coordinate = namedtuple('Coordinate', ['x', 'y'])
co = coordinate(10,20)
print co.x,co.y #10 20
print co[0],co[1] #10 20
co = coordinate._make([100,200])
print co.x,co.y #100 200
co = co._replace(x = 30)
print co.x,co.y #30 200
from collections import namedtuple
websites = [
('Sohu', 'http://www.google.com/', u'张朝阳'),
('Sina', 'http://www.sina.com.cn/', u'王志东'),
('163', 'http://www.163.com/', u'丁磊')
]
Website = namedtuple('Website', ['name', 'url', 'founder'])
for website in websites:
website = Website._make(website)
print website
results:
Website(name='Sohu', url='http://www.google.com/', founder=u'\u5f20\u671d\u9633')
Website(name='Sina', url='http://www.sina.com.cn/', founder=u'\u738b\u5fd7\u4e1c')
Website(name='163', url='http://www.163.com/', founder=u'\u4e01\u78ca')
6、完整示例
实现了一个纸牌类
from itertools import product
from random import choice
Card = collections.namedtuple('Card', 'rank,suit')
class FrenchDeck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = "黑桃,梅花,红桃,方块".split(',')
def __init__(self):
# 构造函数
self._cards = [Card(rank, suit) for rank, suit in product(self.ranks, self.suits)]
# print(self._cards)
def __len__(self):
# 长度
return len(self._cards)
def __getitem__(self, item):
# 获取特定元素
return self._cards[item]
# x = [1, 2, 3]
# y = ['a', 'b', 'c']
# for i, j in product(x, y):
# print(str(i) + j)
deck = FrenchDeck()
print(deck._cards) # 获取所有卡牌
print(choice(deck)) # 随机抽取卡牌
print(deck[:3]) # 拿出前三张牌
suit_values = dict(黑桃=3, 红桃=2, 方块=1, 梅花=0)
# 对于卡牌进行排序
def spades_high(card):
#rank_value:在列表中下标
#suit_value[card.suit]: 卡牌类型的权重
rank_value = FrenchDeck.ranks.index(card.rank)
return rank_value * len(suit_values) + suit_values[card.suit]
for card in sorted(deck, key=spades_high):
print(card)
上述例子中:
虽然FrenchDeck类隐式继承了object类,但功能不是继承而来,是通过数据模型和一些合成来实现的给你。通过__len__和__getitem__这两个特殊方法,使其跟python自有的序列数据类型一样,也体现出Python核心语言特性(迭代和切片)。