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 除法小技巧
Sep 06 Python
python教程之用py2exe将PY文件转成EXE文件
Jun 12 Python
Python中splitlines()方法的使用简介
May 20 Python
python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法
May 24 Python
Python实现学生成绩管理系统
Apr 05 Python
解决Python2.7读写文件中的中文乱码问题
Apr 12 Python
详解pandas的外部数据导入与常用方法
May 01 Python
pycharm如何实现跨目录调用文件
Feb 28 Python
Python3中的f-Strings增强版字符串格式化方法
Mar 04 Python
python实现同一局域网下传输图片
Mar 20 Python
python实现简单遗传算法
Sep 18 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
Sep 28 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
相对路径转化成绝对路径
2007/04/10 PHP
一个PHP数组应该有多大的分析
2009/07/30 PHP
PHP 生成的XML以FLASH获取为乱码终极解决
2009/08/07 PHP
PHP CURL模拟GET及POST函数代码
2010/04/25 PHP
PHP使用POP3读取邮箱接收邮件的示例代码
2020/07/08 PHP
关于文本框的一些限制控制总结~~
2010/04/15 Javascript
javascript中的delete使用详解
2013/04/11 Javascript
JavaScript根据CSS的Media Queries来判断浏览设备的方法
2016/05/10 Javascript
jQueryUI DatePicker 添加时分秒
2016/06/04 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
使用 Vue.js 仿百度搜索框的实例代码
2017/05/09 Javascript
BootStrap中的Fontawesome 图标
2017/05/25 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
2017/12/09 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
jquery写出PC端轮播图实例
2018/01/26 jQuery
layUI实现列表查询功能
2019/07/27 Javascript
使用 JavaScript 创建并下载文件(模拟点击)
2019/10/25 Javascript
node.js中对Event Loop事件循环的理解与应用实例分析
2020/02/14 Javascript
Python抓取淘宝下拉框关键词的方法
2015/07/08 Python
jupyter notebook引用from pyecharts.charts import Bar运行报错
2020/04/23 Python
Python实现简单http服务器
2018/04/12 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
pytorch加载自定义网络权重的实现
2020/01/07 Python
利用Python实现Excel的文件间的数据匹配功能
2020/06/16 Python
浅谈多卡服务器下隐藏部分 GPU 和 TensorFlow 的显存使用设置
2020/06/30 Python
应届生程序员求职信
2013/11/05 职场文书
员工拾金不昧表扬信
2014/01/09 职场文书
公司的门卫岗位职责
2014/09/09 职场文书
大学新生军训自我鉴定范文
2014/09/13 职场文书
晚会开幕词
2015/01/28 职场文书
2015年餐厅服务员工作总结
2015/04/23 职场文书
2015年药品销售工作总结范文
2015/05/25 职场文书
人间正道是沧桑观后感
2015/06/15 职场文书
升职感谢领导的话语及升职感谢信
2019/06/24 职场文书
解决jupyter notebook启动后没有token的坑
2021/04/24 Python
CSS实现渐变色边框(Gradient borders)的5种方法
2022/03/25 HTML / CSS