Як вивантажити (перезавантажити) модуль?


797

У мене давно працює сервер Python, і я хотів би мати можливість оновити послугу без перезавантаження сервера. Який найкращий спосіб зробити це?

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()

53
Порада пам’яті: «імпорт» не означає «завантажувати», це означає «завантажувати, якщо ще не завантажений, а потім імпортувати у простір імен».
Кос

3
питання не повинно включати "вивантажувати", оскільки це неможливо ще в python - однак, перезавантаження є відомою парадигмою, як відповіли нижче
robertmoggach

У мене була така ж проблема при використанні динамічного модуля в додатку py2exe. Оскільки py2exe завжди зберігає байт-код у zip каталогу, перезавантаження не працювало. Але я знайшов робоче рішення за допомогою модуля import_file. Зараз моя програма працює чудово.
Прітам Пан

2
Що робити, якщо ви хочете "розвантажити", оскільки код намагається видалити .pyc-файл?
darkgaze

Відповіді:


788

Ви можете перезавантажити модуль, коли він вже імпортований за допомогою reloadвбудованої функції (лише для Python 3.4+) :

from importlib import reload  
import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

У Python 3 reloadбув переміщений impмодуль. У 3.4 impбув знецінений на користь importlibі reloadбув доданий до останнього. Під час націлювання на 3 або пізнішої версії будь-яке посилання на відповідний модуль під час виклику reloadабо імпортування.

Я думаю, що це те, чого ти хочеш. Веб-сервери на зразок сервера розробки Django використовують це, щоб ви могли бачити наслідки змін вашого коду без перезапуску самого серверного процесу.

Цитувати з документів:

Код модулів Python перекомпілюється, і код рівня модуля знову виконується, визначаючи новий набір об'єктів, які пов'язані з іменами в словнику модуля. Функція init модулів розширення не називається вдруге. Як і у всіх інших об'єктах в Python, старі об'єкти відновлюються лише після того, як їх посилання впаде до нуля. Імена в просторі імен модулів оновлюються, щоб вказувати на будь-які нові або змінені об'єкти. Інші посилання на старі об'єкти (наприклад, імена, що знаходяться поза модулем) не відновлюються для посилання на нові об'єкти і повинні бути оновлені у кожному просторі імен, де вони виникають, якщо цього потрібно.

Як ви зазначили у своєму запитанні, вам доведеться реконструювати Fooоб'єкти, якщо Fooклас знаходиться в fooмодулі.


10
насправді сервер розробки django перезавантажується при зміні файлу .. (він перезапускає сервер, а не просто перезавантажує модуль)
hasen

25
звідки ця функція "is_changed"? Я не бачу жодної документації на нього, і вона не працює в моєму середовищі Python 3.1.3, а також не працює в 2.6.4.
jedmao

5
немає cdleary, Django не може просто використовувати reload: pyunit.sourceforge.net/notes/reloading.html
raylu

14
@BartoszKP якщо Xне модуль, можнаimport sys; reload(sys.modules[X.__module__])
drevicko

5
@jedmao @JamesDraper Я впевнений, що is_changedфункція - це лише довільна функція, яку вам доведеться написати; це не вбудований. Наприклад, він, можливо, може відкрити файл, відповідний модулю, який ви імпортуєте, і відрізняти його кешованою версією, щоб побачити, чи змінився він.
Джеймс Мхуф

252

У Python 3.0–3.3 ви б використовували: imp.reload(module)

BDFL вже відповів на це питання.

Однак impбуло знято в 3.4, на користьimportlib (спасибі @Stefan! ).

Я думаю , отже, ви зараз користуєтесь importlib.reload(module), хоча я не впевнений.


23
Серйозний новачок вдячний дізнатися про критичні нюанси між Python 2 та 3.
Smandoli

24
чи дійсно imp.reload (imp)?
Loïc Faure-Lacroix

2
@ LoïcFaure-Lacroix так само reload(__builtins__)діє і в 2.x
JBernardo

1
@Tarrasch: це модуль Python, який ви хочете перезавантажити, як у прикладі у запитанні.
Пол Д. Уейт

3
@ LoïcFaure-Lacroix так, імп може перезавантажити себе.
Девін Коллі Джонсон

92

Видалити модуль може бути дуже важко, якщо це не чистий Python.

Ось деяка інформація з: Як я дійсно видаляю імпортований модуль?

Ви можете використовувати sys.getrefcount (), щоб дізнатися фактичну кількість посилань.

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

Числа, що перевищують 3, вказують на те, що модуль буде важко позбутися. Доморощений «порожній» (нічого не містить) модуль повинен після збирати сміття

>>> del sys.modules["empty"]
>>> del empty

як третя посилання є артефактом функції getrefcount ().


4
Щойно я виявив, що якщо модуль є частиною пакету, його потрібно також видалити:setattr(package, "empty", None)
u0b34a0f6ae

6
Це правильне рішення, особливо якщо у вас є пакет з вкладеними модулями. reload()перезавантажує лише самий верхній модуль, і все, що знаходиться всередині нього, не буде перезавантажено, якщо ви спочатку не видалите його з sys.modules.
Серін

73

reload(module), але лише в тому випадку, якщо він повністю автономний. Якщо що-небудь ще має посилання на модуль (або будь-який об'єкт, що належить до модуля), то ви отримаєте тонкі та цікаві помилки, спричинені тим, що старий код звисає довше, ніж ви очікували, і такі речі, як isinstanceне працює в різних версіях той самий код.

Якщо у вас є односторонні залежності, ви також повинні перезавантажити всі модулі, які залежать від перезавантаженого модуля, щоб позбутися всіх посилань на старий код. А потім перезавантажуйте модулі, які залежать від перезавантажених модулів, рекурсивно.

Якщо у вас кругові залежності, що дуже часто, наприклад, коли ви маєте справу з перезавантаженням пакету, ви повинні вивантажити всі модулі в групі за один раз. Ви не можете цього зробити, reload()оскільки він повторно імпортує кожен модуль до того, як його залежності будуть оновлені, що дозволить старим посиланням переповзати в нові модулі.

Єдиний спосіб зробити це в цьому випадку - зламати sys.modules, який є непідтримуваним. Вам потрібно буде пройти та видалити кожну sys.modulesзапис, яку ви хочете перезавантажити при наступному імпорті, а також видалити записи, значення яких Noneстосуються проблеми впровадження, пов’язаної з кешуванням невдалого відносного імпорту. Це не дуже приємно, але якщо у вас є повністю автономний набір залежностей, який не залишає посилань поза його кодовою базою, це реально.

Напевно, найкраще перезапустити сервер. :-)


1
Хіба не затягується спеціально для цього сценарію?
Джош

@Josh: ні, це для перезавантаження дерева пакетів, і навіть тоді воно працює лише до тих пір, поки пакет не має зовнішніх / кругових залежностей.
bobince

1
Чи можете ви детально розробити частину зі Noneзначеннями, тому що я точно працюю над цим питанням: я видаляю елементи з sys.modulesі після повторного імпортування деяких імпортованих залежностей None.
шламар

@shclamar: Див stackoverflow.com/questions/1958417 / ... (і посилання звідти) для фону. Мені незрозуміло (навіть дивлячись на import.c-код), як Noneзаписи вдалося пройти назад через механізм імпорту, коли «справжні» записи були видалені, і я не можу зробити це на 2.7; в майбутньому це, звичайно, більше не є проблемою, оскільки неявний відносний імпорт пішов. Тим часом, видалення всіх записів зі Noneзначенням, здається, виправить це.
bobince

1
@Eliethesaiyan: ти маєш на увазі reloadфункцію? Він вбудований, вам не потрібно імпортувати жодну бібліотеку.
bobince

63
if 'myModule' in sys.modules:  
    del sys.modules["myModule"]

3
+1. Моєю метою було провести тести на носі в межах python. Після того, як я завантажив модуль і перейменував деякі функції, старі імена залишилися під час дзвінка nose.run()навіть післяreload(my_module) %run my_module
Петро Д

5
Якщо ваш модуль імпортує власні підмодулі, можливо, вам також доведеться видалити їх. Щось подібне [del(sys.modules[mod] for mod in sys.modules.keys() if mod.startswith('myModule.')].
drevicko

Я не думаю, що це вивантажує модуль. На Python 3.8: import sys; import json; del sys.modules['json']; print(json.dumps([1]))і json модуль все ще працює, хоча він більше не знаходиться в sys.modules.
Сеперман

60

Для Python 2 використовуйте вбудовану функцію reload () :

reload(module)

Для Python 2 та 3.2–3.3 використовуйте перезавантаження з модуля imp :

import imp
imp.reload(module)

Але imp застаріла з версії 3.4 на користь importlib , тому використовуйте:

import importlib
importlib.reload(module)

або

from importlib import reload
reload(module)

2
для вирішення будь-якого з цих випадків: from six import reload_module(потрібно pip install sixспершу звичайно)
Анентроп

@Anentropic: Корисна порада рекомендувати використовувати шість пакунків, але синтаксис є from six.moves import reload_module( doc )
x0s

23

Наступний код дозволяє вам сумісність Python 2/3:

try:
    reload
except NameError:
    # Python 3
    from imp import reload

Ви можете використовувати його як reload()в обох версіях, що робить речі простішими.


18

Прийнята відповідь не обробляє випадок X імпорту Y. Цей код також обробляє його та стандартний регістр імпорту:

def importOrReload(module_name, *names):
    import sys

    if module_name in sys.modules:
        reload(sys.modules[module_name])
    else:
        __import__(module_name, fromlist=names)

    for name in names:
        globals()[name] = getattr(sys.modules[module_name], name)

# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")

У випадку перезавантаження ми присвоюємо імена верхнього рівня значенням, збереженим у щойно перезавантаженому модулі, який оновлює їх.


Помітивши проблему, globals () посилається на модуль, для якого ви визначаєте цю функцію, тож якщо ви визначите її в модулі, відмінному від того, який ви викликаєте, у цьому не працює.
Джозеф Гарвін

Для інтерактивних, після >>> from X import Yперезавантаження>>> __import__('X', fromlist='Y')
Боб Штейн

@ BobStein-VisiBone, чи є спосіб зробити так, коли fromlist='*'?
Майк C

Добре запитання, не знаю @MikeC. До речі, я маю тенденцію припинити майже все використання fromв імпортах заявок. Просто чіткий import <package>і явний package.symbol у коді. Зрозуміти це може не завжди можливо чи бажано. (Ось один виняток: з майбутнього імпорту print_function.)
Боб Штейн

Майк С: що для мене працюєfoo = reload(foo); from foo import *
чемпіон

16

Це сучасний спосіб перезавантаження модуля:

from importlib import reload

Якщо ви хочете підтримувати версії Python старші 3,5, спробуйте:

from sys import version_info
if version_info[0] < 3:
    pass # Python 2 has built in reload
elif version_info[0] == 3 and version_info[1] <= 4:
    from imp import reload # Python 3.0 - 3.4 
else:
    from importlib import reload # Python 3.5+

Для його використання запустіть reload(MODULE), замінивши MODULEмодуль, який ви хочете перезавантажити.

Наприклад, reload(math)перезавантажте mathмодуль.


4
Або просто робити from importlib import reload. Тоді ви можете зробити reload(MODULE_NAME). У цій функції немає потреби.
пауз

Я вважаю, що modulereload(MODULE_NAME)він більше пояснює себе, ніж просто, reload(MODULE_NAME)і має менший шанс конфліктувати з іншими функціями.
Річі Бендалл

@RichieBendall Вибачте, але ця відповідь абсолютно неправильна. Функція reload () приймає об'єкт модуля, а не ім'я модуля ... Прочитайте документи: docs.python.org/3/library/importlib.html#importlib.reload І я погоджуюся з @ pault - це "як modulereload" є чудовим .
mbdevpl

Я змінив свою відповідь, щоб відобразити вашу думку.
Річі Бендалл

13

Якщо ви не на сервері, але розвиваєтеся і вам потрібно часто перезавантажувати модуль, ось чудова порада.

По-перше, переконайтеся, що ви використовуєте відмінну оболонку IPython від проекту Jupyter Notebook. Після встановлення Jupyter ви можете запустити його з ipython, або jupyter console, що ще краще jupyter qtconsole, що дасть вам приємну кольорову консоль із заповненням коду в будь-якій ОС.

Тепер у своїй оболонці введіть:

%load_ext autoreload
%autoreload 2

Тепер при кожному запуску сценарію ваші модулі будуть перезавантажуватися.

Крім того 2, існують і інші варіанти магії автоматичного завантаження :

%autoreload
Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0
Disable automatic reloading.

%autoreload 1
Reload all modules imported with %aimport every time before executing the Python code typed.

%autoreload 2
Reload all modules (except those excluded by %aimport) every time before
executing the Python code typed.

7

Для таких, як я, які хочуть розвантажити всі модулі (під час роботи в інтерпретаторі Python під Emacs ):

   for mod in sys.modules.values():
      reload(mod)

Більш детальна інформація знаходиться в перезавантаженні модулів Python .


Насправді, схоже, це не працює надійно (в 2.6), оскільки не все sys.modules.values()є модулем. Наприклад: >>> введіть (sys.modules.values ​​() [1]) <class 'email.LazyImporter'> Отже, якщо я спробую запустити цей код, він перепадає (я знаю, що це не означає як практичне рішення, просто вказуючи на це).
Френсіс Деві

Це навіть не працює в попередніх пітонах - як написано. Довелося виключити деякі імена. Я оновлю публікацію, коли переміщу цей код на свій новий комп'ютер.

2
Відмінно працює в Python 2.7 після деяких модифікацій:if mod and mod.__name__ != "__main__": imp.reload(mod)
Czarek Tomczak

2
Це добре для мене: імпортувати імп [reload (m) для m в sys.modules.values ​​(), якщо m і не " " в m .__ ім'я, а не imp.is_builtin (m .__ ім'я__)]
Патрік Вовк,

