Python子类conu

2024-09-29 19:23:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个python代码。对于X,结果是TopTest: attr1=0, attr2=1,这很好,但是对于Y,结果是{},我不太理解。在

基本上,我有一个class属性,它是一个计数器,它运行在__init__ method中。当我启动Y时,计数器被设置为2,并且只有在属性被分配之后。我不明白为什么从2点开始。子类不应该复制父类并在0重新启动计数器吗?在

class AttrDisplay: 
  def gatherAttrs(self):        
    attrs = []        
    for key in sorted(self.__dict__):            
        attrs.append('%s=%s' % (key, getattr(self, key)))        
    return ', '.join(attrs)
  def __repr__(self):        
    return '[%s: %s]' % (self.__class__.__name__, self.gatherAttrs())

class TopTest(AttrDisplay): 
    count = 0        
    def __init__(self):            
        self.attr1 = TopTest.count            
        self.attr2 = TopTest.count+1            
        TopTest.count += 2

class SubTest(TopTest):
    pass

X, Y = TopTest(), SubTest()         
print(X)                            
print(Y)                         

Tags: keyselfreturn属性initdefcount计数器
3条回答

您可以显式地访问和使用TopTest.count,并且您的子类将坚持这种明确性。您可能需要考虑使用type(self).count,然后每个实例将使用自己类的变量,该变量可以在每个子类中变为不同的变量。在

要使子类有自己的类变量,只需在其定义中添加一个count = 0

class SubTest(TopTest):
    count = 0

你很接近——当你查找一个对象的属性时,你不一定要查找一个属于对象本身的属性。相反,查找遵循Python的method resolution order,它。。。并不完全简单。但是,在这种情况下,只执行三个步骤:

  1. 检查Y是否具有名为count的属性。在
  2. 它没有,所以检查它的类SubTest是否有一个名为count的属性。在
  3. 它没有,所以检查它的父项TopTest是否有一个名为count的属性。是的,所以访问那个。在

简单地说,当您访问Y.count实际上是在访问TopTest.count。在


还有一个事实是,您的代码子测试增量TopTest的计数中有一个bug,而不是它自己的错误。你的问题的标题是“subclass counter”,但是由于你在__init__()中计数,我假设你在寻找一个实例计数器(要计算子类,我非常确定you'd need to use metaclasses)。这是self.__class__的完美用例,它是一个包含对象类的属性!为了使用它:

def __init__(self):
    self.attr1 = self.__class__.count
    self.attr2 = self.__class__.count + 1            
    self.__class__.count += 2

使用它,当您调用SubTest()时,SubTest.count将递增,而不是{}。在

SubTest的新实例被创建时,TopTest.__init__()被调用-因为SubTest继承了{}-这将使TopTest.count增加两倍。在

而且由于SubTest从未定义类级别的count变量,所以当SubTest.count被执行时,Python会后退并使用TopTest.count。在

可以通过将count本地重新定义为SubTest来修复此行为。在

class SubTest(TopTest):
    count = 0

相关问题 更多 >

    热门问题