单例模式

单例模式:5种方法

实例:连接数据库时,防止每次操作都去创建数据库连接,所以使用单例模式仅在第一次使用时,创建连接,以后均使用该连接即可

4种方法:
a. 基于文件导入实现单例模式(pycheml自带的方式)
b. 基于 classmethod
c. 基于 __new__
d. 基于 metaclass
e. 基于 装饰器

a. 基于文件导入实现单例模式(pycheml自带的方式)

import func1
import func1
# 单例模式 所以只导入一次

import importlib
importlib.reload(func1)   # 可以重新再导入一次模块

b. 基于 classmethod

 1 class Foo(object):
 2     def __init__(self):
 3         self.name = 'alex'
 4     @classmethod
 5     def get_instance(cls,*args,**kwargs):
 6         if not hasattr(cls,'instend'):
 7             print('====lalal')
 8             obj = cls(*args,**kwargs)
 9             cls.instend = obj
10         return cls.instend
11 f1 = Foo.get_instance()
12 f2 = Foo.get_instance()
13 print(f1,f2)  
#<__main__.Foo object at 0x000000000295CFD0> <__main__.Foo object at 0x000000000295CFD0>

c. 基于 __new__

class Foo(object):
    instance = None
    def __init__(self):
        self.a = 1

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            obj = super().__new__(cls, *args, **kwargs)
            cls.instance = obj
        return cls.instance
print(Foo())
print(Foo())

d. 基于 metaclass

class Mytype(type):
    def __call__(self, *args, **kwargs):
        obj = self.__new__(self,*args,**kwargs)
        if not hasattr(self,'instance'):
            print(self,'<<<')
            self.instance = obj
        return self.instance

class Foo(metaclass=Mytype):
    def __init__(self,a):
        self.a = a

print(Foo('alex'))
print(Foo('aaa'))
print(Foo('bbb'))

 e. 基于装饰器

def singletonde(func):
instance = {}
def wrapper(*args, **kwargs):
if func.__name__ not in instance:
instance[func.__name__] = func(*args, **kwargs)
return instance[func.__name__]
return wrapper

@singletonde
class Singleton:
def __init__(self, name):
self.name = name

a = Singleton('aaa')
b = Singleton('bbb')
print(a, a.name)
print(b, b.name)
posted @ 2018-03-16 22:56  JAYWX  阅读(156)  评论(0编辑  收藏  举报