DW学习-Python基础11(魔法方法)

本文介绍了Python中的魔法方法,包括__init__、__new__、__str__、__repr__等初始化方法,详细阐述了它们的作用和执行流程。接着讨论了魔法运算方法,如__add__、__sub__、__mul__等,用于自定义对象的算术运算行为。此外,还涵盖了增量赋值运算符和一元运算符的相关魔法方法。最后,提出了利用魔法方法设计一个简单的定时器类的习题。
摘要由CSDN通过智能技术生成

1基本的魔术方法

1.1__init__

  • 语法:__init__(self[, ...])
  • 作用:
    • 1 会在调用类时自动触发执行,用来为对象初始化自己独有的数据
    • 2 __init__内应该存放的是为对象初始化属性的功能,但是也可以存放其他代码,想要在类调用时就立刻执行
    • 3 __init方法必须返回对象
  • 解释:当对象调用类时,__init__(self[, ...])会自动被触发,Python会自动将当前调用的空对象传给self参数。
  • 过程:
    • 1 先产生一个空对象,调用类内的__new__方法
    • 2 python会自动调用类中的__init__方法,然后将空对象和已经调用类时括号里传入的参数,一同传给__init__
    • 3 返回初始化好的对象
  • 注意:__init__(self[, ...])不能返回什么值,返回的是None。
class Rec:
    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
rect=Rec(3,4) # 将rect这个对象传给self
print(rect.getPeri()) # 14
print(rect.getArea())	# 12

1.2__new__

  • 语法:__new__(cls[, ...])
    • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__
  • 过程:
    • __new__对当前类进行了实例化,并将实例返回,传给__init__self
    • 但是,执行了__new__,并不一定会进入__init__,只有__new__返回了值,当前类cls的实例,当前类的__init__才会进入。
  • 作用:构造方法。__new__是在一个对象实例化的时候所调用的第一个方法,在调用__init__初始化前,先调用__new__
class A:
    # 构造方法,创建一块对象的空间,有一个指针能指向类--》__new__
    def __new__(cls, *args, **kwargs): 
        o=super().__new__(cls)
        print('执行new',o)
        return o
    def __init__(self):
        print('执行init',self)
A()
# 执行new <__main__.A object at 0x000001C29AD65F40>
# 执行init <__main__.A object at 0x000001C29AD65F40>

1.3__str__和__repr__

1__str__

  • 当你打印一个对象的时候,触发__str__
  • 当你使用%s格式化的时候,触发__str__
  • str强转数据类型的时候,触发__str__

2__repr__

  • reprstr的备胎
  • __str__的时候执行__str__,没有实现__str__的时候,执行__repr__
  • repr(obj)内置函数对应的结果是__repr__的返回值
  • 当你使用%r格式化的时候 触发__repr__
class p:
    def __init__(self):
        self.student=[]
    def append(self,name):
        self.student.append(name)

py22=p()
print(py22)	# <__main__.p object at 0x00000252BC1A49D0>
py22.append('jaja')
print(py22)	# <__main__.p object at 0x00000252BC1A49D0>
-------------------------------------
class p:
    def __init__(self):
        self.student=[]
    def append(self,name):
        self.student.append(name)
    def __str__(self):
        return str(self.student)

py22=p()
print(py22)	# []
py22.append('jaja')
print(py22)	# ['jaja']

1.4__del__

  • 作用:析构器,当一个对象将要被系统回收时调用的方法
class C(object):
    def __init__(self):
        print('into C __init__')

    def __del__(self):
        print('into C __del__')
c1 = C()
# into C __init__
c2 = c1
c3 = c2
del c3
del c2
del c1
# into C __del__

2 魔法运算:算数运算

2.1__add__和__sub__

  • __add__(self,other):定义加法的行为
  • __add__(self,other):定义减法的行为
class A(int):
    def __add__(self, other):
        return int.__add__(self,other)
    def __sub__(self, other):
        return int.__sub__(self, other)
a=A(2)
b=A(3)
print(a+b)	# 5
print(a-b)	# -1

2.2其他魔法方法

  • __mul__(self, other)定义乘法的行为:*
  • __truediv__(self, other)定义真除法的行为:/
  • __floordiv__(self, other)定义整数除法的行为://
  • __mod__(self, other) 定义取模算法的行为:%
  • __divmod__(self, other)定义当被 divmod() 调用时的行为
    • divmod(a, b)把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
    print(divmod(7, 2))  # (3, 1)
    print(divmod(8, 2))  # (4, 0)
    
  • __pow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
  • __lshift__(self, other)定义按位左移位的行为:<<
  • __rshift__(self, other)定义按位右移位的行为:>>
  • __and__(self, other)定义按位与操作的行为:&
  • __xor__(self, other)定义按位异或操作的行为:^
  • __or__(self, other)定义按位或操作的行为:|

