1. Определяешь формат файла конфигурации. Вариантов много:
- простой ini-файл (модуль configparser) - удобен, если нужны мало-объемные данные, и не более двух уровней иерархии (т.е. группа-ключ со значением).
- xml-файл (модуль xml) - громоздкий, но зато поддерживает много уровней вложенности и есть средства проверки корректности
- json-файл (модуль json) - куда проще в плане синтаксиса, на выходе получаешь комбинацию из словарей и списков питона. Я бы посоветовал его.
- Можно даже СУБД (типа sqlite3) прикрутить, при желании. Но это оправдано очень не всегда.
2. Выбираешь место хранения конфига.
- В папке программы? Будет одна конфигурация для всех пользователей на ПК. Не факт, что у тебя будут права на запись в эту папку. Зато легко копировать программу на другой комп.
- В папке APPDATA пользователя? Далеко, пользователь вряд ли залезет, зато у разных пользователей на одном компе будут свои настройки. Сложнее перенести программу на другой комп - нужно будет еще найти и скопировать папку настроек. (Сложнее не в плане защиты от копирования, а в плане удобства распространения.)
- В папке Мои документы пользователя? Не факт что это хорошая идея, но плюсы примерно те же что и выше.
- Возможна комбинация предыдущих. Например, я делаю так: если в папке с исполняемым скриптом лежит файл с именем "portable", ищу конфиг тут же. Иначе ищу его в APPDATA.
3. Определяешь, как будешь получать доступ к конфигу внутри программы. Например, отдельный модуль, который будут импортировать все части программы. Модуль содержит класс-синглтон, который содержит значения конфига в форме, удобной для остальной программы. Также этот класс может содержать значения конфигурации по умолчанию. Программа при старте ищет и загружает конфиг в экземпляр этого класса, при работе обращается к этому классу, чтобы получить или задать параметры, а при завершении - сохраняет класс обратно в конфиг.