代码之家  ›  专栏  ›  技术社区  ›  watchtower

python中的cls vs.self vs.类调用

  •  0
  • watchtower  · 技术社区  · 8 年前

    我是一个python初学者,用lutz的书来理解 classmethod , staticmethod 和 instancemethod 是的。此代码的目的是了解 cls ,请 self ,以及直接的类调用( Spam1.numInstances )通过计算创建的实例数。

    这是从这本书中得到的一个例子。我不确定为什么是家长班( Spam1 )属性( numInstances )调用时不递增 Sub1 和 Other1 ,这是子类。

    这是我的代码:

    class Spam1:
        numInstances = 0
        def count(cls):
            cls.numInstances += 1
            print("In count -> number of instances: cls, Spam", cls.numInstances, Spam1.numInstances)
    
        def __init__(self):
            print("-----")
            print("In init, before -> number of instances: self, Spam",self.numInstances,Spam1.numInstances )
            self.count()
            print("In init, after -> number of instances: self, Spam",self.numInstances,Spam1.numInstances )
            print("-----")
    
        count=classmethod(count)
    
    
    class Sub1(Spam1):
        numInstances = 0
    
    class Other1(Spam1):
        pass
    
    a=Spam1() #Output after increment: 1,1,1 (self, cls, Spam1)
    b=Spam1() #Output after increment: 2,2,2 (self, cls, Spam1)
    c=Spam1() #Output after increment: 3,3,3 (self, cls, Spam1)
    d=Sub1()  #Output after increment: 1,1,3 (self, cls, Spam1)
    e=Sub1()  #Output after increment: 2,2,3 (self, cls, Spam1)
    f=Other1() #Output after increment: 4,4,3 (self, cls, Spam1)
    

    我花了一天时间试着调试这段代码,但我不明白 cls.numInstances 因为Pycharm会对 新民寺 处于调试模式。因为沮丧,我读了几篇这样的文章: What does cls() function do inside a class method? , What is the 'cls' variable used for in Python classes? 和 Python - self, no self and cls ,但我不明白发生了什么。

    具体来说,以下是我的问题:

    a)为什么 温泉 当 d ,请 e ,和 f 是被创造出来的?

    我试图回答这个问题:

    我的理解是 CLS 用于访问类属性。为了 丁 和 E类 , self.numInstances 用于访问实例属性,该属性为零,因为 第1款 将继承属性的值归零 努明斯坦 从 SPAM1号 是的。 CLS 访问的类属性 第1款 ,这也与 第1款 上课。因此, 自己 和 CLS公司 我们在输出中看到的值是 第1款 实例和类。我的理解正确吗?

    (第二章) F型 继承 努明斯坦 从 SPAM1号 是的。因此, 努明斯坦赛尔夫 和 新民寺 属于 F型 从中获取值 SPAM1号 是的。它们的价值是递增的,但不是 SPAM1号 因为 CLS公司 指 其他1 因为 自己 指 F型 ,这是 其他1 是的。因此, SPAM1号 的 努明斯坦 从未被触碰过。

    b)我是否理解 努明斯坦赛尔夫 我是说, 新民寺 ,和 温泉 对的?如果没有,有人能解释一下吗?

    我相信我的问题很基本。我希望有人能帮我。我迷路了。

    2 回复  |  直到 8 年前
        1
  •  1
  •   ShadowRanger    8 年前

    你有几个误解:

    1. 有 从未 名为 numInstances 在这段代码的任何一点上。 self.numInstances 检查 对于实例属性,但因为没有 赋值 到 努明斯坦赛尔夫 ,没有要读取的实例属性,因此访问 努明斯坦赛尔夫 最后读取类属性。
    2. f 并不完全“继承”父类的值。什么时候? cls.numInstances += 1 被处死了,它试着抬起头来 Other1.numInstances 发现它不存在,检查超类,最终找到 Spam1.numInstances 是的。它会增加该值,然后将其重新分配给 其他1.Numinstances ( += 在python中,即使工作已经到位,也总是重新分配,并且对于不可变的 int ,工作是 不 在未来,访问 其他1.Numinstances 不会检查 温泉 ,作为 Other1 属性现在存在。
        2
  •  1
  •   jasonharper    8 年前

    当您使用 Sub1 我是说, Spam1 的 numInstances 属性不可访问(通过显式写入除外 Spam1.numInstances )(二) cls 在里面 count() 指 第1款 ,并且该属性在该类中找到,因此无需进一步查找继承链。

    当您使用 Other1 ,初始读数为 努明斯坦 确实来自 SPAM1号 -但是一旦你分配了一个值 其他1 (因为 CLS 是 其他1 现在),所有对该名称的进一步引用现在都会发现 SPAM1号 的版本。

    有三个不同的类属性名为 努明斯坦 在您的代码中:两个存在于类中 SPAM1号 和 第1款 定义的,以及在第一实例之后存在的 其他1 是创建的。