使用python类替换嵌套字典中的值

时间:2018-08-18 23:24:04

标签: python-3.x class dictionary nested

我有一个嵌套的字典,我想替换特定键的所有值。这是输入字典:

{'handlers':
    {'console':
        {'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'simple',
            'stream': 'ext://sys.stdout'},
    'info_file_handler':
    {'class': 'logging.handlers.RotatingFileHandler',
            'level': 'INFO', 'formatter': 'simple',
            'filename': 'var/info.log',
            'maxBytes': 10485760,
            'backupCount': 20,
            'encoding': 'utf8'},
    'error_file_handler':
    {'class': 'logging.handlers.RotatingFileHandler',
            'level': 'ERROR',
            'formatter': 'simple',
            'filename': 'var/errors.log',
            'maxBytes': 10485760,
            'backupCount': 20,
            'encoding': 'utf8'}
    }
}

我的目标是通过类而不是函数来替换嵌套字典中任何地方的某些键的值。我已经有一个为此工作的函数,但想将其转换为类。该类将帮助我将字典视为在某些键的值内添加/插入文本或仅删除键的对象。 尽管花了很多时间在调试上,我仍无法弄清为什么它不起作用...

下面是我的代码:

class ObjDict():
    def __init__(self, dictionary=None):
        if dictionary is not None:
            self.__dict__.update(dictionary)

    def replace_value(self, key_searched, new_value):
        print('---------------------------------------')
        for k, value in self.__dict__.items():
            if isinstance(value, dict):
                self.__dict__[k] = ObjDict.replace_value(value, key_searched, new_value)
        if key_searched in self.__dict__:
            # replace the value
            self.__dict__[key_searched] = new_value
            print('Value replaced:', self.__dict__[key_searched])
        return self.__dict__

instance = ObjDict({'handlers': {'console': {'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'simple', 'stream': 'ext://sys.stdout'}, 'info_file_handler': {'class': 'logging.handlers.RotatingFileHandler', 'level': 'INFO', 'formatter': 'simple', 'filename': 'var/info.log', 'maxBytes': 10485760, 'backupCount': 20, 'encoding': 'utf8'}, 'error_file_handler': {'class': 'logging.handlers.RotatingFileHandler', 'level': 'ERROR', 'formatter': 'simple', 'filename': 'var/errors.log', 'maxBytes': 10485760, 'backupCount': 20, 'encoding': 'utf8'}}})
instance.replace_value('filename', "new filename" + "\\")

如果键未嵌套,则效果很好。如果密钥嵌套,则显示以下消息:

for k, value in self.__dict__.items():   AttributeError: 'dict' object has no attribute '__dict__'

显然,递归无法正常工作,我错过了我无法理解的东西。我已经阅读了许多文章或类似示例,但听起来并不能解决我的问题。带有解释的解决方案将不胜感激。 谢谢

1 个答案:

答案 0 :(得分:0)

进行递归调用时,应使用import React, { Component } from 'react' import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import AppBar from '@material-ui/core/AppBar' import Toolbar from '@material-ui/core/Toolbar' import Typography from '@material-ui/core/Typography' class NavBar extends Component { render() { const { classes } = this.props; return( <div> <AppBar position="static"> <Toolbar> <Typography variant="title" color="inherit"> Test </Typography> </Toolbar> </AppBar> </div> ); } } const styles = theme => ({ title: { color: '#FFF', }, }); NavBar.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(NavBar); 实例化一个新的ObjDict实例,以便您可以实际在其上调用value方法。

更改:

replace_value

收件人:

self.__dict__[k] = ObjDict.replace_value(value, key_searched, new_value)

这样:

self.__dict__[k] = ObjDict(value).replace_value(key_searched, new_value)

将正确输出:

print(instance.replace_value('filename', "new filename" + "\\"))

但是,出于您的目的,您根本不应该更新{'handlers': {'error_file_handler': {'formatter': 'simple', 'backupCount': 20, 'level': 'ERROR', 'encoding': 'utf8', 'class': 'logging.handlers.RotatingFileHandler', 'maxBytes': 10485760, 'filename': 'new filename\\'}, 'console': {'formatter': 'simple', 'class': 'logging.StreamHandler', 'stream': 'ext://sys.stdout', 'level': 'DEBUG'}, 'info_file_handler': {'formatter': 'simple', 'backupCount': 20, 'level': 'INFO', 'encoding': 'utf8', 'class': 'logging.handlers.RotatingFileHandler', 'maxBytes': 10485760, 'filename': 'new filename\\'}}} ,因为您没有尝试将给定字典中的键用作对象的属性,并且这只会带来无意中覆盖其他重要属性的风险相同的名字。

最好将该类实现为dict的子类:

__dict__