2016-04-29 82 views
1

我想知道是否有办法生成类属性,方法是循环遍历init方法的参数,而不明确引用包含init方法的所有参数的列表?如何通过扩展__init__参数来创建实例属性?

在下面的例子中,我可以循环使用hp,image,speed,x,y来创建自我参数吗?

class Character(pygame.sprite.Sprite): 
    def __init__(self, hp, image, speed, x, y): 

     # Call the parent class (Sprite) constructor 
     super(Character, self).__init__() 

     self.image = image 
     self.rect = self.image.get_rect().move(x, y) #initial placement 
     self.speed = speed 
     self.hp = hp 

例如用一个循环,看起来就像是:

class Character(pygame.sprite.Sprite): 
    def __init__(self, hp, image, speed, x, y): 

     # Call the parent class (Sprite) constructor 
     super(Character, self).__init__() 

     for arg in arguments: 
      self.arg = arg 

我不太清楚如何让“论据”是指惠普,图像,速度,X和Y?或者我坚持使用下面的列表?

class Character(pygame.sprite.Sprite): 
    def __init__(self, hp, image, speed, x, y): 

     # Call the parent class (Sprite) constructor 
     super(Character, self).__init__() 

     for arg in [self, hp, image, speed, x, y]: 
      self.arg = arg 
+0

'给arg [自我,惠普,图像,速度,X,Y]:self.arg = arg'只会留下一个单一属性'ARG '用'y'的价值...... – schwobaseggl

+0

@Sorade是有用的答案(如果是的话,请接受)?你解决了你的问题吗(请让其他人知道你是怎么做的)? – salomonderossi

回答

4

您可以使用keyword arguments (kwargs)及定义属性的列表中选择实例需要和因此你期望在你的__init__()。然后你可以遍历它们,并通过setattr分配你的属性:

class Character(pygame.sprite.Sprite): 
    ATTRS = ('hp', 'image', 'speed', 'x', 'y') 

    def __init__(self, **kwargs): 
     # Call the parent class (Sprite) constructor 
     super(Character, self).__init__() 
     for attr in self.ATTRS: 
      setattr(self, attr, kwargs.get(attr)) # sets to None if missing 
     set_rect(...) # do your processing of x, y 

甚至更​​简单,只是把所有kwargs到实例属性:

class Character(pygame.sprite.Sprite): 
    def __init__(self, **kwargs): 
     super(Character, self).__init__() 
     for key, value in kwargs.items(): 
      setattr(self, key, value) 

我会,不过,建议你对这种挂羊头卖狗肉。因为大多数IDE的(Eclipse-PyDev,PyCharm等)代码完成/解析功能都不会在现有实例上检测到这种动态设置的属性,并且也不会提示所需的参数,所以它可能会使得您的代码更短,但会稍后影响您的工作效率。当调用构造函数时,这对使用你的类的其他编码人员尤其恼人。

它也不会让你的代码更具可读性。想象一下,继承一个使用大量这种结构的代码库。你会学会喜欢一个干净明确的版本,就像你在你的问题中建议的第一个版本。一种折衷缩短您的构造函数中使用multiple assignment

self.image, self.speed, self.hp = image, speed, hp 
self.rect = self.image.get_rect().move(x, y) 
-1

您可以使用参数列表,但我不知道这是你想要的...

class Test(object): 
    def __init__(self, *args): 
     for arg in args: 
      print(arg) 

t = Test("one", 2, "three") 
+0

但是你不能以这种方式将它们分配给你的实例字段。 –

+0

你说得对。 @schwobaseggl的回答解决了这个问题;) – salomonderossi