网络编程
位置:首页>> 网络编程>> Python编程>> 单利模式及python实现方式详解

单利模式及python实现方式详解

作者:Hantaozi  发布时间:2021-07-21 21:45:15 

标签:python,单利模式

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保 某一个类只有一个实例存在 。当希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象

python实现单例模式

使用模块实现

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

mysingleton.py


class Singleton:
 def foo(self):
   print('foo')
singleton=Singleton()

其他文件


from mysingleton import singleton
singleton.foo()

装饰器实现


def singleton(cls):
 _instance = {}
 def wraper(*args, **kargs):
   if cls not in _instance:
     _instance[cls] = cls(*args, **kargs)
   return _instance[cls]
 return wraper
@singleton
class A(object):
 def __init__(self, x=0):
   self.x = x
a1 = A(2)
a2 = A(3)

最终实例化出一个对象并且保存在_instance中,_instance的值也一定是

基于__new__方法实现

当我们实例化一个对象时,是 先执行了类的__new__方法 (我们没写时,默认调用object.__new__), 实例化对象 ;然后 再执行类的__init__方法 ,对这个对象进行初始化,所有我们可以基于这个,实现单例模式


class Singleton():
 def __new__(cls, *args, **kwargs):
   if not hasattr(cls,'_instance'):
     cls._instance=object.__new__(cls)
   return cls._instance

class A(Singleton):
 def __init__(self,x):
   self.x=x

a=A('han')
b=A('tao')
print(a.x)
print(b.x)

为了保证线程安全需要在内部加入锁


import threading

class Singleton():
 lock=threading.Lock
 def __new__(cls, *args, **kwargs):
   if not hasattr(cls,'_instance'):
     with cls.lock:
       if not hasattr(cls, '_instance'):
         cls._instance=object.__new__(cls)
   return cls._instance
class A(Singleton):
 def __init__(self,x):
   self.x=x
a=A('han')
b=A('tao')
print(a.x)
print(b.x)

两大注意:

1. 除了模块单例外,其他几种模式的本质都是通过设置中间变量,来判断类是否已经被实例。中间变量的访问和更改存在线程安全的问题:在开启多线程模式的时候需要加锁处理。

2.  __new__方法无法避免触发__init__(),初始的成员变量会进行覆盖。 其他方法不会。

PS:下面看下Python单例模式的4种实现方法


#-*- encoding=utf-8 -*-
print '----------------------方法1--------------------------'
#方法1,实现__new__方法
#并在将一个类的实例绑定到类变量_instance上,
#如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
#如果cls._instance不为None,直接返回cls._instance
class Singleton(object):
 def __new__(cls, *args, **kw):
   if not hasattr(cls, '_instance'):
     orig = super(Singleton, cls)
     cls._instance = orig.__new__(cls, *args, **kw)
   return cls._instance
class MyClass(Singleton):
 a = 1
one = MyClass()
two = MyClass()
two.a = 3
print one.a
#3
#one和two完全相同,可以用id(), ==, is检测
print id(one)
#29097904
print id(two)
#29097904
print one == two
#True
print one is two
#True
print '----------------------方法2--------------------------'
#方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
#同一个类的所有实例天然拥有相同的行为(方法),
#只需要保证同一个类的所有实例具有相同的状态(属性)即可
#所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
#可参看:http://code.activestate.com/recipes/66531/
class Borg(object):
 _state = {}
 def __new__(cls, *args, **kw):
   ob = super(Borg, cls).__new__(cls, *args, **kw)
   ob.__dict__ = cls._state
   return ob
class MyClass2(Borg):
 a = 1
one = MyClass2()
two = MyClass2()
#one和two是两个不同的对象,id, ==, is对比结果可看出
two.a = 3
print one.a
#3
print id(one)
#28873680
print id(two)
#28873712
print one == two
#False
print one is two
#False
#但是one和two具有相同的(同一个__dict__属性),见:
print id(one.__dict__)
#30104000
print id(two.__dict__)
#30104000
print '----------------------方法3--------------------------'
#方法3:本质上是方法1的升级(或者说高级)版
#使用__metaclass__(元类)的高级python用法
class Singleton2(type):
 def __init__(cls, name, bases, dict):
   super(Singleton2, cls).__init__(name, bases, dict)
   cls._instance = None
 def __call__(cls, *args, **kw):
   if cls._instance is None:
     cls._instance = super(Singleton2, cls).__call__(*args, **kw)
   return cls._instance
class MyClass3(object):
 __metaclass__ = Singleton2
one = MyClass3()
two = MyClass3()
two.a = 3
print one.a
#3
print id(one)
#31495472
print id(two)
#31495472
print one == two
#True
print one is two
#True
print '----------------------方法4--------------------------'
#方法4:也是方法1的升级(高级)版本,
#使用装饰器(decorator),
#这是一种更pythonic,更elegant的方法,
#单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
def singleton(cls, *args, **kw):
 instances = {}
 def _singleton():
   if cls not in instances:
     instances[cls] = cls(*args, **kw)
   return instances[cls]
 return _singleton
@singleton
class MyClass4(object):
 a = 1
 def __init__(self, x=0):
   self.x = x
one = MyClass4()
two = MyClass4()
two.a = 3
print one.a
#3
print id(one)
#29660784
print id(two)
#29660784
print one == two
#True
print one is two
#True
one.x = 1
print one.x
#1
print two.x
#1

总结

以上所述是小编给大家介绍的python实现单利模式方式方式详解网站的支持!

来源:http://www.cnblogs.com/hantaozi430/p/8605275.html

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com