【问题标题】:Am I using the constructor __init__ wrong?我使用构造函数 __init__ 错了吗?
【发布时间】:2015-01-26 12:39:01
【问题描述】:

我有一个类试图创建一个实例,该实例随后被定义为一个精灵,但它也允许该实例具有其他变量(这是我在一个 atari 突围游戏上的进展的跟进,我问了另一个问题here。)

只是一个旁注(可能解释得不是很好,抱歉):我最初将我的所有属性都附加到了一个“砖”属性:

self.brick = pygame.sprite.Sprite() # the .brick is now a sprite

因为我认为给精灵用户发明属性是不可能的,例如 self.brick.hardness 所以我这样做了:

self.hardness = 1 # the object has another attribute not interfering with the sprite

这与我的精灵碰撞引擎产生了一些冲突(长话短说; .brick 属性无法调用该方法 blockType 因为它是不是该类的实例),所以我只是决定将实际实例设为精灵,这可能会导致与其隐藏的属性发生一些冲突。

精灵是通过__init_构造函数创建的,其他属性只有在调用相应的方法时才会添加。

class Block:        
    def __init__ (self):
        self = pygame.sprite.Sprite()
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([width, height])
        self.rect = self.image.get_rect()
    def blockType (self, hardness):
        self.hardness = hardness
        if self.hardness == 1:
            self.image.fill (RED)

block = Block () # These parenthesis might be wrong here
block.blockType (1)

现在这个问题可能又是由于继承,但是当我创建实例时,一切都很好。但是,当我尝试调用该方法时,出现错误:

AttributeError: 'Block' object has no attribute 'image'

我认为这很奇怪,因为对象在通过运行构造函数方法创建后应该具有图像属性(如果我不调用该方法,我实际上完全有能力在屏幕上绘制这些精灵,所以它们可以技术上存在)。我已经尝试过解决这个问题,但在这一点上,我完全不知道出了什么问题。

如果您需要更多信息,请告诉我,我会更新。

【问题讨论】:

  • 我可能在您的问题中错过了它,但是您为什么不从pygame.sprite.Sprite() 继承您的Block
  • 你的类Block没有继承自pygame.sprite.Sprite,那为什么要在这里调用Sprite.__init__方法呢?
  • 在上一个问题中,您使用了pygame.sprite.Sprite.__init__(self.brick) 这一行。这也不需要,因为使用Sprite() 创建self.brick 对象已经调用了该方法
  • @MartijnPieters 哇,你是对的。出于某种原因,这就是我的老师教它的方式,而这就是我一直没有质疑的方式。感谢您指出了这一点。另外,关于您的第一条评论,出于某种原因,我认为 Sprite () 方法可以在任何地方调用,因为它是 pygame 的一部分,但我猜类语法总是迫使您在调用它们之前继承其他类属性对吗?
  • @AndresStadelmann:我想你当时误解了一些东西;当继承您(可能)想要调用基类上的原始__init__ 方法。但是你不是在这里继承; Block 不是 Sprite,它仅包含一个 sprite(has-ais-a 关系)。

标签: class python-3.x constructor initialization pygame


【解决方案1】:

使用此代码时

class Block:        
    def __init__ (self):
        self = pygame.sprite.Sprite() # don't overwrite self here
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([width, height])
        self.rect = self.image.get_rect()

您用Sprite 的新实例覆盖self(这是对新创建的Block 实例的引用);并且该实例迟早会被删除,因为您没有保留它的引用。

我猜你的意图是继承 Sprite(这在使用 pygame 时很常见),所以你必须使用:

class Block(Sprite):        
    def __init__ (self):
        super().__init__()
        self.image = pygame.Surface([width, height])
        self.rect = self.image.get_rect()

现在BlockSprite 的子类,并具有imagerect 属性。

【讨论】:

  • 哇!好的,现在更有意义了。我曾经写过class Block (pygame.sprite.Sprite) 来尝试继承它,但它永远不会起作用,但是这正是我所需要的,非常感谢!
猜你喜欢
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2015-02-05
  • 2020-01-04
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
相关资源
最近更新 更多