在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中类属性和实例属性的区别的更多相关文章

  1. python中类变量和实例变量的区别

    类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的).实例变量:实例化之后,每个实例单独拥有的变量. class student(): age = 0 name = 'stu ...

  2. python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法

    类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实 ...

  3. Python中类的声明,使用,属性,实例属性,计算属性及继承,重写

    Python中的类的定义以及使用: 类的定义: 定义类 在Python中,类的定义使用class关键字来实现 语法如下: class className: "类的注释" 类的实体 ...

  4. 关于Python类属性与实例属性的讨论

    标题名字有点长. 之所以想写这个文章是因为碰巧看到网上一篇关于Pyhon中类属性及实例属性区别的帖子.因为我之前也被这个问题困扰过,今天碰巧看到了这篇帖子,发现帖子的作者只是描述了现象,然后对原因的解 ...

  5. Python的程序结构[0] -> 属性/Property[0] -> 类属性、实例属性和私有属性

    类属性.实例属性和私有属性 Python中类的属性主要包括类属性,实例属性和私有属性,下面是对三种属性的简单介绍 类属性 / Class Property 类属性在__init__()之外初始化,在外 ...

  6. Python类属性,实例属性

    1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...

  7. python 类属性和实例属性

    class AAA(): aaa = 10 # 情形1 obj1 = AAA() obj2 = AAA() print obj1.aaa, obj2.aaa, AAA.aaa # 情形2 obj1.a ...

  8. Python中的类属性、实例属性与类方法、静态方法

    1.什么是类对象,实例对象 类对象:类名 实例对象:类创建的对象 2.类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++.Java中类的静态成员变量有点 ...

  9. Python之路-面向对象&继承和多态&类属性和实例属性&类方法和静态方法

    一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强…” 什么是面 ...

随机推荐

  1. wireshark使用心得 centos7安装wireshark: yum install wireshark wireshark-gnome

    centos7 安装wireshark 安装 yum install wireshark yum install wireshark-gnome 关于pcap文件的文件解析网上资料有很多,我在这就不说 ...

  2. Tomcat 类加载器打破双亲委派模型

    我们分为4个部分来探讨: 1. 什么是类加载机制? 2. 什么是双亲委任模型? 3. 如何破坏双亲委任模型? 4. Tomcat 的类加载器是怎么设计的? 我想,在研究tomcat 类加载之前,我们复 ...

  3. 0029 定位:position(相对、绝对、固定、绝对定位盒子居中、z-index、绝对定位改变display属性)

    目标 理解 能说出为什么要用定位 能说出定位的4种分类 能说出四种定位的各自特点 能说出我们为什么常用子绝父相布局 应用 能写出淘宝轮播图布局 1. CSS 布局的三种机制 网页布局的核心 -- 就是 ...

  4. 使用SonarQube+Eclipse来分析python代码

    背景 最近在项目中推广集成测试的理念以及相关工具,在jenkins中集成sonar去分析项目的java代码的时候,意外的发现,sonarqube上还有对应python的插件,而自己写的测试工具大部分都 ...

  5. vue-awesome-swiper手动滑动后不再自动轮播的问题

    <swiper :options="swiperOption" ref="mySwiper" > <!--轮播图内容--> </s ...

  6. Win10系统中搭建服务器的方法

    1.我的电脑->找到并点击“控制面板”->点击“程序”->点击“启用或关闭Windows功能”2.按如下图方式选中复选框   服务器批量管理软件 3.点击确定,打开iis管理器(右键 ...

  7. 07Shell数组

    Shell 数组变量 普通数组:只能使用整数作为数组索引 关联数组:可以使用字符串作为数组索引 普通数组 定义数组 方法1: 一次赋一个值 数组名[索引]=变量值 示例 # array1[0]=pea ...

  8. VS Code 解决 因为在此系统上禁止运行脚本

    vscode执行命令的 主要是由于没有权限执行脚本.开通权限就可以解决啦 在搜索框中输入:powerShell 选择管理员身份运行 输入命令行:set-ExecutionPolicy RemoteSi ...

  9. 转载 css截取td里面的内容 如何固定td th的宽度

    源博客地址:http://blog.csdn.net/u011456552/article/details/53839255 效果图: 源码: <!DOCTYPE html> <ht ...

  10. Animator的小记

    前阵子在做动画相关的内容,整理一下Animator. 1.动画切换 1.1状态之间的切换,在状态间连线(Make Transition),并且设置触发条件,代码里调用SetTrigger.SetBoo ...