Перезагрузка локального модуля не работает - PullRequest
0 голосов
/ 25 июня 2018

Во-первых, я знаю, что это было опубликовано ранее, но либо A) рекомендации не работают, либо B) рекомендуется вручную удалить модуль из пространства имен и повторно импортировать его, как обычно.

У меня есть следующая структура модуля

basedir/
    pytools/
        __init__.py
        tools.py
    setup.py
    test.py

Если я нахожусь в basedir, и импортирую pytools и создаю объект класса testcls. Фактические свойства класса находятся в tools.py. testcls имеет метод с именем testfunc, который просто печатает AAA прямо сейчас:

>>> import pytools
>>> test = pytools.testcls()
>>> test.testfunc()
AAA

Допустим, я изменил testfunc(), чтобы теперь распечатать BBB. Я делаю это и сохраняю файл. Затем я перезагружаю модуль и пытаюсь снова, он не печатает BBB:

>>> from importlib import reload
>>> reload(pytools)
>>> test = pytools.testcls()
>>> test.testfunc()
AAA

Однако Если я выполняю точно такой же процесс, но вместо этого изменяю test.py, импортирую этот файл как модуль, редактирую функцию внутри него и перезагружаю его, он ведет себя как ожидалось:

>>> import test
>>> testvariable = test.testcls()
>>> testvariable.testfunc2()
AAA
# Change the function here
>>> from importlib import reload
>>> reload(test)
>>> testvariable = test.testcls()
>>> testvariable.testfunc2()
BBB

Я действительно не понимаю, что происходит, и это просто очень раздражает меня в этот момент. Это также стоит мне немало времени, но сейчас я более раздражен.

Есть идеи, что происходит ??

Версия:

Python: 3.6.5

Переводчик: IPython, 6.2.1

1 Ответ

0 голосов
/ 25 июня 2018

Давайте назовем вещи более широко:

basedir/
    testpackage/
        __init__.py
        testmodule.py
    test.py

Если testmodule.py содержит:

class TestClass:
    def test_method(self):
        print("AAA")

Тогда следующее работает так, как вы ожидаете:

>>> from testpackage import testmodule
>>> obj = testmodule.TestClass()
>>> obj.test_method()
DDD
>>> # === Edit ===
>>> from importlib import reload
>>> reload(testmodule)
>>> obj = testmodule.TestClass()
>>> obj.test_method()
EEE

Но если __init__.py имеет что-то вроде:

from .testmodule import TestClass

И вы пытаетесь импортировать (и перезагрузить) пакет , а не модуль, происходит следующее:

>>> import testpackage
>>> obj = testpackage.TestClass()
>>> obj.test_method()
EEE
>>> # === Edit ===
>>> from importlib import reload
>>> reload(testpackage)
>>> obj = testpackage.TestClass()
>>> obj.test_method()
EEE

(без изменений)

Обратите внимание на следующий раздел документов :

Если модуль импортирует объекты из другогомодуль, использующий из… import…, вызов reload () для другого модуля не переопределяет импортированные из него объекты - одним из способов является повторное выполнение оператора from, другим - использование импорта и квалифицированных имен (module.name)вместо этого.

Если бы вы перезагрузили и модуль и пакет, в таком порядке, он снова работал бы, как вы ожидаете:

>>> import testpackage
>>> obj = testpackage.TestClass()
>>> obj.test_method()
HHH
>>> # === Edit ===
>>> from importlib import reload
>>> reload(testpackage.testmodule)
>>> reload(testpackage)
>>> obj = testpackage.TestClass()
>>> obj.test_method()
III

Но это кажется глупым и подверженным ошибкам, просто используйте подход в первом примере:

from testpackage import testmodule
...
reload(testmodule)
... 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...