单例模式的实现方法

在python中,我们可以使用多种方法来实现单例:

1,使用模块

2,使用__new__

3,使用装饰器

4,使用元类(metaclass)

 

1,使用模块:python的模块就是天然的单例模式,模块进行歹意吃导入时会生成.pyc文件,第二次导入时直接加载,不会再次执行模块代码,因此我们把模块单独定义在一个模块中,就可以获得一个单例了

#Single.py文件
class MySingle:
    def f(self):
        print('模块单例方式')
s = MySingle()

将上述代码保存在Single.py文件中  在其他文件中进行导入
from Single import s
s.f()

#模块单例方式

2,使用__new__: 为了类只有一个实例,我们可以使用__new__方法来控制创建实例的方法

__init__:初始化方法, 先执行  __new__:创建单例

class Info(object):
    str=None
    def __new__(cls, *args, **kwargs):
        if cls.str==None:           # 如果他是空,就重写 重新赋值  给他新的内存空间      其他在来就都是None
            cls.str=super().__new__(cls)
            return cls.str

    def __init__(self):  # init方法先执行
        print('init方法')

str1=Info()   # 单例模式就是只能生成唯一一个对象,
str2=Info()
print('str1: %s'%str1)
print('str2:%s'%str2)

#init方法
 str1: <__main__.Info object at 0x00000248A2E5A908>
 str2:None

new方法每次实例化的时候都之后一个实例对象:

class A(object):
    _intance=None
    def __new__(cls, *args, **kwargs):
        if cls._intance==None:
            cls._intance=object.__new__(cls)
            return cls._intance       
        else:
            return cls._intance        # 如果他不为空  就返回该对象

a=A()
b=A()
print('a:%s'%a)
print('b:%s'%b)

a:<__main__.A object at 0x000001E42ABEA940>
b:<__main__.A object at 0x000001E42ABEA940>

3,试用装饰器可以动态的修改一个类和函数的功能,或者装饰某个类,用来只生成一个实例对象。

# 使用装饰器
def singleton(cls):
    instances={}
    def getinstance(*args,**kwargs):
        if cls not in instances:
            instances[cls] = cls(*args,**kwargs)
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    print('MyClass')

c1=MyClass()
c2=MyClass()
print(c1==c2)

# MyClass
# True

4,使用元类(metaclass):元类可以控制类的创建过程,是他创建三件事:

1,拦截类的创建

2,修改类的定义

3,返回修改的类

# 使用元类
class Singleton2(type):
    def __init__(self,*args,**kwargs):  #初始化数据
        self._instance=None
        super(Singleton2,self).__init__(*args,**kwargs)

    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance=super(Singleton2,self).__call__(*args,**kwargs)
        return self._instance

class F(metaclass=Singleton2):   #python2中的写法是class F(objects):
    __metaclass__ = Singleton2  # 代码在执行到这里的时候其实已经执行了__init__方法和__call__方法,而不是在执行F实例化是才执行,而且只执行一次

f1 = F()
f2  = F()
print(F.__dict__)
print(f1 is f2)

"""
{'__module__': '__main__', '__metaclass__': <class '__main__.Singleton2'>, '__dict__': <attribute '__dict__' of 'F' objects>, '__weakref__': <attribute '__weakref__' of 'F' objects>, '__doc__': None, '_instance': <__main__.F object at 0x00000215B2A0A940>}
True

此时 '_instance': <__main__.F object at 0x00000215B2A0A940>} 存在一个私有属性来保存属性,而不会污染F类(其实还是会污染,不过是使用_instance属性访问)
"""

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值