小明是个好孩子!python 面向对象:class 类的静态变量与实例变量

2022-08-1720:46:36编程语言入门到精通Comments1,259 views字数 3228阅读模式

class 类的静态变量与实例变量

小明其实是一个内心柔软的孩子文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

---------------------------------------
                  超人小明
--------------------属性----------------
    忍耐度: 小明对 每个人 的忍耐度都是有限的 
    崩溃值: 所有人 对小明的伤害达到顶点,小明就会崩溃
--------------------方法----------------

属性说明:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

  • 忍耐度:
    • 每个人的忍耐度都是相互独立的,这取决于小明和自己的关系
  • 崩溃值:
    • 所有人对小明的伤害都是累加的,这个值是公共的

如上,在代码中标示为:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

 1 #! coding:utf-8
 2 class XiaoMing:
 3 
 4     crash_count = 0
 5     crash_limit = 4
 6 
 7     def __init__(self, relationship, person_limit):
 8         self.relationship = relationship
 9         self.person_limit = person_limit
10         self.person_count = 0
11 
12 
13     def goOut(self):
14         self.person_count += 1
15         if self.person_count < self.person_limit:
16             print("%s 忍耐次数 %s ,忍耐中..."%(self.relationship, self.person_count))
17         else:
18             print ("%s 忍不了了!"%self.relationship)
19 
20         XiaoMing.crash_count += 1
21         if XiaoMing.crash_count < XiaoMing.crash_limit:
22             print ("%s 崩溃忍耐次数 %s ,还没崩溃"%(self.relationship, XiaoMing.crash_count))
23         else:
24             print ("%s 小明已经崩溃了"%self.relationship)
25 
26 brother = XiaoMing("brother",3)
27 classmate = XiaoMing("classmate",2)
28 
29 brother.goOut()
30 # ------------output---------------------#
31 # brother 忍耐次数 1 ,忍耐中...
32 # brother 崩溃忍耐次数 1 ,还没崩溃
33 classmate.goOut()
34 # ------------output---------------------#
35 # classmate 忍耐次数 1 ,忍耐中...
36 # classmate 崩溃忍耐次数 2 ,还没崩溃
37 classmate.goOut()
38 # ------------output---------------------#
39 # classmate 忍不了了!
40 # classmate 崩溃忍耐次数 3 ,还没崩溃
41 brother.goOut()
42 # ------------output---------------------#
43 # brother 忍耐次数 2 ,忍耐中...
44 # brother 小明已经崩溃了

这里我们注意到,XiaoMing.crash_count是每调用一次就全局增加1,这种变量形式就叫做静态变量,也叫做类变量。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

类变量的定义和使用必须有两个要点:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

  1. 定义类变量时,必须在def __init__()函数之外;
  2. 类变量的使用必须为ClassName.classaVariable

另外,上面的实现方式,也可以用如下的方式来实现,效果是一样的,只是不常用文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

1 class XiaoMing:
2     crash_count = 0
3     '''
4         省略其他代码
5     '''
6     @classmethod
7     def boring(cls):
8         cls.crash_count += 1

类的实例变量与类变量之间交互影响

类变量与实例变量之间并不绝对隔离,也可以互相作用影响。具体例子见下面:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

#! coding:utf-8
class XiaoMing:

    crash_count = 0
    crash_limit = 4

    def __init__(self, relationship):
        self.relationship = relationship

    def goOut2(self):
        XiaoMing.crash_count += 1
        if XiaoMing.crash_count < XiaoMing.crash_limit:
            print ("%s 崩溃忍耐次数 %s ,还没崩溃"%(self.relationship, XiaoMing.crash_count))
        else:
            print ("%s 小明已经崩溃了"%self.relationship)


if __name__ == '__main__':
    brother = XiaoMing("brother",3)
    classmate = XiaoMing("classmate",2)

#==========================================
# 类变量也可以直接调用基本类进行修改
    XiaoMing.crash_count = 5
    print(classmate.crash_count)
    print(brother.crash_count)
# -----------------output-----------------
# 5
# 5

#==========================================
# 也可以使用实例对象的class进行反射修改
    brother.__class__.crash_count = 4
    print(classmate.crash_count)
    print(brother.crash_count)
# -----------------output-----------------
# 4
# 4

但是实际上,instance.variable 并不完全等于 classname.variable;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

在使用instance.classVariable进行直接赋值操作时,这个classVariable就被克隆成了一个临时的instanceVariable文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

 1     #id()是用来查看变量指向的内存地址的;同一个变量使用的是同一个内存地址
 2     print(id(brother.crash_count))
 3     print(id(brother.__class__.crash_count))
 4     brother.crash_count =  6
 5     print(id(brother.crash_count))
 6     print(id(brother.__class__.crash_count))
 7 # -----------------output-----------------
 8 # 4297644544
 9 # 4297644544
10 # 4297644576
11 # 4297644544

如果上面概念没有完全理解的话,那么请看下面例子:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html

 1 #==========================================
 2 #但如果使用实例对象来赋值,则就会变为局部变量了。只对当前的实例对象有效,且不会影响到类变量的值
 3     classmate.crash_count = 2
 4     print(classmate.crash_count)
 5     print(classmate.__class__.crash_count)
 6     print(brother.crash_count)
 7     classmate.goOut2()
 8     print(classmate.crash_count)
 9 # -----------------output-----------------
10 # 2
11 # 5
12 # 5
13 # classmate 小明已经崩溃了
14 # 2

思考与练习

  • 为什么类变量一定要定义在__init__函数之外?
  • 类变量与实例变量的使用场景?
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/27359.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/27359.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定