Python的类实例属性访问规则
一般来说,在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基础:新式类的属性访问
一.概述 二.准备工作 1.讨论对象 2.名词解释 三.实例绑定的属性访问 1.获取属性 一般规则 参考源码 示例验证 2.设置属性 一般规则 参考源码 示例验证 3.删除属性 一般规则 参考源码 示 ...
- 第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获
一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...
- python中的实例属性和类属性
在python中,类属性和实例属性的区别是什么? 我认为是作用域的不同,实例对象可以访问类属性,类对象不可以访问实例属性.(类的概念本身就是作用域的概念,你不能让一只猫会飞,猫属于猫类,这一类都不会飞 ...
- python基础-类的属性(类属性,实例属性,私有属性)
一:类的属性 类的属性分为:类属性(公有属性),实例属性和私有属性. 1)类属性(公有属性(静态字段): 类定义时直接指定的属性(不是在__init__方法中),可以通过类名直接访问属性,并且保存 ...
- Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )
通常情况下,我们在访问类或者实例对象的时候,会牵扯到一些属性访问的魔法方法,主要包括: ① __getattr__(self, name): 访问不存在的属性时调用 ② __getattribute_ ...
- 第8.25节 Python风格的__getattribute__属性访问方法语法释义及使用
一. 引言 在<第8.13节 Python类中内置方法__repr__详解>老猿介绍了在命令行方式直接输入"对象"就可以调用repr内置函数或__repr__方法查看对 ...
- python基础学习1-类属性访问
#!/usr/bin/env python # -*- coding:utf-8 -*- #====> __setattr__ 重写 设置类对象属性值时候调用的魔法方法 __getattr__( ...
- python中初始化实例属性
虽然我们可以自由地给一个实例绑定各种属性,但是,现实世界中,一种类型的实例应该拥有相同名字的属性.例如,Person类应该在创建的时候就拥有 name.gender 和 birth 属性,怎么办? 在 ...
- python中创建实例属性
虽然可以通过Person类创建出xiaoming.xiaohong等实例,但是这些实例看上除了地址不同外,没有什么其他不同.在现实世界中,区分xiaoming.xiaohong要依靠他们各自的名字.性 ...
随机推荐
- winform开发中绑定combox到枚举
开发中需要根据下拉框的选择处理一些业务逻辑,使用ID值或Text值都不利于代码维护,所以可以写个扩展方法绑定到枚举上. public static class Extensions { /// < ...
- 发送有序广播Ordered Broadcast
import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.vi ...
- PULL解析
PULL解析类似于SAX解析,都采用事件驱动(利用getEventType()方法)方式进行解析,当PULL解析器开始解析之后,可以不断地调用PULL解析器的next()方法获取下一个解析事件(开始文 ...
- POJ 2762 tarjan缩点+并查集+度数
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15494 ...
- 一模 (6) day1
第一题: 题目大意: 一个n的全排列A[i]是单峰的,当且仅当存在某个x使得A[1]<A[2]<...<A[x]>A[x+1]>...>A[n]. 试求 n 的单峰 ...
- POJ 3691 AC自动机上的dp
题目大意: 给定一些不合理的DNA序列,再给一段较长的dna序列,问最少修改几次可以使序列中不存在任何不合理序列,不能找到修改方法输出-1 这里你修改某一个点的DNA可能会影响后面,我们不能单纯的找匹 ...
- [vijos P1112] 小胖的奇偶
第一次看到这题怎么也不会想到是并查集题目…星期五第一次看到这题,到今天做出来,实在是废了好多功夫.看了很多人的解题都有same和diff数组,我也写了,后来发现不对啊两个数组的话find函数怎么写呢? ...
- android textview 跑马灯
<TextView android:layout_width="match_parent" android:layout_height="48dp" an ...
- [Java]eclipse的使用
1.android sdk help安装 使用SDK Manager.exe下载android sdk的时候把docs也勾选上. 在eclipse的android工程下的android.jar(在an ...
- hadoop生态系统的详细介绍
1.Hadoop生态系统概况 Hadoop是一个能够对大量数据进行分布式处理的软件框架.具有可靠.高效.可伸缩的特点. Hadoop的核心是HDFS和MapReduce,hadoop2.0还包括YAR ...