像属性一样访问字典键?

2023-12-13

我发现访问字典键更方便obj.foo代替obj['foo'],所以我写了这个片段:

class AttributeDict(dict):
    def __getattr__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

不过,我认为一定有某种原因导致 Python 没有提供开箱即用的此功能。以这种方式访问​​字典键有什么注意事项和陷阱?


更新 - 2020

自从这个问题在大约十年前被提出以来,Python 本身已经发生了很大的变化。

虽然我最初的答案中的方法对于某些情况仍然有效(例如,遗留项目坚持旧版本的Python,以及您确实需要处理具有非常动态的字符串键的字典的情况),但我认为一般来说数据类Python 3.7 中引入的解决方案是针对绝大多数用例的明显/正确的解决方案AttrDict.

原答案

最好的方法是:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

一些优点:

  • 它确实有效!
  • 没有隐藏字典类方法(例如.keys()工作得很好。除非 - 当然 - 你为它们分配了一些值,见下文)
  • 属性和项目始终同步
  • 尝试访问不存在的键作为属性正确引发AttributeError代替KeyError
  • 支持[Tab]自动补全(例如在 jupyter 和 ipython 中)

Cons:

  • 方法如.keys() will not如果它们被传入数据覆盖,则工作正常
  • 导致一个内存泄漏在 Python
  • Pylint 很疯狂E1123(unexpected-keyword-arg) and E1103(maybe-no-member)
  • 对于外行来说,这似乎纯粹是魔法。

关于其工作原理的简短说明

  • 所有Python对象在内部将它们的属性存储在一个名为的字典中__dict__.
  • 没有要求内部词典__dict__需要是“只是一个简单的字典”,所以我们可以分配任何子类dict()到内部词典。
  • 在我们的例子中,我们只需分配AttrDict()我们正在实例化的实例(就像我们在__init__).
  • 通过致电super()'s __init__()方法我们确保它(已经)的行为与字典完全相同,因为该函数调用所有字典实例化 code.

Python 不提供开箱即用的功能的原因之一

正如“缺点”列表中所述,这将存储密钥的命名空间(可能来自任意和/或不受信任的数据!)与内置 dict 方法属性的命名空间结合在一起。例如:

d = AttrDict()
d.update({'items':["jacket", "necktie", "trousers"]})
for k, v in d.items():    # TypeError: 'list' object is not callable
    print "Never reached!"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

像属性一样访问字典键? 的相关文章

