微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过属性访问嵌套 dics 的类通过打印和 __dict__ 显示不同的值

如何解决通过属性访问嵌套 dics 的类通过打印和 __dict__ 显示不同的值

我正在开发一个项目,在该项目中我需要具有一些属性(例如日期、名称)的对象,然后是一组值(通常是具有不同聚合的 pd.DataFrames,但我将在此处使用整数作为示例)。与其执行多个嵌套的字典并为诸如 data["df"]["yearly"] 之类的键键入许多额外的字符,使用 data.df.yearly 访问值会更容易。 (有没有更好的结构?)

因此我使用了一个将键设置为属性的类。但是根据我访问数据的方式,我会得到不同的输出

代码如下:

? ? ? ??‍? ?? ?‍?‍?‍?

现在,当我初始化一个实例并按以下方式为其分配一些数据时,我将有两个不同的输出,具体取决于我是写 data.df.yearly 还是 data.df["yearly"]。

有人看到错误了吗(或者是否有更好的数据结构的建议?)。

创建一个 Map() 实例

class Map(dict):
    """
    https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary
    Example:
    m = Map({'first_name': 'Eduardo'},last_name='Pool',age=24,sports=['Soccer'])
    """
    def __init__(self,*args,**kwargs):
        super(Map,self).__init__(*args,**kwargs)
        for arg in args:
            if isinstance(arg,dict):
                for k,v in arg.items():
                    self[k] = v

        if kwargs:
            for k,v in kwargs.items():
                self[k] = v

    def __getattr__(self,attr):
        super( Map,self ).__getattr__( attr )
        return self.get(attr)

    def __setattr__(self,key,value):
        self.__setitem__(key,value)

    def __setitem__( self,value ):
        super( Map,self ).__setitem__( key,value )
        if isinstance( value,dict ):
            self.__dict__.update( {key: Map(value) } )         
        else:
            self.__dict__.update( {key: value} )

    def __delattr__(self,item):
        self.__delitem__(item)

    def __delitem__(self,key):
        super(Map,self).__delitem__(key)
        del self.__dict__[key]   

更改data.df的值

data = Map()
data.start_date = "2020-01-01"
data.finish_date = '2021-01-01'
data.name = "Type A"
data.df = {"yearly" : 0,"monthly" : 0,"weekly" : 0}

预期输出

for time in data.df.keys():
    data.df[time] = 123

输出(与打印(数据)相同):

data
> {'start_date': '2020-01-01',>  'finish_date': '2021-01-01',>  'name': 'Type A',>  'df': {'yearly': 123,'monthly': 123,'weekly': 123}}

通过 dict 输出匹配预期输出

data
> {'start_date': '2020-01-01',>  'df': {'yearly': 0,'monthly': 0,'weekly': 0}}

解决方法

您的 __setitem__ 方法正在使用原始值调用超类方法,但是如果该值是字典,则在将其放入 Map 时会将其转换为 self.__dict__。所以这两个位置包含不同的对象,没有什么可以让它们保持同步。

您应该先将值转换为 Map,然后再将其存储在两个位置。

    def __setitem__( self,key,value ):
        if isinstance(value,dict):
            value = Map(value)
        super( Map,self ).__setitem__( key,value )
        self.__dict__.update({key: value})

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。