第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的世界。

欢迎大家批评指正,谢谢大家关注!

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

  1. 第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter

    上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一.    案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...

  2. 第7.24节 Python案例详解:使用property函数定义属性简化属性访问代码实现

    第7.24节 Python案例详解:使用property函数定义属性简化属性访问代码实现 一.    案例说明 本节将通过一个案例介绍怎么使用property定义快捷的属性访问.案例中使用Rectan ...

  3. 第8.22节 Python案例详解:重写 “富比较”方法控制比较逻辑

    一. 案例说明 本节定义一个小汽车的类Car,类中包括车名carname.百公里油耗oilcostper100km.价格price三个属性.然后实现__lt__.__gt__.__le__.__ge_ ...

  4. Python使用property函数定义的属性名与其他实例变量重名会怎么样?

    首先如果定义的属性名与该属性对应的操作方法操作的实例对象同名就会触发无穷的递归调用,相关部分请参考<Python案例详解:使用property函数定义与实例变量同名的属性会怎样?> 但如果 ...

  5. Python使用property函数定义属性访问方法如果不定义fget会怎么样?

    我们知道Python使用property函数定义属性访问方法时的语法如下: 实例属性=property(fget=None, fset=None, fdel=None, doc=None) 而是要@p ...

  6. 第7.23节 Python使用property函数定义属性简化属性访问的代码实现

    第7.23节 Python使用property函数定义属性简化属性访问的代码实现 一.    背景       在本章前面章节中,我们介绍了类相关的知识,并举例进行了说明,在这些例子中会定义一些形如 ...

  7. 第7.20节 案例详解:Python抽象类之真实子类

    第7.20节 案例详解:Python抽象类之真实子类 上节介绍了Python抽象基类相关概念,并介绍了抽象基类实现真实子类的步骤和语法,本节结合一个案例进一步详细介绍. 一.    案例说明 本节定义 ...

  8. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  9. 第7.16节 案例详解:Python中classmethod定义的类方法

    第7.16节  案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一.    案例说明 本节定义的一个 ...

随机推荐

  1. C++变量的存储类型

    C++变量和函数包括两个属性:数据类型和数据的存储类型.存储类型是指数据在内存中存储的方式.变量的存储类型分为四种:自动类型(auto),寄存器类型(register).静态类型(static)外部类 ...

  2. .net core中的哪些过滤器

    前言 书承接上文,咱们上回说到,.net core中各种日志框架, 今天我讲讲.net core中的内置过滤器吧! 1.什么是过滤器? ASP.NET Core中的筛选器允许代码在请求处理管道中的特定 ...

  3. 重置GrindConrol焦点行FocusedRowHandle

    List<model> list=this.CurrentList; var selectModel=tempselectmodel; //找selectModel在list中得位置 va ...

  4. 总结distinct、group by 、row_number()over函数用法及区别

    distinct和group by 是一样的,查询去重,只能是全部重复的,也可以理解为针对单例,因为一行有一个字段不一样,他们就会认为这两行内容是不重复的.但是使用row_number()over这个 ...

  5. 2w+长文带你剖析ConcurrentHashMap~!

    并发编程实践中,ConcurrentHashMap是一个经常被使用的数据结构,相比于Hashtable以及Collections.synchronizedMap(),ConcurrentHashMap ...

  6. Linux(centos6.8)配置Tomcat环境

    1.下载Linux版的Tomcat包 (1)通过官方下载 tomcat官方:https://tomcat.apache.org/download-80.cgi (2)通过分享下载 如网盘分享等途径 2 ...

  7. 玩转 Comparator 和 Comparable 两接口

    最近项目中有排序的需求,就查看了一下Java文档,发现有两个接口都可以进行排序,Comparable 和 Comparator 两接口到底有啥区别?何时用?怎么用?使用场景我都在底下一一研究分享出来: ...

  8. mysql学习——数据表基本操作1

    选择数据库 创建数据表 包括字段名和数据类型两部分 查看数据表 使用主键约束 主键又称主码,能够唯一的表示表中的一条记录,分为单字段主键与多字段联合主键 单字段主键 定义主键的两种方式: 1.在最后指 ...

  9. YARN-MapReduce的作业提交流程

    YARN分布式资源管理系统 组成: ResourceManager:YARN的资源管理器,主节点,通过NodeManager管理集群中所有的资源 NodeManager:YARN的节点管理器,从节点, ...

  10. 20-SAP PI开发手册-ERP发布服务供外部系统调用(sproxy代理类)

    一.      接口内容 接口详细信息 1.  字段对应关系 发送字段对应关系 返回字段对应关系 2.  报文信息 传入报文(报文结构,外围系统提供) 1 <?xml version=" ...