迭代器模式和观察值模式
"""
行为模式:是对不同的对象之间划分责任和算法的抽象方式。重点在于类和类之间相互作用。
# 迭代器模式
# 观察者模式
"""
1. 迭代器模式
# Iterable: iter方法: return Iterator
# Iterator:next iter方法
# 用于访问 集合对象的时候按照顺访问,不需要集合对象的底层表示。
# 迭代器的抽象类
class Iterator:
def __init__(self,aggregate):
self.aggregate=aggregate
self.curr=0
def First(self):
return self.aggregate[0]
def Next(self):
self.curr+=1
if self.curr<len(self.aggregate):
result=self.aggregate[self.curr]
return result
def CurrIterm(self):
return self.aggregate[self.curr]
def Isdone(self):
# if self.curr+1>=len(self.aggregate):
# return True
# else:
# return False
return True if self.curr+1>=len(self.aggregate) else False
# 抽象的被迭代元素对象
class Aggregate:
def __init__(self):
self.ilist = []
def createIterator(self):
return Iterator(self.ilist)
a=Aggregate()
a.ilist.append(1)
a.ilist.append(2)
a.ilist.append(3)
# 获得自己的迭代器
iter=a.createIterator()
print(iter.First())
print(iter.Next())
print(iter.CurrIterm())
while not iter.Isdone():
print(iter.Next())
"""
适用场景:需要为可迭代的类型提供多种遍历方式。
当遍历可迭代对象时,不希望在内部暴露迭代的细节(first内部,next内容)
优点:对迭代对象进行遍历,进行获取元素。可以自定义获取的方式
缺点:当出现不同的迭代对象时,需要不同的迭代器,需要新增迭代器。
"""
2. 观察者模式:定义对象之间一对多的依赖关系。需要使用观察者模式,当一个对象状态发生
改变,所有依赖于它的对象都会得到通知从而发生改变。
# 学生上课玩手机,班主任看见了,需要批评。
# 学生作为观察者,观察“侦探”,当“侦探”发出通知,学生能够采取对应的措施。多个学生,一个侦探。
# 第一个版本
# 观察者
class Classmates:
def __init__(self,name,detective):
self.name=name
self.detective=detective
def KingGame(self):
return "王者荣耀"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不玩游戏了,开始假装学习".format(self.name))
# 侦探
class Detactive:
def __init__(self):
self.classmates=[]
def discoverTeacher(self):
print("老师来了")
def nofify(self):
for i in self.classmates:
print("{},别{},快学习!".format(i.name,i.KingGame()))
i.update()
# d=Detactive()
# c1=Classmates("张三",d)
# c2=Classmates("李四",d)
# d.classmates=[c1,c2]
# d.nofify()
# 第二个版本:针对不同的同学可能做不同的事情,所以需要有基类,有扩展类。
class Classmates:
def __init__(self,name,detective):
self.name=name
self.detective=detective
def update(self):
pass
class ClassmatesKing(Classmates):
def noStudy(self):
return "王者荣耀"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不玩游戏了,开始假装学习".format(self.name))
class ClassmatesNBA(Classmates):
def noStudy(self):
return "正在看NBA"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不看视频了,开始假装学习".format(self.name))
# 侦探
class Detactive:
def __init__(self):
self.classmates=[]
def discoverTeacher(self):
print("老师来了")
def nofify(self):
for i in self.classmates:
print("{},别{},快学习!".format(i.name,i.noStudy()))
i.update()
# d=Detactive()
# c1=ClassmatesKing("张三",d)
# c2=ClassmatesKing("李四",d)
# c3=ClassmatesNBA("王五",d)
# d.classmates=[c1,c2,c3]
# d.nofify()
# 第三版:侦探可以不是一个 :解决侦探可以扩充子类。
class Classmates:
def __init__(self,name,detective):
self.name=name
self.detective=detective
def update(self):
pass
class ClassmatesKing(Classmates):
def noStudy(self):
return "王者荣耀"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不玩游戏了,开始假装学习".format(self.name))
class ClassmatesNBA(Classmates):
def noStudy(self):
return "正在看NBA"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不看视频了,开始假装学习".format(self.name))
# 侦探
class Detactive:
def __init__(self):
self.classmates = []
def discoverTeacher(self):
print("老师来了")
def nofify(self):
for i in self.classmates:
print("{},别{},快学习!".format(i.name, i.noStudy()))
i.update()
class DetactiveA(Detactive):
def discoverTeacher(self):
print("A大吼一声老师来了")
class DetactiveB(Detactive):
def discoverTeacher(self):
print("B悄悄的说一声老师来了")
# da=DetactiveA()
# db=DetactiveB()
# c1=ClassmatesKing("张三",da)
# c2=ClassmatesKing("李四",da)
# c3=ClassmatesNBA("王五",db)
# da.classmates=[c1,c2]
# db.classmates=[c3]
# da.nofify()
# db.nofify()
#第四版:侦探对于同学可以添加好友,还可以踢出好友
class Classmates:
def __init__(self, name, detective):
self.name = name
self.detective = detective
def update(self):
pass
class ClassmatesKing(Classmates):
def noStudy(self):
return "王者荣耀"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不玩游戏了,开始假装学习".format(self.name))
class ClassmatesNBA(Classmates):
def noStudy(self):
return "正在看NBA"
# 为了保证能够接到侦探通知,同时还能够采取行动
def update(self):
# 1. 得到通知 2采取行动
self.detective.discoverTeacher()
print("{}不看视频了,开始假装学习".format(self.name))
# 侦探
class Detactive:
def __init__(self):
self.classmates = []
def add(self,c):
self.classmates.append(c)
def remove(self,c):
self.classmates.remove(c)
def discoverTeacher(self):
print("老师来了")
def nofify(self):
for i in self.classmates:
print("{},别{},快学习!".format(i.name, i.noStudy()))
i.update()
class DetactiveA(Detactive):
def discoverTeacher(self):
print("A大吼一声老师来了")
class DetactiveB(Detactive):
def discoverTeacher(self):
print("B悄悄的说一声老师来了")
da = DetactiveA()
db = DetactiveB()
c1 = ClassmatesKing("张三", da)
c2 = ClassmatesKing("李四", da)
c3 = ClassmatesNBA("王五", db)
da.add(c1)
da.add(c2)
db.add(c3)
da.remove(c1)
da.nofify()
db.nofify()
"""
观察者:观察者(同学)可以把自己注册到被观察对象中,
观察对象都存放在被观察者(侦探)的容器中。
被观察者:被观察者发生了变化(notify),
会从容器中获得所有注册过的观察者,把通知通知给观察者(update)
被观察者(侦探)可以撤销和注册被观察者(add,remove)
优点:被观察者和观察者是抽象耦合的,使用抽象尽量降低耦合度;
建立一套触发机制,只要notify,所有的观察者都会执行update
缺点:如果一个被观察者对象有很多的观察者,因为会通知到所有的观察者,会浪费时间。如果
观察者的数目过大,可能会造成死机。
"""
元类
"""
元编程:使用元类进行编程
元类----类------对象
"""
"""
一、元类
类可以被赋值、可以作为参数传递、可以打印输出。
"""
def fun():
pass
f = fun
f()
# 可以对类进行赋值。
class A:
pass
p = A
k = p()
print(k)
print(type(k))
# 类作为返回值
def fun():
return A
print(fun())
# 类也可以被当成参数传入
def fun(param):
return param()
print(fun(A))
类也是对象。谁创建的类?---元类
最原始的元类:type,元类还是 由元类自己创建的。
print(type(list()))
print(type(list))
print(type(A))
print(type(type))
二、type
"""
type有两种用法:
1. 使用type返回当前对象(如果是实例,那么返回的是类,如果是类,那么返回的就是元类)的类型
就是返回谁创建的对象。
2. 用type创建一个类(没有指定其他的元类,默认使用type创建)
"""
# 第二种用法type内部是三个参数
# 1. 类的名字(字符串):
# 指的是当使用type(A)显示类是由谁创建时的名字<class '__main__.Person1'>
# 2.所有继承的父类(元组)
# 3.类所关联的属性和方法的名称(字典类型)
def init(self, name):
self.name = name
@classmethod
def copy(cls, person):
copyperson = cls(person.name)
return copyperson
Person = type("Person1", (), {"desc": "人类", "__init__": init, "copy": copy})
p = Person("bill")
print(p.name)
pcopy = Person.copy(p)
print(pcopy.name)
print(Person.__name__)
三、自定义元类
"""
1.继承type,创建元类
2.创建好自定义的元类之后,需要使用metaclass关键字指定用哪一个类创建其他的类
"""
class ModelMetaclass(type):
def __new__(cls, name, bases, attrs):
print("我是新的元类!!!", bases)
return type.__new__(cls, name, bases, attrs)
class A(metaclass=ModelMetaclass):
pass
# a=A()
# print(type(A))
class D:
pass
class B(A):
pass
class C(B, D):
pass
四、三个特殊的函数 魔法方法__init__ __new__ __call__
"""
1.__new__:创建对象的时候执行方法,创建一个对象。是一个静态方法
2.__init__: 初始化实例,执行完__new__,再去执行__init__,实例方法。
3.__call__: 使得类当函数调用 a()====a.__call__()
"""
class ModelMetaclass(type):
def __new__(cls, *args, **kwargs):
print("元类的new方法执行")
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print("元类的init执行")
def __call__(self, *args, **kwargs):
print("执行元类的call方法")
return super().__call__(*args, **kwargs)
class A(metaclass=ModelMetaclass):
def __new__(cls, *args, **kwargs):
print("A的new方法执行")
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print("A的init执行")
super().__init__(*args, **kwargs)
def __call__(self, *args, **kwargs):
print("A的call方法执行")
# 没有return super().call方法
def fun(self):
pass
"""
1.定义了元类之后,只要定义了类使用了这个元类来创建,就会调用元类的new和init方法
无论是否已经有类的对象了,都会执行
2. 当使用这个类创建了实例时,会先调用它的元类下的call方法,然后再去调用这个的new
和init方法。
3. 当仅调用实例时(在实例后面加()),会调用类下面的call
4. 当调用实例的其他方法时,不会调用类的call方法
"""
a = A()
# print(type(A))
a()
a("11")
a("11", "22")
a.fun()
五、元类的应用:元类一般都是自己写一个元类,用来改变类的创建方式。
from datetime import datetime
class ModelMetaclass(type):
def __new__(cls, name, bases, attrs):
print("我是新的元类")
attrs["create_time"] = datetime.now()
for k, v in attrs.items():
print(k, v)
return type.__new__(cls, name, bases, attrs)
class A(metaclass=ModelMetaclass):
pass
a = A()
print(type(A))
print(A.create_time)
1. 创建元类,使得使用这个元类创建的类不能被实例化对象(抽象类abstract)
class AbstarctMeta(type):
def __call__(self, *args, **kwargs):
raise TypeError("不能使用当前类创建对象")
class Card(metaclass=AbstarctMeta):
# 静态方法和类方法、类属性
pass
class Ccard():
pass
class Xcard():
pass
# c=Card()
cc = Ccard()
2.创建一个元类,使得使用这个元类创建的类不能被继承。(终级类final )
# type :name bases attrs
class final(type):
def __init__(self, name, bases, attrs):
super().__init__(name, bases, attrs)
for i in bases:
if isinstance(i, final):
raise TypeError("所继承的父类是终级类,不能有子类")
class A(metaclass=final):
pass
class C:
pass
class B(C):
pass
3.使用元编程完成单例模式
class Singleton(type):
def __new__(cls, *args, **kwargs):
print("元类的new")
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print("元类的init")
super().__init__(*args, **kwargs)
self.instance = None
def __call__(self, *args, **kwargs):
print("元类的call")
if not self.instance:
self.instance = super().__call__(*args, **kwargs)
return self.instance
class A(metaclass=Singleton):
pass