如何在给定虚线路径的对象上设置属性?

时间:2018-08-16 12:17:15

标签: python

给出一个对象,该对象可以是dict类或数组类对象的嵌套结构。给定虚线路径作为字符串的那个对象上设置值的pythonic方法是什么?

示例:

obj = [
    {'a': [1, 2]},
    {'b': {
        'c': [3, 4],
    }},
]

path = '1.b.c.0'

# operation that sets a value at the given path, e.g.
obj[path] = 5

# or
set_value(obj, path, 5)

上述呼叫/分配应将示例中的3替换为5

注意:路径可以包含列表索引以及键。对象的每个级别都可以是arraydict或类似的对象。

解决方案应大致类似于npm软件包object-path在javascript中的工作。

2 个答案:

答案 0 :(得分:4)

非递归版本,也适用于数字字典键:

from collections.abc import MutableMapping

def set_value_at_path(obj, path, value):
    *parts, last = path.split('.')

    for part in parts:
        if isinstance(obj, MutableMapping):
            obj = obj[part]
        else:
            obj = obj[int(part)]

    if isinstance(obj, MutableMapping):
        obj[last] = value
    else:
        obj[int(last)] = value

答案 1 :(得分:3)

听起来像是递归工作和str.partition

def set_value(obj, path, val):
    first, sep, rest = path.partition(".")
    if first.isnumeric():
        first = int(first)
    if rest:
        new_obj = obj[first]
        set_value(new_obj, rest, val)
    else:
        obj[first] = val

由于1"1"不同,因此我在这里做出了让步:如果某物看起来像数字,则将其视为数字。

您可以使它在自定义对象上起作用,但在没有可怕的黑客手段的情况下,实际上不能在内置类型上起作用,因为Python并不等效于object.prototype