最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

python __new__方法与单例模式

来源:博客园


(资料图片)

  • 1、new()至少要有一个参数cls,代表当前类,此参数在实例时由python解释器自动识别,
  • 2、new()必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以 return父类new出来的实例, 如:return super().new(cls),或者直接return object.new(cls)
  • 3、init有一个参数self,就是这个__new__()方法返回的实例, 可以完成一些其它初始化的动作,init不需要返回值(有返回值就会报错)
  • 4、如果__new__()创建的是当前类的实例,会自动调用__init__()函数, 通过return语句里面调用的__new__(cls)函数的第一个参数是cls来保证是当前类实例, 如果是其他类的类名,那么实际创建返回的就是其他类的实例,其实就不会调用当前类的__init__()函数,也不会调用其他类的__init__()函数。
class A(object):    def __init__(self):        print("这是init方法:",self)    def __new__(cls, *args, **kwargs):        print("这是cls类本身的ID:",id(cls))        print("这是new方法:",object.__new__(cls))        # print("这是new方法:",super().__new__(cls))  # 跟上面那句本质一样,都是调用父类的new方法        return object.__new__(cls)A()print("这是A类的ID:",id(A))"""输出结果如下:这是cls类本身的ID: 2790056212288这是new方法: <__main__.A object at 0x000002899CB281C0>这是init方法: <__main__.A object at 0x000002899CB281C0>这是A类的ID: 2790056212288"""

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

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

事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

实现单例模式:
  • 使用模块
  • 使用装饰器
  • 使用类
  • 基于 new方法实现
  • 基于 metaclass 方式实现
1、使用模块

Python 的模块就是天然的单例模式

2、使用装饰器
def singleton(cls):    _instance = dict()    def _singleton(*args, **kwargs):        if cls not in _instance:            _instance[cls] = cls(*args, **kwargs)        return _instance[cls]    return _singleton@singletonclass A(object):    a = 1    def __init__(self, x=0):        self.x = xa1 = A(2)print(a1)a2 = A(3)print(a2)print(a1 is a2)
3、使用类
  • 多线程单例模式
import timeimport threading  class Singleton(object):    _instance_lock = threading.Lock()     def __init__(self):        time.sleep(1)     @classmethod    def instance(cls, *args, **kwargs):        if not hasattr(Singleton, "_instance"):            with Singleton._instance_lock:                if not hasattr(Singleton, "_instance"):                    Singleton._instance = Singleton(*args, **kwargs)        return Singleton._instance  def task(arg):    obj = Singleton.instance()    print(obj)        for i in range(10):    t = threading.Thread(target=task,args=[i,])    t.start()        time.sleep(20)obj = Singleton.instance()print(obj)
4、基于 new方法实现
class Singleton(object):    _instance = None    def __new__(cls, *args, **kwargs):        if not cls._instance:            cls._instance = object.__new__(cls)        return cls._instance
import threading  class Singleton(object):    _instance_lock = threading.Lock()     def __init__(self):        pass      def __new__(cls, *args, **kwargs):        if not hasattr(Singleton, "_instance"):            with Singleton._instance_lock:                if not hasattr(Singleton, "_instance"):                    Singleton._instance = object.__new__(cls)          return Singleton._instance obj1 = Singleton()obj2 = Singleton()print(obj1,obj2) def task(arg):    obj = Singleton()    print(obj) for i in range(10):    t = threading.Thread(target=task,args=[i,])    t.start()
基于 metaclass 方式实现
import threading class SingletonType(type):    _instance_lock = threading.Lock()    def __call__(cls, *args, **kwargs):        if not hasattr(cls, "_instance"):            with SingletonType._instance_lock:                if not hasattr(cls, "_instance"):                    cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)        return cls._instance class Foo(metaclass=SingletonType):    def __init__(self,name):        self.name = name  obj1 = Foo("name")obj2 = Foo("name")print(obj1,obj2)

关键词: