【问题标题】:Get 2 isolated instances of a python module获取 python 模块的 2 个独立实例
【发布时间】:2011-08-08 16:53:19
【问题描述】:

我正在与以非 OO 方式编写的 python 2.x API 交互,它使用模块全局范围来处理一些内部状态驱动的东西。在不再是单例的情况下需要它,并且修改原始代码(不是我们的)不是一种选择。

没有使用单独解释器的子进程运行,有什么方法可以关闭模​​块并与模块的多个实例进行交互(从而将其视为一个对象)?

我需要使用该模块来驱动 2 种不同的设置 - 它在内部似乎无法使用。

免责声明:请不要这样做。请仅在非常奇怪的情况下才这样做 - 并在这样做之前尝试以其他方式改变情况。我这样做是为了处理在询问时无法更改的奇数代码 - 不是为了提供一种方法来增加更多奇数代码。

【问题讨论】:

标签: python


【解决方案1】:

只需从sys.modules 中删除模块:

>>> import sys
>>> import mod as m1
>>> m1.x = 1
>>> del sys.modules['mod']
>>> import mod as m2
>>> m2.x = 2
>>> m1.x
1

【讨论】:

  • 这会使python中的所有类都变得多余吗? (因为可以使用模块)
  • 类和模块都有命名空间,但相似之处到此为止。例如,模块是不可调用的,因此它们不能替换类。
  • 干杯。出于我的目的,我认为我可以完全不上课。我通常使用类的唯一原因是扩展基本功能。我想我仍然可以使用模块来做到这一点,但我只需要根据需要显式调用“子”模块或“父”模块。它稍微多一点思考的努力,但是思考被调用的函数在哪里是有用的......
  • @mulllhausen 请不要。我这样做是为了处理奇怪的代码——而不是提供一种方法来增加更多的奇怪代码。
【解决方案2】:

你可以通过欺骗 sys.modules 来尝试

import badmodule as badmod1

import sys
del sys.modules['badmodule']

import badmodule as badmod2

这是否有效当然取决于坏模块在做什么......

【讨论】:

    【解决方案3】:

    我没有亲自使用过,但似乎 Exocet 库可能会有所帮助。

    【讨论】:

    • 我喜欢使用处理这个问题的库 - 可能比直接修改 sys 好得多,如果有任何错误,我总是可以报告/修复。
    【解决方案4】:

    最简单的方法是制作模块的两个副本并分别导入它们。例如,使用您的模块thingabobber 并制作两个名为thingabobber1thingabobber2 的副本。然后就:

    import thingabobber1, thingabobber2
    

    如果这不可行,请在最初导入模块后从 sys.modules 中删除该模块,以便在第二次导入时获得第二个副本。

    import sys
    
    import thingabobber as thingabobber1
    del sys.modules["thingabobber"]
    import thingabobber as thingabobber2
    

    【讨论】:

      【解决方案5】:

      这可以通过不同路径导入模块来实现。 也就是说 - 如果在您的 sys.path 中有两个不同的点路由到模块,模块缓存将创建具有不同符号树、全局变量等的模块的两个不同实例。

      这也可以用于拥有多个版本的库。

      注意它会导致异常未被捕获(因为您试图捕获错误的符号)。

      【讨论】:

        【解决方案6】:

        我正在尝试使用二进制 (so) 子模块,但该过程失败了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-08
          • 2018-09-07
          • 1970-01-01
          • 2019-07-14
          • 1970-01-01
          • 1970-01-01
          • 2015-06-02
          • 2016-10-08
          相关资源
          最近更新 更多