贰拾肆

一、元类知识补充

1.1 自定义元类

义元类:继承type
class Mymeta(type):
    def __init__(self,name,bases,dic):
        #self 是Person 这个类(对象)
        #在这个位置,其实self也就说Person这个类,内部已经有东西了,名称空间已经有东西了
        #所以在这个地方,可以通过dic来判断名称空间
        #也可以直接通过self.__dict__/self.属性 来判断
        a=dic.get('name')
        if not a :
            raise Exception('没有name属性,不能创建')
    # def __call__(self, *args, **kwargs):
    #     pass

class Person(metaclass=Mymeta):  #Person=Mymeta('Person',(object,),{...}) Mymeta类实例化,会把三个参数传到Mymeta的__init__方法中
# class Person():  #Person=Mymeta('Person',(object,),{...}) Mymeta类实例化,会把三个参数传到Mymeta的__init__方法中
    def __init__(self,name):
        self.name=name
        raise Exception('就不让你创建')


p=Person('lqz')  #自动触发Person类__init__的执行
总结:可以通过自定义元类,重写__init__方法来控制类的产生

1.2 控制对象产生

#模板:控制对象的产生
class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj=object.__new__(self)
        obj.__init__(*args, **kwargs)
        return obj

class Person(metaclass=Mymeta):
    def __init__(self,name):
        self.name=name
    def __call__(self, *args, **kwargs):
        print('xxx')

p=Person('lqz')

​ 注意:

#object.__new__ 传哪个类就得到哪个类的空对象

#__new__和__init__的区别
#__new__ 创建空对象
#__init__ 初始化空对象

#object.__new__(Person)    :生成Person类的对象  空的
#type.__new__(cls,name,bases,dic)  :生了cls这个类对象,里面有东西
#元类中
#__init__:控制类的产生,在__new__之后
#__call__:对着对象的产生
#__new__:控制类产生最根上,其实本质最根上也不是它,是type的__call__,但是我们控制不了了

二、单例模式

2.1 什么是设计模式

​ 设计模式是面对各种问题进行提炼和抽象而形成的解决方案。这些设计方案是前人不断试验,考虑了封装性、复用性、效率、可修改、可移植等各种因素的高度总结。它不限于一种特定的语言,它是一种解决问题的思想和方法。

2.2 为什么用设计模式

​ 公司人事会有变动,程序员也会成长。不管是哪种情况,代码非常有可能会被移交,即代码的编写者和维护者很有可能会是不同的人。那么代码的可读性就显得非常重要了。由于高级语言的出现,让机器读懂你的意图已经不是最主要的“矛盾”,而让人读懂你的意图才是最重要。按照设计模式编写的代码,其可读性也会大大提升,利于团队项目的继承和扩展。

2.4设计模式分类

​ 设计模式可以分为三个大类:创建类设计模式、结构类设计模式、行为类设计模式。

​ 创建类模式:单例模式、工厂模式(简单工厂模式、抽象工厂模式)、建造者模式、原型模式。

​ 结构类模式:代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式。

​ 行为类模式:策略模式、责任链模式、命令模式、中介者模式、模板模式、迭代器模式、访问者模式、观察者模式、解释器模式、备忘录模式、状态模式。

​ 设计模式也衍生出了很多的新的种类,不局限于这23种

2.5 什么是单例模式

​ 单例模式是所有设计模式中比较简单的一类,其定义如下:Ensure a class has only one instance, and provide a global point of access to it.(保证某一个类只有一个实例,而且在全局只有一个访问点)

2.6单例模式优点

​ 1、由于单例模式要求在全局内只有一个实例,因而可以节省比较多的内存空间;

2、全局只有一个接入点,可以更好地进行数据同步控制,避免多重占用;
3、单例可长驻内存,减少系统开销

2.7单例模式缺点

1、单例模式的扩展是比较困难的;
2、赋于了单例以太多的职责,某种程度上违反单一职责原则(六大原则后面会讲到);
3、单例模式是并发协作软件模块中需要最先完成的,因而其不利于测试;
4、单例模式在某种情况下会导致“资源瓶颈”。

2.8单例模式应用

1、生成全局惟一的序列号;
2、访问全局复用的惟一资源,如磁盘、总线等;
3、单个对象占用的资源过多,如数据库等;
4、系统全局统一管理,如Windows下的Task Manager;
5、网站计数器。

三、单例模式的四种方法

3.1 绑定方法

class Single:
    _test = None
    def __init__(self,pore,host):
        self.pore = pore
        self.host = host

    @classmethod
    def get_sing(cls):
        import settings
        if not cls._test:
            cls._test = cls(settings.pore,settings.host)
        return cls._test

3.2 装饰器方法

def get_sing(cls):
    _test = None
    def wrapper(*args,**kwargs):
        if len(args) != 0 or len(kwargs) != 0:
            res = cls(*args,**kwargs)
            return res
        else:
            import settings
            nonlocal _test
            if not _test:
                _test = cls(settings.pore,settings.host)
                return _test
    return wrapper()

@get_sing
class Single():
    def __init__(self,pore,host):
        self.pore = pore
        self.host = host

3.3 通过元类方法

class Mymeta(type):
    def __init__(self,name,bases,dic):
        import settings
        self._test = self(settings.pore,settings.host)
    def __call__(self,*args,**kwargs):
        if len(args) != 0 or len(kwargs) != 0:
            obj = object.__new__(self)
            obj.__init__(*args,**kwargs)
            return obj
        else:
            return self._test
        
class Single():
    def __init__(self,pore,host):
        self.pore = pore
        self.host = host

3.4 导入模块方法

def test():
    from signal import s1
    print(s1)


def test2():
    from signal import s1 as s2
    print(s2)
原文地址:https://www.cnblogs.com/tangceng/p/11461541.html