5

Особливості Enthought Traits має модуль, який досить добре працює для цього. https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

Він перезавантажить будь-який змінений модуль та оновить інші модулі та встановлені об'єкти, які ним користуються. Він не працює більшою частиною часу за допомогою __very_private__методів і може задушити наслідування класів, але це економить мені шалену кількість часу від необхідності перезапустити хост-програму під час написання PyQt guis або матеріалів, які виконуються в таких програмах, як Maya або Nuke. Це не працює, можливо, 20-30% часу, але це все ще неймовірно корисно.

Пакет Enthought не завантажує файли в той момент, коли вони змінюються - ви повинні викликати це чітко - але це не повинно бути все так важко реалізувати, якщо вам це справді потрібно


5

Ті, хто використовує python 3 та перезавантажує з importlib.

Якщо у вас є такі проблеми, схоже, що модуль не перезавантажується ... Це тому, що йому потрібно певний час, щоб перекомпілювати pyc (до 60 сек). Я пишу цей підказку, просто щоб ви знали, чи відчували ви подібні проблеми.



3

Інший варіант. Подивіться, що параметр Python за замовчуванням importlib.reloadпросто повторно імпортує бібліотеку, передану як аргумент. Він не перезавантажить бібліотеки, які імпортує ваш lib. Якщо ви змінили багато файлів і маєте трохи складний пакет для імпорту, ви повинні зробити глибоке перезавантаження .

Якщо у вас встановлено IPython або Jupyter , ви можете використовувати функцію для глибокого перезавантаження всіх ліб:

from IPython.lib.deepreload import reload as dreload
dreload(foo)

Якщо у вас немає Юпітера, встановіть його за допомогою цієї команди у своїй оболонці:

pip3 install jupyter

