Python中类属性和实例属性的区别
在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的值确确实实的是变了。
总的来说,类和实例对于属性的修改权限其实就是作用域的问题,类有权限修改属性,而实例没有,于是,实例就在自己的内存范围内创建一个实例名+属性名的副本,调用的时候就是用的这个。
Python中类属性和实例属性的区别的更多相关文章
- python中类变量和实例变量的区别
类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的).实例变量:实例化之后,每个实例单独拥有的变量. class student(): age = 0 name = 'stu ...
- python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法
类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实 ...
- Python中类的声明,使用,属性,实例属性,计算属性及继承,重写
Python中的类的定义以及使用: 类的定义: 定义类 在Python中,类的定义使用class关键字来实现 语法如下: class className: "类的注释" 类的实体 ...
- 关于Python类属性与实例属性的讨论
标题名字有点长. 之所以想写这个文章是因为碰巧看到网上一篇关于Pyhon中类属性及实例属性区别的帖子.因为我之前也被这个问题困扰过,今天碰巧看到了这篇帖子,发现帖子的作者只是描述了现象,然后对原因的解 ...
- Python的程序结构[0] -> 属性/Property[0] -> 类属性、实例属性和私有属性
类属性.实例属性和私有属性 Python中类的属性主要包括类属性,实例属性和私有属性,下面是对三种属性的简单介绍 类属性 / Class Property 类属性在__init__()之外初始化,在外 ...
- Python类属性,实例属性
1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...
- python 类属性和实例属性
class AAA(): aaa = 10 # 情形1 obj1 = AAA() obj2 = AAA() print obj1.aaa, obj2.aaa, AAA.aaa # 情形2 obj1.a ...
- Python中的类属性、实例属性与类方法、静态方法
1.什么是类对象,实例对象 类对象:类名 实例对象:类创建的对象 2.类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++.Java中类的静态成员变量有点 ...
- Python之路-面向对象&继承和多态&类属性和实例属性&类方法和静态方法
一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强…” 什么是面 ...
随机推荐
- 【11.61%】【codeforces 670F】Restore a Number
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- HDU4609 FFT+组合计数
HDU4609 FFT+组合计数 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意: 找出n根木棍中取出三根木棍可以组成三角形的概率 题解: ...
- sql临时表与变量表
1)临时表存储在 tempdb 中,当不再使用时会自动删除 一般使用如下: --创建临时表 select * into #temp from TABLE --使用临时表 select * from # ...
- Servlet request 面试题
使用request获得请求行:String getmethod():获得请求的资源:String getcontextpath():----web应用名称request是一个域对象request完成请 ...
- jsp页面出错 Cannot call sendRedirect() after the response has been committed
sendRedirect()不能多次调用,检查下代码
- Ceph 之RGW Pub-Sub Module
Overview Pub-Sub module 顾名思义是一个发布订阅相关的模块.Pub-Sub module 为对象存储的变更事件提供一种发布-订阅机制.而发布-订阅架构本身应用非常广泛,如公有云G ...
- layui treeSelect
官方地址:https://fly.layui.com/extend/treeSelect/ 下面介绍一下这个插件的使用方法 1.html页面 <div class="layui-inp ...
- tomcat日志传参乱码问题
问题: 在centos系统下,tomcat8.0.36控制台日志打印会出现中文乱码. 解决方案: 在catalina.sh里加上 JAVA_OPTS="-Dfile.en ...
- .NET设计篇08-线程取消模型和跨线程访问UI
知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂,输出倒逼输入 内容目录 一.线程统一取消模型1.取消令牌2.可以中断的线程1.设计一个中断函数2.创建CancellationTokenSour ...
- swoole通往大神之路——swoole任务中心说明及进程任务架构搭建
Swoole多任务处理中心 如果你还不会用swoole就out了,swoole通往大神之路——swoole任务中心说明及进程任务架构搭建 教学视频: www.bilibili.com/video/av ...