使用点语法访问字典

由题

不多说直接上代码

分析见下

class dot:

    def __init__(self, d=None):
        if d is not None:
            for k,v in d.items():
                if isinstance(v, dict):
                    self[k] = dy(v)
                else:
                    self[k] = v
#可选的函数定义
    def __str__(self):
        return __import__("json").dumps(self.__dict__)
#必须的函数定义
    def __setattr__(self, key, value):
        self.__dict__[key] = value

    def __getattr__(self, key):
        return self.__dict__[key]

    def __getitem__(self, key):
        return self.__dict__.__getitem__(key)

    def __setitem__(self, key, value):
        return self.__dict__.__setitem__(key, value)
#可选的函数定义
    def keys(self):
        return self.__dict__.keys()
    def copy(self):
        return self.__dict__.copy()
    def pop(self, keys):
        return self.__dict__.pop(keys)
    def items(self):
        return self.__dict__.items()
    def values(self):
        return self.__dict__.values()
    #...

所有的attr与item都被保存到了dict

即分别重定义了__getattr__, __setattr__, __getitem__, __setitem__四个函数

甚至不需要继承dict类(欢喜

另外单独定义了values, items等等的dict类原生函数而不是使用类似values = __dict__.values这样的写法, 这样不仅能正常调用而且返回中也不会包括这些函数名

要点在于重定义了__getattr__而不是__getattribute__

在调用这些函数时会首先调用正常的__getattribute__, 正常地找到这些函数并正常地调用, 而当调用后来赋值的attr或item则__getattribute__找不到对应的值便调用__getattr____dict__里找, 万事大吉

需要注意的是这些原生函数只能通过点语法调用(废话), 也能作为字段名重新赋值(还是废话)

一个点字典可以实现以下操作

  1. 转化原生字典a = dot({"x":1, "y":2})
  2. 调用dict原生函数(需要单独定义)a.values()
  3. 同时使用点语法与字段名取赋值a.t = 5ora["t"] = 5

另外需要注意当进行了如a[1] = ...这种给数字索引的赋值的操作后dir(a)会报错, 具体原因未知

不过即使如此取值也是没问题的

empty
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。