Python构造方法、析构方法和单例模式

一、__init__()方法

__init__()通常在初始化一个类实例的时候调用,如:

class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age


stu = Student('weiheng',20) #创建一个Student实例,并且对对象属性初始化
print(stu.name)

在对象被创建后,调用__init__(),但__init__()其实不是实例化一个类的时候第一个被调用的,当Student()去实例化的时候,第一个被调用的使__new__()方法。

二、__new__()方法

class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __new__(cls, *args, **kwargs):
        print('创建一个对象')
        # 创建cls类的一个实例并返回这个实例
        return object.__new__(cls)


stu = Student('weiheng',20) #创建一个Student实例,并且对对象属性初始化
print(stu.name)

当我们运行代码,会发现__new__()会在__init__()之前执行,其实创建一个对象具体的逻辑是:

stu = Student('weiheng',20):

1.首先执行Student()的__new__()方法返回一个Student的一个实例。

2.通过self来指向Student的一个实例,调用Student的__init__()方法进行对类进行初始化。

__init__()和__new__()的区别:

1.__init__()通过实例化一个实例,在类实例被创建之后调用,是一个实例方法;__new__()在实例化的时候调用,创建一个对象并返回这个实例对象

2.__init__()接收的是普通参数,而__new__()接收的是class,并且返回一个new object。

三、单例模式:__new__()的应用 

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统等。

如在Window中,只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果所有窗口显示内容完全一致,将会产生重复对象,浪费资源。

一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。

1.让类自身保存它的唯一实例

2.这个类可以保证没有其他实例被创建的,并且它可以提供一个访问该实例的方法

3.向整个系统提供这个实例

class Person(object):
    _instance = None
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __new__(cls, *args, **kwargs):
        if not Person._instance:
            Person._instance = object.__new__(cls)
        return Person._instance



A = Person('zhangsan',30)
B = Person('zhangsan',30)
C = Person('wangwu',40)

# instance = None
# print(bool(instance)) #False
# print(not instance) #True

#1.
#创建了两个相同的对象.如果两个对象的内容完全一致的话,将会重复创建,浪费内存空间
print(id(A))  #1501042099200
print(id(B))  #1501042099480

#2.
'''
1.让类自身保存类的实例
2.如果类实例不存在的话,就创建,如果存在,就返回已经创建的
'''
print(id(A))  #1781445281048
print(id(C))  #1781445281048

 四、析构函数

析构函数正好和构造函数相反,当对象结束其生命周期的时候,系统会自动调用其析构函数,析构函数往往用于做一些"善后处理"工作,关闭程序所占用的资源。

构造函数会为对象开辟一块内存空间,当对象执行完毕后,会调用析构函数进行释放所占用的内存给操作系统。析构函数没有参数也没有返回值。

'''
析构函数和沟构造函数相反
当对象结束其生命周期的时候,系统会自动调用析构函数
析构函数往往做一些'清理善后'的工作,关闭一些占用的资源
构造函数创建一块内存空间,对象执行完毕后,会调用析构函数释放内存。
没有参数,也没有返回值
'''

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __new__(cls, *args, **kwargs):
        print('create a new object.')
        return object.__new__(cls)

    def __del__(self):
        print('an object of deconstruction.')

zhangsan = Person('zhangsan',30)

#1.被动  当对象执行结束后,系统会自动调用__del__方法

#2.手动  del obj   会手动调用__del__方法,删除对象,回收所占用的资源
del zhangsan

#会报错 NameErro name 'zhangsan' is not defined
print(zhangsan)

 

posted @ 2018-03-13 14:44  短毛兔  阅读(791)  评论(0编辑  收藏  举报