简体   繁体   English

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

[英]Python: Calling class method instead of parent constructor

Say I have the following class definition: 说我有以下类定义:

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

Then I have the following child class: 然后,我有以下子课程:

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)

This works just fine, however it is annoying to have to unpack self.rect like this all throughout my code, instead of just doing it once in the class method. 这很好用,但是在我的整个代码中都self.rect像这样对self.rect进行解压缩,而不是只在class方法中执行一次。 This is happening in many places throughout my project, where several of my methods return a rectangle object, but I need to pass coordinates to a super constructor. 这在我的项目的许多地方都在发生,其中一些方法返回一个矩形对象,但是我需要将坐标传递给超级构造函数。 It doesn't look like its possible to have everything return either coordinates or a rectangle, sometimes it just makes more sense to do one or the other. 使所有内容返回坐标或矩形似乎是不可能的,有时候做一个或另一个更有意义。 Since python doesn't support overloading methods, I'd like to be able to use the class method to initialize the object. 由于python不支持重载方法,因此我希望能够使用class方法来初始化对象。 However I haven't been able to figure out the syntax. 但是我还不能弄清楚语法。 Is this possible? 这可能吗? If so, how? 如果是这样,怎么办?

In your situation, I would add a method for "sub-initializing". 在您的情况下,我将添加一种“子初始化”的方法。 This would post-process the given data: 这将对给定的数据进行后处理:

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)

Then you can have the following child class: 然后,您可以具有以下子类:

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

Besides, you might want to have 此外,您可能想拥有

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

You can even have 你甚至可以拥有

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

(I didn't change self.surface here, but it is not defined at this moment. You should change that.) (我没有在此处更改self.surface ,但目前尚未定义。您应该更改它。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM