Python的类实例属性访问规则探讨


Posted in Python onJanuary 30, 2015

一般来说,在Python中,类实例属性的访问规则算是比较直观的。

但是,仍然存在一些不是很直观的地方,特别是对C++和Java程序员来说,更是如此。

在这里,我们需要明白以下几个地方:

1.Python是一门动态语言,任何实体都可以动态地添加或删除属性。
2.一个类定义了一个作用域。
3.类实例也引入了一个作用域,这与相应类定义的作用域不同。
4.在类实例中查找属性的时候,首先在实例自己的作用域中查找,如果没有找到,则再在类定义的作用域中查找。
5.在对类实例属性进行赋值的时候,实际上会在类实例定义的作用域中添加一个属性(如果还不存在的话),并不会影响到相应类中定义的同名属性。

下面看一个例子,加深对上述几点的理解:

class A:

      cls_i = 0

      cls_j = {}

      def __init__(self):

            self.instance_i = 0

            self.instance_j = {}

在这里,我们先定义类A的一个实例a,然后再看看类A的作用域和实例a的作用域中分别有什么:
>>> a = A()

>>> a.__dict__

{'instance_j': {}, 'instance_i': 0}

>>> A.__dict__

{'__init__': , '__module__': '__main__', 'cls_i': 0, 'cls_j': {}, '__doc__': None}

我们看到,a的作用域中有instance_i和instance_j,A的作用域中有cls_i和cls_j。

我们再来看看名字查找是如何发生的:

>>> a.cls_i

0

>>> a.instance_i

0

在查找cls_i的时候,实例a的作用域中是没有它的,却在A的作用域中找到了它;在查找instance_i的时候,直接可在a的作用域中找到它。

如果我们企图通过实例a来修改cls_i的值,那会怎样呢:

>>> a.cls_i = 1

>>> a.__dict__

{'instance_j': {}, 'cls_i': 1, 'instance_i': 0}

>>> A.__dict__

{'__init__': , '__module__': '__main__', 'cls_i': 0, 'cls_j': {}, '__doc__': None}

我们可以看到,a的作用域中多了一个cls_i属性,其值为1;同时,我们也注意到A作用域中的cls_i属性的值仍然为0;在这里,我们其实是增加了一个实例属性,并没有修改到类属性。

如果我们通过实例a操纵cls_j中的数据(注意不是cls_j本身),又会怎么样呢:

>>> a.cls_j['a'] = 'a'

>>> a.__dict__

{'instance_j': {}, 'cls_i': 1, 'instance_i': 0}

>>> A.__dict__

{'__init__': , '__module__': '__main__', 'cls_i': 0, 'cls_j': {'a': 'a'}, '__doc__': None}

我们可以看到a的作用域没有发生什么变化,但是A的作用域发生了一些变化,cls_j中的数据发生了变化。

实例的作用域发生变化,并不会影响到该类的其它实例,但是类的作用域发生变化,则会影响到该类的所有实例,包括在这之前创建的实例:

>>> A.cls_k = 0

>>> i.cls_k

0
Python 相关文章推荐
Python实现的检测网站挂马程序
Nov 30 Python
Python Web框架Flask中使用百度云存储BCS实例
Feb 08 Python
python学习之编写查询ip程序
Feb 27 Python
go和python变量赋值遇到的一个问题
Aug 31 Python
Python实现二叉树的常见遍历操作总结【7种方法】
Mar 06 Python
对Django中的权限和分组管理实例讲解
Aug 16 Python
Numpy之reshape()使用详解
Dec 26 Python
Python如何通过Flask-Mail发送电子邮件
Jan 29 Python
基于python修改srt字幕的时间轴
Feb 03 Python
Python 统计位数为偶数的数字代码详解
Mar 15 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
Jul 09 Python
Cpython解释器中的GIL全局解释器锁
Nov 09 Python
Python中的作用域规则详解
Jan 30 #Python
Python中使用Boolean操作符做真值测试实例
Jan 30 #Python
Python中的zip函数使用示例
Jan 29 #Python
Python的另外几种语言实现
Jan 29 #Python
python中使用xlrd、xlwt操作excel表格详解
Jan 29 #Python
Python中实现常量(Const)功能
Jan 28 #Python
Python使用random和tertools模块解一些经典概率问题
Jan 28 #Python
You might like
PHP生成静态页面详解
2006/11/19 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
php遍历删除整个目录及文件的方法
2015/03/13 PHP
yii用户注册表单验证实例
2015/12/26 PHP
php redis实现文章发布系统(用户投票系统)
2017/03/04 PHP
PHP实现的折半查找算法示例
2017/12/19 PHP
PHP抽象类基本用法示例
2018/12/28 PHP
js 替换功能函数,用正则表达式解决,js的全部替换
2010/12/08 Javascript
基于jquery的分页控件(C#)
2011/01/06 Javascript
获取元素距离浏览器周边的位置的方法getBoundingClientRect
2013/04/17 Javascript
javascript截取字符串小结
2015/04/28 Javascript
jquery简单实现带渐显效果的选项卡菜单代码
2015/09/01 Javascript
jQuery操作属性和样式详解
2016/04/13 Javascript
javascript使用 concat 方法对数组进行合并的方法
2016/09/08 Javascript
Vue.js中兄弟组件之间互相传值实例
2017/06/01 Javascript
微信小程序使用Promise简化回调
2018/02/06 Javascript
Angular8 简单表单验证的实现示例
2020/06/03 Javascript
Vue路由切换页面不更新问题解决方案
2020/07/10 Javascript
vue使用echarts图表自适应的几种解决方案
2020/12/04 Vue.js
如何使用原生Js实现随机点名详解
2021/01/06 Javascript
python pyheatmap包绘制热力图
2018/11/09 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
Python TCPServer 多线程多客户端通信的实现
2019/12/31 Python
python不使用for计算两组、多个矩形两两间的iou方式
2020/01/18 Python
简单了解Python多态与属性运行原理
2020/06/15 Python
基于python爬取链家二手房信息代码示例
2020/10/21 Python
HTML5 Web 存储详解
2016/09/16 HTML / CSS
Bibloo奥地利:购买女装、男装、童装、鞋和配件
2018/10/18 全球购物
什么叫做SQL注入,如何防止
2016/10/04 面试题
责任胜于能力演讲稿
2014/05/20 职场文书
运动会400米加油稿(8篇)
2014/09/22 职场文书
2015年文明创建工作总结
2015/04/30 职场文书
圣诞晚会主持词开场白
2015/05/28 职场文书
高老头读书笔记
2015/06/30 职场文书
Mysql 文件配置解析介绍
2022/05/06 MySQL
MySQL 语句执行顺序举例解析
2022/06/05 MySQL