Списки в ConfigParser

Я использую сценарии оболочки, чтобы переключить меня на любую учетную запись, которую я хочу быть «активным». По сути, вы начинаете с нового старта, настраиваете и настраиваете одну учетную запись, а затем переместите эти файлы на имя с соответствующим префиксом. С этого момента вы можете использовать команду «github» или «gitxyz» для переключения:

# my github script
cd ~/.ssh

if [ -f git_dhoerl -a -f git_dhoerl.pub -a -f config_dhoerl ]
then
    ; 
else 
    echo "Error: missing new files"
    exit 1
fi 

# Save a copy in /tmp, just in case
cp id_rsa /tmp
cp id_rsa.pub /tmp
cp config /tmp
echo "Saved old files in /tmp, just in case"

rm id_rsa
rm id_rsa.pub
rm config
echo "Removed current links/files"

ln git_dhoerl id_rsa
ln git_dhoerl.pub id_rsa.pub
ln config_dhoerl config

git config --global user.email "dhoerl@<company>.com"
git config --global github.user "dhoerl"        
git config --global github.token "whatever_it_is"

ssh-add -D

Мне повезло с этим. Я также создал сценарий запуска в Xcode (для вас, пользователей Mac), поэтому он не будет строить мой проект, если у меня не будет надлежащей настройки (с его использованием git):

Запустите скрипт, расположенный после зависимостей (используя / bin / ksh в качестве оболочки):

if [ "$(git config --global --get user.email)" != "dhoerl@<company>.com" ]
then
    exit 1
fi

EDIT: добавлены тесты для существования новых файлов и копирования старых файлов в / tmp для адресации комментария @naomik ниже.

147
задан Donald Duck 27 November 2017 в 22:18
поделиться

5 ответов

Нет ничего мешающего Вам упаковать список в разграниченную строку и затем распаковать его, как только Вы получаете строку от конфигурации. Если бы Вы сделали это этот путь, то Ваш раздел конфигурации был бы похож:

[Section 3]
barList=item1,item2

Это не симпатично, но это функционально для самых простых списков.

118
ответ дан Gringo Suave 27 November 2017 в 22:18
поделиться

Я столкнулся с той же проблемой в прошлом. Если Вы нуждаетесь в более сложных списках, рассматриваете создание Вашего собственного синтаксического анализатора путем наследования ConfigParser. Тогда Вы перезаписали бы получить метод с этим:

    def get(self, section, option):
    """ Get a parameter
    if the returning value is a list, convert string value to a python list"""
    value = SafeConfigParser.get(self, section, option)
    if (value[0] == "[") and (value[-1] == "]"):
        return eval(value)
    else:
        return value

С этим решением Вы также будете в состоянии определить словари в своем файле конфигурации.

, Но быть осторожным! Это не столь безопасно: это означает, что любой мог выполнить код через Ваш файл конфигурации. Если бы безопасность не является проблемой в Вашем проекте, я рассмотрел бы использование непосредственно классов Python как файлов конфигурации. Следующее намного более мощно и потребляемо, чем файл ConfigParser:

class Section
    bar = foo
class Section2
    bar2 = baz
class Section3
    barList=[ item1, item2 ]
2
ответ дан Mapad 27 November 2017 в 22:18
поделиться

Только типы примитивов поддерживаются для сериализации синтаксическим анализатором конфигурации. Я использовал бы JSON или YAML для такого требования.

2
ответ дан M. Utku ALTINKAYA 27 November 2017 в 22:18
поделиться

