第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的世界。

欢迎大家批评指正,谢谢大家关注!

第7.13节 案例详解:Python类变量的更多相关文章

  1. 第7.20节 案例详解:Python抽象类之真实子类

    第7.20节 案例详解:Python抽象类之真实子类 上节介绍了Python抽象基类相关概念,并介绍了抽象基类实现真实子类的步骤和语法,本节结合一个案例进一步详细介绍. 一.    案例说明 本节定义 ...

  2. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  3. 第7.16节 案例详解:Python中classmethod定义的类方法

    第7.16节  案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一.    案例说明 本节定义的一个 ...

  4. 第7.9节 案例详解:Python类封装

    上节介绍了Python中类的封装机制,本节结合一个具体例子进行详细说明. 我们定义一个Person类,其内部有姓名.年龄和类型三个实例变量,并定义了相关的存取方法: class Person():   ...

  5. 第7.11节 案例详解:Python类实例变量

    上节老猿介绍了实例变量的访问方法,本节结合一个具体案例详细介绍实例变量访问. 本节定义一个Vehicle类(车),它有三个实例变量self.wheelcount(轮子数).self.power(动力) ...

  6. 第7.7节 案例详解:Python类继承机制

    本节实现一个类继承的小程序,下面一边结合代码一边介绍相关继承的知识.例子以车.汽车为例,车为父类.汽车为子类. 一.    定义父类Vehicle class Vehicle():    def __ ...

  7. 第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter

    上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一.    案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...

  8. 第7.25节 Python案例详解:使用property函数定义与实例变量同名的属性会怎样?

    第7.25节 Python案例详解:使用property函数定义与实例变量同名的属性会怎样? 一.    案例说明 我们上节提到了,使用property函数定义的属性不要与类内已经定义的普通实例变量重 ...

  9. 第7.24节 Python案例详解:使用property函数定义属性简化属性访问代码实现

    第7.24节 Python案例详解:使用property函数定义属性简化属性访问代码实现 一.    案例说明 本节将通过一个案例介绍怎么使用property定义快捷的属性访问.案例中使用Rectan ...

随机推荐

  1. python爬虫02通过 Fiddler 进行手机抓包

    我们要用到一款强大免费的抓包工具 Fiddler你可以到 https://www.telerik.com/download/fiddler去下载 一般情况下 我们通过浏览器来请求服务器的时候 是点对点 ...

  2. 英特尔与 Facebook 合作采用第三代英特尔® 至强® 可扩展处理器和支持 BFloat16 加速的英特尔® 深度学习加速技术,提高 PyTorch 性能

    英特尔与 Facebook 曾联手合作,在多卡训练工作负载中验证了 BFloat16 (BF16) 的优势:在不修改训练超参数的情况下,BFloat16 与单精度 32 位浮点数 (FP32) 得到了 ...

  3. Entity Fremework以及Fluentapi学习

    一.Entity Framework的入门  我这里采用的方式是数据库自己建立  然后模型类自己建立 数据库上下文类自己建立的方式 目的在于弄懂原理 其他的数据库优先等方式这里就不写了  教程有很多. ...

  4. 自己常用的Content-Type几种值用法

    Content-Type 的值类型: application/json:消息主体是序列化后的 JSON 字符串 这里要注意的是 我在使用webapi,前台使用$.ajax的时候 假如我要传递的数据为 ...

  5. uni-app 动态控制下拉刷新

    扫码查看原文,搜索uni-app 动态控制下拉刷新: 前置条件: 开发环境:windows 开发框架:uni-app , H5+,nativeJS 编辑器:HbuilderX 2.8.13 4.兼容版 ...

  6. cmd 命令行

    理想的情况下,所有的程序都能自描述, 比如 mysql -h,支持哪些命令,每项命令需要哪些参数 命令行工具有几个有关进程的命令, tasklist taskkill http://hi.baidu. ...

  7. linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图:  一.互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...

  8. flink1.10版local模式提交job流程分析

    1.WordCount程序实例 2.本地监听9000端口后测试结果 3.job提交流程 4.local模式执行StreamGraph任务 5.流程分析 flink job提交流程个人理解可以大致分为定 ...

  9. MFC的消息响应机制说明

    MFC的快速理解: 1.MFC的设计者们在设计MFC时,有一个主要的方向就是尽可能使得MFC的代码要小,速度尽可能快.为了这个方向,工程师们使用了许多技巧,主要表现在宏的运用上,实 现MFC的消息映射 ...

  10. Python_Tips

    Python绝对路径与相对路径读写文件[上级目录: os.path.dirname(os.getcwd())] # coding:utf8 ''' 知识点:Python读写文件时候的相对路径与绝对路径 ...