p140-
# #练习
# #用类现 队列Queue 和 栈Stack 分别实现put 和get方法
class Queue(object):
def __init__(self):self.l1 = []
def put(self,a):self.l1.append(a)
def get(self):
if len(self.l1)>0:
return self.l1.pop(0)
class Stack(object):
def __init__(self): self.l1 = []
def put(self, a): self.l1.append(a)
def get(self):
if len(self.l1)>0:
return self.l1.pop()
q = Queue()
q.put(1)
q.put(3)
q.put('aa')
s = Stack()
s.put(2)
s.put(3)
s.put('aa')
# #自定义Pickle 借助pickle模块完成简化的dump 和 load
# #1、对象=Pickle('路径') 2、对象.load() 拿到文件中所有的对象 3、对象.dump() 要写入文件的对象
import os
import pickle
class MyPickle():
def __init__(self,path):
self.path = path
def dump(self,obj):
if os.path.isfile(self.path):
with open(self.path,mode='ab') as f1:
pickle.dump(obj,f1)
def load(self):
if os.path.isfile(self.path):
with open(self.path,mode='rb') as f1:
while True:
try:
yield pickle.load(f1)
except EOFError:break
pc = MyPickle('player.info')
pc.dump(q)
for i in pc.load():
print(i.l1)
#继承 解决代码重用问题
#通过继承实现类的开发规范
#多继承的继承顺序问题
#多态 Python中处处是多态,一切皆对象
#类实例化的过程总是先开空间,再调用init ,调用init 的时候,总是把新开的空间作为参数传递给self
# #练习,写结果
class A(object):
l1 = []
def __init__(self):self.l1=[]
def func(self):self.l1.append(1)
class B(A):
def __init__(self):self.l1=[] # 函数里的l1 变量不开辟空间,在实例化成对象的时候开辟空间
def func(self):self.l1.append(2)
b = B()
b.func()
print(A.l1) #[]
print(B.l1) #[] #B类空间里没有l1 从A类空间里找,在init函数里的l1 在实例化成对象b的时候,在b对象空间里才开辟l1空间
print(b.l1) #[2]
#多继承的深度优先 和 广度优先
#经典类-深度优先 ,新式类-广度优先
#广度优先遵循C3算法,可以用mrc查看顺序
#C3算法内容
#1、如果是单继承 总是按照子类->父类的顺序
#2、如果是多继承,merge规则:
#merge规则:1、如果一个类出现在从左到右所有顺序的最左侧,并没有在其他位置出现,那么闲提出来作为继承顺序的第一个
#2、或者一个类出现在从左到右顺序的最左侧,并没有在其他顺序中出现,那么闲提出来作为继承顺序的第一个
# 如果从左到右第一个顺序中的第一个类出现在后面且不是第一个,那么不能提取,顺序向后继续找其他顺序中符合上述条件的类
#抽象类
from abc import ABCMeta,abstractmethod
class C1(metaclass=ABCMeta): # 遇到这样的类,在C1的子类中都要实现 @@abstractmethod 标注的方法
@abstractmethod
def func(self,argv1):
raise NotImplementedError('请在子类中实现func函数')
#多态 一个类型表现出来的多种状态,通过继承实现
#在java中,参数必须制定类型,如果一个参数可以传2种类型,那么必须让这两种类型继承自同一个父类,在指定参数类型的时候用父类
class Wechat:
def __init__(self,name):self.name = name
def pay(self,price):print(f'{self.name} 用微信付了 {price} 元')
class Alipay:
def __init__(self,name):self.name = name
def pay(self,price):print(f'{self.name} 用支付宝付了 {price} 元')
w = Wechat('tom')
w.pay(300) #tom 用微信付了 300 元
a = Alipay('jerry')
a.pay(4000) #jerry 用支付宝付了 4000 元
#写一个调用支付的接口函数
def pay(obj,price): #这里的参数是obj
print(f'{obj.name} 付了 {price} 元')
pay(w,300)
pay(a,4000)
#java中必须指定参数,即要指定Wechat 又要指定Alipay 可以定义一个这2个类的父类
#super
#封装,广义封装,狭义封装,封装语法,原理
#类中的3个装饰器(内置函数)property classmethod staticmethod
#super 按照mro顺序找当前类的下一个类
#在python3中不需要传参数,自动帮我们找当前类的mro顺序下一个类中的同名方法
#在python2中新式类中,需要主动传递参数super(子类名字,子类对象).函数名()
#这样才能够帮我们调用到这个子类的mro顺序的下一个类中的方法
#在python2的经典类中,并不支持使用super 找下一个类
#在单继承的程序中,super就是找父类
class User:
def __init__(self,name):
self.name = name
class VIPUser(User):
def __init__(self,name,level,start_date,end_date):
super().__init__(name)
self.level = level
self.start_date = start_date
self.end_date = end_date
u=VIPUser('tom',3,'2020-08-01','2021-08-01')
print(u.__dict__) #{'name': 'tom', 'level': 3, 'start_date': '2020-08-01', 'end_date': '2021-08-01'}