【问题标题】:Python Class Inheritance, __init__ and clsPython 类继承、__init__ 和 cls
【发布时间】:2013-10-18 12:59:51
【问题描述】:

代码的期望输出是我有一个类变量 Team.stuff,它有一个包含 b 实例的条目,并且 Player.stuff 变量应该为空。相反,我得到一个错误...

class Player:
  stuff=[]
  def __init__(self):
    cls.stuff.append(self)

class Team(Player):
  def __init__(self):
    super(Team, self).__init__()

b=Team()

错误

cls.stuff.append(self)
NameError: global name 'cls' is not defined

我可以在 Team.__init__() 中传递 cls 变量,但我不确定这是否是“正确”的方式,更重要的是 Player.__init__() 需要一个类变量,我不确定如何做到这一点的语法。

【问题讨论】:

    标签: python inheritance initialization class-method class-variables


    【解决方案1】:
    class Player(object):
        stuff=[]
        def __init__(self):
            self.stuff.append(self)
    
    class Team(Player):
        def __init__(self):
            super(Team, self).__init__()
    
    b = Team()
    print(Team.stuff)
    

    打印(类似)

    [<__main__.Team object at 0xb7519dec>]
    

    【讨论】:

    • 谢谢,但这不是我需要的。我需要打印(Team.stuff),而不是打印(b.stuff)
    【解决方案2】:

    请记住,cls 在 Python 中不是关键字。相反,当该方法应该是类函数而不是在某个特定实例上调用的方法时,它是该方法的第一个参数的约定。

    如果您希望stuff 成为函数的属性,您必须像这样定义它:self.stuff=[]

    然后,当您在方法中引用它时,也可以使用 self 关键字:self.stuff.append(..)

    【讨论】:

      【解决方案3】:

      原因是你的__init__ 函数中的cls 没有定义。参数名称selfcls 只是命名约定。实际上,您可以分别将它们命名为 foobar 作为实例和类方法,foo 将指向类实例,而 bar 将指向类本身。

      此外,self.stuff 将是有效的,因为在搜索属性时,如果对象在其 __dict__ 字典中没有此类名称的属性,则会查找其类的 __dict__。如果两者都缺失,则根据mro 顺序进行进一步查找。

      请注意,一旦您在对象实例上设置属性stuff,它将隐藏类定义。

      举例说明:

      class MyClassA(object):
          stuff = []
      
      class MyClassB(MyClassA):
           def __init__(foobar):
               # `foobar` points at the instance of `MyClassB` class.
      
               # MyClassA.stuff gets `1` object appended to it.
               foobar.stuff.append(1)
      
               # This should print '[1]'
               print foobar.stuff
      
               # `MyClassB` object gets a _new_ attribute named `stuff` pointing at a list.
               foobar.stuff = []
      
               # This should print '[]'.
               print foobar.stuff
      

      【讨论】:

        猜你喜欢
        • 2011-09-26
        • 2012-01-31
        • 2011-08-03
        • 2010-10-19
        • 2020-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多