首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python contextmanager和对象创建

Python contextmanager和对象创建
EN

Stack Overflow用户
提问于 2018-08-15 22:22:47
回答 2查看 536关注 0票数 2

我想要创建一个contextmanager,它将拦截来自这个类的一个或多个子类的任何对象实例化,并对该对象执行一些操作。

我需要代码,它看起来像这样:

代码语言:javascript
复制
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中做这样的事情吗?

最好的方法是在对象完全实例化之后只执行回调。

重要:我不能修改任何对象类,它们在一个库中,我对它没有任何控制。当这个库的一些类被实例化时,我只想引发一个回调。

也许contextmanager不是最好的主意,我对任何其他解决方案都是开放的。

EN

回答 2

Stack Overflow用户

发布于 2018-08-15 23:33:47

上下文管理器实际上看不到with块中的代码。如果您看到一个库正在执行这样的“神奇”操作,通常在后台某个地方有一个隐藏的全局变量,并且在with块中调用的函数积极地与上下文管理器协作。

话虽如此,你还有两个选择。一个是合理的,一个是非常丑陋的。

有意义的是:

代码语言:javascript
复制
# 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__方法,并在上下文管理器退出后返回它.当然,这是不推荐的,因为你基本上是把手指贴在不应该的地方,并且可能会引入难以找到的bug。

除此之外,恐怕做不到。

票数 2
EN

Stack Overflow用户

发布于 2018-08-15 23:25:49

我可以看到,您可以很容易地实现一个稍微不同的上下文管理器:

代码语言:javascript
复制
with my_context_watchdog(some_instance):
     pass

..。但这可能与检查器函数一样好,而不是您想要的功能。上下文管理器的神奇之处在于__enter__方法,所以这里可能发生的事情太多了,没有任何大规模的重载。可能有一种方法可以让__init__方法

您还可以创建一些构造函数来区分类名,并考虑将其应用于__new__方法:

代码语言:javascript
复制
def new(cls):
     if cls.__name__ == 'BaseClass':
          pass
          # do something
     else:
          pass
          # do a different thing
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51867255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档