Я пытаюсь перезагрузить из скрипта Python пользовательскую функцию, потому что я постоянно редактирую функцию и не хочу перезагружать ядро каждый раз, когда вношу изменения в файл. Я прочитал, что могу использовать importlib
.
Однако, когда я пытаюсь использовать перезагрузку, я получаю ImportError: module Classifier not in sys.modules
Мой код:
from importlib import reload
from FilterFile import Classifier as foo
reload(foo)
Я пробовал просто использовать reload(Classifier)
и reload(FilterFile import Classifier)
, но получаю ту же ошибку.
В этом случае Classifier
не является модулем или подмодулем, это то, что вы импортировали из модуля FilterFile
(from-imports фактически по-прежнему импортирует все из модуля, но позволяет вам получить доступ только к тому, что вы запросили) .
Вместо этого вам нужно сделать import FilterFile
(вы все равно можете сделать что-то вроде import FilterFile as foo
, если то, что вы перезагружаете, является ссылкой на реальный модуль).
В качестве функции Classifier
я протестировал следующую функцию (та же логика применима к классам и тому подобному):
def Classifier():
print('before')
Во время тестирования я менял 'before'
на 'after'
во время задержки. Когда я попробовал следующее, ошибок не возникло, но Classifier
фактически не обновлялся, если не вызывался через модуль:
import time
import FilterFile as bar
from importlib import reload
from FilterFile import Classifier as foo
foo() # "before"
time.sleep(3.5) # (a delay so I could change `Classifier`)
reload(bar)
foo() # "before" <- wrong!!!
bar.Classifier() # "after"
Однако вы можете повторить импорт из импорта, чтобы обновить его:
import time
import FilterFile as bar
from importlib import reload
from FilterFile import Classifier as foo
foo() # "before"
time.sleep(3.5) # (a delay so I could change `Classifier`)
reload(bar)
from FilterFile import Classifier as foo
foo() # "after" <- hooray!!!
Я рекомендую обернуть importlib.reload()
в вашу собственную функцию, которая также переделывает импорт из. Возможно, существует хитрый способ сделать это, не требуя настоящего оператора импорта и не переделывая импорт из импорта, но я надеюсь, что это приемлемо для ваших целей.
Я предполагаю, что
Classifier
— это настоящая функция, а не подмодуль, содержащий эту функцию (не могу сказать этого из опубликованных вами подробностей).importlib.reload()
имеет дело только с целыми модулями, а не с объектами, содержащимися в них, но вы не импортировали сам модуль, поэтому нет ничего, к чему вы могли бы правильно передатьreload()
. Вам нужно написать это какimport FilterFile
иreload(FilterFile)
— функция будет называтьсяFilterFile.Classifier
. Если вы все еще хотите использоватьfrom FilterFile import Classifier as foo
, вам придется повторять эту строку после КАЖДОЙ перезагрузки.