将变量赋给类对象属性的更方便的方法

时间:2012-09-14 07:22:15

标签: python

将一组变量分配给类对象,通常是这样的:

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

因为list和tuple允许你这样做

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。这是一种更懒惰的方式吗?

7 个答案:

答案 0 :(得分: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'})

答案 1 :(得分:2)

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

不短,但使用字典可以在更多实例中使用,而不仅仅是像您提供的直接示例。

答案 2 :(得分: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}

答案 3 :(得分: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")

答案 4 :(得分: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)]

但它并没有真正改善任何事情(您的trashNone一样多len(attribute_names) ...

答案 5 :(得分:0)

您可以使用一种方法将对您可能会发现的属性的更改(例如def edit(self, **kwargs)或仅位置args)和对此类型中的播放器类分配self.property = kwargs.get(propertyName, default)进行换行。您还可以在类上创建一个属性,该属性执行您在示例中使用的那种元组赋值。

答案 6 :(得分:0)

我不是百分百肯定,但在我看来,在这种情况下,使用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添加便捷方法。