Подтвердить что ты не робот

Как перезагрузить класс в оболочке python?

Если я импортирую модуль, определяющий класс с тем же именем, принадлежащим пакету, он импортируется как класс, а не модуль из-за __init__.py родительского пакета. Подробнее см. различные результаты импорта в разных каталогах. В оболочке Python или оболочке ipython, если я делаю

from MyPak import MyMod

MyModule всегда импортируется как класс, поэтому я не могу его перезагрузить (reload() работает только для модулей). Выполнить

from MyPak import MyMod

снова, похоже, не обновляет определение класса. Может ли кто-нибудь предложить способ обновления класса в оболочке python?

пс. без перезапуска интерпретатора python.

имп. На всякий случай у вас есть код в руке и вы хотите его протестировать: я действительно говорю о BioPython, и я работаю над Bio.PDB.PDBParser. У меня есть оболочка ipython (v0.10) и редактирование PDBParser.py. Просто не удалось перезагрузить его в ipython.

так вот что я сделал:

# 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 :(

Я не мог видеть напечатанный текст. Изменения не были применены.

4b9b3361

Ответ 1

Наконец-то я нашел ответ:

import MyPak
from MyPak import MyMod

после редактирования файла MyPak/MyMod.py, чтобы перезагрузить класс MyMod в файле MyMod.py, нужно

import sys
del sys.modules['MyPak.MyMod'] 
reload(MyPak)
from MyPak import MyMod

Предостережения

  • Выполнение del MyPak или del MyMod или del MyPak.MyMod не решает проблему, так как просто удаляет привязку имени. Python ищет только sys.modules, чтобы увидеть, были ли модули уже импортированы. Проверьте обсуждение в сообщении имени модуля в sys.modules и globals().

  • При перезагрузке MyPak python пытается выполнить строку from MyMod import MyMod в MyPak/__init__.py. Однако он находит MyPak.MyMod в sys.modules, поэтому он будет НЕ перезагрузите MyMod, хотя MyPak/MyMod.py был обновлен. И вы обнаружите, что не генерируется новый MyPak/MyMod.pyc.

Ответ 2

Только на Python 3 импортируйте функцию reload:

>>> from importlib import reload

На обоих Python 2.x и 3.x вы можете просто вызвать reload в модуле:

>>> import MyPak
>>> reload(MyPak)
>>> from MyPak import MyMod

Однако экземпляры старого класса не будут обновляться (просто нет кода, описывающего механизм обновления).

Ответ 3

Есть ли способы решить эту проблему:

1. Используйте import MyPak.MyMod вместо from MyPak import MyMod

Затем вы можете написать:

from importlib import reload  # If on Python 3
import MyPak.MyMod
reload(MyPak.MyMod)

и он работает.

2. Используйте IPython.lib.deepreload

from MyPak import MyMod
from IPython.lib.deepreload import reload
reload(MyPak)  # This should also reload all submodules

3. Используйте autoreload magic

%load_ext autoreload
%autoreload 2
import MyPak.MyMod  # All changes to MyPak.MyMod will be loaded automatically

Ответ 4

У меня есть один файл myfile.py, который содержит один класс MyClass

Для импорта просто выполните:

from myfile import MyClass
mc = MyClass()

Чтобы перезагрузить:

import sys
del sys.modules['myfile']
from myfile import MyClass
modifiedmc = MyClass()

Это очень полезно при создании модулей. их можно встроить в функцию и просто вызвать функцию

def myreload():
   import sys
   del sys.modules['myfile']
   from myfile import MyClass
   modifiedmc = MyClass()
   global mc
   mc = modifiedmc

Ответ 5

Вы можете использовать магическую функцию:

%load_ext autoreload
%autoreload 2
from MyPak import MyMod

Ответ 6

Он работает для меня, используя python 3.5.2:

import importlib
importlib.reload(class)
from class import module