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 07 Python
在Django的通用视图中处理Context的方法
Jul 21 Python
Python程序中设置HTTP代理
Nov 06 Python
python、java等哪一门编程语言适合人工智能?
Nov 13 Python
Python实现朴素贝叶斯分类器的方法详解
Jul 04 Python
python批量创建指定名称的文件夹
Mar 21 Python
python3+PyQt5 使用三种不同的简便项窗口部件显示数据的方法
Jun 17 Python
django框架面向对象ORM模型继承用法实例分析
Jul 29 Python
python 实现屏幕录制示例
Dec 23 Python
python关于变量名的基础知识点
Mar 03 Python
python openssl模块安装及用法
Dec 06 Python
安装不同版本的tensorflow与models方法实现
Feb 20 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
全国FM电台频率大全 - 5 内蒙古自治区
2020/03/11 无线电
《PHP编程最快明白》第四讲:日期、表单接收、session、cookie
2010/11/01 PHP
php随机获取金山词霸每日一句的方法
2015/07/09 PHP
PHP读取文件内容的五种方式
2015/12/28 PHP
curl 出现错误的调试方法(必看)
2017/02/13 PHP
Jquery 实现表格颜色交替变化鼠标移过颜色变化实例
2013/08/28 Javascript
Jquery之Bind方法参数传递与接收的三种方法
2014/06/24 Javascript
使用jquery 简单实现下拉菜单
2015/01/14 Javascript
解决jquery插件:TypeError:$.browser is undefined报错的方法
2015/11/21 Javascript
jQGrid动态填充select下拉框的选项值(动态填充)
2016/11/28 Javascript
js事件冒泡与事件捕获详解
2017/02/20 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
微信小程序实现红包雨功能
2018/07/11 Javascript
微信小程序wx.getUserInfo授权获取用户信息(头像、昵称)的实现
2020/08/19 Javascript
jquery实现简单每周轮换的日历
2020/09/10 jQuery
node使用async_hooks模块进行请求追踪
2021/01/28 Javascript
[27:28]Ti4 冒泡赛第二天 iG vs NEWBEE 1
2014/07/15 DOTA
Python中pip安装非PyPI官网第三方库的方法
2015/06/02 Python
Python网站验证码识别
2016/01/25 Python
TensorFlow实现模型评估
2018/09/07 Python
对python的unittest架构公共参数token提取方法详解
2018/12/17 Python
python3去掉string中的标点符号方法
2019/01/22 Python
使用Python操作FTP实现上传和下载的方法
2019/04/01 Python
css3实现动画的三种方式
2020/08/24 HTML / CSS
欧洲最大的球衣网上商店:Kitbag
2017/11/11 全球购物
init进程的作用
2015/08/20 面试题
Python是如何进行类型转换的
2013/06/09 面试题
JAVA程序设计笔试题面试题一套
2015/07/28 面试题
《称象》教学反思
2014/04/25 职场文书
师范学院毕业生求职信
2014/06/24 职场文书
老人再婚离婚协议书范本
2014/10/27 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
交通安全学习心得体会
2016/01/18 职场文书
教师实习自我鉴定总结
2019/08/20 职场文书
mysql 8.0.24 安装配置方法图文教程
2021/05/12 MySQL
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android