上一篇文章简要介绍了python类使用的基本框架,实际上已经简要介绍了类变量。本文再进一步介绍一下类变量相关的一些重要内容和类变量的使用。要注意一下类中定义的函数也叫方法哦,不要被搞懵了,因为我可能两种说法都在用。

讲的比较啰嗦,但是认真看的话会有收获的喔!

附上类使用专栏的其它文章的链接:

  • python 类的使用(1) 之类使用的基本框架
  • python 类的使用(2) 之类变量
  • python 类的使用(3)之类中常用的三个装饰器@classmethod、@staticmethod、@property
  • python 类的使用(4)之类常用的魔法方法
  • python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)
  • python 类的使用(6)之类的继承
  • python 类的使用(7)之类的私有属性和方法 (类中以单下划线或双下划线开头的变量名或函数名)

文章目录

  • 类变量
    • 基础的类变量被函数使用的例子
    • 在类的函数中改变类变量
    • 在外部调用类时改变类变量
  • 总结
    • 叮!

类变量

类变量就是某个类中定义的在类方法之外独立存在的变量,由于类变量不存在于某个函数中,因此可以直接在使用某个类的时候被调用。在调用某个类时还能够在类的外部重新定义类变量的值或者新增某些类变量;除此外类变量还能够被类中定义的方法所使用及改变。一眼看到这些语句可能会有点懵,咱们一个一个看例子吧:

基础的类变量被函数使用的例子

class Worker:   # 此处类命名也可以加上括号,不影响raise_percent = 1.05  # 这样在类中独立定义的变量就是类变量,可以被类本身或者类方法直接调用 (此处的意义是涨工资的比例)num_of_worker = 0     # 工人数量def __init__(self, name, salary):self.name = nameself.salary = salaryWorker.num_of_worker += 1     '''在初始函数init中调用类本身的类变量,此处的意思是每传入一次类实例,就会增加一个工作人员,也就是这里是对整个类来说的。而这里Worker.num_of_worker的Worker也最好不要使用self代替,使用self的意思不是很明确,因为self本身只代表一个类实例,其不能代表整个类的情况。'''def raise_salary(self):self.salary = self.salary * self.raise_percent'''这里的函数中传入了self,因此函数可以通过self.raise_percent获取到类变量,从而参与计算,这里的意义是将类实例传入的工资乘以上涨工资的比例从而将工资提升。当然要改变涨工资的比例即raise_percent这个类变量也是可以的,接下来会展示其它例子'''A = Worker('Jack',1000)   # 传入一个类实例
print('Jack的初始工资:',A.salary)
print('涨工资的比例:',A.raise_percent)    # 打印查看类实例的类变量
A.raise_salary()          # 通过调用类中涨工资的函数给A实例涨工资
print('涨工资后Jack的工资是:',A.salary)           # 查看工资是否涨成功
print('工作人员数:',A.num_of_worker)    # 查看另一个类变量即工作人员数是否变化

运行上面代码的结果:


从这个结果中看出来,使用涨工资函数后,工资确实被涨了,工作人员数也从开始的0个变为了1个。应该也不需要什么解释啦。

在类的函数中改变类变量

使用类的时候,我们在某些函数调用后可能需要修改一下函数的类变量,这样的情况就可以在类函数中修改类的变量,其实使用方式很简单啦,就展示一下例子就好啦!

class Worker:   # 此处类命名也可以加上括号,不影响raise_percent = 1.05  def __init__(self, name, salary):self.name = nameself.salary = salarydef raise_salary(self):          # # 涨普通工资的方法self.salary = self.salary * self.raise_percentreturn self.salarydef raise_higher_salary(self):    # 涨高工资的方法self.raise_percent = 1.08self.salary = self.salary * self.raise_percentreturn self.salarydef raise_lower_salary(self):     # 涨低工资的方法self.raise_percent = 1.03self.salary = self.salary * self.raise_percentA = Worker('Jack', 1000)
B = Worker('Mary', 1000)
C = Worker('Lucy', 1000)A.raise_salary()
print('A涨薪后的工资:',A.salary)
print(A.raise_percent)
print(Worker.raise_percent)B.raise_higher_salary()    # B涨的是高工资
print('B涨薪后的工资:', B.salary)
print(B.raise_percent)
print(Worker.raise_percent)C.raise_lower_salary()     # C涨的是低工资
print('C涨薪后的工资:', C.salary)
print(C.raise_percent)
print(Worker.raise_percent)

结果:

这里简单解释一下,可以看到上面的工资都改变了,同时A、B、C三者的涨薪比例也都不一样了,但是可以看到Worker类的涨薪比例未改变,这表明了在类函数中修改的类变量仅在函数中生效,是局部变量,不影响整个类的类变量,那么你可能会想我如果想让类方法中修改的类变量在整个类中生效的话要怎么办呢,这就可以用到后续的类方法装饰器也即classmethod啦,使用nonlocal或者global好像有点问题,类方法在下一篇博客哦。

在外部调用类时改变类变量

