Как получить ссылку на модуль внутри самого модуля?


159

Как я могу получить ссылку на модуль из этого модуля? Кроме того, как я могу получить ссылку на пакет, содержащий этот модуль?


7
Я подозреваю, что вы, возможно, задаете этот вопрос, потому что у вас есть переменная в области видимости модуля (например, BLAH = 10 вне функции или класса), затем переменная класса / функции с именем BLAH, и вы хотите провести различие. Правильный вопрос здесь: это необходимо? Общеизвестно, что правила Scope подвержены ошибкам, особенно со стороны «идиота», который забирает ваш код после вас (т. Е. Вас, 6 месяцев спустя). Такие хитрости редко нужны; Я стараюсь их полностью избегать, потому что они часто путают и неправильно изменяют позже.
Кевин Дж. Райс

2
@ KevinJ.Rice "идиот", который забирает твой код после того, как ты (то есть ты, 6 месяцев спустя) "сделал мой день!
arctelix

8
Кого волнует, почему он задает вопрос? Есть много веских причин для этого.
Кристофер Барбер

Должен быть закрыт. Слишком полезно
mlvljr

Ответы:


212
import sys
current_module = sys.modules[__name__]

3
за исключением того, что это будет не совсем правильно, если модуль перезагружается; Я не думаю, что есть место, где гарантированно сохраняется ссылка, если бы она была, перезагрузка не сработала бы, верно?
Дима Тиснек

14
Перезагрузка повторно использует тот же объект модуля; новый объект модуля не создается, поэтому он все еще корректен перед лицом повторной загрузки.
Букзор

18

Еще один метод, который не импортирует модуль sys и, возможно, зависит от вашего вкуса - проще:

current_module = __import__(__name__)

Имейте в виду, что нет импорта. Python импортирует каждый модуль только один раз.


Это похоже на действительно хороший способ избежать импорта sys. Кроме того, что он немного нелогичен для чтения, есть ли потенциальные недостатки этого подхода?
JeremyDouglass

@JeremyDouglass. Не то, чтобы я знал. import - это легальная, документированная, встроенная функция (единственная функция xx ). Вы можете заменить его пакетом importlib (вам придется импортировать его). Возможно - никогда не случалось со мной - у вас может возникнуть проблема с относительным / абсолютным импортом, если в sys.path имеется модуль с тем же именем, и в этом случае вы можете решить это с помощью аргумента 'level' функции.
Ури

16

Если у вас есть класс в этом модуле, то __module__свойство класса - это имя модуля класса. Таким образом, вы можете получить доступ к модулю через sys.modules[klass.__module__]. Это также работает для функций.


4
На самом деле, кажется, что (по крайней мере) для функции __module__свойство является не модулем, а строкой; таким образом, происходит inspect.getabsfile(func.__module__)сбой с " TypeError: 'os' не является объектом модуля, класса, метода, функции, traceback, frame или code "; пока inspect.getabsfile(sys.modules[o.__module__])что проходит.
sdaau

12

Вы можете получить название текущего модуля, используя __name__

Ссылка на модуль находится в sys.modulesсловаре.

Смотрите документацию по Python


1

Вы можете передать его снаружи:

mymod.init(mymod)

Не идеально, но это работает для моего текущего варианта использования.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.