python学习笔记 day28 内置函数进阶实例

内置函数,内置模块,内置基础类型都跟类的内置方法有着千丝万缕的联系;

1. collections模块的namedtuple

from collections import namedtuple
Point=namedtuple('Point',['x','y','z'])  # namedtuple其实创建了只有属性的类
p=Point(1,2,3)  # 给属性传值
print(p.x)
print(p.y+p.z)

运行结果:

 

接下来使用collections  的namedtiple 以及 random模块的choice shuffle实现抽牌和洗牌的操作;

 

from collections import namedtuple
import json
Card=namedtuple('Card',['rank','suit'])
class FranchDeck():
    rank=[str(i) for i in range(2,11)]+list('JQKA')
    suit=['红心','花块','梅花','黑桃']
    def __init__(self):
        self.__cards=[Card(rank,suit) for rank in FranchDeck.rank for suit in FranchDeck.suit]
    def __getitem__(self,item):  # 当使用对象名[]的形式时就会调用__getitem__()方法
        return self.__cards[item]  # item 其实就是index索引,返回第几张牌
    def __str__(self):   # 当执行print(对象)时就会调用__str__()方法,由于__str__()必须返回字符串类型的,所以我们可以使用json序列化成字符串格式的
        return json.dumps(self.__cards,ensure_ascii=False)
deck=FranchDeck()
print(deck[0])  # deck是一个对象,对象[]就会调用__getitem__()方法-----返回第一张牌
print(deck)  # print(obj)可以调用__str__()方法,返回的是序列化的self.__cards 列表---查看所有的牌

 

运行结果:

 

利用random 模块的choice 和 shuffle方法完成抽牌和洗牌操作

from collections import namedtuple
import json
import random
Card=namedtuple('Card',['rank','suit'])
class FranchDeck():
    rank=[str(i) for i in range(2,11)]+list('JQKA')
    suit=['红心','花块','梅花','黑桃']
    def __init__(self):
        self.__cards=[Card(rank,suit) for rank in FranchDeck.rank for suit in FranchDeck.suit ]

    def __getitem__(self,item): # obj[]会调用__getitem__()方法
        return self.__cards[item] # 返回列表__cards中的第item个元素,就是第几张牌

    def __str__(self):  # print(obj)会调用__str__()方法,返回值必须是字符串类型的,所以使用了json ,返回序列化后的列表自己定制功能,打印所有的牌Card(rank,suit)
        return json.dumps(self.__cards,ensure_ascii=False)  # 返回序列化的self.__cards 就是列表 存的都是Card(rank,suit)

    def __len__(self):  # random.choice(obj)当从牌中随机挑选一张,需要内部实现__len__()方法
        return len(self.__cards)

    def __setitem__(self,key,value):  # random.shuffle()方法需要类内部实现__setitem__()方法。告诉被修改对象的索引需要赋予新的值
        self.__cards[key]=value

deck=FranchDeck()
print(deck)  # 调用__str__()方法,返回所有的牌Card(rank,suit) 是列表的字符串形式
print(deck[1])  # obj[] 调用__getitem__()方法,返回第几张牌

print(random.choice(deck))  # random.choice()方法需要类里面实现__len__()方法---随机抽一张牌
random.shuffle(deck)  # random.shuffle()需要类内部实现__setitem__()方法,因为shuffle就是打乱列表顺序,牵涉到列表索引和更改值的操作----洗牌
print(deck[1])  # 洗牌之后,第一张牌(跟未洗牌对比)
print(deck) # 洗牌之后的Card内容

 

运行结果:

 

 2. set()方法里面放对象时,对象所在的类中必须实现__hash__方法和__eq__方法

比如,有一百个对象,需要录入信息,包括对象的年龄,姓名和性别 ,明年在对这个对象重新录入信息,相当于存在了200个对象,但是我们知道只是年龄变了,就造成一个人对应着两个对象,我们可以使用set()方法,对对象去重,由于set()方法跟__eq__() 比较两个对象的值,以及__hash__()方法,比较两个对象的哈希值,我们就可以在类中重写这两个方法,来完成set()两个对象时依据什么标准对对象去重:

 

class Person():
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def __hash__(self):  # 自己定制__hash__()方法 当两个对象的name 和sex 都一样时,返回的哈希值也是一样的
        return hash(self.name+self.sex)
    def __eq__(self,other):  # 自己定制==值相等的定义,此处就是当两个对象的姓名和性别都一样时,就认为两个对象相等==成立
        if self.name==other.name and self.sex==other.sex:
            return True
        return False

p1=Person('xuanxuan',22,'')
p2=Person('xuanxuan',23,'')
print(set((p1,p2)))  # set()就是去重,当p1 和 p2这两个对象的哈希值和值相等时 就认为是一个对象,set之后就是一个对象,print(set())就是这个对象的地址

运行结果:

 

posted @ 2018-09-25 15:12  写的BUG代码少  阅读(173)  评论(0编辑  收藏  举报