课时41:魔法方法:构造和析构

发布时间:2019-03-03 10:30:29编辑:auto阅读(2153)

    目录:

      一、_ _init_ _(self[, ...])

      二、_ _new_ _(cls[, ...])

      三、_ _del_ _(self)

      四、课时41课后习题及答案

     

    说的那么厉害,那什么是魔法方法呢?

    (1)魔法方法总是被双下划线包围,例如_ _init_ _()。

    (2)魔法方法是面对对象的Python的一切。

    (3)魔法方法的“魔力”体现在它们总能够在适当的时候被调用。

     

    **************************

    一、_ _init_ _(self[, ...])

    **************************

    之前我们讨论过 _ _init_ _()方法,说它相当于其它面向对象编程语言的构造方法,也就是类在实例化成对象的时候首先会调用的一个方法。

    也许你会问:“有些时候在定义时写_ _init_ _()方法,有些时候却没有,这是为什么呢?”举个例子:

    #p12_1.py
    class Rectangle:
          """
          定义一个矩形类,
          需要长和宽两个数据,
          拥有计算周长和面积的两个办法。
          拥有对象在初始化的时候拥有"长"和"宽"两个参数,
          因此需要重写_ _init_ _()方法,因为我们说过,
          _ _init_ _()方法是类在实例化成对象的时候首先会调用的一个方法,
          """
          def __init__(self,x,y):
                self.x = x
                self.y = y
    
          def getPeri(self):
                return (self.x + self.y) * 2
    
          def getArea(self):
                return self.x * self.y
    >>> #先运行p12_1.py
    >>> rect = Rectangle(3,4)
    >>> rect.getPeri()
    14
    >>> rect.getArea()
    12

    这里需要注意的是,_ _init_ _()方法的返回值一定是None,不能是其它:

    >>> class A:
        def __init__(self):
            return "A for A - Cup"
    
        
    >>> cup = A()
    Traceback (most recent call last):
      File "<pyshell#4>", line 1, in <module>
        cup = A()
    TypeError: __init__() should return None, not 'str'

    所以一般在需要进行初始化的时候才重写__init__()方法。其实,这个__init__()并不是实例化对象时第一个被调用的魔法方法。

     

    ***************************

    二、_ _new_ _(cls[, ...])

    ***************************

    _ _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 ZWW")
    >>> a
    'I LOVE ZWW'

    这里返回str.__new__(cls,string)这种做法是值得推崇的,只需要重写我们关注的那部分内容,然后其它的琐碎东西交给Python的默认机制去完成就可以了,毕竟它们出错的几率要比我们自己写小很多。

     

    *********************

    三、_ _del_ _(self)

    *********************

    如果说__init__()和__new__()方法是对象的构造器的话,那么Python也提供了一个析构器,叫做__del__()方法。当对象将要被销毁的时候,这个方法就会被调用。但一定要注意的是,并非del x就相当于自动调用x.__del__(),__del__()方法是当垃圾回收这个对象的时候调用的。举个例子:

    >>> class C:
        def __init__(self):
            print("我是__init__()方法,我被调用了...")
        def __del__(self):
            print("我是__del__()方法,我被调用了...")
    
            
    >>> c1 = C()
    我是__init__()方法,我被调用了...
    >>> c2 = c1
    >>> c3 = c2
    >>> del c1
    >>> del c2
    >>> del c3
    我是__del__()方法,我被调用了...

     

    *******************************

    四、课时41课后习题及答案

    *******************************

     

关键字