流畅的python

2020-01-07  本文已影响0人  L丶Y1122

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核心语言特性(迭代和切片)。

上一篇下一篇

猜你喜欢

热点阅读