Есть один python-проект для общения с сервисом в сети. Интерфейс выполнен в виде набора скриптов, причём одни скрипты используют разный набор модулей в проекте, т.е. одному скрипту нужен модуль для работы с БД и с сетью, другому просто покопаться в БД. Для настройки всего этого использую один файл настроек. При этом пытаюсь сделать чтобы все эти модули настраивались одной и той же процедурой:
.
├── config.py
├── config.ini
├── script.py
├── db_module
│ ├── __init__.py
│ ├── config.py
│ └── db_api.py
└── rpc_module
├── __init__.py
├── config.py
└── fetch.py
#!/usr/bin/env python3
from pprint import pprint
from rpc_module.fetch import fetch_some
import config
config.configure(config_file = "init.ini")
pprint(fetch_some())
Может конечно config в корне загрузить config каждого модуля, каждый из которых настроит переменные в коде каждого модуля, но таким образом загрузится почти весь код всех модулей, что далеко не каждому скрипту нужно. Пока решил, что init.py каждого модуля добавляет процедуру настройки в список из корневого config.py, а единая процедура просто запускает все процедуры в этом списке:
## __init__.py
from ..config import __configurators
from .config import configure
__configurators.append(configure)
## config.py
from collections import deque
from configparser import ConfigParser
__configurators = deque()
def read (f = "config.ini"):
c = ConfigParser()
c.read(f)
return c
def configure (config_file = None):
if config_file is None:
config = read()
else:
config = read(config_file)
for configurator in __configurators:
configurator(config)
Получаю:
ImportError: attempted relative import beyond top-level package
Гугл подсказывает как обойти это хаком с sys.path, но может есть другие решения?