zoukankan      html  css  js  c++  java
  • 第二十三天

    迭代器模式和观察值模式

    """
    行为模式:是对不同的对象之间划分责任和算法的抽象方式。重点在于类和类之间相互作用。
    # 迭代器模式
    # 观察者模式
    """
    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
    

      



  • 相关阅读:
    FATAL ERROR: please install the following Perl modules before executing /usr/bin/mysql_install_db:
    redis分布式锁原理与实现
    java中如何将 string 转化成 long
    FastJson中JSONObject用法及常用方法总结
    Spring IOC 一——容器装配Bean的简单使用
    静态代理和动态代理
    Spring AOP——Spring 中面向切面编程
    什么是分布式锁?实现分布式锁的三种方式
    @Consumes @Produces的作用
    pro、pre、test、dev环境
  • 原文地址:https://www.cnblogs.com/ztx695911088/p/9484447.html
Copyright © 2011-2022 走看看