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脚本生成随机IP的简单方法
Jul 30 Python
详解Python中最难理解的点-装饰器
Apr 03 Python
PyTorch学习笔记之回归实战
May 28 Python
Python使用tkinter库实现文本显示用户输入功能示例
May 30 Python
TensorFlow 滑动平均的示例代码
Jun 19 Python
Python tkinter label 更新方法
Oct 11 Python
python爬虫之自制英汉字典
Jun 24 Python
用python的turtle模块实现给女票画个小心心
Nov 23 Python
wxpython多线程防假死与线程间传递消息实例详解
Dec 13 Python
python文件处理fileinput使用方法详解
Jan 02 Python
五种Python转义表示法
Nov 27 Python
如何用 Python 子进程关闭 Excel 自动化中的弹窗
May 07 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实现生成透明背景的PNG缩略图函数分享
2014/07/08 PHP
PHP图像处理之imagecreate、imagedestroy函数介绍
2014/11/19 PHP
php+Ajax无刷新验证用户名操作实例详解
2019/03/04 PHP
alixixi runcode.asp的代码不错的应用
2007/08/08 Javascript
Javascript 原型和继承(Prototypes and Inheritance)
2009/04/01 Javascript
Prototype源码浅析 Enumerable部分之each方法
2012/01/16 Javascript
jQuery学习笔记之控制页面实现代码
2012/02/27 Javascript
JQuery入门—JQuery程序的代码风格详细介绍
2013/01/03 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
jQuery/CSS3图片特效插件整理推荐
2014/12/07 Javascript
Java中Timer的用法详解
2015/10/21 Javascript
深入浅析Bootstrap列表组组件
2016/05/03 Javascript
解析jQueryEasyUI的使用
2016/11/22 Javascript
jQuery实现手势解锁密码特效
2017/08/14 jQuery
vue-cli实现多页面多路由的示例代码
2018/01/30 Javascript
原生js添加一个或多个类名的方法分析
2019/07/30 Javascript
layui表格 列自动适应大小失效的解决方法
2019/09/06 Javascript
nodejs处理tcp连接的核心流程
2021/02/26 NodeJs
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
Python中使用摄像头实现简单的延时摄影技术
2015/03/27 Python
用Python从零实现贝叶斯分类器的机器学习的教程
2015/03/31 Python
pytorch dataloader 取batch_size时候出现bug的解决方式
2020/02/20 Python
Python爬虫爬取糗事百科段子实例分享
2020/07/31 Python
J2EE面试题集锦(附答案)
2013/08/16 面试题
如何进行有效的自我评价
2013/09/27 职场文书
项目开发计划书
2014/01/09 职场文书
计算机多媒体专业自荐信
2014/07/04 职场文书
优秀少先队辅导员事迹材料
2014/12/24 职场文书
预备党员入党感言
2015/08/01 职场文书
社区宣传标语口号
2015/12/26 职场文书
教师远程培训心得体会
2016/01/09 职场文书
关于拾金不昧的感谢信(五篇)
2019/10/18 职场文书
Python实现天气查询软件
2021/06/07 Python
Java实现二分搜索树的示例代码
2022/03/17 Java/Android
Python学习之包与模块详解
2022/03/19 Python
python微信智能AI机器人实现多种支付方式
2022/04/12 Python