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之路-面向对象&继承和多态&类属性和实例属性&类方法和静态方法
一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强…” 什么是面 ...
随机推荐
- Little Elephant and Array CodeForces - 220B (莫队)
The Little Elephant loves playing with arrays. He has array a, consisting of npositive integers, ind ...
- C# 如何解析XML
- 聊聊固态硬盘1--人生头两块SSD
第一块固态硬盘--浦科特m6s 来源:京东双11 价格:319rmb 第二款固态--饥饿鲨ocz arc100 来源:美国亚马逊 黑色星期五 价格:366rmb ...
- Servlet 的面试题
Servlet运行在Servlet容器中,其生命周期由容器来管理.Servlet的生命周期通过javax.servlet.Servlet接口中的init().service()和destroy()方法 ...
- centos 下yum lock的解决办法
centos 下yum lock的解决办法 centos7下yum install的时候,报了一堆错误,如下: Another app is currently holding the yum loc ...
- ELK学习实验003:Elasticsearch 集群安装
前面已经介绍了Elasticsearch这个工具,并对单机安装做了简单介绍,现在使用三台机器做一个elasticsearch集群 一 环境准备 1.1 机器准备 1.2 同步时间 [root@node ...
- Mysql 最全查询语句
基本查询语句及语法: select distinct from where group by having limit 一.单表查询 前期表与数据准备: # 创建一张部门表 create table ...
- 洛谷$P2057\ [SHOI2007]$ 善意的投票 网络流
正解:网络流 解题报告: 传送门! $umm$看到每个人要么0要么1就考虑最小割呗,,,? 然后贡献有两种?一种是违背自己的意愿,一种是和朋友的意愿违背了 所以考虑开一排点分别表示每个人,然后$S$表 ...
- Linux下自动化部署ASP.NET CORE 3.1(Docker+Jenkins+Nginx)
1.先配置好Docker阿里云加速,可以使用阿里云容器服务 (可自己在阿里云申请,要不然安装东西直接很慢)注意:https://XXXX.mirror.aliyuncs.com为阿里云加速服务分配地址 ...
- HDU3886 Final Kichiku “Lanlanshu” 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3886 题目大意: 给一定区间 \([A,B]\) ,一串由 /, \ , - 组成的符号串.求满足符号 ...