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 获取文件列表(或是目录例表)
Mar 25 Python
Django自定义认证方式用法示例
Jun 23 Python
Python及PyCharm下载与安装教程
Nov 18 Python
使用tensorflow实现AlexNet
Nov 20 Python
tensorflow: variable的值与variable.read_value()的值区别详解
Jul 30 Python
详解python中Numpy的属性与创建矩阵
Sep 10 Python
Python3中编码与解码之Unicode与bytes的讲解
Feb 28 Python
python实现对输入的密文加密
Mar 20 Python
django的model操作汇整详解
Jul 26 Python
VSCode中自动为Python文件添加头部注释
Nov 14 Python
浅谈tensorflow之内存暴涨问题
Feb 05 Python
Python 阶乘详解
Oct 05 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 str_pad 函数用法简介
2009/07/11 PHP
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
Drupal 添加模块出现莫名其妙的错误的解决方法(往往出现在模块较多时)
2011/04/18 PHP
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
PHP7匿名类用法分析
2016/09/26 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
2017/03/25 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
javascript中RegExp保留小数点后几位数的方法分享
2013/08/13 Javascript
浏览器页面区域大小的js获取方法
2013/09/21 Javascript
利用JavaScript阻止表单提交的两种方法
2016/08/11 Javascript
jquery easyui DataGrid简单示例
2017/01/23 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
2017/08/15 Javascript
JS实现匀加速与匀减速运动的方法示例
2017/09/04 Javascript
Vue父子模版传值及组件传值的三种方法
2017/11/27 Javascript
js中getter和setter用法实例分析
2018/08/14 Javascript
Vue 路由切换时页面内容没有重新加载的解决方法
2018/09/01 Javascript
vue2中引用及使用 better-scroll的方法详解
2018/11/15 Javascript
JS如何在不同平台实现多语言方式
2020/07/16 Javascript
详解vue父子组件状态同步的最佳方式
2020/09/10 Javascript
Python中创建字典的几种方法总结(推荐)
2017/04/27 Python
Python 编码规范(Google Python Style Guide)
2018/05/05 Python
Python matplotlib的使用并自定义colormap的方法
2018/12/13 Python
pyhanlp安装介绍和简单应用
2019/02/22 Python
提升Python程序性能的7个习惯
2019/04/14 Python
对django 模型 unique together的示例讲解
2019/08/06 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
Python 程序员必须掌握的日志记录
2020/08/17 Python
CSS3制作圆角图片和椭圆形图片
2016/07/08 HTML / CSS
幼师自我鉴定范文
2013/10/01 职场文书
经典优秀个人求职信分享
2013/12/12 职场文书
公益活动策划方案
2014/01/09 职场文书
校园活动宣传方案
2014/03/28 职场文书
药品业务员岗位职责
2014/04/17 职场文书
委托书怎么写
2014/07/31 职场文书
土木工程生产实习心得体会
2016/01/22 职场文书
靠谱的活动总结
2019/04/16 职场文书