面向对象的进阶
item系列方法
通过item方法,可以实现像字典一样操作对象
class Foo: def __init__(self,name,age,sex): self.name=name self.age = age self.sex = sex def __getitem__(self, item): return self.__dict__[item] def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): del self.__dict__[key] f=Foo('tom',24,'男') print(f['name'])#可以实现像字典一样取值 f['hobby']='男' print(f.hobby,f['hobby']) del f.hobby#这种方法是object原生支持,其实内部运行的是__delattr__ del f['hobby']#和__delitem__配合删除了f['hobby'],这是通过delitem配合实现 print(f.__dict__)
new
__init__初始化方法
__new__构造方法,创建一个方法
class A: def __init__(self): self.x=1 print('in init function') def __new__(cls,*args,**kwargs): print('in new function') return object.__new__(A,*args, **kwargs)#代码先执行到这里,此时还没有self,所以这里用了object a=A() D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py in new function in init function Process finished with exit code 0
单例模式:
一个类始终只有一个实例。当第一次实例化这个对象的时候,就创建一个实例化对象
当之后再来实例化的时候,就用之前创建的对象。也就是说实例不变,变化的只是对象
class A: __isinstance=False def __init__(self,name,age): self.name=name self.age = age def __new__(cls,*args,**kwargs): if cls.__isinstance: return cls.__isinstance cls.__isinstance=object.__new__(A) return cls.__isinstance Jack=A('jack',24) Jack.cloth='red' Tom=A('tom',24) print(Jack) print(Tom) print(Jack.name) print(Tom.name) print(Jack.cloth)
__eq__
class A: def __init__(self,name): self.name=name ob1=A('egg') ob2=A('egg') print(ob1==ob2)#虽然ob1和ob2内容相同,但是计算机是根据内存地址判断,两个的内存地址不一样,所以结果肯定是false
加上__eq__方法后,结果为true
class A: def __init__(self,name): self.name=name def __eq__(self, other): if self.name==other.name: return True else: return False ob1=A('egg') ob2=A('egg') print(ob1==ob2)
__hash__
class A: def __init__(self,name,sex): self.name=name self.sex=sex def __hash__(self): return hash(self.name+self.sex) a=A('egg','男') b=A('egg','男') print(hash(a)) print(hash(b))#结果完全相同 D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py 8412774350429136977 8412774350429136977 Process finished with exit code 0
加上__hash__
class A: def __init__(self,name): self.name=name a=A('egg') b=A('egg') print(hash(a)) print(hash(b))#结果完全不同 D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py -9223371863945030947 172909893033 Process finished with exit code 0
利用面向对象的内置方法实现纸牌游戏:
import json from collections import namedtuple Card=namedtuple('Card',['rank','suit']) class FranchDeck: ranks=[str(n) for n in range(2,11)]+list('JQKA') suits=['红心','方块','梅花','黑桃'] def __init__(self): self._cards=[Card(rank,suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits] def __len__(self): return len(self._cards) def __getitem__(self, item): return self._cards[item] def __setitem__(self, key, value): self._cards[key]=value def __str__(self): return json.dumps(self._cards,ensure_ascii=False) deck=FranchDeck() print(deck[0]) from random import choice print(choice(deck))#这里实现了随机抽牌 from random import shuffle#这里实现了洗牌 shuffle(deck) print(deck[10]) print(deck)
题目:数据库中的人名和性别不变,随着年数的增长,年龄逐渐增长
class A: def __init__(self,name,sex,age): self.name=name self.sex = sex self.age=age def __hash__(self): return hash(self.name+self.sex) a=A('egg','男',18) b=A('egg','男',17) print(set((a,b))) D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py {<__main__.A object at 0x000001E030115B00>, <__main__.A object at 0x000001E030115BE0>} Process finished with exit code 0
可见,单纯使用hash值无法解决问题
class A: def __init__(self,name,sex,age): self.name=name self.sex = sex self.age=age def __eq__(self, other): if self.name==other.name and self.sex==other.sex: return True return False def __hash__(self): return hash(self.name+self.sex) a=A('egg','男',18) b=A('egg','男',17) print(set((a,b))) D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py {<__main__.A object at 0x00000211D31F5B38>} Process finished with exit code 0