还是使用上面的代码,不过这次增加一些工作人员:

class Worker:   # 此处类命名也可以加上括号,不影响raise_percent = 1.05  num_of_workers = 0     # 工人数量def __init__(self, name, salary):self.name = nameself.salary = salaryWorker.num_of_workers += 1     def raise_salary(self):self.salary = self.salary * self.raise_percentA = Worker('Jack',1000)
B = Worker('Mary',1000)
C = Worker('Lucy',1000)# 这里查看三个类实例是否是独立存在于内存中的
print(A)
print(B)
print(C)# 接下来查看在类外部修改类变量后的结果及对类的影响,即A、B的涨薪比例
print('初始涨工资的比例:',A.raise_percent)
A.raise_salary()
print('A涨薪后的工资:',A.salary)B.raise_percent = 1.1
B.raise_salary()
print('B涨薪后的工资:',B.salary)
print('A的涨薪比例:',A.raise_percent,'C的涨薪比例',C.raise_percent)# 这里通过类实例和类本身来查看类变量的变化情况
print('工作人员数:',A.num_of_workers)
print('工作人员数:',B.num_of_workers)
print('工作人员数:',Worker.num_of_workers)

运行结果如下:

这里介绍一下上面的结果:

  • 首先打印三个类实例对象,可以看出它们在内存中存在的位置不同,因此他们并不代表同一个东西哦。
  • 首先类中的类变量即raise_percent默认设置为1.05,因此A在未调整涨薪比例的情况下涨的工资是在初始的比例下进行的,A涨薪后的工资就只有1050
  • 但是接下来我将B的涨薪比例提高到了1.1,这样对B使用涨薪函数后,B的工资涨到了1100,这是按照1.1的比例来得到的
  • 之后再尝试查看A和C的涨薪比例,两者没有发生变化,代表对B的类变量的改变没有影响到A和C的类变量
  • 但接下来查看工作人员数即num_of_workers,发现无论通过A、B或者是Worker类来查看得到的结果都是3。但是我实际上创建A、B、C三个类实例的时候是分开创建的,上面的内存位置也显示他们的储存位置不同,但这里他们的类变量却混用了。
  • 这是咋回事呢?经过查看网上的博客和反复思考,个人认为原因如此:由于A、B、C分开创建,它们各自的创建使用的类变量是公用的,也就是每创建一个类实例,整个类的类变量(包含类实例所能访问到的类变量)会被更新(init函数中设定的更新)。也就是说通过类创建的类实例都共用类变量,每次创建类实例时使用的类变量是上一次创建类实例更新后的类变量,而创建类实例后的类变量也就成为了之前所有类实例和整个类的类变量。这样也就能解释上面的现象了。而查看num_of_workers的内存地址也发现它们都是一样的(如下)。
  • 但是上面的B的类变量raise_percent被改变了后为什么A与C的类变量raise_percent没有被改变呢?这是因为,在类外部对某个类实例拥有的类变量进行直接的修改相当于只改变了这个特定类实例的类变量属性,这是不会影响到其它的类实例和类变量的。即使不是直接修改,如使用A.num_of_worker += 1这样的方式也是只会改变A的类变量属性哦(可以自己试一下)。
  • 还有另外的一些情况在类外部操作类变量也不会改变整个类的类变量,那就是列表、集合、字典、自定义类等这些类变量,这些情况下的类变量也是可以在外部进行增删的操作的,但是要注意不能直接修改哦,修改的话就和上面修改类变量无异了。

看下例子:

class new_list:l = []A = new_list()
B = new_list()
C = new_list()A.l.append('yes')print(A.l)
print(B.l)
print(C.l)

代码运行结果为:

而如果是改的情况:

class new_list:l = []A = new_list()
B = new_list()
C = new_list()A.l = 'no'print(A.l)
print(B.l)
print(C.l)

结果如下:

这样就能看出来类变量若是是列表之类的形式,那么所有的类实例就都是共用一个内存地址了吧。以后一定不要搞混啦!

总结

感觉内容有点散,需要总结一下。

  • 首先类变量的定义,是在类中独立定义的不在类方法中的变量
  • 其次若无特殊情况(比如外部对类实例的修改等情况),所有创建的类实例都使用同一个共用的类变量,其在内存中的地址相同。
  • 在类的方法(即函数)中对类变量进行修改是不会影响到类本身的变量的,其修改仅在函数中局部有效。
  • 若某个类实例对类变量修改,那么只是这个实例的类变量被修改,其它类实例及类本身的类变量不改变。
  • 列表、字典等变量形式可以在不改变类变量的公用性的情况下进行增删操作,即某个类实例对列表或字典类的类变量进行增删操作是会同时操作到其它类实例的类变量的,它们使用的类变量是共用的。

叮!

最近忙呀,没啥时间写。今天的文章写的可能也不好,因为写的太冗长了,读起来可能较花时间。但是还是花功夫认真写了,若是认真读下来我觉得还是会有收获的。大家一起加油吧!

参考:https://blog.csdn.net/xuzhexing/article/details/93915962

