Как удалить импорт модуля Python?
Я нахожусь в процессе кодирования приложения, которое должно получить метаданные (автор, версия.. и т. Д.) Из нескольких модулей (файлы.py) и отобразить их. Пользователь выбирает сценарий, и сценарий выполняется. (Новые скрипты могут быть добавлены, а старые - из целевой папки, как система плагинов).
Сначала я импортирую скрипт и извлекаю метаданные, затем перехожу к следующему. Но я хочу удалить все остальные модули, кроме того, который выбрал пользователь.
Как я могу это реализовать?
Я пробовал это
1. del module
2. del sys.modules['module']
Последний не сработал. Я попробовал #python и получил ответ, что нецелесообразно де-импортировать модули, но я хочу знать чистый способ реализации этого. Любые идеи / предложения помогут.
3 ответа
Я думаю, что этот пост должен помочь вам
изменить: для обеспечения доступности этой информации (в случае, если ссылка умирает или что-то подобное), я включу оригинальное сообщение из списка рассылки репетитора здесь:
14.08.06 Дик Мурс написал:
На самом деле, мой вопрос, после использования IDLE для импорта модулей и инициализации переменных, как вернуть его в исходное состояние без закрытия и повторного открытия.
Так, например, после того, как я сделал
>>> import math, psyco >>> a = 4**23
Как я могу стереть их, не закрывая IDLE? (Раньше я знал, как, но я забыл.)
Привет Дик,
Обычно это влечет за собой удаление из "реестра модулей" и удаление ссылок на него в коде. Если у вас действительно хорошо используемый модуль (например, модуль с параметрами конфигурации, импортированными в каждый модуль), то у вас будет дополнительный шаг удаления его из каждый модуль. Кроме того, если вы используете "из psyco import ...", то вы не сможете легко освободить модуль и ссылку на модуль (это из этого модуля или импортировано из третьего модуля? смотрите "если параноик: код ниже).
Приведенная ниже функция удаляет модуль по имени из интерпретатора Python, параметр "paranoid" представляет собой список имен переменных, которые нужно удалить из любого другого модуля (предположительно, удаляемого с помощью модуля). Будьте ОЧЕНЬ осторожны с параноидальным параметром; это может вызвать проблемы для вашего интерпретатора, если ваши функции и классы названы одинаково в разных модулях. Одним из распространенных случаев этого является "ошибка" для исключений. У многих библиотек есть одно исключение "ловить все", называемое "ошибка" в модуле. Если вы также назвали свое исключение "ошибка" и решили включить это в список параноиков... там есть много других объектов исключений.
def delete_module(modname, paranoid=None):
from sys import modules
try:
thismod = modules[modname]
except KeyError:
raise ValueError(modname)
these_symbols = dir(thismod)
if paranoid:
try:
paranoid[:] # sequence support
except:
raise ValueError('must supply a finite list for paranoid')
else:
these_symbols = paranoid[:]
del modules[modname]
for mod in modules.values():
try:
delattr(mod, modname)
except AttributeError:
pass
if paranoid:
for symbol in these_symbols:
if symbol[:2] == '__': # ignore special symbols
continue
try:
delattr(mod, symbol)
except AttributeError:
pass
Тогда вы сможете использовать это как:
delete_module('psyco')
или же
delete_module('psyco', ['Psycho', 'KillerError'])
# only delete these symbols from every other module
# (for "from psyco import Psycho, KillerError" statements)
-Arcege
Недавно я нашел этот пост https://www.geeksforgeeks.org/reloading-modules-python/, поэтому для Python 3.4 или более поздней версии используйте
import importlib
importlib.reload(module)
Предложение: Импортируйте ваши модули динамически, используя __import__
Например
module_list = ['os', 'decimal', 'random']
for module in module_list:
x = __import__(module)
print 'name: %s - module_obj: %s' % (x.__name__, x)
Будет производить:
name: os - module_obj: <module 'os' from '/usr/lib64/python2.4/os.pyc'>
name: decimal - module_obj: <module 'decimal' from '/usr/lib64/python2.4/decimal.pyc'>
name: random - module_obj: <module 'random' from '/usr/lib64/python2.4/random.pyc'>
Хотя это не удалит его из реестра модулей. В следующий раз, когда он будет импортирован, он не будет перечитывать файл пакета / модуля и не выполнит его. Для этого вы можете просто изменить приведенный выше фрагмент кода следующим образом:
import sys
module_list = ['os', 'decimal', 'random', 'test1']
for module_name in module_list:
x = __import__(module_name)
print 'name: %s - module_obj: %s' % (x.__name__, x)
del x
sys.modules.pop(module_name)
Я знаю, что этот пост устарел, но я только столкнулся с этой проблемой и боролся с ней в течение последних нескольких дней. Теперь я пришел к выводу, что могу полностью решить эту проблему. Пожалуйста, посмотрите пример кода ниже:
try:
theMod = sys.modules['ModNeedToBeDel']
except:
theMod = None
if theMod:
del sys.modules['ModNeedToBeDel']
#The extra try/except below is because I implemented the block in a module of a sub-package; this ModNeedToBeDel in my case was imported either by the toppest level Main code, or by the other sub-package modules. That's why I need two different try/except.
try:
theMod = sys.modules['UpperFolder.ModNeedToBeDel']
except:
theMod = None
if theMod:
del sys.modules['UpperFolder.ModNeedToBeDel']
import ModNeedToBeDel # or UpperFolder.ModNeedToBeDel here
Обратите внимание, что del sys.modules[theMod]
не будет работать, потому что он просто удаляет ссылку, а не фактическую ModNeedToBeDel
,
Надеюсь, что это может помочь кому-то, чтобы им не пришлось бороться по этому вопросу в течение нескольких дней!