#python #module #import
#python #модуль #импорт
Вопрос:
У меня большой код на python со множеством модулей и классов. У меня есть специальный класс, единственный экземпляр которого необходим повсюду в коде (это многопоточное приложение, и этот экземпляр класса также содержит локальное хранилище потоков, блокировки и т. Д.). Немного неудобно всегда «заполнять» этот экземпляр в каждом импортированном модуле. Я знаю, что использование глобальных файлов — не лучшая практика, но в любом случае: есть ли в python какой-либо «импортный хук», чтобы я мог подключиться к нему, чтобы мой экземпляр был доступен во всех модулях без дополнительной работы? Он должен работать для обычного импорта, «из mod import …» тоже, и для конструкций импорта тоже. Если это невозможно, можете ли вы предложить лучшее решение? Конечно, неинтересно передавать этот экземпляр конструкторам всех классов и т. Д… Наследование также не помогает, поскольку у меня есть модули без классов, а также мне нужен один экземпляр, а не сам класс…
class master():
def import_module(self, name):
mod = __import__(name)
mod.m = self
return mod
[...]
m = master()
В настоящее время я думаю примерно так: но тогда я должен использовать m.import_module() для импорта модулей, тогда у других модулей будет экземпляр мастер-класса с именем «m», поэтому я тоже могу использовать m.import_module() и т.д. Но тогда я должен отказаться от использования «обычных» операторов импорта, и я должен написать это:
example_mod = m.module_import("example_mod")
вместо этого:
import example_mod
(но наверняка я тоже могу это сделать, чтобы присвоить «m» example_mod.m тогда)
Ответ №1:
Конечно, неинтересно передавать этот экземпляр конструкторам всех классов
Вам не обязательно это делать. Настройте свой глобальный класс в подобном модуле config
и импортируйте его
# /myapp/enviroment/__init__.py
class ThatSingleInstanceClass: pass
# create the singleton object directly or have a function init the module
singleton = ThatSingleInstanceClass()
# /myapp/somewhere.py
# all you need to use the object is importing it
from myapp.enviroment import singleton
class SomeClass:
def __init__(self): # no need to pass that object
print "Always the same object:", singleton
Комментарии:
1. Большое спасибо! Кажется, мне еще многому нужно научиться, до этого я бы предположил, что импорт instace приводит к разным экземплярам, но теперь я хорошо понимаю, что если модуль импортирован, это пространство имен используется, даже если оно импортировано из другого модуля, поэтому оно не будет новым. Просто мне любопытно, достаточно ли это грязно, если у меня есть имя класса master, тогда я создаю экземпляр с именем master [итак, то же имя] 🙂 Итак, после этого никакие другие модули не могут импортировать сам класс по ошибке, только экземпляр 🙂 Это работает для меня в любом случае.
2. @LGB: если вы следуете pep8 (вы должны), вы бы назвали свой класс
Master
(классы используют PascalCase в python), и тогда не возникнет конфликта сmaster
экземпляром — за исключением того, что вы должны выбрать более значимое имя переменной? Как люди используют переменную? Назовите это так.
Ответ №2:
Что плохого в том, что каждый модуль импортирует необходимый объект? Явное лучше, чем неявное.
Комментарии:
1. Ну, это тоже некрасиво, поскольку этот экземпляр часто используется, поэтому я хочу поместить его в глобальное пространство имен импортируемого мода, поэтому мне не нужно каждый раз писать «self»: если я передам экземпляр моего «master» класса конструкторукласс в импортированном модуле, для этого нужен уродливый хак, чтобы сказать «global m», а затем «m = m_in», где m_in — параметр для конструктора. Другое решение — поместить в пространство имен класса, но тогда я должен использовать его в других методах как «self.something». Поскольку в python есть некоторые глобальные переменные, такие как sorted() , я бы хотел, чтобы мой «m» везде был глобальным.
2. Смотрите ответ @Йохена Ритцеля. Это то, что я имел в виду.
3. Хорошо, извините, я совершенно неправильно понял. Я согласен, просто — кажется — у меня были проблемы с пониманием деталей импорта python 🙂