2011-08-08 9 views
14

Estoy interactuando con una API python 2.x escrita de una manera no OO, utiliza el alcance global del módulo para algunas cosas impulsadas por el estado interno. Es necesario en un contexto donde ya no es singleton, y modificar el código original (no el nuestro) no es una opción.Obtenga 2 instancias aisladas de un módulo python

A falta de utilizar subprocesos de intérpretes separados, ¿hay alguna forma de que pueda descartar los módulos e interactuar con varias instancias del módulo (tratándolo así como un objeto)?

Necesito usar el módulo para manejar 2 configuraciones diferentes, que internamente no parece funcionar.

Descargo de responsabilidad: Por favor, no haga esto. Haga esto solo si se encuentra en una situación muy extraña y trate de alterar la situación de otras maneras antes de hacer esto. Hice esto para hacer frente a un código extraño que no se pudo cambiar al momento de preguntar, no para proporcionar una forma de proliferar más códigos impares.

+1

duplicado posible de [Cómo hacer una copia de un módulo de Python en tiempo de ejecución?] (Https://stackoverflow.com/questions/11170949/how-to-make-a-copy-of-a-python-module -at-runtime) – ThorSummoner

+0

@ThorSummoner sí, creo que sí, con una muy buena respuesta. –

Respuesta

1

No he utilizado personalmente, pero parece que Exocet biblioteca puede ayudar.

+1

Me gusta el uso de una biblioteca que maneje esto; probablemente sea mucho mejor que retocar directamente con sys, y siempre puedo informar/corregir errores si los hay. –

13

Basta con retirar el módulo de 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 
+0

¿Esto hace que todas las clases en python sean redundantes? (dado que los módulos se pueden usar en su lugar) – mulllhausen

+0

Las clases y los módulos tienen espacios de nombres, pero las similitudes terminan ahí. Por ejemplo, los módulos no se pueden llamar, por lo que no pueden reemplazar clases. – phihag

+0

aplausos. para mis propósitos, creo que puedo ir por completo sin clases. la única razón por la que normalmente uso clases es para extender la funcionalidad básica. Creo que todavía puedo hacer esto con los módulos, pero solo tengo que invocar explícitamente el módulo "hijo" o el módulo "principal" según sea necesario. es un poco más de esfuerzo mental, pero luego es útil pensar dónde vive la función invocada de todos modos ... – mulllhausen

3

Usted puede tratar por sys.modules engañando

import badmodule as badmod1 

import sys 
del sys.modules['badmodule'] 

import badmodule as badmod2 

Si esto funciona o no depende, por supuesto, en lo que el módulo está haciendo mal ..

0

La manera más fácil es hacer dos copias del módulo e importarlas por separado. Por ejemplo, tome su módulo thingabobber y haga dos copias llamadas thingabobber1 y thingabobber2. A continuación, sólo:

import thingabobber1, thingabobber2 

Si esto no es posible, elimine el módulo de sys.modules después de la importación en un principio para que pueda obtener una segunda copia en el segundo importación.

import sys 

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

Esto se puede lograr mediante la importación del módulo a través de diferentes rutas. Es decir, si en su sys.path tiene dos rutas de puntos diferentes al módulo, la memoria caché del módulo creará dos instancias diferentes del módulo con diferentes árboles de símbolos, globales, y así sucesivamente.

Esto también se puede utilizar para tener varias versiones de una biblioteca.

Ten en cuenta que no se detectarán excepciones (ya que estás tratando de atrapar el símbolo equivocado).

Cuestiones relacionadas