杂:Python中的__setattr__修改大法

setattr(self, item, value):
当试图对对象的item特性赋值的时候将会被调用。
我们在编程当中如果对__setattr__这一方法进行操作修改的时候,有时候会造成无限递归。

class Mutilate:
    def __init__(self,a=0,b=0):
        self.a = a
        self.b = b

    def __setattr__(self,name,value):
        if name == 'square':
            self.a = value
            self.b = value
        else:
            self.name = value
            #super().__setattr__(name,value)

    def getresult(self):
        return self.a * self.b

这里以一个乘法为例子,当我们输入:r1=Mutilate(10,20)企图计算10*20的时候,在命令行会返回我们无限递归的错误。
在这里插入图片描述
我们来看一下上述的源代码:
在我们对a,b赋值的时候,程序转到的是def__setattr__中的if-else语句中的else语句,即self.name = value。这里的赋值“=”又会让程序重新跳到__setattr__这里,那么就会继续执行def__setattr__中的if语句内的else语句,即self.name = value。所以这样写程序便会跳到无限递归里面,在命令行操作就会出现红色提醒的错误。

我们可以对程序的else语句内赋值语句重新修改,这里介绍super()函数,这个函数可以保存继承的父类的属性。具体操作如下:

class Mutilate:
    def __init__(self,a=0,b=0):
        self.a = a
        self.b = b

    def __setattr__(self,name,value):
        if name == 'square':
            self.a = value
            self.b = value
        else:
            super().__setattr__(name,value)

    def getresult(self):
        return self.a * self.b

运行结果如下图所示:
在这里插入图片描述
我们在给予a,b初始值2和9之后,由于name !=‘square’,因此直接进入else循环语句,这样第一个name=a,此时value=2,把2赋值给a,第二次进入后name = b,此时value =9,将9赋值给b。最后执行getresult语句,得到二者的乘积。
如果我们声明了类型是’square’后,会出现下列的结果:
在这里插入图片描述
这里程序先进入if的判断,然后进入self.a = value。此时注意!!!程序在执行赋值的时候重新进入了 __setattr__语句当中,但这个时刻,name已经是a了,所以第二次又进入了else语句当中,将value(值为9)赋给name(此时是a),完成了第一次赋值。b的赋值过程类似于a,这里就不细说了。

总结:Python中的__setattr__同一般类型的函数不同,这个函数属于基础的函数,因此在对它进行加工的时候要千万小心赋值语句的使用。应当注意:改变不能乱编!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值