首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >python中cls与自身与类调用的比较

python中cls与自身与类调用的比较
EN

Stack Overflow用户
提问于 2018-07-14 08:33:14
回答 2查看 2.6K关注 0票数 0

我是Python的初学者,使用Lutz的书来理解classmethodstaticmethodinstancemethod。这段代码的目的是通过计算创建的实例数来理解clsself和直接类调用(Spam1.numInstances)之间的区别。

这里有一个来自这本书的例子。我不确定为什么父类(Spam1)属性(numInstances)在通过Sub1Other1调用时不会递增,这两个类都是子类。

下面是我的代码:

代码语言:javascript
复制
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会显示cls.numInstances的“无引用”。感到沮丧的是,我读了一些这样的帖子: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,但我不明白发生了什么。

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

创建Spam1.numInstances d**,** e**,和** f 时,为什么没有增加?a)

以下是我对这个问题的回答:

a.i)据我所知,cls是用来访问类属性的。对于de__,self.numInstances用于访问实例属性,该属性为零,因为Sub1将从Spam1__继承的属性numInstances的值设为零。cls访问Sub1__的类属性,该属性也与Sub1类的属性相同。因此,我们在输出中看到的selfcls值分别是Sub1实例和类。我的理解正确吗?

a.ii) fSpam1__继承了numInstances。因此,fself.numInstancescls.numInstancesSpam1__中获取值。它们的值是递增的,但不是Spam1的值,因为cls引用Other1,并且self引用f__,后者是Other1__的对象。因此,Spam1__的numInstances永远不会被触动。

B)我对self.numInstances**,** cls.numInstances**,和** Spam1.numInstances 区别的理解是否正确?****cls.numInstances**,和**有什么区别?如果没有,有人能解释一下吗?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-14 09:08:31

你在这里有一些误解:

  1. 在此代码中的任何位置都不存在名为numInstances的实例属性。self.numInstances检查实例属性,但是因为没有任何东西赋值给self.numInstances,所以没有实例属性可读,因此对self.numInstances的访问最终读取了类attribute.
  2. f并不完全“继承”父类的值。当cls.numInstances += 1被执行时,它试图查找Other1.numInstances,发现它不存在,并检查超类,最终找到Spam1.numInstances。它递增该值,然后将该值重新赋值给Other1.numInstances (Python中的+=总是重新赋值,即使它完成了工作,对于不可变的int,工作也没有到位);将来,访问Other1.numInstances将不会检查Spam1.numInstances,因为Other1的属性现在存在。
票数 1
EN

Stack Overflow用户

发布于 2018-07-14 09:04:58

当您使用Sub1的实例时,Spam1numInstances属性是不可访问的(除非显式编写Spam1.numInstances);count()中的cls引用Sub1,并且该属性在该类中找到,因此不需要进一步查找继承链。

当您使用Other1的实例时,numInstances的初始读取确实来自Spam1 -但一旦您赋值,它就会进入Other1 (因为cls现在是Other1 ),所有对该名称的进一步引用现在都会发现该名称而不是Spam1的版本。

代码中有三个名为numInstances的不同类属性:两个在定义Spam1Sub1类时立即存在,另一个在创建Other1的第一个实例后存在。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51334255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档