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

159

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

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

Ответы:

212
import sys
current_module = sys.modules[__name__]
truppo
источник
3
за исключением того, что это будет не совсем правильно, если модуль перезагружается; Я не думаю, что есть место, где гарантированно сохраняется ссылка, если бы она была, перезагрузка не сработала бы, верно?
Дима Тиснек
14
Перезагрузка повторно использует тот же объект модуля; новый объект модуля не создается, поэтому он все еще корректен перед лицом повторной загрузки.
Букзор
18

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

current_module = __import__(__name__)

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

Uri
источник
Это похоже на действительно хороший способ избежать импорта 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

PKIT
источник
1

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

mymod.init(mymod)

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

Сэм Уоткинс
источник