首页 > 技术文章 > 单例模式

MrYang161 原文

单例模式

如果我们从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了

单例模式概念:多次实例化指向的都是同一块内存地址,拿到的都是同一个对象

好处:节约空间

#settings
PORT=3306
HOST='127.0.0.1'

第一种:通过类方法第一种方法

class Sql:
    _instance=None
    def __init__(self,port,host):
        self.port=port
        self.host=host

    @classmethod
    def get(cls):
        import settings
        if not cls._instance:
            cls._instance=cls(settings.PORT,settings.HOST)
        return cls._instance
s1=Sql.get()
s2=Sql.get()
s3=Sql(456,165.415)
print(s3)
print(s1)
print(s2)

<main.Sql object at 0x00000207356D2B00>
<main.Sql object at 0x00000207356D2AC8>
<main.Sql object at 0x00000207356D2AC8>

第二种:通过装饰器

def pop(func):
    _instance=None
    def wratter(*args,**kwargs):
        if len(args)!=0 or len(kwargs)!=0:
            res=func(*args,**kwargs)
            return res
        else:
            import settings
            nonlocal _instance
            if not _instance:
                _instance=func(settings.PORT,settings.HOST)
            return _instance
    return wratter
@pop
class Sql:
    def __init__(self,port,host):
        self.port=port
        self.host=host


s1=Sql()
s2=Sql()

s3=Sql(456,165.415)
print(s3)
print(s1)
print(s2)

<main.Sql object at 0x000002073569CA20>
<main.Sql object at 0x000002073569CE48>
<main.Sql object at 0x000002073569CE48>

第三种:通过元类

class My(type):
    def __init__(self,name,bases,dic):
       import settings
       self._instance=self(settings.PORT,settings.HOST)
       # super().__init__(name,bases,dic)
    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._instance
class Sql(metaclass=My):
    def __init__(self,port,host):
        self.port=port
        self.host=host
s1=Sql()
s2=Sql()

s3=Sql(456,165.415)
print(s3)
print(s1)
print(s2)

<main.Sql object at 0x000001CD0DF7CC18>
<main.Sql object at 0x000001CD0DF7CBA8>
<main.Sql object at 0x000001CD0DF7CBA8>

第四种:通过模块导入

#SP
import settings
class Sql:
    def __init__(self,port,host):
        self.port=port
        self.host=host

s1=Sql(settings.PORT,settings.HOST)
def test():
    from SR import s1
    print(s1.port)
    print(s1)

def test2():
    from SR import s1 as  s2

    print(s2)

test()
test2()

from SR import s1
from SR import Sql
s2=Sql(45456,523415)
print(s1)
print(s2)

<SR.Sql object at 0x00000174C927D390>
<SR.Sql object at 0x00000174C927D390>
<SR.Sql object at 0x00000174C927D390>
<SR.Sql object at 0x00000174C922CDD8>

推荐阅读