Python:使用 pre 和 post 方法包装方法调用

2024-01-19

我正在实例化一个 A 类(我从某人那里导入 否则,所以我无法修改它)到我的 X 类中。

有没有办法可以拦截或包装对 A 中方法的调用? 即,在下面的代码中我可以调用

x.a.p1()

并得到输出

X.pre
A.p1
X.post

很多TIA!

class A:
    # in my real application, this is an imported class
    # that I cannot modify
    def p1(self): print 'A.p1'

class X:
    def __init__(self):
        self.a=A()
    def pre(self): print 'X.pre'
    def post(self): print 'X.post'

x=X()
x.a.p1()

这是我和我的同事提出的解决方案:

from types import MethodType

class PrePostCaller:
    def __init__(self, other):
        self.other = other

    def pre(self): print 'pre'
    def post(self): print 'post'

    def __getattr__(self, name):
        if hasattr(self.other, name):
            func = getattr(self.other, name)
            return lambda *args, **kwargs: self._wrap(func, args, kwargs)
        raise AttributeError(name)

    def _wrap(self, func, args, kwargs):
        self.pre()
        if type(func) == MethodType:
            result = func( *args, **kwargs)
        else:
            result = func(self.other, *args, **kwargs)
        self.post()
        return result

#Examples of use
class Foo:
    def stuff(self):
        print 'stuff'

a = PrePostCaller(Foo())
a.stuff()

a = PrePostCaller([1,2,3])
print a.count()

Gives:

pre
stuff
post
pre
post
0

因此,在创建对象的实例时,请使用 PrePostCaller 对象包装它。之后,您可以继续使用该对象,就好像它是包装对象的实例一样。使用此解决方案,您可以在每个实例的基础上进行包装。

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

Python:使用 pre 和 post 方法包装方法调用 的相关文章

