python 魔法方法

1 魔法方法介绍

  • 是Python类与对象里的方法,之所以称之为魔法方法,是因为魔法方法总能在适当的时候Python调用,完成一定的功能

魔法方法具有一定的特征:

  • 该方法在重写时,两边总是被双下滑线包围,例如:__init__(self,*args):
  • Python因为有魔法方法而变得十分强大,魔法方法总能在适当的时候被调用

2 构造方法 __new__(cls[,...]):

 __new__(cls[,...])
  • 是第一个被执行的方法,它的第一个参数是一个类,大多情况下它不需要重写,Python会默认执行。当继承一个不可变的类的时候,又需要对其中的内容进行修改,则需修改该方法
class CapStr(str):
    def __new__(cls,string):  #修改新类里的new方法,需传入一个参数
        string = string.upper()
        return str.__new__(cls,string)   #用父类里的new方法进行返回,直接饭后构造后的对象
  • new()方法有返回值,它的返回值是类对象实例化出来的类,因此需要返回一个类
def __new__(self,*args,*kwargs):
	```
	return object.__new__(cls,*atgs,*kwargs)
  • 第一个参数 cls 是当前正在实例化的类,Python里的机制是:如果在新类中没有重写new()方法,Python会默认调用父类new()的方法来构造该类的实例。如果该类的父类也没有重写new()方法,那么会一直追溯到object类的new()方法,因为object类是所有类的基类
  • 如果新类中重写了new()方法,那么可以自由选择任何一个其他类的new方法类构造实例,但应该注意:在任何新式类的new()方法中,不能调用自身类的new方法来构造实例,这样会造成递归死循环

3 new()方法 与 init()方法的关系:

  • 在新的类开始实例化时,new()方法会返回cls的实例化对象,然后该类的init()方法作为构造方法会接受这个实例(即self)作为自己的第一个参数,再依次接收位置参数(args)和命名参数(kwargs)
  • new()方法为新类提供了实例化的框架,然后调用init()方法使其更加丰满

类的初始化方法:__init__(self,*args)

  • 类在初始化时自动调用该方法,可以实现对实例化类属性的修改self.value = value,其返回值为None,如果试图返回,则会报错:
TypeError: __init__() should return None

例如;

class Rectangle():
    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

4 删除对象的方法__del__(self)

  • 对象被删除时,该方法会被自动调用,Python里的垃圾回收机制自动清除内存。在所有指向该对象的变量名被删除时,del方法才会被调用,例如:
class C():
    def __init__(self):
        print("__init__方法被调用")
    def __del__(self):  #只有实例化后的对象被清理,__del__内置方法才被执行
        print("__del__方法被调用")
>>> c0 = C()
__init__方法被调用
>>> c1 = c0
>>> c2 = c0
>>> del c0
>>> del c1
>>> del c2       #最后一个指向对象的变量被删除,调用del方法
__del__方法被调用
  • 对于魔法方法,可以对其进行重写,以算数运算为例,其魔法方法有:
方法算数运算符
__ add__(self, other)定义加法的行为:+
__ sub__(self, other)定义减法的行为:-
__ mul__(self, other)定义乘法的行为:*
__ truediv__(self, other)定义真除法的行为:/
__ floordiv__(self, other)定义整数除法的行为://
__ mod__(self, other)定义取模算法的行为:%
__ divmod__(self, other)定义当被 divmod() 调用时的行为
__ pow__(self, other[, modulo])定义当被 power() 调用或 ** 运算时的行为
__ lshift__(self, other)定义按位左移位的行为:<<
__ rshift__(self, other)定义按位右移位的行为:>>
__ and__(self, other)定义按位与操作的行为:&
__ xor__(self, other)定义按位异或操作的行为:^
__ or__(self, other)定义按位或操作的行为:
  • 在Python2.2以前,类与类型是分开的两个概念,类是属性与方法的封装,而类型是整型、浮点型、字符串、布尔类型等等
  • 在以后的版本中,Python将他们进行了合并,即Python只有类的概念,将类型的概念也封装为类。Python封装的方式为把BIF改写为工厂函数,我们可以对类型进行重写,类重新定义类,

例如

class New_int(int):
    def __add__(self,other):
        return int.__sub__(self,other)  
    def __sub__(self,other):
        return int.__add__(self,other)
>>> a = New_int(2)
>>> b = New_int(3)
>>> a + b
-1
>>> a - b
5

代码执行的逻辑是:

  1. 首先把对象实例化,即 a , b 是实例化的对象
  2. 在进行二目运算符 + 时,Python会现找第一个对象的__add__方法,把实例化的对象传入,self = a,other = b
  3. 传入后递归寻找其父类的方法,最终使用了int.__sub__方法
  • 有时第一个对象并没有进行类的实例化,这是Python就会采用备用机制,找到第二个对象的方法,进行反运算
方法对应运算符
__ radd__(self, other)当左操作数不支持相应的操作时被调用
__ rsub__(self, other)当左操作数不支持相应的操作时被调用
__ rmul__(self, other)当左操作数不支持相应的操作时被调用
__ rtruediv__(self, other)当左操作数不支持相应的操作时被调用
__ rfloordiv__(self, other)当左操作数不支持相应的操作时被调用
__ rmod__(self, other)当左操作数不支持相应的操作时被调用
__ rdivmod__(self, other)当左操作数不支持相应的操作时被调用
__ rpow__(self, other)当左操作数不支持相应的操作时被调用
__ rlshift__(self, other)当左操作数不支持相应的操作时被调用
__ rrshift__(self, other)当左操作数不支持相应的操作时被调用
__ rand__(self, other)当左操作数不支持相应的操作时被调用
__ rxor__(self, other)当左操作数不支持相应的操作时被调用
__ ror__(self, other)当左操作数不支持相应的操作时被调用
>>> class Nint(int):
	def __radd__(self,other):
		return int.__sub__(self,other)
>>> b = Nint(2)
>>> 1 + b
1
>>> b + 1
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)定义赋值按位或操作的行为:

等等,Python提供了许多魔法方法,通过重写魔法方法,可以自由灵活地使用这门语言

5 引用

摘自鱼C论坛

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值