Python 客制化类的创建过程

Python类的创建过程比较复杂,我们一步步来进行分析。
首先,从实现一个Singleton做起,先看下面的代码

import copy
class Singleton:
    def __new__(cls, *args, **kwargs):
        print("In Singleton __new__")
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance
    _instance = None

class SubSingleton(Singleton):
    def __init__(self):
        self.x = 188
        self.y = 2

if __name__ == '__main__':
    s1 = SubSingleton()
    s2 = SubSingleton()
    s3 = copy.deepcopy(s1)
    print(id(s1), id(s2), id(s1.x), id(s2.x))

输出:

In Singleton __new__
In Singleton __new__
In Singleton __new__
40697360 40697360 1457642880 1457642880

从输出我们可以看出无论通过何种方式新建SubSingleton的实例,返回的结果都只是一个相同的实例,为什么?
因为Python解释器在新建一个类的实例时new()是在init()前面的,而且init()的第一个参数self就是new()的返回结果;简单点说就是new是创建实例,init是初始化实例。

减少实例占用内存大小
Python对象实例都有一个dict存放attribute

class SubSingleton():
    def __init__(self):
        self.x = 188
        self.y = 2
    # __slots__ = ['x', 'y']

    def func(self):
        pass

if __name__ == '__main__':
    s1 = SubSingleton()
    print(s1.__dict__)

输出:

{'x': 188, 'y': 2}

我们可以使用sys.getsizeof(instance)去测试dict占用的内存,会发现随着成员的增长内存占用是非常可观的。Python提供了一个方法免去了dict

class SubSingleton():
    def __init__(self):
        self.x = 188
        self.y = 2
    __slots__ = ['x', 'y']    # 注意这里

    def func(self):
        pass

if __name__ == '__main__':
    s1 = SubSingleton()
    print(s1.__dict__)
    s1.z = 1                 # 这一句同样会报错,没有__dict__的类是不能动态加入attribute的。

Traceback (most recent call last):
File “E:/QQSyncFolder/prj/mysite/pattern/customer_class.py”, line 32, in
print(s1.dict)
AttributeError: ‘SubSingleton’ object has no attribute ‘dict
“`

Python类定义语句运行的流程如下:

  1. the appropriate metaclass is determined
  2. the class namespace is prepared
  3. the class body is executed
  4. the class object is created
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值