如何将字典键值作为属性添加到对象

How to add dictionary key-values to an object as properties

这个问题已经有人问过,但不完全是这样(我不能使用任何答案):我想调用一个 returns 字典的函数,如果这个字典不是None,循环它并在一个对象上使用它的键+值。注意:此对象来自 class,它的 class 无法修改 。类似于:

def check_ok(s):
  return {'prop_1': 'x',
          'prop_2': 'y'}


def check_and_update(obj, st):
    result = check_ok(st)
    if result is not None:
        for k, v in result.items():
            obj.k = v  # doesn't work, of course

解决方法是什么?

您可以通过以下方式实现:

  1. 创建你自己的class
  2. 通过使用 set_attr 方法将这些值添加到对象的字典中
def check_ok(s):
  return {'prop_1': 'x',
          'prop_2': 'y'}


class UpdateableObject(object):
    pass

def check_and_update(obj, st):
    result = check_ok(st)
    if result is not None:
        for k, v in result.items():
            setattr(obj, k, v)

uob = UpdateableObject()
# Passed None because the `check_ok` functions doesn't use the `st` parameter
check_and_update(uob, None)

# {'prop_1': 'x', 'prop_2': 'y'}
print(f'{uob.__dict__}')

让我解释一下"NB: this object is from a class and its class can't be modified."的意思of: 你不能修改class的代码,但是修改实例属性就可以了。

然后可以使用setattr修改对象:

def check_and_update(obj, st):
    result = check_ok(st)
    if result is not None:
        for k, v in result.items():
            setattr(obj, k, v)

此外,尽早 stopping/exiting 实施可能是个好主意,这取决于您的代码有多长(并且取决于您在这种情况下想要做什么) .这消除了代码的一级缩进并使代码更容易阅读,因为“reader”对于 elifelse 子句不是 waiting/looking:

def check_and_update(obj, st):
    result = check_ok(st)
    if result is not None:
        return  # or whatever you want to do here
    for k, v in result.items():
        setattr(obj, k, v)

并且如果由于某种原因 class 的 obj 实际上是不可变的,您总是可以尝试继承 class 并覆盖关键部分:

class MyMutableClass(ImmutableClass):
    def __init__(self, arguments):
         pass  # do whatever is necessary to make changes...