Python 上下文管理器和对象创建

标签 python callback contextmanager

我想创建一个上下文管理器,它可以拦截给定类或此类的子类中的任何对象实例化,并对该对象执行某些操作。

我 sudo 代码可能看起来像这样:

with my_context_watchdog(my_callback, BaseClass):
     obj_1 = BaseClass(name) # launch callback
     obj_2 = SubClass(name) # launch callback

     obj_3 = RandomClass(name) # does not launch callback

def my_callback(new_obj):
     print("new object name:", new_obj.name)

我可以用Python做这样的事情吗?

最好是仅在对象完全实例化之后执行回调。

重要提示:我无法修改任何对象类,它们位于库中,我对其没有任何控制权。我只想在实例化该库的某些类时引发回调。

也许上下文管理器不是最好的主意,我愿意接受任何其他解决方案。

最佳答案

上下文管理器实际上看不到 with block 中的代码。如果您看到一个库在做这样的“神奇”事情,那么通常在后台某个地方有一个隐藏的全局变量,并且在 with block 内调用的函数主动与上下文管理器合作。

也就是说,您有两种选择。一种是有道理的,一种是非常丑陋的。

有意义的:

# somewhere in the context manager:
class ContextManagerReturnVal:
    def instantiate(self, cls, *args, **kwargs):
        obj = cls(*args, **kwargs)
        if issubclass(cls, self.base_class):
            self.callback(cls, *args, **kwargs)
        return obj

with watchdog(callback, BaseClass) as instantiate:
    obj1 = instantiate(BaseClass, name)
    obj2 = instantiate(SubClass, name)

最难看的是对 BaseClass 进行猴子修补。您在评论中说您无法修改 BaseClass - 取决于您的具体含义。如果您无法修改源代码,您仍然可以在运行时修改该类,如下所示:Monkey patching a class in another module in Python 您必须存储原始的 __init__ 方法并在上下文管理器退出后返回它...这当然不推荐,因为您基本上是在不应该做的地方,并且可能会引入硬性-查找错误。

除此之外,恐怕做不到。

关于Python 上下文管理器和对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51867255/

相关文章:

python - 是否可以重试一段特定的代码而不考虑异常?

python - 如何动态应用多个 with 语句

python - 值错误: I/O operation on closed file within context manager scope

python - 开始使用 python 处理数据

jquery - 即使图像不存在,也会触发图像加载回调

python - 组合不同图像的 block 并产生新图像

c# - Action 字典期望其键的类型

java - 带有指向结构参数的指针的 JNA 回调函数

python - 终端命令未完成

python - 如果条目满足特定条件,则绘制函数 python