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获取多线程及子线程的返回值
Nov 15 Python
Python2.7下安装Scrapy框架步骤教程
Dec 22 Python
浅谈python可视化包Bokeh
Feb 07 Python
无法使用pip命令安装python第三方库的原因及解决方法
Jun 12 Python
Python模块的加载讲解
Jan 15 Python
详解用python写网络爬虫-爬取新浪微博评论
May 10 Python
Python文件操作中进行字符串替换的方法(保存到新文件/当前文件)
Jun 28 Python
python3.x提取中文的正则表达式示例代码
Jul 23 Python
Python 实现递归法解决迷宫问题的示例代码
Jan 12 Python
python实现xlwt xlrd 指定条件给excel行添加颜色
Jul 14 Python
django Model层常用验证器及自定义验证器详解
Jul 15 Python
python 如何利用argparse解析命令行参数
Sep 11 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记录用户通过搜索引擎进网站的关键词
2014/02/13 PHP
PHP编译安装中遇到的两个错误和解决方法
2014/08/20 PHP
php多线程实现方法及用法实例详解
2015/10/26 PHP
PHP生成及获取JSON文件的方法
2016/08/23 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
2019/12/12 PHP
JQuery扩展插件Validate 1 基本使用方法并打包下载
2011/09/05 Javascript
IE6中链接A的href为javascript协议时不在当前页面跳转
2014/06/05 Javascript
浅析nodejs实现Websocket的数据接收与发送
2015/11/19 NodeJs
js无法获取到html标签的属性的解决方法
2016/07/26 Javascript
a标签跳转到指定div,jquery添加和移除class属性的实现方法
2016/10/10 Javascript
JavaScript的变量声明提升问题浅析(Hoisting)
2016/11/30 Javascript
jQuery动态生成不规则表格(前后端)
2017/02/21 Javascript
ES6字符串模板,剩余参数,默认参数功能与用法示例
2017/04/06 Javascript
JavaScript实现图片切换效果
2017/08/12 Javascript
开发Vue树形组件的示例代码
2017/12/21 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
2021/03/01 Vue.js
python实现Dijkstra静态寻路算法
2019/01/17 Python
python实现计数排序与桶排序实例代码
2019/03/28 Python
python打印异常信息的两种实现方式
2019/12/24 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
2020/04/23 Python
python实现简单的五子棋游戏
2020/09/01 Python
Java Unsafe类实现原理及测试代码
2020/09/15 Python
遮罩层 + Iframe实现界面自动显示的示例代码
2020/04/26 HTML / CSS
bonprix荷兰网上商店:便宜的服装、鞋子和家居用品
2020/07/04 全球购物
北京天润融通.net面试题笔试题
2012/02/20 面试题
个人能力自我鉴赏
2014/01/25 职场文书
医生爱岗敬业演讲稿
2014/08/26 职场文书
关于工作时间玩手机的检讨书
2014/09/18 职场文书
2014年社区卫生工作总结
2014/12/18 职场文书
大学生就业推荐表自我评价
2015/03/02 职场文书
2015年感恩父亲节演讲稿
2015/03/19 职场文书
2017元旦晚会开幕词
2016/03/03 职场文书
mysql批量新增和存储的方法实例
2021/04/07 MySQL
python面向对象版学生信息管理系统
2021/06/24 Python
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
PHP面试题 wakeup魔法 Ezpop pop序列化与反序列化
2022/04/11 PHP