除非由类调用提供,否则为属性设置默认值的最简洁方法是什么?

时间:2016-09-11 17:55:25

标签: python python-3.x

目前这就是我正在做的事情:

class NewShip:
    def __init__(self, position = (0,0), x_velocity = 25, y_velocity = 15, anim_frame = 1, frame1 = "space_ship_1.png", frame2 = "space_ship_2.png", angle = 0, border_size = 900):
        self.position = position
        self.angle = angle
        self.x_velocity = x_velocity #in pixels per frame
        self.y_velocity = y_velocity #in pixels per frame
        self.anim_frame = anim_frame
        self.frame1 = pygame.image.load(frame1).convert_alpha()
        self.frame2 = pygame.image.load(frame2).convert_alpha()
        self.frame1 = pygame.transform.scale(self.frame1, (128,128))
        self.frame2 = pygame.transform.scale(self.frame2, (128,128))
        self.position = DummyObject()
        self.position.x = position[0]
        self.position.y = position[1]
        self.border_size = border_size

但老实说这很乏味,并且使得添加任何兼性属性成为一种真正的痛苦。

我是否应该跳过整个'让人们用关键字参数声明属性'并在更改任何属性之前将对象设置为完全默认状态?

编辑: 显然这很完美:

class NewShip:
    def __init__(self, **kwargs):
        self.angle = 0
        self.x_velocity = 25 #in pixels per frame
        self.y_velocity = 15 #in pixels per frame
        self.anim_frame = 1
        frame1 = "space_ship_1.png"
        frame2 = "space_ship_2.png"
        self.position = DummyObject()
        self.position.x = 0
        self.position.y = 0
        self.border_size = 900
        for element in kwargs: setattr(self, element, kwargs[element])
        self.frame1 = pygame.image.load(frame1).convert_alpha()
        self.frame2 = pygame.image.load(frame2).convert_alpha()
        self.frame1 = pygame.transform.scale(self.frame1, (128,128))
        self.frame2 = pygame.transform.scale(self.frame2, (128,128))

也就是说,只需设置所有默认值,然后使用for element in kwargs: setattr(self, element, kwargs[element])

关键字args覆盖它们

让我知道是否有更清洁的方式,但我不得不说我对此更满意。

1 个答案:

答案 0 :(得分:3)

为了减少混乱,您可以选择定义默认字典属性_init_attrs,例如使用**kwargs定义您的函数,然后使用循环在setattr上定义self,如果没有提供参数,请使用_init_attrs[k]作为default的{​​{1}}值:

kwargs.get

这使class NewShip: def __init__(self, **kwargs): _init_attrs = {'angle': 0, 'anim_frame': 1, 'border_size': 900, 'frame1': 'space_ship_1.png', 'frame2': 'space_ship_2.png', 'position': (0, 0), 'x_velocity': 25, 'y_velocity': 15 } for k, v in _init_attrs.items(): setattr(self, k, kwargs.get(k, v) 更加神秘,但实现了在缩小规模的同时使其更具可扩展性的目标。