刷题1——面试题2:实现Singleton模式

2019-06-16  本文已影响0人  咋家

面试题2:实现Singleton模式

题目:设计一个类,我们只能生成该类的一个实例。

首先,我们需要知道什么是单例模式(Singleton Pattern),这是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。也就是说,在整个系统中,只允许某个类出现一个实例。

在python中,可以用多种方法来实现单例模式:

1、使用模块

在python中模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当再次导入时,就会直接加载.pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得单例对象。

#mysingleton.py
class Singleton():
    def foo(self):
        pass
   
my_singleton =Singleton()
 
from mysingleton import my_singleton
 
my_singleton.foo()

2、使用new

先来了解下new,在定义一个类时,使用的最多的就是init,而newcall很少使用到,都知道init方法负责对象的初始化,要想初始化,得先有对象不是,new的作用就是实例化一个对象并返回该实例对象,然后才能被init调用进行初始化。

换个角度说,new是用来创建一个实例对象的,因此我们可以通过修改new方法来使类只出现一个实例,代码如下:

class Singleton():
    _instance ={}
   
    def __new__(cls, *args, **kwargs):
        if cls not in cls._instance:
            cls._instance[cls] =super(Singleton, cls).__new__(cls)
           
        return cls._instance
   
class MyClass(Singleton):
   
    def __init__(self, val):
        self.val =val
              
if __name__ =='__main__':
    a =MyClass(1)
    b =MyClass(2)
    print(a is b)   #True

3、使用装饰器

我们知道,装饰器可以动态的修改一个类或函数的功能,因此也可以使用装饰器来装饰某个类,使其只能生成一个实例。

注意一点,python装饰器被装饰后的函数其实已经是另一个函数(函数名等函数属性会发生改变),为了不影响,python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。

from functools import wraps
 
def singleton(cls):
    instances ={}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] =cls(*args, **kw)
        return instances[cls]
    return getinstance
 
@singleton
class Myclass():
    a =1
   
a =Myclass()
b =Myclass()
print(a is b)  #True

4、使用元类

元类(参考:深刻理解python中的元类)是用于创建类对象的类,类对象创建实例对象时一定会调用call方法,因此在调用call时候保证始终只创建一个实例即可,type是python中的一个元类。

class Singleton(type):
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance =super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instance
   
class Foo(metaclass=Singleton):
    pass
   
f1 =Foo()
f2 =Foo()
print(f1 is f2) #True

更多精彩,关注“咋家”

咋家.png
上一篇 下一篇

猜你喜欢

热点阅读