学python的,学过类与对象的,都会经常看到和用到__init__(self, ),__new__(cls, ),__del__(self)。
但是很多可能见过的,却不知道怎么用,或者为什么用。没有真正的了解它们。
然而其实这些就是我们学习面向对象编程语言中的构造方法和析构方法。
这三个其实还有另一种称呼叫做魔法方法.
魔法方法顾名思义,就是总是被左右各两个下划线包围的方法称为魔法方法,如__init__().(注:这里我不会细说魔法方法,只会针对这三个方法进行讲解。)
__init__()方法,相当于其他面向对象编程语言的构造方法,与就是类在实例化成对象的时候首先会调用的一个方法。
我们可能看到过这种情况,有时候在类定义时写__init__()方法,有时候则没有写,这是为什么呢?
其实这就好比是一种需求。就比如有一种something是迫使人去奋苦拼搏不惜一切代价也要得到的,这个something就是需求。你在定义其他的构造方法时有时候需要一些比如参数的需求,这时就需要了__init__()方法了。我相信我说到这,应该就已经理解了得到答案了。
如果还没有理解,那好吧,我来举个例子:
class Rectangle:
'''
我们定义一个矩形类,
需要长和宽两个参数,
拥有计算周长和面积两个方法。
因此我们知道了我们的需求了,这是就需要__init__()方法了
因此我们需要重写__init__()方法,因为我们也说过,该方法是类在实例化成对象的时候首先会调用的一个方法,
说到这应该都可以理解了吧。
'''
def __init__(self, l, w):
self.l = l
self.w = w
def getPeri(self):
return (self.l + self.w) * 2
def getArea(self):
return self.l * self.w
test = Rectangle(3, 4)
peri = test.getPeri()
area = test.getArea()
print(peri, area)
#输出结果为:14 12
注意:__init__()方法的返回值一定是None,不能为其他(否则会出错):
class A:
def __init__(self):
return 'abc'
a = A()
#输出结果为:
Traceback (most recent call last):
File "E:/PycharmProjects/untitled2/ceshi.py", line 1, in <module>
a = A()
TypeError: __init__() should return None, not 'str'
所以,只有在需要进行初始化的时候才重写__init__()方法。
其实万事都留一手,这个__init__()并不是实例化对象时第一个被调用的魔法方法。
事实上,__new__()才是在一个对象实例化的时候调用的第一个方法。它与其他魔法方法不同,它的第一个参数不是 self 而是这个类(cls),而其它参数会直接传递给__init__()方法。
__new__()方法需要返回一个实例对象,通常是 cls 这个类实例化的对象,当然也可以返回其他对象。
__new__()方法平时很少去重写它,一般让Python用默认的方案执行就可以了。但是有一种情况需要重写这个魔法方法,就是当继承一个不可变的类型的时候,它的特性就显得尤为重要了。
class CapStr(str):
def __new__(cls, string):
string = string.upper()
return str.__new__(cls, string)
a = CapStr('I Love apple')
print(a)
#输出结果为:I LOVE APPLE
这里返回 str.__new__(cls, string) 这种做法是值得推崇的,只需要重写我们关注的那部分内容,然后其他的琐碎东西交给 Python 的默认机制去完成就可以了,毕竟它们出错的概率要比我们自己写小得多。
如果说 __init__() 和 __new__() 方法是对象的构造器的话,那么 Python 也提供了一个析构器,称为 __del__() 方法。当对象将要被销毁的时候,这个方法就会被调用。但一定要注意的是,并非 del x 就相当于自动调用了 x.__del__(), __del__()方法是当垃圾回收机制回收这个对象的时候调用的。
例:
class B:
def __init__(self):
print('我是 __init__()方法,我被调用了')
def __del__(self):
print('我是 __del__()方法,我被调用了')
b1 = B()
print('123')
print('456')
结果为:
我是 __init__()方法,我被调用了
123
456
我是 __del__()方法,我被调用了
class B:
def __init__(self):
print('我是 __init__()方法,我被调用了')
def __del__(self):
print('我是 __del__()方法,我被调用了')
b1 = B()
print('123')
del b1
print('456')
结果为:
我是 __init__()方法,我被调用了
123
我是 __del__()方法,我被调用了
456