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中用PIL库批量给图片加上序号的教程
May 06 Python
Python运算符重载用法实例分析
Jun 01 Python
用Python写一个无界面的2048小游戏
May 24 Python
python获取指定时间差的时间实例详解
Apr 11 Python
Python Selenium 之数据驱动测试的实现
Aug 01 Python
基于python的selenium两种文件上传操作实现详解
Sep 19 Python
Python 从attribute到property详解
Mar 05 Python
推荐值得学习的12款python-web开发框架
Aug 10 Python
Pycharm 如何一键加引号的方法步骤
Feb 05 Python
python神经网络编程之手写数字识别
May 08 Python
pytorch 权重weight 与 梯度grad 可视化操作
Jun 05 Python
如何使用pdb进行Python调试
Jun 30 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连接MySQL代码的参数说明
2008/06/07 PHP
调试PHP程序的多种方法介绍
2014/11/06 PHP
10个超级有用值得收藏的PHP代码片段
2015/01/22 PHP
PHP查看当前变量类型的方法
2015/07/31 PHP
phplist及phpmailer(组合使用)通过gmail发送邮件的配置方法
2016/03/30 PHP
php each 返回数组中当前的键值对并将数组指针向前移动一步实例
2016/11/22 PHP
发布BlueShow v1.0 图片浏览器(类似lightbox)blueshow.js 打包下载
2007/07/21 Javascript
js一组验证函数
2008/12/20 Javascript
jquery 常用操作整理 基础入门篇
2009/10/14 Javascript
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
2013/12/04 Javascript
js设置文本框中焦点位置在最后的示例代码(简单实用)
2014/03/04 Javascript
jQuery仿天猫实现超炫的加入购物车
2015/05/04 Javascript
前端框架Vue.js构建大型应用浅析
2016/09/12 Javascript
详解webpack+angular2开发环境搭建
2017/06/28 Javascript
jQuery选择器之属性过滤选择器详解
2017/09/28 jQuery
nodejs中express入门和基础知识点学习
2018/09/13 NodeJs
VUE项目初建和常见问题总结
2019/09/12 Javascript
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
[49:08]Secret vs VP 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python中还原JavaScript的escape函数编码后字符串的方法
2014/08/22 Python
Python中List.index()方法的使用教程
2015/05/20 Python
Ubuntu下安装PyV8
2016/03/13 Python
对pandas的dataframe绘图并保存的实现方法
2017/08/05 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
Python 用matplotlib画以时间日期为x轴的图像
2019/08/06 Python
python 申请内存空间,用于创建多维数组的实例
2019/12/02 Python
Keras loss函数剖析
2020/07/06 Python
英国高档时尚男装购物网站:MR PORTER
2016/08/09 全球购物
adidas爱尔兰官方网站:阿迪达斯运动鞋和运动服
2019/11/01 全球购物
酒店经理职责
2014/01/30 职场文书
初中英语教师个人工作总结
2015/02/09 职场文书
莫言诺贝尔获奖感言(全文)
2015/07/31 职场文书
如何写好活动总结
2019/06/21 职场文书
用javascript制作qq注册动态页面
2021/04/14 Javascript
HTML CSS 一个标签实现带动画的抖音LOGO
2022/04/26 HTML / CSS