一般来说,在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的类实例属性访问规则的更多相关文章

  1. Python基础:新式类的属性访问

    一.概述 二.准备工作 1.讨论对象 2.名词解释 三.实例绑定的属性访问 1.获取属性 一般规则 参考源码 示例验证 2.设置属性 一般规则 参考源码 示例验证 3.删除属性 一般规则 参考源码 示 ...

  2. 第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

  3. python中的实例属性和类属性

    在python中,类属性和实例属性的区别是什么? 我认为是作用域的不同,实例对象可以访问类属性,类对象不可以访问实例属性.(类的概念本身就是作用域的概念,你不能让一只猫会飞,猫属于猫类,这一类都不会飞 ...

  4. python基础-类的属性(类属性,实例属性,私有属性)

      一:类的属性 类的属性分为:类属性(公有属性),实例属性和私有属性. 1)类属性(公有属性(静态字段): 类定义时直接指定的属性(不是在__init__方法中),可以通过类名直接访问属性,并且保存 ...

  5. Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )

    通常情况下,我们在访问类或者实例对象的时候,会牵扯到一些属性访问的魔法方法,主要包括: ① __getattr__(self, name): 访问不存在的属性时调用 ② __getattribute_ ...

  6. 第8.25节 Python风格的__getattribute__属性访问方法语法释义及使用

    一. 引言 在<第8.13节 Python类中内置方法__repr__详解>老猿介绍了在命令行方式直接输入"对象"就可以调用repr内置函数或__repr__方法查看对 ...

  7. python基础学习1-类属性访问

    #!/usr/bin/env python # -*- coding:utf-8 -*- #====> __setattr__ 重写 设置类对象属性值时候调用的魔法方法 __getattr__( ...

  8. python中初始化实例属性

    虽然我们可以自由地给一个实例绑定各种属性,但是,现实世界中,一种类型的实例应该拥有相同名字的属性.例如,Person类应该在创建的时候就拥有 name.gender 和 birth 属性,怎么办? 在 ...

  9. python中创建实例属性

    虽然可以通过Person类创建出xiaoming.xiaohong等实例,但是这些实例看上除了地址不同外,没有什么其他不同.在现实世界中,区分xiaoming.xiaohong要依靠他们各自的名字.性 ...

随机推荐

  1. 使用MediaPlayer播放音频-----之一

    MediaPlayer提供了如下方法来指定装载相应的音频文件: 1.void  setDataSource( String  path):指定装载path路径所代表的文件. 2.void  setDa ...

  2. 如何删除 Ubuntu 上不再使用的旧内核

    提问:过去我已经在我的Ubuntu上升级了几次内核.现在我想要删除这些旧的内核镜像来节省我的磁盘空间.如何用最简单的方法删除Ubuntu上先前版本的内核? 在Ubuntu上,有几个方法来升级内核.在U ...

  3. NOIP 2003解题报告

    第一题(神经网络): 题目大意,给出一些点,每个点都有2个值,c和u,给出一些有向边,权值为w.入度为0的点的c已知,其它点的c未知,每个入度不为0的点node的c等于sum(c[k]*w[k][no ...

  4. tab模块

    #!/usr/bin/env python # python startup file import sys import readline import rlcompleter import ate ...

  5. 【STL】-auto_ptr的用法

    初始化: #include<memory> //auto_ptr header void f() { auto_ptr<classA> ptr(new classA); } 拷 ...

  6. 分布式一致性原理—CAP

    背景 随着分布式事务的出现,传统的单机事务模型(ACID)已经无法胜任,尤其是对于一个高访问量.高并发的互联网分布式系统来说. 如果我们要求严格一致性,很可能就需要牺牲掉系统的可用性,反之亦然.但两者 ...

  7. 各种注释--------html,jsp

    1. <!--到梦之都XHTML教程的链接--> <a href="http://www.dreamdu.com/xhtml/"> 学习XHTML < ...

  8. java中this的用法?

    2008-07-28 08:10cztx5479 | 分类:JAVA相关 | 浏览4533次 java中this的用法? import java.awt.*; import java.awt.even ...

  9. vs2012 断点不能调试

    调试ASP.NET时发现,设置的断点被视而不见 提示错误 debugging information for ‘iisexpress.exe’cannot be found or does not m ...

  10. iOS7中计算UILabel中字符串的高度

    iOS7中计算UILabel中字符串的高度 iOS7中出现了新的方法计算UILabel中根据给定的Font以及str计算UILabel的frameSize的方法.本人提供category如下: UIL ...