Python 客制化类的创建过程

来源:互联网 发布:原知宏大野智 编辑:程序博客网 时间:2024/06/02 00:08

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

import copyclass 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 = Noneclass SubSingleton(Singleton):    def __init__(self):        self.x = 188        self.y = 2if __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):        passif __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):        passif __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
原创粉丝点击