모듈을 언로드 (다시로드)하려면 어떻게합니까?


797

오래 실행되는 Python 서버가 있으며 서버를 다시 시작하지 않고 서비스를 업그레이드하고 싶습니다. 가장 좋은 방법은 무엇입니까?

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

53
메모 팁 : "가져 오기"는 "로드"를 의미하지 않으며 "아직로드되지 않은 경우로드 한 다음 네임 스페이스로 가져 오기"를 의미합니다.
Kos

3
즉 아직 파이썬에서 수 없습니다로 질문은 '언로드'를 포함하지 않아야 - 재 장전 그러나 알려진 패러다임 아래의 대답으로
robertmoggach

py2exe 앱에서 동적 모듈을 사용할 때도 같은 문제가 발생했습니다. py2exe는 항상 zip 디렉토리에 바이트 코드를 유지하므로 다시로드가 작동하지 않았습니다. 그러나 import_file 모듈을 사용하여 작동하는 솔루션을 찾았습니다. 이제 내 응용 프로그램이 제대로 작동합니다.
Pritam Pan

2
코드에서 .pyc 파일을 삭제하려고하는데 "언로드"하려면 어떻게해야합니까?
darkgaze

답변:


789

reload내장 함수 를 사용하여 이미 가져온 모듈을 다시로드 할 수 있습니다 (Python 3.4+ 만 해당) .

from importlib import reload  
import foo

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

파이썬 3에서는 모듈 reload로 옮겨졌습니다 imp. 3.4에서는 imp찬성이 사용됩니다 importlib, 그리고 reload후자에 추가되었습니다. 3 이상을 대상으로하는 경우 호출 reload하거나 가져올 때 적절한 모듈을 참조하십시오 .

나는 이것이 당신이 원하는 것이라고 생각합니다. Django의 개발 서버와 같은 웹 서버는이를 사용하여 서버 프로세스 자체를 다시 시작하지 않고도 코드 변경의 영향을 볼 수 있습니다.

문서에서 인용하려면 :

파이썬 모듈의 코드가 다시 컴파일되고 모듈 수준 코드가 다시 실행되어 모듈 사전의 이름에 바인딩되는 새로운 객체 집합을 정의합니다. 확장 모듈의 초기화 기능은 두 번째로 호출되지 않습니다. 파이썬의 다른 모든 객체와 마찬가지로 이전 객체는 참조 횟수가 0으로 떨어진 후에 만 ​​재생됩니다. 모듈 네임 스페이스의 이름은 새로운 객체 또는 변경된 객체를 가리 키도록 업데이트됩니다. 이전 개체에 대한 다른 참조 (예 : 모듈 외부의 이름)는 새 개체를 참조하기 위해 리 바인드되지 않으며 원하는 경우 각 네임 스페이스에서 업데이트되어야합니다.

질문에서 언급했듯이 클래스가 모듈 에 Foo있으면 객체 를 재구성 Foo해야 foo합니다.


10
실제로, 장고 dev에 서버가 다시 시작 자체가 당신이 파일을 변경할 때 .. (이것은 서버를 다시 시작합니다,뿐만 아니라 모듈을 다시로드)
하센

25
이 "is_changed"함수는 어디에서 오는가? 나는 그것에 관한 문서를 보지 못했고 파이썬 3.1.3 환경에서 실행되지 않거나 2.6.4에서 실행되지도 않습니다.
jedmao

5
장고는 reload를 사용할 수 없습니다 : pyunit.sourceforge.net/notes/reloading.html
raylu

14
@BartoszKP X모듈이 아닌 경우 다음을 수행 할 수 있습니다.import sys; reload(sys.modules[X.__module__])
drevicko

5
@jedmao @JamesDraper이 is_changed함수는 여러분이 작성해야 할 임의의 함수일 것입니다. 내장되어 있지 않습니다. 예를 들어, 가져 오는 모듈에 해당하는 파일을 열고 캐시 된 버전으로 비교하여 변경되었는지 확인할 수 있습니다.
James Mchugh

252

Python 3.0–3.3에서는 다음을 사용합니다. imp.reload(module)

