python实现单例与__new__()方法

python实现单例与new()方法

new 和 init 方法

  1. _ new _ 方法进行分配空间
  2. _ init _ 对象初始化

在利用init方法实例化对象会首先使用new方法创建一个空间,即一个内存地址。

new() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器。

class B:
    def __init__(self):
        print("init")
    def __new__(cls, *args, **kwargs):
        print("new")
        return object.__new__(cls)
    
a = B()

执行结果:

new
init

所以比较容易看出,首先执行的时new方法,然后执行init

需要单例的原因

在对一个类对象进行实例化时,可以实例化出很多不同对象。每一次实例化出的对象,内存中需要重新分配一个地址,因此会造成空间浪费。而且在类似于线程池时,需要实现同步,不发生冲突,也需要在同一块数据空间操作。还有类似于windows中垃圾桶操作。

例:

class A:
    pass

a = A()
print('a对象所在的内存地址是 %d, A类所在的内存地址是 %d' % (id(a), id(A)))
b = A()
print('b对象所在的内存地址是 %d, A类所在的内存地址是 %d' % (id(b), id(A)))
c = A()
print('c对象所在的内存地址是 %d, A类所在的内存地址是 %d' % (id(c), id(A)))

输出:

a对象所在的内存地址是 1343886076112, A类所在的内存地址是 1343831237640
b对象所在的内存地址是 1343886085592,  A类所在的内存地址是 1343831237640
c对象所在的内存地址是 1343886076280,  A类所在的内存地址是 1343831237640

python实现单例

instance变量名中“_” 代表着类的私有变量;

class A:
    _instance = None
    def __init__(self, name, age):
        self.name = name
        self.age = age
   
    def __new__(cls, *args, **kwargs):
        #此处去掉对于是否初次实例化_instance值的判断
        cls._instance = object.__new__(cls)
        return cls._instance
 
b = A('one', 1)
print(b)
c = A('two', 2)
print(c)

输出:

<__main__.A object at 0x00000138E5DC29E8>
<__main__.A object at 0x00000138E5DC2BE0>

通过python实现单例,通过_instance(bool型)值的判定,决定是否再次分配新的数据空间。

class A:
    _instance = None
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return cls._instance

b = A('one', 1)
print(b)
c = A('two', 2)
print(c)

输出:

<__main__.A object at 0x00000138E5DC2D30>
<__main__.A object at 0x00000138E5DC2D30>

不难发现,空间地址是没有发生变化的,实现了单例;

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容