Skip to content

Latest commit

 

History

History
83 lines (68 loc) · 2.12 KB

File metadata and controls

83 lines (68 loc) · 2.12 KB

__new__()和__init__()方法

  • __new__():是类的构造方法,在实例创建前被调用,它的作用就是创建实例并返回实例对象,是一个静态方法
  • __init__():是类的初始化方法,当实例对象被创建后调用,然后初始化实例对象的属性值,是一个实例方法
  • new()方法先被调用,创建实例对象,然后将实例对象传递给init()方法的self,进行初始化操作

__new__()实现单例

class Singleton:

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls)
        return cls.instance

if __name__ == '__main__':
    s1 = Singleton()
    s2 = Singleton()
    print('s1:{}'.format(id(s1)))
    print('s2:{}'.format(id(s2)))
    print('s1 is s2:{}'.format(s1 is s2))
s1:1891632871352
s2:1891632871352
s1 is s2:True

以上看似实现了单例模式,但实际在多线程的情况下会有问题,多个线程同时创建单例对象,如果不加锁的情况下是不安全的。

import time
import threading

class Singleton:

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            time.sleep(0.05)
            cls.instance = super().__new__(cls)
        return cls.instance

def func():
    s = Singleton()
    print('s:{}'.format(id(s)))

if __name__ == '__main__':
    for _ in range(5):
        # 开启5个线程同时创建对象
        td = threading.Thread(target=func)
        td.start()
s:1230297165896
s:1230297245008
s:1230297372152
s:1230297270648
s:1230297296176

多线程下创建单例对象需要加锁

import threading

class Singleton:
    _instance_lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        # 加锁
        with cls._instance_lock:
            if not hasattr(cls, 'instance'):
                cls.instance = super().__new__(cls)
        return cls.instance

def func():
    s = Singleton()
    print('s:{}'.format(id(s)))

if __name__ == '__main__':
    for _ in range(5):
        td = threading.Thread(target=func)
        td.start()