zl程序教程

您现在的位置是:首页 >  后端

当前栏目

第7.13节 案例详解:Python类变量

2023-09-27 14:26:59 时间

第7.13节 案例详解:Python类变量

上节介绍了类变量的定义和使用方法,并举例进行了说明。本节将通过一个更完整的例子来说明。
一、    定义函数dirp

def dirp(iter): return [i for i in dir(iter) if not i.startswith('__')]

该函数的作用是去掉对象属性中以双下划线开头的变量,双下划线开头的变量要么是私有变量、要么是特殊变量(双下划线结尾时),实际上私有变量Python进行了转换,真正存储时不是双下划线开头,因此该函数实际上就是去掉对象的那些特殊变量,这些特殊变量大部分都是继承object类的(因为Python3中,所有自定义类都是object类的子类,请见前面章节的内容)。
通过该函数能够方便看到对象中自定义的属性和方法。
二、    类定义

class VarTest():
  classvar='classvar'
  objectcount=0
  samenamevar='samenamevar in class'
  def __init__(self):
     self.objvar='objvar'
     self.samenamevar='samenamevar in obj'
     samenamevar='samenamevar in __init__'
     VarTest.objectcount += 1
     
  def output(self):
      print("通过self访问类变量classvar的值:",self.classvar)
      print("通过self访问实例变量objvar的值:",self.objvar)
      print("通过self访问类变量和实例变量都定义了的samenamevar的值:",self.samenamevar)
print("通过类名访问类变量classvar的值:",VarTest.classvar)
      print("通过类名访问类变量和实例变量都定义了的samenamevar的值:",VarTest.samenamevar)
      print("类变量objectcount的值:",VarTest.objectcount) 
      if hasattr(VarTest,'varcnt'):print("类变量varcnt的值:",VarTest.varcnt) 
          else:print("类中没有定义变量varcnt")
try:print("实例方法直接访问classvar的值:",classvar)
      except:print("实例方法直接访问classvar的值失败")

上述代码:
1、    在类体代码中定义了类变量classvar(初始值为字符串'classvar')、objectcount(初始值为0,准备用来记录类生成的实例数量)、samenamevar(初始值为字符串'samenamevar in class',并且在实例中将定义同名变量);
2、    在构造方法中,定义了实例变量objvar(初始值为'objvar')、同名实例变量samenamevar(初始值为samenamevar in __init__),同时对类变量VarTest.objectcount计数加一;
3、    定义了一个输出实例方法output,输出:
1)    通过self输出self.classvar、self.objvar、self.samenamevar的值,注意此时除了self.classvar是类变量的值,self.samenamevar是实例变量的值(当类和实例都有同名变量时,通过self访问的是实例变量的值);
2)    通过类名访问classvar、samenamevar、objectcount、varcnt的值,其中varcnt在类中没有定义,准备是在调用方通过类名赋值方式访问,为了确保相关代码不报错,加了一个判断类是否有varcnt属性的判断;
3)    最后直接访问classvar,此时没通过类名称和self,应该报错,因此加了异常处理。

三、    调用代码
下面是老猿写的调用代码,我们逐一来看:

var1=VarTest()#定义实例var1
dirp(var1)#显示实例的属性['classvar', 'objectcount', 'objvar', 'output', 'samenamevar']
var1.output()
VarTest.varcnt=0
dirp(var1)

到目前为止相关代码的截图:
 
上面标记部分说明如下:
1、    直接访问classvar是失败的,这个classvar应该是一个局部变量;
2、    对于类和实例都有的变量samenamevar,通过self.samenamevar是访问的实例变量的值,通过类名访问是类变量的值;
3、    当执行VarTest.varcnt=0后,类就有了属性varcnt,即类变量varcnt。不过这种方式不推荐使用,所有类变量应该在类体中定义;

我们继续在命令行逐行执行后续代码:

var2=VarTest()
dirp(var2)
var1.output()
var2.output()
var2. varcnt, var1.varcnt
var2.varcnt=2
var2. varcnt, var1.varcnt

执行截屏如下:


 
上面标记部分说明如下:
1、    类变量objectcount在var2定义后变成了2,如果通过var1.objectcount,var2.objectcount发现都是2;
2、    执行var2.varcnt=2后,实际是定义了var2的实例变量varcnt并赋值为2,而类变量的值保持0不变,这点需要各位重点注意。

本节通过例子详细介绍了类变量的定义和访问方法,从上述例子可以得出:
1、    类变量和实例变量同名时,通过实例访问时只能访问实例变量;
2、    “实例.类变量”方式的赋值语句实际上不是给类变量赋值,而是定义新的实例变量,因此尤其需要引起重视,这也是为什么老猿推荐使用类名方式访问类变量的原因。

老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!