第7.12节 可共享的Python类变量
第7.12节 可共享的Python类变量
一、 引言
在上节已经引入介绍了类变量和实例变量,类体中定义的变量为类变量,默认属于类本身,实例变量是实例方法中定义的self对象的变量,对于每个实例都是独有数据,而类变量是该类所有实例共享的属性和方法。
二、 类变量的定义方式
类变量的定义其实就是对变量赋值,有如下方式可以进行类变量的定义:
1. 在类体代码中,直接用变量名赋值。类体代码是在类定义时执行;
2. 在实例方法中(含构造方法和普通方法),直接用“类名.变量名”方式赋值;
3. 在类方法中,直接用“类名.变量名”或“cls.变量名”方式赋值,关于cls请参考下面“类方法”章节的解释;
4. 在类外调用方代码中直接用“类名.变量名”方式赋值。
注意:类变量无论是哪种方法定义后,会立即对该类所有实例对象产生影响,所有实例无论是类变量定义前就产生的实例还是类变量定义后的实例都可以访问该变量。
三、 类变量的访问方式
类变量的访问方式与类变量的定义方式有2点不同,一是因为类体代码仅在类定义时执行,因此不能在类定义后再通过类体代码访问,二是类变量可以在类外调用方通过实例方式访问。具体支持的访问方式如下:
1. 在实例方法中(含构造方法和普通方法),直接用“类名.变量名”方式访问;
2. 在类方法中,直接用“类名.变量名”方式访问;
3. 在类外调用方代码中直接用“类名.变量名”方式访问;
4. 在类外调用方代码中直接用“实例名.变量名”方式访问,注意这种方式不能用来直接赋值,只能读取,如果是赋值就变成了实例变量的定义。
从以上说明中,可以得知:
1. 类变量是可以在类定义的实例方法和类方法、以及类外调用时动态增加,并且一旦增加,对所有已经定义及后续需要新定义的实例变量都可见;
2. 程序通过对象访问类变量,其本质还是通过类名在访问类变量,但如果类变量和实例变量重名时,必须通过类名才能访问类变量。这是因为Python总是先到实例对象中查找属性,再到类属性中查找属性,有点类似局部变量和全局变量的关系;
3. Python 允许通过对象访问类变量,但如果程序通过对象尝试对类变量赋值,此时性质就变了,Python 是动态语言,赋值语句往往意味着定义新的实例变量。因此,如果程序通过对象对类变量赋值,其实不是对“类变量赋值”,而是定义新的实例变量。
如果把类当成类命名空间,那么类变量其实就是定义在类命名空间内的变量, Python 可以使用类来读取、修改类变量。对于类变量而言,它们就是属于在类命名空间内定义的变量,因此程序不能直接访问这些变量,主要使用类名的方式来访问类变量,同时Python 完全允许使用实例对象来访问该对象所属类的类变量,但Python主要推荐使用类名访问类变量。因此老猿强烈建议大家使用类名访问类变量,使用实例方式访问很容易出错,大家可以结合下面的举例好好理解一下。
四、 举例
1、 定义一个类VarTest和实例,在类体代码中对类变量classvar赋值
class VarTest():
classvar='classvar在类体代码赋值'
定义个实例:var=VarTest()
2、 查看相关变量的值
查看var.classvar和VarTest.classvar的值,都显示为:'classvar在类体代码赋值'
执行:var.classvar is VarTest.classvar,返回True
3、 执行赋值语句
var.classvar='classvar在类外通过实例赋值'
4、 再次查看相关变量的值
此时查看var.classvar和VarTest.classvar的值,二者已经不同,一个是'classvar在类外通过实例赋值',一个是'classvar在类体代码赋值'
执行:var.classvar is VarTest.classvar,返回False
相关代码执行截图:

5、 如果上面第3个步骤不是通过直接给变量赋值,而是先引用再赋值会怎么样?看下面代码的执行情况:

注本次新定义一个实例,可以看到最开始的var1.classvar和VarTest.classvar是同一个变量,执行var1.classvar+=的操作语句,这个语句的效果等同于“var1.classvar=var1.classvar+' 在类体外通过实例访问类变量'”
可以看到,执行后还是新定义了一个实例变量。
本节介绍了类变量的定义和使用方法,并举例进行了说明,虽然类变量的定义和访问可以通过实例方式进行,但老猿强烈推荐大家按类名方式进行定义和访问。
老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!
第7.12节 可共享的Python类变量的更多相关文章
- Python高级特性: 12步轻松搞定Python装饰器
12步轻松搞定Python装饰器 通过 Python 装饰器实现DRY(不重复代码)原则: http://python.jobbole.com/84151/ 基本上一开始很难搞定python的装 ...
- python 类变量 在多线程下的共享与释放问题-乾颐堂
最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...
- 第8.29节 使用MethodType将Python __setattr__定义的实例方法与实例绑定
一. 引言 在<第7.14节Python类中的实例方法解析>介绍了使用"实例对象名.方法名 = MethodType(函数, 对象)"将动态定义的方法与实例进行绑定 在 ...
- python 类变量 在多线程下的共享与释放问题
最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...
- JAVA 可视化分析工具 第12节
JAVA 可视化分析工具 第12节 经过前几章对堆内存以及垃圾收集机制的学习,相信小伙伴们已经建立了一套比较完整的理论体系!那么这章我们就根据已有的理论知识,通过可视化工具来实践一番. 我们今天要讲 ...
- Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌
原文:Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌 通过前两期的学习,我们可以正确搭建好Android Studio的开发环境,也创建了HelloWorld工程 ...
- 第7.13节 案例详解:Python类变量
第7.13节 案例详解:Python类变量 上节介绍了类变量的定义和使用方法,并举例进行了说明.本节将通过一个更完整的例子来说明. 一. 定义函数dirp def dirp(iter): ret ...
- Python 类变量和成员变量
Python 类变量和成员变量 类与对象的方法 我们已经讨论了类与对象的功能部分,现在我们来看一下它的数据部分.事实上,它们只是与类和对象的名称空间 绑定 的普通变量,即这些名称只在这些类与对象的前提 ...
- 第9.12节 Python中其他文件操作方式
一. 引言 本章老猿主要介绍了Python 内置io模块的文件操作相关功能,其实除了内置io模块可以进行文件操作外,Python的不同模块还提供了多种文件操作方式,下面简单将这些模块和方法介绍一下. ...
随机推荐
- leetcode116:search-for-a-range
题目描述 给出一个有序数组,请在数组中找出目标值的起始位置和结束位置 你的算法的时间复杂度应该在O(log n)之内 如果数组中不存在目标,返回[-1, -1]. 例如: 给出的数组是[5, 7, 7 ...
- 13 SOAP
13 SOAP SOAP(原为Simple Object Access Protocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,使用在计算机网络Web服务(web service) ...
- .NET 5.0正式发布,功能特性介绍(翻译)
本文由葡萄城技术团队翻译并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 我们很高兴今天.NET5.0正式发布.这是一个重要的版本-其中也包括了C# ...
- javascript播放带透明通道的mp4动画
随着互联网的发展,动画效果也在一直更新,从刚开始的flsh动画,cocos骨骼动画,到YY开源的svga动画.最近1年来,带有透明通道的mp4动画被使用的极为广泛,对于app端.github上有开源的 ...
- 论文解读 - Composition Based Multi Relational Graph Convolutional Networks
1 简介 随着图卷积神经网络在近年来的不断发展,其对于图结构数据的建模能力愈发强大.然而现阶段的工作大多针对简单无向图或者异质图的表示学习,对图中边存在方向和类型的特殊图----多关系图(Multi- ...
- SQL:获取每个key下最新创建的记录
今天遇到了一个好玩的问题 问题: 有一个含有key和createdTime字段的表,表里存在很多不同的key值,每个key值下有很多记录. 我想要查出每个key下面cratedTime最大的记录,即每 ...
- 钉钉自定义机器人webhook
这篇博文主要讲的是如何进行自定义定时发送一些text类的消息的自定义机器人.添加过程不细讲了. 首先我们需要拿到一个Hook地址,就是你在添加自定义机器人的时候有个,如图: 然后开始编写我们的脚本,我 ...
- ceph在centos7下一个不容易发现的改变
在centos6以及以前的osd版本,在启动osd的时候,回去根据ceph.conf的配置文件进行挂载osd,然后进行进程的启动,这个格式是这样的 [osd.0] host = hostname de ...
- Python面试题_初级版
1.如何在一个函数内部修改全局变量 a=5 def fn(): a=4 fn() print(a) # 5 #在一个函数内部修改全局变量 a=5 def fn(): global a a=4 fn() ...
- PVE 下的虚拟机磁盘扩容
扩容背景:一台测试机磁盘不足,需要扩容: /dev/mapper/centos-root 40G 40G 20K 100% / 先到PVE网页上对需要扩容的机器扩容,这里新建20G示例: 另外之前也分 ...