随机推荐

  • 查找给定矩阵的子矩阵

    我正在尝试编写一种算法来在给定的子矩阵中查找子矩阵 为了解决这个问题我编写了以下代码 public class SubMatTry param args public static void main String args TODO Au
  • 添加到 Google 日历呈现链接不显示用户的当地时间

    我可以使用此谷歌日历链接创建一个活动 但我认为 UTC 时间即将到来 比我想要的活动时间提前了 5 30 小时 例子 这个链接将创建一个活动 但显示时间为中午 12 30 至下午 4 点 该活动预计在上午 6 30 至上午 10 点进行 根
  • 是否可以使用单个 SQL 语句将记录从一个表移动到另一个表?

    我需要一个查询将记录从一个表移动到另一个表而不使用多个语句 不可以 您不能在一条 SQL 语句中移动记录 你必须使用一个INSERT随后是一个DELETE陈述 您应该将这些语句包装成交易 以确保复制操作保持原子性 START TRANSAC
  • 使用 oauth2 和 Google API 时无法识别的参数

    我在一些脚本中使用 Google API 服务 但遇到了一些问题 这个错误有点奇怪 但我们开始了 我有一个列出我的 Google 云端硬盘文件的脚本 from apiclient import discovery from httplib2
  • 如何获取成员变量的注解?

    我想知道一个类的一些成员变量的注释 我使用BeanInfo beanInfo Introspector getBeanInfo User class 反思一个类 并使用BeanInfo getPropertyDescriptors 查找特定
  • 如何从一个元组到一个元组引用元组中的元素?

    我有一个 C 11 元组 我想要一个元组std reference wrappers 到元组的相同元素 有没有简单的方法可以做到这一点 映射一个元组很容易一组索引 e g include
  • 在代码中处理语音命令以执行命令的智能方法

    我想知道是否可以寻求更好的方法来处理和处理命令 而不是使用可能变得非常长且非常乏味的 Switch Case 或 IF 布尔检查 E G if settings getName Command Speak I am here if Get
  • 如何用 Python 可视化回归树

    我正在寻找可视化回归使用 scikit learn 中的任何集成方法构建的树 梯度增强回归器 随机森林回归器 装袋回归器 我看过这个问题很接近 并且这个问题它处理分类树 但这些问题需要 树 方法 而该方法不适用于 SKLearn 中的回归模
  • 在 Spring Integration 中,RequestHandlerRetryAdvice 无法与 Ftp.outboundGateway 一起使用

    我的情况与描述的类似这个问题 区别在于我不使用WebFlux outboundGateway but an Ftp outboundGateway我称之为AbstractRemoteFileOutboundGateway Command G
  • phpmyadmin 中的自动增量

    我有一个使用 PHP MySQL 和 phpMyAdmin 的现有数据库 当用户成为我网站的会员时 我需要系统使用五位数字为他们创建一个唯一的会员号码 例如 83773 我想这就像生成一个随机密码 只不过我只想要我的会员的数字 该 ID 号
  • urllib2 HTTPPasswordMgr 不起作用 - 凭据未发送错误

    以下 python curl 调用具有以下成功结果 gt gt gt import subprocess gt gt gt args curl H X Requested With Demo https username email pro
  • Jenkinsfile主动选择参数

    如何在多分支管道 Jenkinsfile 声明性 中使用此 dsl 脚本 parameters activeChoiceParam States description Select a state option filterable ch
  • Ajax 如何与 PHP 配合使用?

    我在使用 ajax 和 php 时遇到问题 我想做的是调用一个 ajax 函数 该函数从表单的输入中获取一个值 并检查该电子邮件是否存在于数据库中 这是我当前的 JavaScript Checks for Existing Email fu
  • 如何同步调用ajax而不冻结网页

    我有一些 javascript 可以触发大约 100 个对 php 脚本的调用 php 脚本占用大量内存并需要几秒钟才能完成 然后返回通过或失败的 json 响应 我不希望 ajax 调用是异步的 因为服务器会在运行 100 个自身实例时突
  • 彼得森算法

    在经典的 Peterson 算法中 您在进入关键部分之前检查 2 个标志 flag1 和 flag2 以及转变量 如果我先检查转 然后检查标志 这会起作用吗 是的 如果你先检查一下 它会起作用turn然后检查flag 0 or flag 1
  • Python 断言引发用户定义的异常

    以下问题是由讨论引发的这个帖子 假设有两个文件 foob ar py and foob ar unittest py File foob ar py包含一个类 FooBar 有两个函数 foo and bar 功能bar引发内置异常 函数f
  • 如何使用 SQL 将值相乘

    好的 我正在做作业 但无法弄清楚如何与 SQL 相乘以及如何正确排序 我应该 创建一个查询 列出球员 player name 当前工资和一个新的 创建的 列 该列反映工资增加 10 计算为工资 1 1 按工资降序对数据进行排序 这只是我们老
  • 如何将包含数组的列表从 C# 序列化为 JSON?

    我希望从 C Sharp 序列化为 JSON 我希望输出是 Info item1 Count 5749 Info item2 Count 2610 Info item3 Count 1001 Info item4 Count 1115 In
  • 抽象基类的注册方法实际上做了什么?

    我对 ABC 注册方法感到困惑 采取以下代码 import io from abc import ABCMeta abstractmethod class IStream metaclass ABCMeta abstractmethod d
  • 像属性一样访问字典键?

    我发现访问字典键更方便obj foo代替obj foo 所以我写了这个片段 class AttributeDict dict def getattr self attr return self attr def setattr self a