结合 setattr 和 getattr 的 Python

标签 python class getattr setattr

我想动态地更新一个类的属性,但似乎 setattr 和 getattr 的组合并不能像我想使用的那样工作。

这是我的主要类(class):

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 到 len(values) 的切片创建 values 的副本需要循环。

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

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

然后运行:

Container(attributes, values)

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

关于结合 setattr 和 getattr 的 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15293006/

相关文章:

python - 如何在 Python 中使用编码 utf-8.py 而不是 cp1252.py

python - 在遍历字典列表时避免 KeyError

python - 如何显示 basemap 的颜色条

c++ - 一个指针,c++中的两个不同的类

JavaScript:允许访问您尝试访问的 attr 的 __defineGetter__ 版本?

python - 一台计算机上的 Bokeh 服务器,为另一台计算机服务

PHP:覆盖静态方法无法按预期工作

php - 在类中包含类是不好的做法吗?

C++ 相当于 Python getattr

python - 添加自定义对象会忽略带有运算符的 __getattr__