拦截对对象属性的 __getitem__ 调用

2024-05-27

问题:我怎样才能拦截__getitem__调用对象属性?

解释:

所以,场景如下。我有一个对象将类似字典的对象存储为属性。每次__getitem__该属性的方法被调用,我想拦截该调用并根据键对获取的项目进行一些特殊处理。我想要的看起来像这样:

class Test:

    def __init__(self):
        self._d = {'a': 1, 'b': 2}

    @property
    def d(self, key):
        val = self._d[key]
        if key == 'a':
            val += 2
        return val
t = Test()
assert(t.d['a'] == 3) # Should not throw AssertionError

问题是 @property 方法实际上无法访问__getitem__调用,所以我根本无法检查它来执行我的特殊后处理步骤。

重要提示:我不能只是子类化 MutableMapping,重写__getitem__我的子类的方法来执行此特殊处理,并将子类的实例存储在self._d。在我的实际代码中self._d已经是 MutableMapping 的子类,并且该子类的其他客户端需要访问未修改的数据。

感谢您的任何帮助!


一种解决方案是Mapping代理底层映射。这d属性将包裹底层self._d在代理包装器中映射并返回它,并且使用该代理将表现出必要的行为。例子:

from collections.abc import Mapping

class DProxy(Mapping):
    __slots__ = ('proxymap',)
    def __init__(self, proxymap):
        self.proxymap = proxymap
    def __getitem__(self, key):
        val = self.proxymap[key]
        if key == 'a':
            val += 2
        return val
    def __iter__(self):
        return iter(self.proxymap)
    def __len__(self):
        return len(self.proxymap)

一旦你做到了,你原来的课程可以是:

class Test:
    def __init__(self):
        self._d = {'a': 1, 'b': 2}

    @property
    def d(self):
        return DProxy(self._d)

然后用户将访问实例Test with test.d[somekey]; test.d将返回代理,然后代理将修改结果__getitem__根据需要somekey。他们甚至可以存储参考资料locald = test.d然后使用locald同时保留必要的代理行为。你可以把它变成一个MutableMapping如果需要的话,但是一个简单的Mapping当目标是读取值而不是通过代理修改它们时,基于代理可以避免复杂性。

是的,这创造了一个新的DProxy每次访问时的实例d;如果您愿意,您可以缓存它,但考虑到它的简单性DProxy班级的__init__也就是说,只有通过合格的访问,成本才有意义d属性在最热门的代码路径上频繁执行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

拦截对对象属性的 __getitem__ 调用 的相关文章

