内置函数,内置模块,内置基础类型都跟类的内置方法有着千丝万缕的联系;
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())就是这个对象的地址
运行结果: