Питон подклассы ConfigParser


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

Я делаю это более сложным, чем он должен быть? Я пытаюсь сделать его легким для других модулей/скриптов на этом системы для хранения и извлечения их параметры. Следовательно, почему я ловушку ConfigParser.NoOptionError ошибку и вернуть ничего и создать раздел, если его не существует в набор() метод.

Предложения?

import ConfigParser
import os

from ast import literal_eval as Eval

class _ConfParse(ConfigParser.ConfigParser):
    def __init__(self, confpath, conffile):
        ConfigParser.ConfigParser.__init__(self)
        self.conf_file = os.path.join(confpath, conffile)
        try: self.readfp(open(self.conf_file), 'r')
        except IOError as Err:
            if Err.errno == 2: pass
            else: raise Err

    def set(self, section, option, value):
        if self.has_section(section):
            ConfigParser.ConfigParser.set(self, section, option, str(value))
        else:
            self.add_section(section)
            ConfigParser.ConfigParser.set(self, section, option, str(value))

    def get(self, section, option):
        try: return Eval(ConfigParser.ConfigParser.get(self, section, option))
        except ConfigParser.NoOptionError: return None

    def save(self):
        self.write(open(self.conf_file, 'w'))

    def __del__(self):
        self.save()

class LocalConfig(_ConfParse):
    def __init__(self, conffile, confpath = '/etc/local/cnf'):
        _ConfParse.__init__(self, confpath, conffile)

class SysConfig(_ConfParse):
    def __init__(self, conffile, confpath = '/etc/sys/cnf'):
        _ConfParse.__init__(self, confpath, conffile)


3199
2
задан 2 июня 2011 в 02:06 Источник Поделиться
Комментарии
1 ответ

Одна проблема, которую я вижу заключается в том, что вернувшись ни один из измененного метода GET() конфликты с нормальными случае бесполезны вариант (снизу модуля документы для ConfigParser):

>>> import ConfigParser
>>> import io

>>> sample_config = """
... [mysqld]
... user = mysql
... pid-file = /var/run/mysqld/mysqld.pid
... skip-external-locking
... old_passwords = 1
... skip-bdb
... skip-innodb
... """
>>> config = ConfigParser.RawConfigParser(allow_no_value=True)
>>> config.readfp(io.BytesIO(sample_config))

>>> # Settings with values are treated as before:
>>> config.get("mysqld", "user")
'mysql'

>>> # Settings without values provide None:
>>> config.get("mysqld", "skip-bdb")

>>> # Settings which aren't specified still raise an error:
>>> config.get("mysqld", "does-not-exist")
Traceback (most recent call last):
...
ConfigParser.NoOptionError: No option 'does-not-exist' in section: 'mysqld'

Обратите внимание на предпоследний пример в комментарии "параметры без значений предоставить никто:" конечно, это не проблема, если вы намереваетесь исключить такой вариант. Кроме этого, мне нравится авто-раздел.

Хотя, я бы склонялся к добавление к интерфейсу, а не маскировать и изменять поведение, поэтому вместо того, чтобы заменять вам/набор, добавить версиях safe_:

def safe_set(self, section, option, value):
if self.has_section(section):
self.set(section, option, str(value))
else:
self.add_section(section)
self.set(section, option, str(value))

def safe_get(self, section, option):
if self.has_option(section, option):
return self.get(section, option)
else:
return None

Это позволит сделать ее более гибкой, так как код будет по-прежнему иметь доступ к нормальным интерфейсом ConfigParser и возможность использовать "безопасный" звонки, которые не бросают исключений.

1
ответ дан 3 июня 2011 в 08:06 Источник Поделиться