修改setattr以批量赋值多个属性不同的值

3 投票
2 回答
3490 浏览
提问于 2025-04-18 10:04

我想创建一个类,这个类可以一次性给多个属性赋不同的值。于是,我尝试修改setattr来实现这个功能。

class hello():
    def __setattr__(self,attr,value):
        if type(attr) == str:
            self.__dict__[attr] = value
        elif type(attr) == list:
            for item,val in zip(attr,value):
                self.__dict__[item] = val
        else:
            print "Error!!!"

这样我的类就会有以下属性:

>>> hola = hello()
>>> setattr(hola,["a","b"],[1,2])
>>> hola.a
1
>>> hola.b
2

但是这样做会返回

TypeError: attribute name must be string, not 'list'

确实,我可以在类里面定义一个特殊的方法来完成这个任务,比如说:

def assigner(self, attrlist, valuelist):
    for item,value in zip(attrlist,valuelist):
        self.__dict__[item] = value

但我想知道为什么通过setattr不行,以及做这个工作的最有效的方法是什么。

2 个回答

0

这个TypeError错误说得很清楚:第二个参数的名字必须是一个字符串,而不是一个列表。

这里的参数包括一个对象、一个字符串和一个任意的值。

https://docs.python.org/2/library/functions.html#setattr

2

来自关于setattr函数的文档

这个函数需要三个参数:一个对象,一个字符串和一个任意的值。

第二个参数必须str类型,也就是字符串。

一个可能的解决办法是定义__setitem__,而不是__setattr__

class hello():
    def __setitem__(self, k, v):
        self.__dict__.update(zip(k, v) if type(k) is tuple else [(k, v)])

这样你就可以像操作字典一样给值赋值了。

In [2]: heya = hello()

In [3]: heya['a', 'b'] = [1, 2]

In [4]: heya.a
Out[4]: 1

In [5]: heya.b
Out[5]: 2

不过,依然没有什么能阻止你用这种方式来赋值。

In [15]: heya.a, heya.b = [1, 2]

撰写回答