第二十三天
Posted ztx695911088
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二十三天相关的知识,希望对你有一定的参考价值。
迭代器模式和观察值模式
"""
行为模式:是对不同的对象之间划分责任和算法的抽象方式。重点在于类和类之间相互作用。
# 迭代器模式
# 观察者模式
"""
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
以上是关于第二十三天的主要内容,如果未能解决你的问题,请参考以下文章