BDFL는대답 이 질문을.

그러나 @Stefan 덕분 imp에 3.4에서 더 이상 사용되지 않습니다 importlib. ).

나는 생각한다 그러므로 당신이 지금 사용하는 거라고, importlib.reload(module)잘 모르겠어요하지만,.


23
진지한 초보자는 Python 2와 3 사이의 중요한 뉘앙스에 대해 알게되어 기쁩니다.
Smandoli

24
reload (imp)가 유효합니까?
Loïc Faure-Lacroix

2
@ LoïcFaure - 라크 르와 같은 방식으로는 reload(__builtins__)2.X에서 유효
JBernardo

1
@Tarrasch : 질문의 예와 같이 다시로드하려는 Python 모듈입니다.
Paul D. Waite

3
@ LoïcFaure-Lacroix 예, imp가 다시로드 될 수 있습니다.
데빈 콜리어 존슨

92

순수한 파이썬이 아닌 경우 모듈을 삭제하는 것이 특히 어려울 수 있습니다.

가져온 정보는 어떻게 삭제합니까?

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에서 먼저 삭제하지 않으면 내부의 모든 항목이 다시로드되지 않습니다.
Cerin

73

reload(module)그러나 완전히 독립형 인 경우에만 가능합니다. 다른 것이 모듈 (또는 모듈에 속하는 객체)에 대한 참조가 있으면 이전 코드가 예상보다 오래 걸려서 미묘하고 호기심 많은 오류가 발생합니다.isinstance 합니다. 같은 코드.

단방향 종속성이있는 경우 이전 코드에 대한 모든 참조를 제거하려면 다시로드 된 모듈에 종속 된 모든 모듈을 다시로드해야합니다. 그런 다음 재로드 된 모듈에 의존하는 모듈을 재귀 적으로 다시로드하십시오.

예를 들어 패키지 재로드를 처리 할 때 매우 일반적인 순환 종속성이있는 경우 그룹의 모든 모듈을 한 번에 언로드해야합니다. 당신은 이것을 할 수 없습니다reload()종속성을 새로 고치기 전에 각 모듈을 다시 가져 와서 이전 참조가 새 모듈로 들어올 수 있기 때문에이 .

이 경우이를 수행하는 유일한 방법은 해킹 sys.modules하는 것입니다. sys.modules다음 가져올 때 다시로드 할 각 항목을 살펴보고 삭제 None해야하며 실패한 상대 가져 오기 캐싱과 관련된 구현 문제를 처리 해야하는 값을 가진 항목도 삭제해야합니다 . 별로 좋지는 않지만 코드베이스 외부에 참조를 남기지 않는 완전히 독립적 인 종속성 세트가있는 한 실행 가능합니다.

서버를 다시 시작하는 것이 가장 좋습니다. :-)


1
해당 시나리오를 위해 특별히 드레로드하지 않습니까?
Josh

@ 조쉬 : 아니, 패키지 트리를 다시로드하기위한 것이며 심지어 패키지에 외부 / 원형 종속성이없는 한 작동합니다.
bobince

1
None이 문제가 정확히 발생하기 때문에 값으로 부품을 정교하게 할 수 있습니까? sys.modules다시 가져 오기 한 후 항목을 삭제 하고 있습니다 None. 가져온 일부 종속성은 입니다.
schlamar

@shclamar : 배경에 대해서는 stackoverflow.com/questions/1958417/… (및 해당 링크)를 참조하십시오 . None'실제'항목이 삭제되었을 때 항목이 가져 오기 메커니즘을 통해 어떻게 되돌아 오는지 잘 알지 못합니다 (import.c 코드를 보더라도) . 내재적 상대적 수입이 사라지면서 미래에는 더 이상 문제가되지 않습니다. 그 동안 None가치가있는 모든 항목을 삭제 하면 문제가 해결되는 것으로 보입니다.
bobince

1
@Eliethesaiyan : reload기능 을 의미 합니까? 내장되어 있으므로 라이브러리를 가져올 필요가 없습니다.
bobince

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

