programacion - poo python 3
cómo recargar una clase en Python Shell? (6)
Finalmente encontré la respuesta:
import MyPak
from MyPak import MyMod
después de editar el archivo MyPak/MyMod.py
, para volver a cargar la clase MyMod
en el archivo MyMod.py
, se necesita
import sys
del sys.modules[''MyPak.MyMod'']
reload(MyPak)
from MyPak import MyMod
Advertencias :
Ejecutar
del MyPak
odel MyMod
odel MyPak.MyMod
no resuelve el problema ya que simplemente elimina el enlace del nombre. Python solo buscasys.modules
para ver si los módulos ya se han importado. Consulte la discusión en el nombre del módulo de publicación en sys.modules y globals () .Al volver a cargar MyPak, python intenta ejecutar la línea
from MyMod import MyMod
enMyPak/__init__.py
. Sin embargo, encuentraMyPak.MyMod
ensys.modules
, por lo que NO volverá a cargarMyMod
aunqueMyPak/MyMod.py
se haya actualizado. Y descubrirá que no se genera ningúnMyPak/MyMod.pyc
nuevo.
Si importo un módulo que define una clase del mismo nombre que pertenece a un paquete, se importa como Clase, no como Módulo debido a __init__.py del paquete principal. Vea diferentes resultados de importación en diferentes directorios para más detalles. En Python shell o ipython shell, si lo hago
from MyPak import MyMod
MyModule siempre se importa como clase, por lo que no puedo volver a cargarlo (reload () funciona solo para los módulos). correr
from MyPak import MyMod
nuevamente no parece actualizar la definición de Clase. ¿Alguien podría sugerir una forma de actualizar la clase en Python Shell?
PD. sin reiniciar el intérprete de Python.
pps . En caso de que tenga el código en la mano y desee probarlo: en realidad estoy hablando de BioPython, y estoy trabajando en Bio.PDB.PDBParser. Tengo un shell ipython (v0.10) y edito PDBParser.py. Simplemente no tengo forma de volver a cargarlo en ipython.
entonces esto es lo que hice:
# start ipython v0.10
import Bio
from Bio.PDB import PDBParser
p = PDBParser()
s = p.get_structure()
# then I make changes,e.g. simply print some text, in PDBParser.py
del Bio
del PDBParser
del s
import Bio # or reload(Bio) without deleting all the objects
from Bio.PDB import PDBParser
p = PDBParser()
s = p.get_structure() # expected output after change not seen :(
No pude ver el texto impreso. Los cambios no se aplicaron de alguna manera.
Funciona para mí usando Python 3.5.2:
import importlib
importlib.reload(class)
from class import module
Hay formas de resolver esto:
1. Usa import MyPak.MyMod
lugar de from MyPak import MyMod
Entonces puedes escribir:
from importlib import reload # If on Python 3
import MyPak.MyMod
reload(MyPak.MyMod)
y funciona.
2. Utilice IPython.lib.deepreload
from MyPak import MyMod
from IPython.lib.deepreload import reload
reload(MyPak) # This should also reload all submodules
3. Utiliza la magia de autoreload
%load_ext autoreload
%autoreload 2
import MyPak.MyMod # All changes to MyPak.MyMod will be loaded automatically
Puedes usar una función mágica:
%load_ext autoreload
%autoreload 2
from MyPak import MyMod
Solo en Python 3, importe la función de reload
:
>>> from importlib import reload
En Python 2.x y 3.x, puede simplemente llamar a reload
en el módulo:
>>> import MyPak
>>> reload(MyPak)
>>> from MyPak import MyMod
Sin embargo, las instancias de la clase anterior no se actualizarán (simplemente no hay un código que describa el mecanismo de actualización).
Tengo un archivo myfile.py que contiene una clase MyClass
Para importar solo hazlo:
from myfile import MyClass
mc = MyClass()
Para volver a cargar:
import sys
del sys.modules[''myfile'']
from myfile import MyClass
modifiedmc = MyClass()
Esto es muy útil al construir módulos. uno puede poner estos dentro de una función y simplemente llamar a la función
def myreload():
import sys
del sys.modules[''myfile'']
from myfile import MyClass
modifiedmc = MyClass()
global mc
mc = modifiedmc