programación practicar para más modulos lista español ejercicios contador python python-import

practicar - más de 400 ejercicios de programación en python pdf



Python: volver a cargar el componente Y importado con ''desde X importar Y''? (8)

Responder

De mis pruebas. La respuesta marcada, que sugiere una reload(X) simple reload(X) , no funciona.

De lo que puedo decir la respuesta correcta es:

import X reload( X ) from X import Y

Prueba

Mi prueba fue la siguiente (Python 2.6.5 + bpython 0.9.5.2)

X.py:

def Y(): print "Test 1"

bpython

>>> from X import Y >>> print Y() Test 1 >>> # Edit X.py to say "Test 2" >>> print Y() Test 1 >>> reload( X ) # doesn''t work because X not imported yet Traceback (most recent call last): File "<input>", line 1, in <module> NameError: name ''X'' is not defined >>> import X >>> print Y() Test 1 >>> print X.Y() Test 1 >>> reload( X ) # No effect on previous "from" statements >>> print Y() Test 1 >>> print X.Y() # first one that indicates refresh Test 2 >>> from X import Y >>> print Y() Test 2 >>> # Finally get what we were after

En Python, una vez que he importado un módulo X en una sesión de intérprete usando import X , y los cambios del módulo en el exterior, puedo recargar el módulo con reload(X) . Los cambios entonces estarán disponibles en mi sesión de intérprete.

Me pregunto si esto también es posible cuando importo un componente Y desde el módulo X usando from X import Y

La instrucción de reload Y no funciona, ya que Y no es un módulo en sí, sino solo un componente (en este caso, una clase) dentro de un módulo.

¿Es posible recargar componentes individuales de un módulo sin salir de la sesión de intérprete (o importar todo el módulo)?

EDITAR:

Para aclarar, la pregunta es acerca de importar una clase o función Y desde un módulo X y volver a cargar en un cambio, no un módulo Y desde un paquete X.


  1. reload() módulo X ,
  2. reload() modulo importando Y desde X

Tenga en cuenta que la recarga no cambiará los objetos ya creados enlazados en otros espacios de nombres (incluso si sigue la guía de estilo de Alex).


En primer lugar, no deberías usar recargar, si puedes evitarlo. Pero supongamos que tiene sus razones (es decir, la depuración dentro de IDLE).

La recarga de la biblioteca no devolverá los nombres al espacio de nombres del módulo. Para hacer esto, simplemente reasigne las variables:

f = open(''zoo.py'', ''w'') f.write("snakes = [''viper'',''anaconda'']/n") f.close() from zoo import snakes print snakes f = open(''zoo.py'', ''w'') f.write("snakes = [''black-adder'',''boa constrictor'']/n") f.close() import zoo reload(zoo) snakes = zoo.snakes # the variable ''snakes'' is now reloaded print snakes

Usted podría hacer esto de otras maneras. Puede automatizar el proceso buscando en el espacio de nombres local y reasignando todo lo que era del módulo en cuestión, pero creo que estamos siendo lo suficientemente malos.


Si Y es un módulo (y X un paquete), la reload(Y) estará bien; de lo contrario, verá por qué las buenas guías de estilo de Python (como mi empleador) dicen que nunca se debe importar nada, excepto un módulo (este es uno de muchas y muy buenas razones: sin embargo, la gente sigue importando funciones y clases directamente, no importa cuánto explique que no es una buena idea ;-).


Si quieres hacer esto:

from mymodule import myobject

Haga esto en su lugar:

import mymodule myobject=mymodule.myobject

Ahora puede usar myobject de la misma manera que estaba planeando (sin las referencias de mymodule indescriptibles y aburridas en todas partes).

Si está trabajando de forma interactiva y desea volver a cargar myobject desde mymodule, ahora puede utilizar:

reload(mymodule) myobject=mymodule.myobject


Solo para dar seguimiento a las AlexMartelli''s y Catskul''s , hay algunos casos realmente simples pero desagradables que parecen confundir la reload , al menos en Python 2.

Supongamos que tengo el siguiente árbol fuente:

- foo - __init__.py - bar.py

Con el siguiente contenido:

init.py:

from bar import Bar, Quux

bar.py:

print "Loading bar" class Bar(object): @property def x(self): return 42 class Quux(Bar): object_count = 0 def __init__(self): self.count = self.object_count self.__class__.object_count += 1 @property def x(self): return super(Quux,self).x + 1 def __repr__(self): return ''Quux[%d, x=%d]'' % (self.count, self.x)

Esto funciona bien sin usar reload :

>>> from foo import Quux Loading bar >>> Quux() Quux[0, x=43] >>> Quux() Quux[1, x=43] >>> Quux() Quux[2, x=43]

Pero intenta volver a cargar y no tiene efecto o corrompe las cosas:

>>> import foo Loading bar >>> from foo import Quux >>> Quux() Quux[0, x=43] >>> Quux() Quux[1, x=43] >>> reload(foo) <module ''foo'' from ''foo/__init__.pyc''> >>> Quux() Quux[2, x=43] >>> from foo import Quux >>> Quux() Quux[3, x=43] >>> reload(foo.bar) Loading bar <module ''foo.bar'' from ''foo/bar.pyc''> >>> Quux() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "foo/bar.py", line 17, in __repr__ return ''Quux[%d, x=%d]'' % (self.count, self.x) File "foo/bar.py", line 15, in x return super(Quux,self).x + 1 TypeError: super(type, obj): obj must be an instance or subtype of type >>> Quux().count 5 >>> Quux().count 6 >>> Quux = foo.bar.Quux >>> Quux() Quux[0, x=43] >>> foo.Quux() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "foo/bar.py", line 17, in __repr__ return ''Quux[%d, x=%d]'' % (self.count, self.x) File "foo/bar.py", line 15, in x return super(Quux,self).x + 1 TypeError: super(type, obj): obj must be an instance or subtype of type >>> foo.Quux().count 8

La única manera de asegurar que se recargara el submódulo de la bar era reload(foo.bar) ; la única forma de acceder a la clase de Quux recargada es alcanzarlo y extraerlo del submódulo recargado; pero el propio módulo foo mantuvo el objeto original de la clase Quux , presumiblemente porque usa la from bar import Bar, Quux (en lugar de la import bar seguida de Quux = bar.Quux ); Además, la clase Quux se desincronizó consigo misma, lo cual es simplemente extraño.


asumiendo que usaste from X import Y , tienes dos opciones:

reload(sys.modules[''X'']) reload(sys.modules[__name__]) # or explicitly name your module

o

Y=reload(sys.modules[''X'']).Y

algunas consideraciones:

A. si el ámbito de importación no es de todo el módulo (e, g: importar en una función), debe usar la segunda versión.

B. si Y se importa a X desde otro módulo (Z), debe volver a cargar Z, luego volver a cargar X y luego volver a cargar su módulo, incluso volver a cargar todos sus módulos (e, g: usar [ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ] ) puede recargar X antes de recargar Z - y no actualizar el valor de Y.


from modulename import func import sys reload(sys.modules[''modulename'']) from modulename import func