码迷,mamicode.com
首页 > 其他好文 > 详细

第二十三天

时间:2018-08-16 00:38:58      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:base   抽象类   highlight   nba   类型   视频   class   --   result   

迭代器模式和观察值模式

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

  



第二十三天

标签:base   抽象类   highlight   nba   类型   视频   class   --   result   

原文地址:https://www.cnblogs.com/ztx695911088/p/9484447.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!