Python——easydict包的使用


整体说明

  • EasyDict 是一个轻量级的 Python 库,旨在简化字典操作,它允许用户像访问对象属性一样访问字典的键值对,从而提高代码的可读性和简洁性
  • EasyDict 通过重写字典的几个关键方法,如__getattr____setattr__等,实现了将字典键转换为对象属性的功能
  • EasyDict 不仅支持顶级字典的属性访问方式,还能递归应用于内嵌的字典,使得处理多层次数据结构变得简单易行
  • EasyDict 实例仍然遵循标准字典的所有操作,保证了灵活性

安装 EasyDict

  • 可以使用pip进行安装,命令如下:
    1
    pip install easydict

使用示例

  • 简单使用示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from easydict import EasyDict as edict
    # 创建一个EasyDict对象
    data = edict({'name': 'John', 'age': 30, 'job': 'Engineer'})
    # 访问字典元素
    print(data.age)
    print(data.job)
    # 添加新的键值对
    data.gender = 'Male'
    print(data.gender)
  • 嵌套字典的访问:

    1
    2
    3
    4
    5
    6
    7
    8
    my_dict = edict({
    'level1': edict({
    'level2': edict({
    'key': 'value'
    })
    })
    })
    print(my_dict.level1.level2.key)
  • 动态设置属性:

    1
    2
    3
    my_dict = edict()
    my_dict.key1 = 'value1'
    print(my_dict.key1)
  • 常见的字典操作:

    1
    2
    3
    4
    5
    6
    7
    my_dict = edict({'key1': 'value1'})
    # 更新字典
    my_dict.update({'key2': 'value2'})
    print(my_dict.key2)
    # 删除一个键值对
    my_dict.pop('key1')
    print(my_dict.key1) # 会抛出AttributeError,因为'key1'不再存在
  • 获取默认值:

    1
    2
    3
    my_dict = edict({'name': 'Alice'})
    value = my_dict.get('nonexistent_key', 'default_value')
    print(value)

EasyDict 和 namedtuple 对比

  • EasyDict 和 namedtuple 都是 Python 中用于简化数据访问的工具
  • TDRL:namedtuple 是”先定义类,再用类创建实例”;EasyDict 是”直接用通用类创建实例,动态定义结构”
    • namedtuple 需要先定义特定结构的类(如Person),再创建该类的实例,适合固定结构的数据
    • EasyDict 直接使用通用的EasyDict创建实例,实例的字段结构可以动态变化,适合灵活的数据场景
  • TDRL:若需 固定结构、不可变数据 ,追求性能和内存效率,用 namedtuple;若需 动态结构、灵活修改 ,优先便捷性,用 EasyDict

本质与继承关系

  • namedtupletuple 的子类,属于不可变(immutable)数据结构
    • 一旦创建,其字段值无法修改,类似元组的特性
  • namedtuple 定义时需要指定固定的字段名,结构是静态的,不能动态添加新字段
  • EasyDict 是 dict 的子类,属于可变(mutable)数据结构
    • 创建后可以随时修改字段值,也能动态添加/删除新字段,保留了字典的灵活性

数据访问方式

  • 两者都支持 属性式访问(如 obj.field)和 键值访问(如 obj['field']),但底层实现不同:
    • namedtuple 本质是元组,字段值存储在固定位置,访问速度更快
    • EasyDict 本质是字典,通过重写 __getattr__ 实现属性访问,性能略低于 namedtuple

可变性

  • namedtuple 不可变:创建后无法修改字段值,也不能添加新字段,类似常量集合,示例如下:

    1
    2
    3
    4
    from collections import namedtuple
    Person = namedtuple('Person', ['name', 'age'])
    p = Person('Alice', 30)
    p.age = 31 # 报错:'Person' object does not support item assignment
  • EasyDict 可变:支持修改现有字段、添加新字段、删除字段等操作,示例如下:

    1
    2
    3
    4
    5
    from easydict import EasyDict as edict
    p = edict(name='Alice', age=30)
    p.age = 31 # 允许修改
    p.gender = 'Female' # 允许添加新字段
    del p.age # 允许删除字段

定义类情况

  • namedtuple 显式定义了一个新的类(如Person),这个类继承自tuple,并且在定义时就固定了字段结构,例如:

    1
    2
    3
    4
    from collections import namedtuple
    # 这里显式创建了一个名为 Person 的类
    Person = namedtuple('Person', ['name', 'age'])
    print(type(Person)) # 输出:<class 'type'>,说明是一个类
    • 后续使用时,Person() 是创建该类的实例,每个实例都严格遵循预定义的字段结构
  • EasyDict 没有要求你显式定义新的类(如Person),但它本身是一个通用的 EasyDict 类,所有实例都属于这个类,例如:

    1
    2
    3
    4
    from easydict import EasyDict as edict
    # 直接创建 EasyDict 类的实例,无需预先定义结构
    p = edict(name='Alice', age=30)
    print(type(p)) # 输出:<class 'easydict.EasyDict'>
    • 你将 p 视为一个”动态对象”,它属于 EasyDict 类,但其字段可以灵活添加/修改,不需要提前定义特定的类(如Person

适用场景

  • namedtuple 适合存储 固定结构、不可变的数据(如配置项、记录、坐标等),强调数据的稳定性和内存效率
    • 例如:表示点坐标 Point(x=1, y=2)、数据库查询结果等
  • EasyDict 适合处理 动态结构、需要灵活修改的数据(如嵌套配置、JSON 数据解析等),强调操作的便捷性
    • 例如:解析 API 返回的 JSON 数据(可动态添加/修改字段)、多层级的配置文件等

其他差异

  • 内存占用namedtuple 比 EasyDict 更轻量,内存占用更少
  • 序列化 :两者都支持序列化,但 namedtuple 可直接通过 _asdict() 转换为普通字典,EasyDict 本身就是字典,可直接序列化
  • 类型提示namedtuple 在定义时已明确字段,类型提示更友好;EasyDict 动态字段较多,类型提示较弱