Использование Configparser для создания объектов класса?

#python #oop #configparser

#python #ооп #configparser

Вопрос:

Я немного озадачен тем, как это сделать.

Допустим, у меня есть файл employees.ini, который выглядит следующим образом:

 [amber]
sex=female
age=29
location=usa
income=60000
debt=300

[john]
sex=male
age=19
location=usa
income=19000
debt=nan
  

У меня есть цикл for для доступа к каждой части информации и присвоения переменной.

 from configparser import ConfigParser
config=ConfigParser()
config.read('employees.ini')
for section in config.sections():
    name=section
    sex=config[section]['sex']
    age=config[section]['age']
    location=config[section]['location']
    income=config[section]['income']
    debt=config[section]['debt']
  

У меня также есть класс, в котором каждый раздел может быть принят как объект:

 class Users:
    def __init__(self, name, sex, age, location, debt):
        self.__name=name
        self.__sex=sex
        self.__age=age
        self.__location=location
        self.__income=income
        self.__debt=debt

    def foo(self):
        do a thing

    def bar(self):
        do a different thing ...
  

Я надеялся, что теперь смогу получить доступ к amber.foo и john.bar. Однако я затрудняюсь с тем, как передать переменные из цикла for в класс, прежде чем они будут перезаписаны на следующей итерации цикла. Я чувствую, что, возможно, я слишком много думаю об этом.

Я думал, что это сделало бы код намного более удобным для пользователя, поскольку большую часть кода можно было бы оставить нетронутой, и только .ini нужно было бы обновлять, когда нужен новый пользователь.

Спасибо за любую помощь, которую вы могли бы оказать.

Ответ №1:

Я бы добавил метод класса для преобразования данных файла конфигурации в новый объект.

 class User:
    def __init__(self, name, sex, age, location, debt):
        self.__name=name
        self.__sex=sex
        self.__age=age
        self.__location=location
        self.__income=income
        self.__debt=debt

    @classmethod
    def from_config(cls, name, config):
        return cls(name, config['sex'], config['age'], config['location'], config['debt']

    def foo(self):
        do a thing

    def bar(self):
        do a different thing ...
  

Теперь подробности о том, как на самом деле создать экземпляр User , абстрагированы в самом классе; коду, который выполняет итерацию по конфигурации, нужно только передать соответствующие данные методу класса.

 from configparser import ConfigParser
config=ConfigParser()

config.read('employees.ini')
users = [User.from_config(section, config[section]) for section in config.sections()]
  

Поскольку ваш класс использует имена ключей файла конфигурации в качестве имен параметров, вы могли бы просто распаковать dict и использовать __init__ напрямую вместо определения метода класса.

 from configparser import ConfigParser
config=ConfigParser()

config.read('employees.ini')
users = [User(section, **config[section]) for section in config.sections()]
  

Комментарии:

1. Спасибо за вашу помощь. Мне нужно больше изучить абстракцию, концепция для меня новая. Потребует ли лучшее решение импорта ABC? Распаковка dict в класс была очень элегантным решением. Я начал внедрять это в код. Большое спасибо