3
+1. 내 목표는 파이썬 내에서 코 테스트를 실행하는 것이 었습니다. 내가 모듈을로드하고 일부 기능의 이름을 변경 한 후 호출 할 때, 이전 이름은 남아 nose.run()후에도reload(my_module) %run my_module
피터 D

5
모듈이 자체 하위 모듈을 가져 오는 경우 해당 하위 모듈도 삭제해야 할 수 있습니다. 같은 것 [del(sys.modules[mod] for mod in sys.modules.keys() if mod.startswith('myModule.')].
drevicko 2016 년

나는 그것이 모듈을 언로드한다고 생각하지 않습니다. Python 3.8 : import sys; import json; del sys.modules['json']; print(json.dumps([1]))json 모듈이 더 이상 sys.modules에 없어도 여전히 작동합니다.
Seperman

60

Python 2의 경우 내장 함수 reload ()를 사용하십시오 .

reload(module)

Python 2 및 3.2–3.3의 경우 모듈 imp에서 다시로드를 사용하십시오 .

import imp
imp.reload(module)

그러나 importlib에 찬성하여 버전 3.4부터 imp 더 이상 사용되지 않으므로 다음을 사용하십시오.

import importlib
importlib.reload(module)

또는

from importlib import reload
reload(module)

2
이러한 경우를 처리하기 위해 : from six import reload_module( pip install six물론 첫 번째 필요 )
Anentropic

@Anentropic : 6 개의 패키지를 사용하는 것이 좋지만 구문은 from six.moves import reload_module( doc )
x0s

23

다음 코드는 Python 2/3 호환성을 허용합니다.

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

reload()두 버전 모두 에서처럼 사용할 수 있으므로 작업이 더 간단 해집니다.


18

허용 된 답변은 from from X import 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 ()는이 함수를 정의한 모듈을 참조하므로 문제가있는 모듈과 다른 모듈에서 정의하면 작동하지 않습니다.
Joseph Garvin

대화 형, >>> from X import Y>>> __import__('X', fromlist='Y')
Bob Stein

@ BobStein-VisiBone, 언제 그 일을 할 수있는 방법이 fromlist='*'있습니까?
Mike C

좋은 질문입니다, @MikeC를 모릅니다. 그건 그렇고 나는 from수입 명세서에서 거의 모든 사용을 중단하는 경향이 있습니다. 그냥 스탁 import <package>및 코드에서 명시 적 package.symbol. 이것이 항상 가능하거나 바람직하지는 않다는 것을 인식하십시오. (한가지 예외가 있습니다 : 향후 import print_function에서)
Bob Stein

Mike C : 저에게 foo = reload(foo); from foo import *
효과적인

16

이것은 모듈을 다시로드하는 현대적인 방법입니다.

from importlib import reload

3.5 이전의 Python 버전을 지원하려면 다음을 시도하십시오.

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). 이 기능이 필요하지 않습니다.
pault

나는 modulereload(MODULE_NAME)단순한 것보다 더 설명이 필요 reload(MODULE_NAME)하고 다른 기능과 충돌 할 가능성이 낮다고 생각합니다.
Richie Bendall

@RichieBendall 죄송하지만이 답변은 완전히 틀 렸습니다. reload () 함수는 모듈 이름이 아닌 모듈 객체를 사용합니다 ... 문서를 읽으십시오 : docs.python.org/3/library/importlib.html#importlib.reload 그리고 @ pault에 동의합니다. .
mbdevpl

귀하의 의견을 반영하여 답변을 변경했습니다.
Richie Bendall

13

당신이 경우에 없는 서버에 있지만 개발 과 자주 모듈을 다시로드해야, 여기에 좋은 팁입니다.

먼저 Jupyter Notebook 프로젝트에서 우수한 IPython 셸을 사용하고 있는지 확인하십시오 . Jupyter를 설치 한 후에는 ipython, 또는 jupyter console, 또는 더 나은으로 시작할 수 있으며 jupyter qtconsole, 이는 모든 OS에서 코드 완성이 가능한 멋진 색상의 콘솔을 제공합니다.

