在Python中经常会混淆类属性和实例属性的概念,今天专门记录一下个人理解以免日后忘记。

看下面的例子:

class Tencent():
i = 10 # 此处i为类属性
def __init__(self,name):
self.name = name # 此处name为实例属性
def function(self):
print(self.name) a = Tencent(100) #实例化
print(a.i)
print(a.name)
print(Tencent.i)

运行当然是没有问题的,输出结果为:

10
100
10

但是当我们加入这样一段代码:

print(Tencent.name)

运行后会报错,这是因为不能通过类名+属性名的方式去调用实例属性,当类实例化后,只能通过类名去调用方法中的属性。

下面进行这样的操作:

Tencent.i += 1
print(a.i)print(Tencent.i)

输出结果为:

11
11

然后再进行:

a.i + = 1
print(a.i)
print(Tencent.i)

输出结果则为:

11
10

Why?同样是对类属性的修改,为什么用不通的调用方式修改后输出的值却不一样呢?

我自己的解释如下:

当我们使用实例名+属性名,即a.i的方式修改属性i的值时:相当于新建了一个i的副本,+1这个操作实际上是进行在这个i的副本上的,而当我们用类名+属性名的方式调用i时,输出的其实是原封未动的类属性i

验证如下:

print(id(a.i)
print(Tencent.i)
a.i += 1
print(a.i,end=" "),print(id(a.i)) #输出修改后a.i的内存地址
print(Tencent.i,end=" "),print(id(Tencent.i)) #输出修改后Tencent.i的内存地址

输出结果为:

140712785339504
140712785339504
11 140712785339536
10 140712785339504

结果显示,修改前后,类属性i的内存地址其实是没有变的,通过实例调用修改i其实只是修改了副本。

同理,假如我们直接通过类名的调用方式来修改i,结果为:

print(id(a.i))
print(id(Tencent.i))
Tencent.i += 1
print(a.i,end=" "),print(id(a.i))
print(Tencent.i,end=" "),print(id(Tencent.i)) 140712785339504
140712785339504
11 140712785339536
11 140712785339536

可以看到,如果我们直接使用类名+属性名的方式修改i,那么在修改后i的值确确实实的是变了。

总的来说,类和实例对于属性的修改权限其实就是作用域的问题,类有权限修改属性,而实例没有,于是,实例就在自己的内存范围内创建一个实例名+属性名的副本,调用的时候就是用的这个。

最新文章

  1. SQL分组和聚合(Grouping and Aggregates)
  2. 自己动手写UI库——引入ExtJs(布局)
  3. PetaPoco.Core.ttinclude修改
  4. ASP.NET中使用 Response.Write("<script>alert('****');</script>");后CSS界面发生变化的解决方法 (经验证)
  5. 并行查询提高sql查询速度
  6. 人机ai五子棋 ——五子棋AI算法之Java实现
  7. VS2013编译FileZilla0.9.44
  8. 201521123031 《Java程序设计》第11周学习总结
  9. org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression
  10. 修改应用进程open file值
  11. 高性能之html
  12. 四元数与欧拉角(RPY角)的相互转换
  13. 关于mysql中字符集和排序规则说明
  14. 学习笔记15—Python 存储集
  15. 1120 Friend Numbers (20 分)
  16. objelement = event.target || event.srcElement;
  17. vue 组件-组件定义的4种方式
  18. 我认为比较有用的快捷键(Eclipse)
  19. vue3.0环境最新安装步骤
  20. PAT 甲级 1002 A+B for Polynomials

热门文章

  1. The Zen of Python —— Python 之禅
  2. python类中的一些神奇方法
  3. Java中的选择结构
  4. 小白学 Python 爬虫(30):代理基础
  5. ELK学习实验006:Nginx的日志分析系统之filebeat配置
  6. 【他山之石】mybatis打印sql日志 相关配置
  7. echarts实现group关系图案例
  8. $AT2292\ Division\ into\ Two$ $dp$
  9. 1091 N-自守数 (15 分)C语言
  10. 使用K均值算法进行图片压缩