day 49 索引,python遗留:元类,单例

元类metaclass

元类是什么?

 

 

 

单例
单例是什么?

  是一种设计模式。是设计模式中比较简单的。
  指的是 一个类有且仅有一个实例 就叫单例。

 

如何实现单例的思路?: 就是控制类生成对象的方式,通过判断是否已经创建过对象。

 

为什么要使用单例这种模式?
之前在创建对象时 每个对象中的数据不相同 ,对象实际上是数据和处理数据的方法的结合体。
当对象中的数据是 相同的、共享的时候 ,使用单例。

例如遇到以下情况:
u1 = user("张三",29,"man")
u2 = user("张三",29,"man")
u3 = user("张三",29,"man")
不同的对象, 我们发现3个对象有完全相同的数据 ,所以没有必要每个人保存一份。

u1 = user("张三",29,"man")
u2 = u1
u3 = u1
如此 可以减少内存资源开销 ,大家共享一个数据 只有一个对象。

 

单例实现方式一:通过类绑定方法
class User:
def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex # 通过我们指定的方法来获取实例,而不是调用类来创建新对象。
   instance = None
    @classmethod  #一种通过绑定类方法
    def get_instance(cls,name,age,sex):
        if not cls.instance:
            cls.instance = cls(name,age,sex)
        return cls.instance

    @staticmethod  #另一种通过非绑定方法
    def get_instance2(name,age,sex):
        if not User.instance:
            User.instance = User(name,age,sex)
        return User.instance

u1 = User.get_instance2("张三",20,"man")
print(u1)
u2 = User.get_instance2("张三",20,"man")
print(u2)
====》输出两个对象的内存地址一样,即为一个对象,实现单例。

注意有问题:通过classMethod 可以完成单例,但是还是可以通过直接调用类产生新对象。怎么办?  我们此时就需要用到元类。
u3 = User("张三",20,"man")
 

 

单例实现方式二:元类法

class
MyMetaClass(type): instance = None def __call__(cls, *args, **kwargs): if not MyMetaClass.instance: # 利用object类内的_new_方法,创建空对象。 MyMetaClass.instance = object.__new__(cls) print("创建新的播放器对象!") #初始化出对象。 MyMetaClass.instance.__init__(*args,**kwargs) #返回对象。 return MyMetaClass.instance # 只能有一个播放器实例 class CDPlayer(metaclass=MyMetaClass): def play(self,music): print("切换音乐",music) def __init__(self,music_name): self.music_name = music_name p1 = CDPlayer("你发如雪!") p1.play("菊花台") p1.play("菊花台2") p1.play("菊花台3") # 不会创建新对象 p1 = CDPlayer("你发如雪!") p1 = CDPlayer("你发如雪!") p1 = CDPlayer("你发如雪!") p1 = CDPlayer("你发如雪!") # 元类实现单例的原理: 就是 调用类时,拦截了CDPlayer类中的__init__的正常执行,
而是触发执行自定义元类内的_call_函数,使得创建对象都必须经过自己判断逻辑。

 

posted @ 2018-11-27 17:31  timm_book  阅读(439)  评论(0)    收藏  举报