이제 쉘에 다음을 입력하십시오.

%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

나와 같은 사람들은 모든 모듈을 언로드하고 싶어합니다 ( Emacs 의 Python 인터프리터에서 실행할 때 ).

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

자세한 정보는 Python 모듈 다시로드에 있습니다.


실제로 모든 것이 sys.modules.values()모듈이 아니기 때문에 (2.6에서) 안정적으로 작동하지 않는 것 같습니다 . 예를 들면 다음과 같습니다. >>> type (sys.modules.values ​​() [1]) <class 'email.LazyImporter'> 따라서 해당 코드를 실행하려고하면 코드가 넘어갑니다 (실제 해결책이 아니라는 것을 알고 있습니다. 지적).
Francis Davey

이전의 파이썬에서는 작동하지 않습니다. 일부 이름을 제외해야했습니다. 해당 코드를 새 컴퓨터로 옮길 때 게시물을 업데이트하겠습니다.

2
일부 수정 후 파이썬 2.7에서 잘 작동 :if mod and mod.__name__ != "__main__": imp.reload(mod)
Czarek Tomczak

2
이것은 잘 작동합니다 : import imp [ m .__ name에서 m이 아닌 " "가 아닌 경우 sys.modules.values ​​()에서 m에 대한 reload (m) is_builtin (m .__ name__)]
Patrick Wolf

5

Enthought Traits에는이를 위해 상당히 잘 작동하는 모듈이 있습니다. https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

변경된 모듈을 다시로드하고이를 사용하는 다른 모듈 및 인스턴스화 된 객체를 업데이트합니다. 대부분의 경우 __very_private__메서드 와 함께 작동하지 않으며 클래스 상속을 막을 수는 있지만 PyQt GUI를 작성할 때 호스트 응용 프로그램을 다시 시작하거나 Maya 또는 Nuke와 같은 프로그램 내에서 실행되는 항목을 다시 시작 해야하는 시간을 크게 절약합니다. 아마도 20-30 %의 시간 동안 작동하지는 않지만 여전히 굉장히 도움이됩니다.

Enthought의 패키지는 파일이 변경되는 순간에 파일을 다시로드하지 않습니다. 명시 적으로 호출해야하지만 실제로 필요한 경우 구현하기가 쉽지는 않습니다.


5

파이썬 3을 사용하고 importlib에서 다시로드하는 사람들.

모듈이 다시로드되지 않는 것 같은 문제가있는 경우 ... pyc를 다시 컴파일하는 데 시간이 필요하기 때문에 (최대 60 초).이 종류의 문제가 발생했는지 알고있는 힌트를 작성합니다.



3

다른 옵션. 파이썬 기본값 importlib.reload은 인수로 전달 된 라이브러리를 다시 가져옵니다. 그것은 하지 않습니다 당신의 lib 디렉토리 가져 오기 그 라이브러리를 다시로드합니다. 많은 파일을 변경하고 가져 오기 위해 다소 복잡한 패키지가있는 경우에는 다시로드 해야합니다. .

당신이있는 경우 IPython 또는 Jupyter가 설치되어, 당신은 깊은 재 장전 모든 libs와에 대한 기능을 사용할 수 있습니다 :

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

Jupyter가없는 경우 쉘에 다음 명령으로 설치하십시오.

pip3 install jupyter

importlib의이 Ipython dreload와 reload ()는 모두 불평합니다 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를 사용 하고 선언 된 모든 모듈 속성을 재귀 적으로 덮어 쓰는 함수 를 작성했습니다 . Python 버전 3.6으로 테스트되었습니다.importlibreload

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

Abaqus의 경우 나를 위해 그것이 작동하는 방식입니다. 파일이 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_plugin.py데 사용 하는 코드를 기반으로 Sublime Text에서 모듈을 다시로드하기 위해이 유틸리티를 작성할 수있었습니다 .

아래는 이름에 공백이있는 경로에서 모듈을 다시로드 할 수있게 한 다음 나중에 다시로드 한 후에 평소와 같이 가져올 수 있습니다.

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.
모든 근로자가 필수적
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.