开发者社区> 问答> 正文

延迟评估/对数据结构中原子数据类型的引用

在Python 3中,我使用将数据序列化为JSON的方法如下:

import json

config = {
   'server' : {
      'host' : '127.0.0.1',
      'port' : 12345
    }
}

serialized_config = json.dumps(config)

由于json.dumps和JSON格式是固定的,我无法任意更改python数据的结构,例如,当将config配置传递给json.dumps时,host需为字符串。我不能将其包装在'host':['1.1.1.1]'`这样的列表中

现在,数据比本示例中的要复杂得多,但是大部分都是冗余的(例如,只有一个“主机”是恒定的,但是在整个配置中出现在各个位置。现在,我喜欢定义一些模板,如下所示:

template = {
   'server' : {
      'host' : SERVER_IP,
      'port' : 12345
   }
}

然后用实际的服务器ip等替换所有出现的SERVER_IP。关键是我在定义模板时不知道SERVER_IP的值。简单的方法是将原子字符串转换为非原子的python结构,例如:

server = {
    'host' : '1.1.1.1',
    'port' : 12345
}

template = {
   'server' : server
}

...

# Here the actual value of 'host' has been set
server['host'] = '192.168.0.1'

print(json.dumps(template))

这个转储

'{"server": {"host": "192.168.0.1", "port": 12345}}'

如通缉。

但是,由于port等也发生了变化,所以我更喜欢类似(pseudo-code)的东西:

server_ip = '1.1.1.1' # not the actual value

template = {
   'server' : {
      'host' : ref(server_ip), # Don't copy the string, but either delay the evaluation or somehow create a ref to the string
      'port' : 12345
   }
}

...
server_ip = '192.168.0.1'

我知道我可以编写仅遍历python数据并“手动”将某些字符串替换为不同值的代码。

但是,我很好奇是否有更好的解决方案。

例如,我像这样促进getattribute的玩耍:

class DelayedEval:

    def __init__(self, d):
        self.data = d

    def __getattribute__(self, key):
        # Recursive matters let aside for sake of simplicity...
        data = object.__getattribute__(self, 'data')
        v = data[key]
        try:
            v = v()
        except:
            pass
        return v

    # possibly overwrite __getitem__() etc as well ...

server_ip = '1.1.1.1'

template = {

    'server' : {
        'host' : lambda: server_ip, # prevents 'premature evalutation'
        'port' : 12345
    }
}

...

server_ip = '192.168.0.1'

print(json.dumps(DelayedEval(template))) # Does not work

我不是要解决此代码,而是要寻求任何解决我的问题的解决方案,无论如何,只要您认为它比手动遍历和替换的支撑方法“更好”。

修复此代码可能会解决我的问题,但可能会有更好的解决方案(或没有解决方案?)。

我知道这是一个相当复杂的问题,可能是因为我的用例过于复杂,但是,我很好奇,除了蛮力的“搜索并替换”方法之外,是否还有可行的解决方案...

是否有某种方法可以像Python中那样定义“自完成模板结构”?

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 09:40:50 550 0
1 条回答
写回答
取消 提交回答
  • 一种简单的方法是使模板本身成为lambda函数:

    template = lambda: {
        'server' : {
            'host' : server_ip,
            'port' : 12345
        }
    }
    
    ...
    
    server_ip = '192.168.0.1'
    
    print(json.dumps(template()))
    

    回答来源:stackoverflow

    2020-03-24 09:40:58
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
如何使用Tair增强数据结构构建丰富在线实时场景 立即下载
Apache Flink 流式应用中状态的数据结构定义升级 立即下载
HBase2.0重新定义小对象实时存取 立即下载