我想动态更新类的属性,但是setattr和getattr的组合似乎无法使用,因为我想使用它。

这是我的主要课程:

class Container(object):
    def __init__(self):
        pass
container = Container()
attributes = ['a', 'b', 'c', 'd']
values = [[1, 2, 3, 4, 5], [True, False], ['red', 'blue', 'green'], [0, 1, -1, -5, 99]]


请注意,出于该示例的目的,我明确构造了属性及其各自值的列表。但是,在此代码的实际应用中,我事先一无所知。它们的编号,名称或值都没有。这就需要动态地做到这一点。

这是其余的代码:

for key, value in zip(attributes, values):
    setattr(container, key, [])
    for val in value:
        setattr(container, key, getattr(container, key).append(val))


当我运行代码时,此部分不起作用。我可以将getattr部分保存在tmp变量中,然后在调用setattr之前为列表调用append方法,但是如果可能的话,我希望将其压缩。

谁能解释我为什么这行不通?我有什么选择?

谢谢你的帮助

最佳答案

您将就地添加到列表。像所有就地突变函数一样,.append()返回None,所以最后一行:

setattr(container, key, getattr(container, key).append(val))


最终评估为:

setattr(container, key, None)


只需在课程上设置列表的副本即可:

for key, value in zip(attributes, values):
    setattr(container, key, values[:])


其中,[:]通过以简写表示法从0切片为values来创建len(values)的副本,而无需循环。

如果您要做的只是创建一个将键和值作为属性提供的对象(很像dict仍具有属性访问权限而不是项目访问权限),则还可以使用:

class Container(object):
    def __init__(self, names, values):
        self.__dict__.update(zip(names, values))


然后运行:

Container(attributes, values)


这消除了在循环中调用setattr()的需要。

08-06 10:08