• 第7.25节 Python案例详解:使用property函数定义与实例变量同名的属性会怎样?


    第7.25节 Python案例详解:使用property函数定义与实例变量同名的属性会怎样?

    一、    案例说明
    我们上节提到了,使用property函数定义的属性不要与类内已经定义的普通实例变量重名,如果是重名会发生什么呢?本案例通过这个例子一是说明重名可能产生的后果,也想说明property定义属性在类内访问会遇到什么情况。
    为了直接说明问题,本案例还是以上节的Rectangle为例,不过去掉了大部分属性和方法,只留下了可以说明问题的必要代码。
    二、    案例代码
    1.    定义类,类体内定义了实例变量self.length,并定义了类的构造方法、setLen、getLen方法;

    class Rectangle():
       def __init__(self,length,width): self.width,self.length = width,length
       def setLen(self,length):
           print("execute setLen")
           self.length=length
       def getLen(self):
           print("execute getLen")
           return self.length


    2.    通过property定义属性length,这个属性被设置成可读写的,与实例变量self.length变量名相同;   

    length = property(getLen, setLen,None,'长方形的长')

    3.    定义实例对象

    rect = Rectangle(5,3)

    执行后,我们看到系统不停的输出“execute setLen”,重复很多次后报“RecursionError: maximum recursion depth exceeded while pickling an object”。部分执行截图:
     


     
    三、    案例问题分析
    1.    原因分析
    对这个问题老猿初略分析原因如下:
    1)    从上述报错信息可以看出,报错是因为定义实例变量执行构造函数对实例变量self.length赋值时触发了setLen方法,而setLen又会执行self.length赋值导致setLen不停递归调用,最终导致资源耗尽才终止;
    2)    为什么self.length的赋值会触发setLen调用呢,肯定是因为自定义属性与实例变量同名导致的。但为什么会这样老猿没有明白,详见下面老猿的疑惑。
    2.    老猿的疑惑
    为什么定义属性与实例变量同名就会触发递归调用?老猿暂时无法深入分析,在这有两个问题老猿没有弄明白:
    1)    property定义的实例属性,其定义语句是在类体中执行的,按理来说这个定义的实例属性是类变量,其类型比较特殊,是property类型,但根据这个实例属性的访问情况来看是通过实例访问,并且不同实例对象之间互不干扰的,因此这个实例属性应该不是类变量,这个不知道property是怎么实现的?
    2)    第二个问题是property类型主要有什么属性,可以让它和实例变量关联,我们知道它有四个参数,其中三个方法会被property的 getter(), setter()和delete()所使用,但是哪个属性记录了这些方法访问的实例?
    本节介绍了使用property定义与实例变量相同的属性,发现这种定义会导致程序触发递归调用而异常退出,这说明:
    1、    不能使用property定义与实例变量同名的实例属性;
    2、    实例属性定义后任何在类内和类外的访问都会触发相关方法执行,因此在访问该属性时一定要注意,防止出现本例类似的递归调用。
    老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
    欢迎大家批评指正,谢谢大家关注!

  • 相关阅读:
    抓老鼠啊,亏了还是赚了
    币值转换
    2019春第七周作业
    2019春第六周作业
    2019春第五周作业
    2019年春季学期第四周作业
    2019年春季学期第三周作业
    2019年春季学期第二周作业
    在人生路上对我影响最大的三位老师
    第七周作业
  • 原文地址:https://www.cnblogs.com/LaoYuanPython/p/11087689.html
Copyright © 2020-2023  润新知