І цей Ipython dreload і reload () від importlib все ж скаржаться reload() argument must be module. Я використовую імпорт власної функції і, здається, не працює. Використання вбудованих модулів спрацьовує. :-( марно витрачати час на перезавантаження iPython на кожну маленьку зміну, яку я внесла до свого коду ...
m3nda

2

Редагувати (відповідь V2)

Рішення від раніше добре для отримання інформації про скидання, але воно не змінить усіх посилань (більше, ніж reloadменше, ніж потрібно). Щоб насправді встановити всі посилання, мені довелося зайти в сміттєзбірник і переписати там посилання. Тепер це працює як шарм!

Зауважте, що це не спрацює, якщо GC вимкнено або перезавантажте дані, які не контролюються GC. Якщо ви не хочете возитися з GC, оригінальної відповіді вам може бути достатньо.

Новий код:

import importlib
import inspect
import gc
from weakref import ref


def reset_module(module, inner_modules_also=True):
    """
    This function is a stronger form of importlib's `reload` function. What it does, is that aside from reloading a
    module, it goes to the old instance of the module, and sets all the (not read-only) attributes, functions and classes
    to be the reloaded-module's
    :param module: The module to reload (module reference, not the name)
    :param inner_modules_also: Whether to treat ths module as a package as well, and reload all the modules within it.
    """

    # For the case when the module is actually a package
    if inner_modules_also:
        submods = {submod for _, submod in inspect.getmembers(module)
                   if (type(submod).__name__ == 'module') and (submod.__package__.startswith(module.__name__))}
        for submod in submods:
            reset_module(submod, True)

    # First, log all the references before reloading (because some references may be changed by the reload operation).
    module_tree = _get_tree_references_to_reset_recursively(module, module.__name__)

    new_module = importlib.reload(module)
    _reset_item_recursively(module, module_tree, new_module)


def _update_referrers(item, new_item):
    refs = gc.get_referrers(item)

    weak_ref_item = ref(item)
    for coll in refs:
        if type(coll) == dict:
            enumerator = coll.keys()
        elif type(coll) == list:
            enumerator = range(len(coll))
        else:
            continue

        for key in enumerator:

            if weak_ref_item() is None:
                # No refs are left in the GC
                return

            if coll[key] is weak_ref_item():
                coll[key] = new_item

def _get_tree_references_to_reset_recursively(item, module_name, grayed_out_item_ids = None):
    if grayed_out_item_ids is None:
        grayed_out_item_ids = set()

    item_tree = dict()
    attr_names = set(dir(item)) - _readonly_attrs
    for sub_item_name in attr_names:

        sub_item = getattr(item, sub_item_name)
        item_tree[sub_item_name] = [sub_item, None]

        try:
            # Will work for classes and functions defined in that module.
            mod_name = sub_item.__module__
        except AttributeError:
            mod_name = None

        # If this item was defined within this module, deep-reset
        if (mod_name is None) or (mod_name != module_name) or (id(sub_item) in grayed_out_item_ids) \
                or isinstance(sub_item, EnumMeta):
            continue

        grayed_out_item_ids.add(id(sub_item))
        item_tree[sub_item_name][1] = \
            _get_tree_references_to_reset_recursively(sub_item, module_name, grayed_out_item_ids)

    return item_tree


def _reset_item_recursively(item, item_subtree, new_item):

    # Set children first so we don't lose the current references.
    if item_subtree is not None:
        for sub_item_name, (sub_item, sub_item_tree) in item_subtree.items():

            try:
                new_sub_item = getattr(new_item, sub_item_name)
            except AttributeError:
                # The item doesn't exist in the reloaded module. Ignore.
                continue

            try:
                # Set the item
                _reset_item_recursively(sub_item, sub_item_tree, new_sub_item)
            except Exception as ex:
                pass

    _update_referrers(item, new_item)

Оригінальний відповідь

Як написано у відповіді @ bobince, якщо вже є посилання на цей модуль в іншому модулі (особливо якщо він був імпортований з asключовим словом типу import numpy as np), цей екземпляр не буде перезаписаний.

Це виявилося вельми проблематично для мене , коли застосування тестів , які вимагають «чистого аркуша» стан модулів конфігурації, тому я написав функцію з ім'ям , reset_moduleякий використовує importlib«и reloadфункції і рекурсивно перезаписує всі атрибути Заявлена модуля. Він був протестований з версією 3.6 Python.

import importlib
import inspect
from enum import EnumMeta

_readonly_attrs = {'__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
               '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__func__', '__ge__', '__get__',
               '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__',
               '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__',
               '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__',
               '__subclasshook__', '__weakref__', '__members__', '__mro__', '__itemsize__', '__isabstractmethod__',
               '__basicsize__', '__base__'}


def reset_module(module, inner_modules_also=True):
    """
    This function is a stronger form of importlib's `reload` function. What it does, is that aside from reloading a
    module, it goes to the old instance of the module, and sets all the (not read-only) attributes, functions and classes
    to be the reloaded-module's
    :param module: The module to reload (module reference, not the name)
    :param inner_modules_also: Whether to treat ths module as a package as well, and reload all the modules within it.
    """

    new_module = importlib.reload(module)

    reset_items = set()

    # For the case when the module is actually a package
    if inner_modules_also:
        submods = {submod for _, submod in inspect.getmembers(module)
                   if (type(submod).__name__ == 'module') and (submod.__package__.startswith(module.__name__))}
        for submod in submods:
            reset_module(submod, True)

    _reset_item_recursively(module, new_module, module.__name__, reset_items)


def _reset_item_recursively(item, new_item, module_name, reset_items=None):
    if reset_items is None:
        reset_items = set()

    attr_names = set(dir(item)) - _readonly_attrs

    for sitem_name in attr_names:

        sitem = getattr(item, sitem_name)
        new_sitem = getattr(new_item, sitem_name)

        try:
            # Set the item
            setattr(item, sitem_name, new_sitem)

            try:
                # Will work for classes and functions defined in that module.
                mod_name = sitem.__module__
            except AttributeError:
                mod_name = None

            # If this item was defined within this module, deep-reset
            if (mod_name is None) or (mod_name != module_name) or (id(sitem) in reset_items) \
                    or isinstance(sitem, EnumMeta):  # Deal with enums
                continue

            reset_items.add(id(sitem))
            _reset_item_recursively(sitem, new_sitem, module_name, reset_items)
        except Exception as ex:
            raise Exception(sitem_name) from ex

Примітка: Використовуйте обережно! Використання їх на не периферійних модулях (наприклад, модулі, що визначають класи, що використовуються зовні) може призвести до внутрішніх проблем у Python (таких як проблеми з підбиранням / відкочування).


1

для мене для випадку Абаку це так, як він працює. Уявіть, що ваш файл - Class_VerticesEdges.py

sys.path.append('D:\...\My Pythons')
if 'Class_VerticesEdges' in sys.modules:  
    del sys.modules['Class_VerticesEdges']
    print 'old module Class_VerticesEdges deleted'
from Class_VerticesEdges import *
reload(sys.modules['Class_VerticesEdges'])

Ця відповідь є прямою копією звідси: ebanshi.cc/questions/1942/…
SiHa

0

У мене виникло багато проблем, намагаючись перезавантажити щось всередині Sublime Text, але нарешті я міг написати цю утиліту для перезавантаження модулів на Sublime Text на основі коду, який sublime_plugin.pyвикористовується для перезавантаження модулів.

Нижче описано, що ви можете перезавантажувати модулі з контурів із пробілами в їх іменах, а пізніше після перезавантаження ви можете просто імпортувати, як зазвичай.

def reload_module(full_module_name):
    """
        Assuming the folder `full_module_name` is a folder inside some
        folder on the python sys.path, for example, sys.path as `C:/`, and
        you are inside the folder `C:/Path With Spaces` on the file 
        `C:/Path With Spaces/main.py` and want to re-import some files on
        the folder `C:/Path With Spaces/tests`

        @param full_module_name   the relative full path to the module file
                                  you want to reload from a folder on the
                                  python `sys.path`
    """
    import imp
    import sys
    import importlib

    if full_module_name in sys.modules:
        module_object = sys.modules[full_module_name]
        module_object = imp.reload( module_object )

    else:
        importlib.import_module( full_module_name )

def run_tests():
    print( "\n\n" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )

    from .tests import semantic_linefeed_unit_tests
    from .tests import semantic_linefeed_manual_tests

    semantic_linefeed_unit_tests.run_unit_tests()
    semantic_linefeed_manual_tests.run_manual_tests()

if __name__ == "__main__":
    run_tests()

Якщо ви запускаєтесь вперше, це має завантажити модуль, але якщо пізніше ви знову зможете використовувати метод / функцію, run_tests()він перезавантажить файли тестів. З Sublime Text ( Python 3.3.6) це трапляється багато, тому що його інтерпретатор ніколи не закривається (якщо ви не перезапустите Sublime Text, тобто Python3.3інтерпретатор).


-1

Іншим способом може бути імпорт модуля у функції. Таким чином, коли функція завершує модуль, збирається сміття.


4
Модуль ніколи не збирає сміття, оскільки глобальна довідка проводиться принаймні в sys.modules.
Усі працівники найважливіші
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.