随机推荐

  • 根据 WooCommerce 中的自定义字段值将文本添加到订单摘要

    我已成功将自定义字段添加到我的 WooCommerce 结帐页面 该字段是客户可以选择从中提取商品的不同商店的选择器 目前 它在结帐页面上显示此字段 我正在使用 jQuery 在选择器下方添加信息并相应地更新运费 接下来我需要做的是在客户的
  • iOS 崩溃:未加载库 mremap_encrypted

    应用程序审查团队说我的应用程序总是在启动时崩溃 他们给了我一些崩溃日志 如下所示 Dyld Error Message Dyld Message Library not loaded rpath RestKit framework Rest
  • 打印二维列表的Pythonic方法——Python

    我有一个这样的二维字符列表 a 1 2 3 4 5 6 7 8 9 将列表作为整个块打印的最 Pythonic 方法是什么 IE 没有逗号或括号 123 456 789 有很多方法 大概是一个str join的映射的str joins gt
  • 判断不定冠词的Javascript库

    是否存在用于确定名词的不定冠词 a 与 an 的 JavaScript 库 我可以从一个简单的正则表达式开始 如下所示 var pattern aeiou i pattern test umbrella 但这不能处理像这样的情况 user
  • int foo = foo 的标准参考

    int foo foo 编译 C 标准的哪一部分允许这样做 3 3 1 声明点 basic scope pdecl 名称的声明点紧接在其完整声明符 第 8 条 之后和其初始值设定项 如果有 之前 如果声明位于文件范围内 则行为已明确定义 如
  • 如何放心地比较\断言双值

    我正在尝试将 JSON 中的 assert double 与java 原始double 值进行比较 正确的做法是什么 我用简单而常规的方式来做到这一点 使用Matchers equalTo方法见下文 public class A priva
  • Java:相当于Python的范围(int,int)?

    Java 有与 Python 相当的东西吗range int int method 老问题 新答案 针对 Java 8 IntStream range 0 10 forEach n gt System out println n 或使用方法
  • C++ 中的线程安全单例实现

    以下是 C 中单例模式的一个众所周知的实现 但是 我不完全确定它是否是线程安全的 根据之前对类似问题的回答 它似乎是线程安全的 是这样吗 Curiously Recurring Template Pattern Separates a cl
  • SQL 仅当所有行都满足条件时才选择行

    我对 SQL 还很陌生 虽然我可以编写大部分查询 但在这个方面我一无所获 我想在可以使用 JPA 执行的单个查询中实现此目的 TABLE RULE RULE ID ENABLED 1 0 2 0 3 0 4 1 5 1 TABLE MISC
  • PHP - cookie 变量和会话变量的有趣行为

    我在下面写了一个 PHP 脚本来演示我的问题 像这样运行下面的代码 http localhost test php test 10 http localhost test php test 10 然后运行http localhost tes
  • 如何从 Haskell 中的字符串中提取所有数字?

    所以基本上 假设我有一个 String W2932 B23829 W29 如何提取所有数字以便我有一个列表 2932 23829 29 遗憾的是还没有在 SO 或 google 上找到任何解决方案 我考虑过检查字符串的每个字符是否为数字 然
  • 如何在 Rails 的页面中执行操作而不渲染新页面

    在我的 Rails 应用程序中 我尝试添加一个联系人用户弹出框 用于向用户发送电子邮件 我有 javascript 来显示弹出表单 它本身就是一个部分 当用户单击联系表单上的 提交 时 它会调用发送邮件的控制器操作 提交消息后 我想留在同一
  • Google Colab 中的交互式 matplotlib 图形

    通常在 jupyter 笔记本中我会使用 matplotlib notebook显示交互式窗口的魔法 但这似乎不适用于 google colab 有没有解决方案 或者无法在 google colab 中显示交互式窗口 下面是创建交互的示例i
  • 将一个或多个数据帧中的列添加到另一个 python pandas

    我一直在网上搜索并发现类似的问题 但仍然找不到我正在寻找的答案 我有2个excel文件 data1 ColumnA columnB columnC columnD A B C D A B C D A B C D data2 ColumnE
  • 我可以在 .NET 中使用“System.Currency”吗?

    是否可以使用system currency 它说 system currency 由于其保护级别而无法访问 货币的替代品是什么 你必须使用Decimal http msdn microsoft com en us library 364x0
  • 如何在 gitlab-runner 容器内运行的 docker 中的 docker 中运行 docker-compose?

    我在 docker 容器内有一个 gitlab 运行程序 如果我运行像 nginx 这样的图像 则运行良好 但现在我尝试在 gitlab 运行程序内的 docker dind 中运行 docker 并且我想在 dind 内运行 docker
  • Angular-animate - 未知提供者:$$asyncCallbackProvider <- $$asyncCallback <- $animate <- $compile

    我有一个奇怪的问题 我想在我的 AngularJS 项目中包含 angular animate 我正在使用 AngularJS v1 2 6 我已经添加了angular animate到我的凉亭文件 它已下载并添加到源中的 HTML 文件中
  • 如何将整个 MongoDB 数据库转储为 text/json?

    如何将整个 MongoDB 数据库转储为文本 纯文本 json 或 CSV 我正在使用一个我不太熟悉的应用程序 我想 清除数据库 加载种子数据 将整个数据库转储为文本 做一些事情 再次转储 然后区分两者 Using mongodump an
  • Dart 将列表转换为 JSON 编码的映射条目

    我问了一个question https stackoverflow com questions 25615241 dart json decoder然而 在关于 Dart 编码 解码到 JSON 之前 建议的库并不完整 我决定手动处理它 目
  • Python:使用 pre 和 post 方法包装方法调用

    我正在实例化一个 A 类 我从某人那里导入 否则 所以我无法修改它 到我的 X 类中 有没有办法可以拦截或包装对 A 中方法的调用 即 在下面的代码中我可以调用 x a p1 并得到输出 X pre A p1 X post 很多TIA cl