参考:Corey Schafer的python视频教程

python 类的使用(2) 之类变量相关推荐

  1. 第八章 Python类中常用的特殊变量和方法

    上章花了近三十章节介绍类的知识,本章估计内容也比较多,讲完这些,其实还有更多.为什么这么多类有关的知识呢,这是因为在Python里面一切皆对象,就连整型.浮点数.字符串这些比较常规的类型都是作为类来实 ...

  2. [转载] Python学习系列之下划线与变量命名规则

    参考链接: Python中的命名空间和范围 一.定义 1.1 从入口函数谈起 从其他语言比如C++和Java,转到Python的同学经常遇到这个问题,入口函数是什么?Python如何执行? 后来我们发 ...

  3. python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)

    在阅读博客中,发现了类装饰器的存在,由于之前就在写类相关的专栏,这次就赶紧补上之前的内容啦.类装饰器这个词是有歧义的,因为类本身可以作为装饰器,一个类也可以被函数装饰器所装饰.今天就简单介绍一下这两种 ...

  4. python定义私有变量的方法_Python怎么修改私有属性 如何访问python类中的私有方法...

    python 类为什么不能定义私有属性和方法 因为b.name[0] = 'zhang'修改的是类属性,类属性是全局的,所有的实例共享,如果想私有化,可以添加 def __init__( self ) ...

  5. python创建变量_Python每天一分钟:给类对象动态新增/删除成员变量和方法(函数)...

    一般类对象新增变量或方法的过程 在面向对象(OOP)的编程方法中,如果需要给实例化的类对象新增方法或者属性,一般都是在class类的定义中新增内容,然后才能用类对象来调用新增的方法或变量.如在C++中 ...

  6. python类成员变量_Python 类变量和成员变量

    Python 类变量和成员变量 类与对象的方法 我们已经讨论了类与对象的功能部分,现在我们来看一下它的数据部分.事实上,它们只是与类和对象的名称空间 绑定 的普通变量,即这些名称只在这些类与对象的前提 ...

  7. python 类可以调用实例变量_python面向对象中类对象、实例对象、类变量、实例变量、类方法、实例方法、静态方法...

    1. 类对象和实例对象 Python中一切皆对象,Python类本身也是一种对象,类定义完成后,会在当前作用域中定义一个以类名为名字的命名空间.类对象具有以下两种操作: 可以通过"类名()& ...

  8. python类中变量作用域_python进阶14变量作用域LEGB

    作用域 "作用域"定义了Python在哪一个层次上查找某个"变量名"对应的对象.接下来的问题就是:"Python在查找'名称-对象'映射时,是按照什么 ...

  9. python类中包含一个特殊的变量、它可以访问类的成员_Python 类的特殊成员介绍...

    类的成员有两种形式 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能方法,私有成员命名时,前两个字符是下划线. class Foo: def __init__(self, name, age ...

最新文章

  1. 产品报价单模板_一文说透报价单,这么做才是专业!附模板及注意事项
  2. C#输入框InputBox问题
  3. Objective-C中,ARC下的 strong和weak指针原理解释
  4. pdf密码强制解除软件下载 | 专业PDF解密软件 | PDF Decrypter Pro
  5. 论外挂入门(辅助入门)图色辅助与内存辅助的优与弊
  6. 计算机的影视后期论文,浅谈影视后期制作-毕业论文提纲范文
  7. 基于matlab特征脸Eigenface算法的实现
  8. c++11总结19——std::mutex
  9. Entry name ‘META-INF/androidx.vectordrawable_vectordrawable.version‘ collided
  10. Python Selenium 字节校招实习岗筛选
  11. 解决方案Solution
  12. 【百度快照推广】网页快照在SEO优化中的作用
  13. **rosdep init** 或者**rosdep update** 连接错误的解决办法
  14. W2-D1-linux下文件目录基本操作
  15. 仿360影视网站模板html
  16. 【Windows】windows10 更新到1903后 vmware14/15 无法启动解决方法
  17. 微软开源3D人体姿态估计的交叉视图融合算法,提高SOTA精度
  18. 建構收益率曲線 Yield Curve (1) 工作日調整 Business Day Convention - 用 Python 和 QuantLib
  19. H5新特性(六)——Workers和WebSocket
  20. MAC上Python升级到最新版

热门文章

  1. 智慧物流:RFID智能仓储管理解决方案-新导智能
  2. Python-4.6 查看进程的pid和ppid
  3. 【华为认证】HCIP-Datacom 2023最新题库
  4. 火车联网售票数据库设计和余票查询
  5. 数控软件怎么做自动化测试,数控机床仿真软件
  6. 【PaddlePaddle+OpenVINO】打造一个指哪读哪的AI“点读机”
  7. emWin 2天速成实例教程007_Graph波形曲线图形控件使用方法
  8. C语言实现大写字母A转换为小写a
  9. Visual Studio2005 + Visual SourceSafe 2005 实现团队开发、
  10. 合并多个HEX文件的方法