在 Python 中动态编辑字典树

Dynamically edit dict tree in Python

我有一段 PHP 代码正在尝试移植到 Python,我不确定如何在没有引用的情况下工作。

本质上它是一个像树一样工作的配置 class,每个键可以有一个简单的值,或者它自己的一组键和值。 class 的一部分要求能够设置树的一个特定部分,而不必为根键发送一个全新的字典。

{ "caching": { "enabled": true }}

例如,上面可以是一个简单的配置。调用下面的代码会将 true 更改为 false

Config.set('caching:enabled', false);

为了在 PHP 中完成此操作,我使用了引用

class Config
{
    private static $aValues;

    public static function set($key, $value)
    {
        if(strpos($key, ':')) {
            $aKeys  = explode(':', $key);
            $iCount = count($aKeys);
        } else {
            $aKeys  = array($key);
            $iCount = 1
        }

        $mData  = &self::$aValues
        for($i = 0; $i < $iCount; ++$i)
        {
            if(!isset($mData[$aKeys[$i])) {
                $mData[$aKeys[$i]]  = array();
            }

            $mData  = &$mData[$aKeys[$i]];

            if($i == ($iCount - 1)) {
                $mData  = $value;
            }
        }
    }
}

但是如果我尝试在 Python

中做类似的事情
_dmValues = dict()

def set(key, value):
    global _dmValues

    if key.find(':'):
        aKey    = key.split(':')
        iCount  = len(key)
    else:
        aKey    = (key,)
        iCount  = 1

    mData   = _dmValues;
    for i in range(0, iCount):
        if key[i] not in mData.keys():
            mData[key[i]]   = dict()

        mData   = mData[key[i]]

        if i == (iCount - 1):
            mData   = value

不行,mData是正确的值,但是既然我已经写入了,就不再是参考了。

我该怎么做呢?在 Python 中甚至有可能吗,还是我应该从头开始重写我的逻辑并放弃一个完美的端口?

您可以按如下方式设置您的设置方法:

_dmValues = { "caching": { "enabled": True }}

def set(key, value):
    global _dmValues

    key1,key2    = key.split(':')    

    mData   = _dmValues;

    if key1 in mData:
        if key2 in mData[key1]:
            mData[key1][key2] = value


set('caching:enabled', False)

print(_dmValues)  # {'caching': {'enabled': False}}    

尽管删除全局值并将对 dict 的引用作为参数传递可能会更好:

def set(mData, key, value):       
    key1,key2    = key.split(':')           
    if key1 in mData:
        if key2 in mData[key1]:
            mData[key1][key2] = value


set(_dmValues, 'caching:enabled', False)

print(_dmValues) # {'caching': {'enabled': False}}   

我尝试了更多,发现我有解决方案,我只是应用不当。

每个字典,即使它是另一个字典的键的一部分,都可以通过引用传递。这意味着如果我更改该字典中的键,它也会在父项​​中更改。不幸的是,我正在更改引用字典的变量,而不是字典本身。

这非常有效

mData = _dm_Values
for i in range(0, iCount):
    if i == (iCount - 1):
        mData[key[i]] = value
    else:
        if key[i] not in mData.keys():
            mData[key[i]] = dict()
        mData = mData[key[i]]