一次设置多个对象属性

问题描述 投票:0回答:5

有没有一种方法可以在一行中设置同一对象的多个属性,类似于为多个变量赋值的方式?

如果我会写的话

a,b,c=1,2,3

我想要一些类似的东西

someObject.(a,b,c)=1,2,3

效果相同
someObject.a=1
someObject.b=2
someObject.c=3
python variables attributes
5个回答
24
投票
def setattrs(_self, **kwargs):
    for k,v in kwargs.items():
        setattr(_self, k, v)

像这样使用此功能:

setattrs(obj,
    a = 1,
    b = 2,
    #...
)

您也可以在类上定义此函数,但这会不太通用(即仅适用于该类实例)。

另一个答案提到了

__dict__.update
,可以重写它以去掉引号:
obj.__dict__.update(a=1, b=2)
,但是我不建议使用这种方法:它不适用于属性,如果您从简单迁移,可能很难注意到属性到属性。基本上,
__dict__
是“隐藏”属性,实现细节,除非您确实想以某种方式更改实现,否则您不应该使用它。


6
投票

首先,您可以对对象属性执行与其他变量相同的操作:

someObject.a, someObject.b, someObject.c = 1,2,3

不确定这是否是您的想法。如果你想更新任意属性(例如在函数中),那么你可以利用 Python 对象将其属性存储在字典中的事实,该字典支持 update() 方法:

someObject.__dict__.update({"a":1, "b":2, "c":3})

但是,必须小心操作!如果有人在函数中提供此功能,则可以使用该函数更改 someObject 的任何属性,甚至可以插入新属性!


3
投票

您可以使用

map
通过属性和值的字典来更新对象的属性。

attrs = {'a': 1, 'b': 2, 'c': 3}

map(lambda item: setattr(someObject, *item), attrs.iteritems())

在 Python 3 中,您需要用列表包围

map
调用,并将
iteritems
转换为
items
,如下所示。

list(map(lambda item: setattr(someObject, *item), attrs.items()))

1
投票
attributes = ['a', 'b', 'c']
values = [1, 2, 3]
for attr, val in zip(attributes, values):
    setattr(obj, attr, val)

0
投票

我已经按照@cariocelus 的回答进行操作,并且它有效。但是,如果您尝试设置一个不存在的属性,该函数将创建它。我创建了一个类和一个设置器,只有在变量已经初始化时才起作用。

class my_object():
    def __init__(self):
        self.a = 0
        self.b = 0
        
    def set_state(self, **kwargs):
        for k, v in kwargs.items():
            if k in dir(self):
                setattr(self, k, v)
x = my_object
x.set_state(a=1, b=2, c=3)

print(x.c)
AttributeError: 'my_object' object has no attribute 'c'
© www.soinside.com 2019 - 2024. All rights reserved.