随机推荐

  • 为什么某些 float < integer 比较比其他比较慢四倍?

    将浮点数与整数进行比较时 某些值对的计算时间比类似大小的其他值要长得多 例如 gt gt gt import timeit gt gt gt timeit timeit 562949953420000 7 lt 56294995342100
  • 算法 - 树中所有节点的最大距离

    所以 找到树中两个节点之间的最长路径相当容易 但我想要的是找到从节点出发的最长路径x到树中的另一个节点 对于所有x 这个问题也可以用以下方式表达 计算从给定的树中可以生成的所有有根树的高度 One way of course is to j
  • 如何使 WPF 中的窗口对鼠标事件不可见?

    我创建了这个类 它非常适合使我的 WPF 应用程序对鼠标事件透明 using System Runtime InteropServices class Win32 public const int WS EX TRANSPARENT 0x0
  • 从基本控制器继承 LINQ-to-SQL 数据上下文

    我的基本控制器类 BaseController 由面向公众的控制器继承 用于使用 LINQ to SQL 访问请求之间的共享数据上下文 我是否可以通过将数据存储在中来以高效且安全的方式访问我的数据上下文HttpContext Current
  • Jetpack Compose Navigation:直接导航到非 startDestination 的嵌套图中的路由

    我正在开发 Jetpack Compose Navigation 演示 并且有一个嵌套导航图 其中包含两个不同的嵌套路线以及每个嵌套路线的屏幕 登录图 主图 登录图具有三种路线 用于显示三个不同的屏幕 路由 登录 以显示登录屏幕 路由 re
  • 绘制长方体

    我正在尝试使用 matplotlib 绘制不同大小的长方体 这样 旋转后 长方体不会以非物理方式在视觉上重叠 立方体具有不同的颜色和围绕它们绘制的框 我读过几篇博客文章和 stackoverflow 页面引用类似的问题 但总是有细微的差别
  • 使用:text/plain; 有什么缺点吗?字符集=“UTF-8”

    我的网络服务器提供的内容在 95 的情况下只是简单的 ascii 但在极少数情况下 内容包含一些德语非 ASCII 字符 现在我可以设置content type通过检测内容是否包含任何非 ASCII 字符来响应标头 或者我可以始终设置响应标
  • 如何从系统属性获取Windows操作系统环境变量

    我遇到一个关于系统属性环境变量的奇怪问题 如你所知 我们可以打开Computer gt Property gt Advanced System Settings gt Advanced gt System Environment Varia
  • 为什么在 WinForms 中可以跨线程添加控件,而在 WPF 中却不能?

    在虚拟 WinForms 应用程序中 我可以在设计时创建 ListBox 在运行时创建后台线程 然后从后台线程将控件添加到 ListBox 但如果我在 WPF 中执行相同的操作 则会出现错误 为什么我可以在 WinForms 中执行此操作
  • Python将文件从Linux复制到WIndows

    我正在构建一个网站 该网站有一个表单 可以捕获用户数据并在用户数据上运行一些cgi cgi 的第一步是需要将文件从 Linux Web 服务器复制到 Windows 计算机 服务器将使用 Active Directory 角色帐户作为复制凭
  • angular2 使用 router.subscribe 来观察 url 变化

    我在用着router event subscribe angular router观察 url 变化以执行if虽然声明event subscribe工作正常 但我的问题是我怎样才能避免重复我的if声明只是为了在这些网址上显示标题 这可能是别
  • 生成总和恒定的随机数

    我在想是否有办法生成一组随机数 其总和始终是一个常数 例如 20 可以分为 5 个数字 1 2 3 4 10 我不在乎这 5 个数字分别是什么 只要它们的总和等于 20 有没有办法以编程方式执行此操作 为了获得均匀分布 技巧是将总和视为一条
  • OOP概念混乱?

    在阅读一些编程书籍时 我注意到作者说 在OOP中 你在理解OOP的主要思想时可能会有些困惑 是啊 我有些困惑 您是否也有同样的情况 是什么让程序员 甚至是经验丰富的程序员 感到困惑 如果你拥有它 你怎么能打败这个 Thanks The An
  • 计算对象数组内的数组数量

    假设我有一个对象数组 预期产量 阿尔法 4 贝塔 8 为此我尝试过 const apple name alpha details attachment 123 456 attachment 1454 1992 name beta detai
  • 列出当前请求中使用的所有 Twig 模板

    我正在使用 Symfony2 和 Twig 模板引擎 有没有办法输出当前请求中加载的所有 Twig 模板文件的列表 包括通过加载的模板文件extends include etc 当覆盖第三方捆绑包的块时 这将使我的生活变得更加轻松 但我找不
  • 获取每个训练实例的损失值 - Keras

    我想获得每个实例的损失值作为模型训练 history model fit 例如 上面的代码返回每个时期的损失值 而不是小批量或实例 做这个的最好方式是什么 有什么建议么 在这个 keras 官方文档页面的末尾 正是您要寻找的内容https
  • 如何替换 Logstash 中字段中的字符串

    我的 Windows 事件日志中有一个 IP 地址字段 其中 IP 地址前面包含类似 fffff 的字符 我无法更改此处的源 因此我必须在 Logstash 中修复此问题 我一定很不擅长谷歌搜索 但我真的找不到一种简单的方法来从logsta
  • 运行 mocha 排除路径

    我有这个 在 gulpfile js 中 var gulp require gulp var mocha require gulp mocha gulp task test function gulp src test js node mo
  • Android 中拍摄的照片方向发生变化

    我通过单击按钮打开相机应用程序 并在下一个活动中显示捕获的照片 但拍摄的照片旋转了90度 当我捕获图像后在视图中显示图像时 它的方向始终是横向的 为什么在纵向模式下拍摄照片时 照片显示的不是纵向 onClick 按钮 Intent i ne
  • 拦截对对象属性的 __getitem__ 调用

    问题 我怎样才能拦截 getitem 调用对象属性 解释 所以 场景如下 我有一个对象将类似字典的对象存储为属性 每次 getitem 该属性的方法被调用 我想拦截该调用并根据键对获取的项目进行一些特殊处理 我想要的看起来像这样 class