2015-02-23 117 views
0

我有一段PHP代码,我试图将其移植到Python,我不确定如何在没有引用的情况下工作。在Python中动态编辑字典树

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

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

例如,以上可以是简单的配置。并调用下面的代码将假

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甚至有可能,或者我应该重新编写我的逻辑并放弃一个完美的端口?

+0

什么是全球'_dmValues'? – Marcin 2015-02-23 22:57:32

+0

@Marcin这是一个模块全局的字典。我已经修复了这个例子,谢谢你指出:) – 2015-02-24 15:17:56

回答

0

我打周围更多,并意识到我有解决方案,我只是不正确地应用它。

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

这工作完全

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

你可以让你的设置方法如下:

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

虽然可能会更好,除去全球价值,并通过参考字典作为参数:

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}} 
+0

对不起,但这只适用于单个冒号。我给出的例子就是这样一个例子,字符串可以有多个冒号,并且可以有几个深度。此外,该模块设计为只有一棵树,所以在每次传递时都没有意义。 – 2015-02-24 15:16:04