2.3反运算

反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔法方法多了一个“r”。当文件左操作不支持相应的操作时被调用。

  • __radd__(self, other)定义加法的行为:+
  • __rsub__(self, other)定义减法的行为:-
  • __rmul__(self, other)定义乘法的行为:*
  • __rtruediv__(self, other)定义真除法的行为:/
  • __rfloordiv__(self, other)定义整数除法的行为://
  • __rmod__(self, other) 定义取模算法的行为:%
  • __rdivmod__(self, other)定义当被 divmod() 调用时的行为
  • __rpow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
  • __rlshift__(self, other)定义按位左移位的行为:<<
  • __rrshift__(self, other)定义按位右移位的行为:>>
  • __rand__(self, other)定义按位与操作的行为:&
  • __rxor__(self, other)定义按位异或操作的行为:^
  • __ror__(self, other)定义按位或操作的行为:|

a + b
这里加数是a,被加数是b,因此是a主动,反运算就是如果a对象的__add__()方法没有实现或者不支持相应的操作,那么 Python 就会调用b__radd__()方法。

class Nint(int):
    def __radd__(self, other):
        return int.__sub__(other, self) # 注意 self 在后面
a = Nint(5)
b = Nint(3)
print(a + b)  # 没有调用__radd__方法
# 8 
print(1 + b) # 没有找到1的__add__方法,只找到b的__radd__方法
# -2 

3增量赋值运算符

  • __iadd__(self, other)定义赋值加法的行为:+=
  • __isub__(self, other)定义赋值减法的行为:-=
  • __imul__(self, other)定义赋值乘法的行为:*=
  • __itruediv__(self, other)定义赋值真除法的行为:/=
  • __ifloordiv__(self, other)定义赋值整数除法的行为://=
  • __imod__(self, other)定义赋值取模算法的行为:%=
  • __ipow__(self, other[, modulo])定义赋值幂运算的行为:**=
  • __ilshift__(self, other)定义赋值按位左移位的行为:<<=
  • __irshift__(self, other)定义赋值按位右移位的行为:>>=
  • __iand__(self, other)定义赋值按位与操作的行为:&=
  • __ixor__(self, other)定义赋值按位异或操作的行为:^=
  • __ior__(self, other)定义赋值按位或操作的行为:|=

4一元运算符

  • __neg__(self)定义正号的行为:+x
  • __pos__(self)定义负号的行为:-x
  • __abs__(self)定义当被abs()调用时的行为
  • __invert__(self)定义按位求反的行为:~x

6 习题

1、上面提到了许多魔法方法,如__new__,__init__, __str__,__rstr__,__getitem__,__setitem__等等,请总结它们各自的使用方法。

  • __init__:构造器,当一个实例被创建的时候调用的初始化方法
  • __new__:返回一个实例对象,__new__方法返回类的实例对象,这个实例对象传给__int__方法中定义的self参数。若__new__方法返回None,则不会调用__init__方法。
  • __str__:当你打印一个对象的时候,或者当你使用%s格式化的时候,str强转数据类型的时候,会触发__str__
  • __rstr__:反运算的魔法方法多了一个“r”。当文件左操作不支持相应的操作时被调用。
  • __getitem__:定义获取容器中元素的行为,相当于self[key]
  • __setitem__:定义设置容器中指定元素的行为,相当于self[key] = value

2、利用python做一个简单的定时器类
要求:

  • 定制一个计时器的类。
  • startstop方法代表启动计时和停止计时。
  • 假设计时器对象t1print(t1)和直接调用t1均显示结果。
  • 当计时器未启动或已经停止计时时,调用stop方法会给予温馨的提示。
  • 两个计时器对象可以进行相加:t1+t2
  • 只能使用提供的有限资源完成。
import time


class Mytime(object):
   def __init__(self):
       self.__info = '未开始计时!'
       self.__begin = None
       self.__end = None
       self.__jg = 0

   def __str__(self):
       return self.__info

   def __repr__(self):
       return self.__info

   def start(self):
       print('计时开始...')
       self.__begin = time.localtime()

   def stop(self):
       if not self.__begin:
           print('提示:请先调用start()开始计时!')
           return
       self.__end = time.localtime()
       self.__jg = time.mktime(self.__end) - time.mktime(self.__begin)
       self.__info = '共运行了%d秒' % self.__jg
       print('计时结束!')
       return self.__jg

   def __add__(self, other):
       return '共运行了%d秒' % (other.__jg + self.__jg)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值