Как упомянуто Питером Смитом ( https://stackoverflow.com/a/11866695/7424596) Вы могли бы хотеть расширить ConfigParser, кроме того, Делающий интерполяции может использоваться, чтобы автоматически преобразовать в и из списка.

Для справки внизу Вы можете найти кодекс, который автоматически преобразовывает конфигурацию как:

[DEFAULT]
keys = [
    Overall cost structure, Capacity, RAW MATERIALS,
    BY-PRODUCT CREDITS, UTILITIES, PLANT GATE COST,
    PROCESS DESCRIPTION, AT 50% CAPACITY, PRODUCTION COSTS,
    INVESTMENT, US$ MILLION, PRODUCTION COSTS, US ¢/LB,
    VARIABLE COSTS, PRODUCTION COSTS, MAINTENANCE MATERIALS
  ]

Поэтому, если Вы просите ключи, Вы доберетесь:

<class 'list'>: ['Overall cost structure', 'Capacity', 'RAW MATERIALS', 'BY-PRODUCT CREDITS', 'UTILITIES', 'PLANT GATE COST', 'PROCESS DESCRIPTION', 'AT 50% CAPACITY', 'PRODUCTION COSTS', 'INVESTMENT', 'US$ MILLION', 'PRODUCTION COSTS', 'US ¢/LB', 'VARIABLE COSTS', 'PRODUCTION COSTS', 'MAINTENANCE MATERIALS']

Кодекс:

class AdvancedInterpolator(Interpolation):
    def before_get(self, parser, section, option, value, defaults):
        is_list = re.search(parser.LIST_MATCHER, value)
        if is_list:
            return parser.getlist(section, option, raw=True)
        return value


class AdvancedConfigParser(ConfigParser):

    _DEFAULT_INTERPOLATION = AdvancedInterpolator()

    LIST_SPLITTER = '\s*,\s*'
    LIST_MATCHER = '^\[([\s\S]*)\] 

Ps имеют в виду важность indentdation. Как читает в докторе ConfigParser стринги:

Ценности могут охватить несколько строк, пока они заказаны глубже, чем первая строка ценности. В зависимости от режима анализатора пустые строки можно рассматривать как части многострочных ценностей или проигнорировать.

def _to_list(self, str): is_list = re.search(self.LIST_MATCHER, str) if is_list: return re.split(self.LIST_SPLITTER, is_list.group(1)) else: return re.split(self.LIST_SPLITTER, str) def getlist(self, section, option, conv=lambda x:x.strip(), *, raw=False, vars=None, fallback=_UNSET, **kwargs): return self._get_conv( section, option, lambda value: [conv(x) for x in self._to_list(value)], raw=raw, vars=vars, fallback=fallback, **kwargs ) def getlistint(self, section, option, *, raw=False, vars=None, fallback=_UNSET, **kwargs): return self.getlist(section, option, int, raw=raw, vars=vars, fallback=fallback, **kwargs) def getlistfloat(self, section, option, *, raw=False, vars=None, fallback=_UNSET, **kwargs): return self.getlist(section, option, float, raw=raw, vars=vars, fallback=fallback, **kwargs) def getlistboolean(self, section, option, *, raw=False, vars=None, fallback=_UNSET, **kwargs): return self.getlist(section, option, self._convert_to_boolean, raw=raw, vars=vars, fallback=fallback, **kwargs)

Ps имеют в виду важность indentdation. Как читает в докторе ConfigParser стринги:

Ценности могут охватить несколько строк, пока они заказаны глубже, чем первая строка ценности. В зависимости от режима анализатора пустые строки можно рассматривать как части многострочных ценностей или проигнорировать.

0
ответ дан 23 November 2019 в 21:37
поделиться

Так иначе то, которое я предпочитаю, должно просто разделить значения, например:

#/path/to/config.cfg
[Numbers]
first_row = 1,2,4,8,12,24,36,48

Мог быть загружен как это в список строк или целых чисел, следующим образом:

import configparser

config = configparser.ConfigParser()
config.read('/path/to/config.cfg')

# Load into a list of strings
first_row_strings = config.get('Numbers', 'first_row').split(',')

# Load into a list of integers
first_row_integers = [int(x) for x in config.get('Numbers', 'first_row').split(',')]

Этот метод препятствует тому, чтобы Вы должны были перенести свои значения в скобках для загрузки как JSON.

0
ответ дан 23 November 2019 в 21:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: