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

Как де-импортировать модуль Python?

Я занимаюсь кодированием приложения, которое должно получать метаданные (author, version..etc) из нескольких модулей (.py файлов) и отображать их. Пользователь выбирает script и выполняется script. (Новые скрипты могут быть добавлены, а старые - из целевой папки, как система плагинов).

Во-первых, я импортирую script, и я вывожу метаданные, затем я перехожу к следующему. Но я хочу де-импортировать все остальные модули, кроме тех, которые выбрал пользователь.

Как это реализовать?

Я пробовал эти

1. del module
2. del sys.modules['module']

Последнее не сработало. Я попробовал #python и получил ответ, что было неплохо де-импорт модулей, но я хочу знать, как это реализовать. Любые идеи/предложения помогут.

4b9b3361

Ответ 1

Я думаю, этот пост должен помочь вам

изменить: чтобы обеспечить доступность этой информации (в случае, если ссылка умирает или что-то подобное), я включу исходное сообщение из списка рассылки здесь:


8/14/06, Дик Мурс писал:

Собственно, мой вопрос заключается в том, что после использования IDLE для импорта модулей и инициализации переменных, как вернуть их в начальное состояние без закрытия и повторного открытия.

Итак, например, после того, как я сделал

>>> import math, psyco
>>> a = 4**23

Как я могу стереть их без закрытия IDLE? (Я знал, как, но я забыл.)

Привет, Дик,

Обычно это подразумевает удаление из "реестра модулей" и удаление ссылки на него в коде. Если у вас действительно хорошо используемый модуль (например, один с параметрами конфигурации, импортированными в каждый модуль), тогда у вас будет дополнительный шаг удаления из каждого модуля. Кроме того, если вы используете "от импорта psyco...", то вы не сможете освободить модуль и легко ссылаться на модуль (это он из этого модуля или импортирован из третий модуль? см. "если параноид: код ниже".

Функция ниже удаляет модуль по имени из интерпретатора Python, Параноидальный параметр - это список имен переменных для удаления из любого другого модуль (предположительно, удаляется вместе с модулем). Будьте ОЧЕНЬ осторожны с параноидальный параметр; это может вызвать проблемы у вашего переводчика, если функции и классы называются одинаковыми в разных модулях. Один общий это означает "ошибку" для исключений. Многие библиотеки имеют один исключение "catch-all", называемое "ошибкой" в модуле. Если вы также назвали свой исключение "ошибка" и решил включить это в параноидальный список... там перейдите много других объектов исключений.

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

Ответ 2

Предложение: динамически импортируйте модули с помощью __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)

Ответ 3

Я знаю, что это сообщение устарело, но я просто столкнулся с этой проблемой и в течение последних нескольких дней боролся с этим. Теперь я пришел к выводу, что вполне может решить эту проблему. См. Пример кода ниже:

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 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.

Надеюсь, это может помочь кому-то, чтобы им не пришлось бороться по этому вопросу в течение нескольких дней!