Python:调用类方法而不是父构造函数

时间:2014-07-16 07:45:00

标签: python

说我有以下类定义:

class WorldObject(pygame.sprite.Sprite):

    @classmethod
    def fromImgRect(cls, rect, image, collideable = True):
        return cls(rect.left, rect.top, rect.width, rect.height, image, collideable)        

    def __init__(self, x, y, w, h, image, collideable = True):
        self.rect = pygame.rect.Rect(x,y,w,h)
        self.collideable = collideable
        self.image = image

然后我有以下子类:

class Doodad(WorldObject):    
    def __init__(self,c1x, c1y, c2x, c2y, color = (200,0,180)):
        self.color = color
        self.rect = orderPoints(c1x, c1y, c2x, c2y)
        x1 = self.rect.left
        y1 = self.rect.top
        w = self.rect.width
        h = self.rect.height
        super(Doodad, self).__init__(x1,y1,w,h,self.surface, False)

这很好用,但是在我的代码中必须解包这样的self.rect是很烦人的,而不是只在类方法中执行一次。这在整个项目的许多地方都会发生,我的几个方法返回一个矩形对象,但我需要将坐标传递给超级构造函数。它看起来似乎不可能让所有东西都返回坐标或矩形,有时候只做一个或另一个更有意义。由于python不支持重载方法,我希望能够使用类方法初始化对象。但是我无法弄清楚语法。这可能吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:0)

在你的情况下,我会为"子初始化"添加一个方法。这将对给定数据进行后处理:

class WorldObject(pygame.sprite.Sprite):

    @classmethod
    def fromImgRect(cls, rect, *a, **k):
        return cls(rect.left, rect.top, rect.width, rect.height, *a, **k)

    def __init__(self, x, y, w, h, image, collideable=True):
        self._init_coords(x, y, w, h)
        self.collideable = collideable
        self.image = image

    def _init_coords(self, x, y, w, h):
        self.rect = pygame.rect.Rect(x,y,w,h)

然后您可以拥有以下子类:

class Doodad(WorldObject):
    def _init_coords(self, c1x, c1y, c2x, c2y):
        self.rect = orderPoints(c1x, c1y, c2x, c2y)

    def __init__(self,c1x, c1y, c2x, c2y, color=(200, 0, 180)):
        super(Doodad, self).__init__(c1x, c1y, c2x, c2y, self.surface, False)
        self.color = color

此外,你可能想要

def unpack_rect(rect):
    return rect.left, rect.top, rect.width, rect.height

你甚至可以拥有

class WorldObject(pygame.sprite.Sprite):

    def __init__(self, *a, **k):
        if hasattr(a[0], 'left'):
            rect = a[0]
            self._init_coords(rect.left, rect.top, rect.width, rect.height)
            rest = a[1:]
        else:
            self._init_coords(*a[0:4])
            rest = a[4:]
        self._init_rest(*rest, **k)

    def _init_coords(self, x, y, w, h):
        self.rect = pygame.rect.Rect(x,y,w,h)

    def _init_rest(self, image, collideable=True):
        self.collideable = collideable
        self.image = image


class Doodad(WorldObject):
    def _init_coords(self, c1x, c1y, c2x, c2y):
        self.rect = orderPoints(c1x, c1y, c2x, c2y)

    def _init_rest(color=(200, 0, 180)):
        super(Doodad, self)._init_rest(self.surface, False)
        self.color = color

(我这里没有改变self.surface,但现在没有定义。你应该改变它。)