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中使用pngquant压缩png图片的教程
Apr 09 Python
python使用socket远程连接错误处理方法
Apr 29 Python
Python中return语句用法实例分析
Aug 04 Python
深入学习Python中的装饰器使用
Jun 20 Python
详解python里使用正则表达式的全匹配功能
Oct 19 Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 Python
Python装饰器使用你可能不知道的几种姿势
Oct 25 Python
在notepad++中实现直接运行python代码
Dec 18 Python
scrapy框架携带cookie访问淘宝购物车功能的实现代码
Jul 07 Python
Python延迟绑定问题原理及解决方案
Aug 04 Python
python使用matplotlib:subplot绘制多个子图的示例
Sep 24 Python
利用Python读取微信朋友圈的多种方法总结
Aug 23 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/07/08 PHP
php str_pad 函数用法简介
2009/07/11 PHP
PHP遍历XML文档所有节点的方法
2015/03/12 PHP
PHP实现对二维数组某个键排序的方法
2016/09/14 PHP
thinkPHP中volist标签用法示例
2016/12/06 PHP
做网页的一些技巧
2007/02/01 Javascript
jQuery实现类似滑动门切换效果的层切换
2013/09/23 Javascript
JS正则表达式获取分组内容的方法详解
2013/11/15 Javascript
javascript中定义类的方法汇总
2014/12/28 Javascript
浅谈AngularJS中ng-class的使用方法
2016/11/11 Javascript
Bootstrap php制作动态分页标签
2016/12/23 Javascript
深入理解Angular4订阅(Subscribe)与取消
2017/11/22 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题
2018/04/08 Javascript
jQuery md5加密插件jQuery.md5.js用法示例
2018/08/24 jQuery
javascript实现拖拽碰撞检测
2020/03/12 Javascript
JS使用for in有序获取对象数据
2020/05/19 Javascript
Vue 实现一个简单的鼠标拖拽滚动效果插件
2020/12/10 Vue.js
Python实现远程调用MetaSploit的方法
2014/08/22 Python
Python制作CSDN免积分下载器
2015/03/10 Python
对django后台admin下拉框进行过滤的实例
2019/07/26 Python
浅谈python3中input输入的使用
2019/08/02 Python
PyQt5 closeEvent关闭事件退出提示框原理解析
2020/01/08 Python
keras 如何保存最佳的训练模型
2020/05/25 Python
波兰补充商店:Muscle Power
2018/10/29 全球购物
Woods官网:加拿大最古老、最受尊敬的户外品牌之一
2020/09/12 全球购物
自我介绍演讲稿
2014/01/15 职场文书
大学社团活动策划书
2014/01/26 职场文书
八项规定整改方案
2014/02/21 职场文书
酒店管理毕业生自我鉴定
2014/03/02 职场文书
党员学习群众路线心得体会
2014/11/04 职场文书
安全保证书
2015/01/16 职场文书
技术员个人工作总结
2015/03/03 职场文书
2015年庆祝国庆节66周年演讲稿
2015/07/30 职场文书
Python torch.flatten()函数案例详解
2021/08/30 Python
Windows11性能真的上涨35%? 桌面酷睿i9实测结果公开
2021/11/21 数码科技