2012-09-14 33 views
0

分配的变量集类对象更方便的方法,通常是这样的:变量分配给类对象的属性

player.x = 1 
player.y = 10 
player.name = 'John' 

因为列表和元组允许你这样做

a,b,c = (1,10,'John') 

所以这个作品

player.x,player.y,player.name = (1,10,'John') 

或本

player.x,player.y,player.name = 1,10,'John' 

我想要更改player属性,我需要输入太多player。这是一种更懒惰的方式吗?

+0

第一个有什么问题?你想做什么? – grc

+1

其实,在这两种情况下,你都会输入“player”三次。在第二种解决方案中,输入更多字符,因为您需要输入括号和逗号来创建元组。 –

+1

设置p =玩家。 – verbsintransit

回答

2

什么是这样的:

def set_properties(instance, properties): 
    for property in properties: 
     setattr(instance, property, properties[property]) 

因为我们正在谈论的是一个懒惰的程序员,你可以重写功能:

def set_properties(instance, properties): 
    for key,val in properties.iteritems(): 
     setattr(instance, key, val) 

上面的代码是有点短,但也应对于大型字典运行速度更快,因为它在循环之前解压一次。比较每个迭代都会调用属性字典的第一个版本。

用法:

set_properties(player, {'x': 1, 'y': 10, 'name': 'John'}) 
0

您可以使用一种方法将属性的更改包装在一起,这些属性可能总是发生在一起,如def edit(self, **kwargs)或只是位置参数,并在此范围内为玩家分配self.property = kwargs.get(propertyName, default)。您也可以在该类上创建一个属性,以执行您在示例中使用过的那种元组分配。

2
player.__dict__.update({'x':12,'y':24,'name':'Billy'}) 

为不短,但使用的字典可以比像您只是一个直接的例子多个实例得心应手。

1

使用zip()player.__dict__

In [14]: class player: 
    ....:  pass 
    ....: 

In [15]: for prop,value in zip(("x","y","name"),(1,10,"john")): 
    player.__dict__[prop]=value 
    ....:  
    ....:  

In [18]: player.__dict__ 
Out[18]: {'__doc__': None, '__module__': '__main__', 'name': 'john', 'x': 1, 'y': 10} 
1

这里是这样做的另一种方式,但所有的其他人一样,它比你开始什么用的可读性:如果您设置相同的

from functools import partial 

map(partial(setattr, player), ("x", "y", "name"), (1, 10, 'John')) 

在你的代码中的几个地方设置或设置属性,或许为每个这样的设置添加一个命名方法是更好的选择?

class Player(object): 

    # [...] 

    def set_stats(self, x, y, name): 
     self.x = x 
     self.y = y 
     self.name = name 

然后你就可以使用代码是短期和非常可读的设置这些属性:

player.set_stats(1, 10, "John") 
1

基本回路可以工作:

for (k,v) in zip(attribute_names, attributes_values): 
    setattr(player, k, v) 

当然,你可以起诉一些列表理解,如:

trash = [setattr(player, k, v) for (k,v) in zip(attribute_names, attributes_values)] 

,但它并没有真正改善任何东西(你trash拥有多达None作为len(attribute_names) ...

0

我不是100%肯定,但它的声音,我认为在这种情况下,使用namedtuple会是一个更好方法:需要注意的是只有已知字段应该存在(即不能动态地添加/删除),并且类实际上不过是具有属性样式访问字段的记录。

from collections import namedtuple 

Player = namedtuple('Player', 'x y name') 
player = Player._make([1, 3, 'Bob']) 
print player 
# Player(x=1, y=3, name='Bob') 
player = player._replace(name='Jim', x=13) 
print player 
# Player(x=13, y=3, name='Jim') 

否则,我会亲自去为您的Player class添加一个方便的方法。