Як отримати посилання на модуль всередині самого модуля?


158

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


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

2
@ KevinJ.Rice "ідіот", який забирає ваш код за вами (тобто ви, через 6 місяців) ", зробив мій день!
arctelix

8
Кого хвилює, чому він задає питання? Для цього потрібно багато вагомих причин.
Крістофер Барбер

Потрібно закрити. Занадто корисно.
mlvljr

Відповіді:


211
import sys
current_module = sys.modules[__name__]

3
крім цього це буде не зовсім коректно, якщо модуль буде перезавантажений; Я не думаю, що немає місця, де гарантовано зберігатимуться посилання, якби вони були, перезавантаження насправді не спрацювало б, правда?
Діма Тиснек

14
Перезавантаження повторно використовує той самий об'єкт модуля; не створюється новий об'єкт модуля, тому він все ще є правильним перед повторним завантаженням.
bukzor

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" не є модулем, класом, методом, функцією, прослідковуванням, фреймом або об'єктом коду "; поки 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.