Трудно сказать, является ли поведение желательным (для кого), но оно ожидается.
Нет большой разницы между вашим образцом кода и следующим:
In [3]: class Foo:
...: def qwe(self, once_again=True):
...: print('original qwe')
...: if once_again:
...: self.qwe(once_again=False)
...: qwe1 = qwe
...:
...: def qwe(self, once_again=True):
...: print('new qwe')
...: if once_again:
...: self.qwe(once_again=False)
...: a = Foo()
...: a.qwe1()
...:
...:
original qwe
new qwe
После выполнения оператора import mod1
и func1
являются просто переменными, которые хранят ссылки на соответствующие объекты.Когда вы перезагружаете модуль, вы просто назначаете другое значение переменной с именем mod1
.
Кстати, вы можете наблюдать аналогичный эффект, когда сохраняете ссылку на регистратор уровня модуля или уровня впеременная: LOG = logging.getLogger(__name__)
, так как ничто не мешает пользователю вашего кода вызывать logging.config.dictConfig
где-то в середине срока службы приложения.Если новая конфигурация предназначена для подавления вывода из вашего модуля, ваш код не будет ничего знать о новом логгере для вашего модуля, и вы продолжите запись в журнал.
Я бы сказал, что поведениепо крайней мере предназначен.
UPD: вопрос оказался немного сложнее.
Если переменная отсутствует в текущей лексической области действия функции, она берется из области действия модуля.(если это не замыкание, в этом случае используется поле __closure__
).Чтобы получить область действия модуля, функция обращается к переменным уровня модуля через sys.modules[func1.__module__]
, который был обновлен с помощью reload
.