17.1 Python入门之魔法方法

构造和析构

1)魔法方法总被双下划线包围

2)魔力体现在方法在适当时机调用


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


该方法为构造方法,在类实例化为对象时首先调用,返回值一定是None,只在需要初始化时才重写


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


_ _new_ _()才是类实例化时调用的第一个方法,它的第一个参数与众不同,不是self,而是这个类(cls),而其他参数会直接传递给_ _init_ _()方法


_ _new_ _()需要返回一个实例对象,通常是这个类实例化后的对象,也可返回其他对象


_ _new_ _()很少重写,一般只要当继承一个不可变的类型时,才需要重写


class CapStr(str):

   def _ _new_ _(cls,string):

    string = string.upper()

    return str._ _new_ _(cls,string)  #只重写关注的部分内容


>>>a = CapStr('haha')

>>>a

'HAHA'


_ _del_ _(self)


Python提供了一个析构器:_ _del_ _()方法,当对象被销毁时,该方法被调用,,即当垃圾回收机制回收该对象时调用,而不是del x(并不会自动调用_ _del_ _()方法)


>>>class C:

    def_ _del_ _(self):

      print("del is doing")

>>>c1 = C()

>>>c2 = c1

>>>del c1

>>>del c2

del is doing


算术运算


工厂函数


将int(),float(),str(),list(),tuple()这些BIF转化为工厂函数(不再是普通的BIF)


>>>type(int)

<class 'type'>


type类型,即类对象,所谓的工厂函数即类对象,当调用这些方法时,实际是创建一个相应的实例对象


>>>a = int('123')

>>>b = int('345')

>>>a + b

468


可见对象可以进行算术计算


算术操作符


算术运算相关的魔法方法,如


>>>class New_int(int):   #(int)代表继承???

     def _ _add_ _(self,other):

         return int._ _sub_ _(self,other)  #Python默认的魔法方法

    def _ _sub_ _(self,other):

         return int._ _add_ _(self,other) #Python默认的魔法方法

>>>a = New_int(3)

>>>b = New_int(5)

>>>a + b   #涉及加法操作,自动调用魔法方法_ _add_ _()

-2

>>>a - b

8


>>>class Try_int(int):

     def _ _add_ _(self,other):

        return self + other

     def _ _sub(self,other):

       return self - other

>>>a = Try_int(1)

>>>b = Try_int(3)

>>>a + b


#error,陷入无限递归,因为涉及加法操作,自动调用魔法方法_ _add_ _(),返回值仍然是对象相加,再次自动调用魔法方法_ _add_ _(),进入死循环,可改写为


>>>class Try_int(int):

     def _ _add_ _(self,other):

        return int(self) + int(other)

     def _ _sub(self,other):

       return int(self) - int(other)

>>>a = Try_int(1)

>>>b = Try_int(3)

>>>a + b

4


反运算


反运算相当于算术运算增加了"r",如add变为radd


>>>class Nint(int):

    def _ _radd_ _(self,other)

       return int._ _sub_ _(other,self)  #参数位置调换

>>>a = Nint(5)

>>>b= Nint(3)

>>>a + b

8  #a对象(主动)默认有_ _add_ _()方法,所以b的_ _radd_ _()不执行

>>>1 + b

-2 #_ _add_ _()方法表示对象相加,1没有,则b的_ _add_ _()不执行


注意参数顺序的变化,此时self为b,other为1(1-3=-2)


增量赋值运算

>>>a = a + b

>>>a += b


一元操作符


_ _neg_ _()(表示正号行为),_ _pos_ _()(表示负号行为),_ _abs_ _()(表示当abs()调用时行为,取绝对值),_ _invert_ _()(按位取反行为)


简单定制


要求:

定制一个计时器的类

start和stop方法代表启动计时和停止计时

假设计时器对象t1,print(t1)和直接调用t1均显示结果

当计时器未启动或已经停止计时,调用stop方法会给予提示

两个计时器对象可相加

只使用提供的有限资源

总结:对象进行相关算术运算,自动调用魔法方法


_ _str_ _()和_ _repr_ _()魔法方法

>>>class A:

    def _ _str_ _(self):

       return "haha"

>>>a = A()

>>>print(a)

haha

>>>class B:

    def _ _repr_ _(self):

       return "hehe"

>>>b = B()

>>>b

hehe


localtime()返回一个时间元组的结构


import time as t


class MyTimer:


   def start(self):

     self.start = t.localtime()

     print('start')


   def stop(self):

     self.stop = t.localtime()

     self._calc()   #内部方法,计算时间

      print('stop')


    def _ calc(self):

     self.lasted = []

     self.prompt ='total'

     for index in range(6):

       self.lasted.append(self.stop[index] - self.start[index])

       self.prompt += str(self.lasted[index])

     print(self.prompt)


   def _ _str_ _(self):

      return self.prompt

   _ _repr_ _= _ _str_ _

#所有属于实例对象的变量最好在_ _init_ _()中先定义

    def _ _init_ _(self):

     self.prompt = 'need to be activated'

     self.lasted = []

     self.start = 0   #error,因为start方法的存在,属性覆盖方法

     self.stop = 0

    修改为

def _ _init_ _(self):

     self.prompt = 'need to be activated'

     self.lasted = []

     self.begin = 0  

     self.end = 0


添加列表存放单位


def _ _init_ _(self):

     self.unit = ['year','month','day','hour','minute','second'] #修改处

     self.prompt = 'need to be activated'

     self.lasted = []

     self.begin = 0  

     self.end = 0


def _ calc(self):

     self.lasted = []

     self.prompt ='total'

     for index in range(6):

       self.lasted.append(self.stop[index] - self.start[index])

       if self.lasted[index]:

          self.prompt += (str(self.lasted[index]) + self.unit[index])

      #初始化变量

      self.begin = 0

      self.end = 0


#计时器对象相加,返回时间和

def _ _add_ _(self,other)

    prompt = "total"

    result = []

    for index in range(6):

        result.append(self.lasted[index] + other.lasted[index])

   if result[index]:

         prompt +=  (str(result.lasted[index]) + self.unit[index])

   return prompt

  



猜你喜欢

转载自blog.csdn.net/lwz45698752/article/details/79202961
今日推荐