Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在Python中动态编辑dict树_Php_Python_Reference_Tree - Fatal编程技术网

Php 在Python中动态编辑dict树

Php 在Python中动态编辑dict树,php,python,reference,tree,Php,Python,Reference,Tree,我有一段PHP代码,我正试图将其移植到Python,我不确定如何在没有引用的情况下工作 本质上,它是一个像树一样工作的配置类,每个键可以有一个简单的值,或者它自己的一组键和值。类的一部分要求能够设置树的一个特定部分,而不必为根键发送整个新dict { "caching": { "enabled": true }} 例如,上面的配置可能很简单。调用下面的代码会将true更改为false Config.set('caching:enabled', false); 为了在PHP中实现这一点,我使用

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

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

{ "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;
            }
        }
    }
}
它不起作用,mData是正确的值,但由于我已经编写了它,它不再是一个引用


我该怎么做呢?在Python中是否有可能,或者我是否应该从头开始重新编写逻辑,放弃一个完美的端口?

您可以按如下方式创建set方法:

_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]]

什么是全局的
\u dmValues
?@Marcin它是一个对模块全局的字典。我已经修复了这个示例,感谢您指出:)对不起,这只适用于单个冒号。我举的例子就是,一个例子,字符串可以有多个冒号,并且有好几层深。此外,模块被设计为只有一棵树,因此每次传入都没有意义。
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]]