单例模式

单例模式

一、什么是单例模式

  • 单例模式:基于某种方法实例化多次得到实例是同一个

二、为什么用单例模式

  • 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例

三、单例模式

3.1 静态方法实现

"""
当用户输入端口和地址,实例化产生新对象
当用户输入端口和地址,每次拿到的对象,是同一个
"""
class Single:
    _single_model = None

    def __init__(self, port, host):
        self.port = port
        self.host = host

    @classmethod
    def single_cls(cls):
        import settings

        if not cls._single_model:
            cls._single_model = cls(settings.PORT, settings.HOST)
        return cls._single_model


# 拿到的对象会是同一个
s = Single.single_cls()
s2 = Single.single_cls()
print(s)
print(s2)

<__main__.Single object at 0x00000210F3F7CD68>
<__main__.Single object at 0x00000210F3F7CD68>

3.2通过装饰器实现

"""
第二种方法,通过装饰器实现
当用户输入端口和地址,实例化产生新对象
当用户不输入端口和地址,每次拿到的对象,都是同一个
"""

def get_siggle(cls):
    import settings
    siggle = cls(settings.PORT, settings.HOST)

    def wrapper(*args, **kwargs):
        if len(args) != 0 or len(kwargs) != 0:
            res = cls(*args, **kwargs)
            return res
        else:
            return siggle

    return wrapper


@get_siggle
class Single:

    def __init__(self, port, host):
        self.port = port
        self.host = host


s1 = Single()
s2 = Single()
print(s1)
print(s2)
"""

"""

<__main__.Single object at 0x000001A4DE282198>
<__main__Single object at 0x000001A4DE282198>

3.3 通过元类

"""
第三种方法通过元类
当用户输入端口和地址,实例化产生新对象
当用户不输入端口和地址,每次拿到的对象,都是同一个
"""

class Mymeta(type):
    def __init__(self, name, base, dic):
        # self 是singie类
        import settings
        # 把实例化好的对象,放到了类的名称空间
        self._singie = self(settings.PORT, settings.HOST)

    def __call__(self, *args, **kwargs):
        if len(args) != 0 or len(kwargs) != 0:
            obj =self.__new__(self)
            obj.__init__(*args, **kwargs)
            return obj
        else:
            return self._singie




class Singie(metaclass=Mymeta):
    def __init__(self, port, host):
        self.port = port
        self.host = host


s1 = Singie()
s2 = Singie()
print(s1, "dddd")
print(s2,"dfd")

<__main__.Singie object at 0x000001324C1247F0>
<__main__.Singie object at 0x000001324C1247F0>

3.4通过模块实现

# settings.py

PORT = '3306'
HOST = '127.0.0.0'

# singie.pyt
import settings
class Singies():
    def __init__(self, port, host):
        self.port = port
        self.host = host

s1 = Singies(settings.PORT, settings.HOST)

# 通过模块导入(python的模块是天然的单例)
def test():

    from singie import s1
    print(s1.port)
    print(s1)
def test2():
    from singie import s1 as s2
    print(s2)
test()
test2()

from singie import Singies
s3 = Singies('3306', '198.2.2.1')
print(s3)

<singie.Singies object at 0x000001324C1249E8>
<singie.Singies object at 0x000001324C1249E8>
<singie.Singies object at 0x000001324C124860>

四、总结

单例模式,只要把握类名()创建对象是唯一一个就行

posted @ 2019-09-04 19:03  RandySun  阅读(228)  评论(0编辑  收藏  举报