Python ConfigParser - значения между кавычками

При использовании модуля ConfigParser я хотел бы использовать значения, содержащие несколько слов, заданных в файле cfg. В этом случае для меня кажется тривиальным, чтобы окружать строку кавычками вроде (example.cfg):

[GENERAL]
onekey = "value in some words"

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

config = ConfigParser()
config.read(["example.cfg"])
print config.get('GENERAL', 'onekey')

Я уверен, что есть встроенная функция, позволяющая печатать только 'value in some words' вместо '"value in some words"'. Как это возможно? Спасибо.

Ответ 1

Я ничего не видел в руководстве configparser, но вы можете просто использовать метод строк .strip, чтобы избавиться от ведущие и конечные двойные кавычки.

>>> s = '"hello world"'
>>> s
'"hello world"'
>>> s.strip('"')
'hello world'
>>> s2 = "foo"
>>> s2.strip('"')
'foo'

Как вы можете видеть, .strip не изменяет строку, если она не запускается и не заканчивается указанной строкой.

Ответ 2

import ConfigParser

class MyConfigParser(ConfigParser.RawConfigParser):
    def get(self, section, option):
        val = ConfigParser.RawConfigParser.get(self, section, option)
        return val.strip('"')

if __name__ == "__main__":
    #config = ConfigParser.RawConfigParser()
    config = MyConfigParser()

    config.read(["example.cfg"])
    print config.get('GENERAL', 'onekey') 

Ответ 3

Извините, решение было тривиально - я просто могу оставить кавычки, он выглядит, что python просто берет правую сторону равенства.

Ответ 4

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

from ConfigParser import RawConfigParser
from StringIO import StringIO

s = RawConfigParser()
s.readfp(StringIO('[t]\na= 1 2 3'))
s.get('t','a')
> '1 2 3'

Это не применяется ни к ведущим, ни к конечным пробелам! Если вы хотите сохранить их, вам нужно будет заключить их в кавычки, как было предложено. Воздержитесь от использования ключевого слова eval, поскольку у вас будет огромная дыра в безопасности.

Ответ 5

Дэви,

Как вы говорите, вы можете просто оставить цитаты со своей строки.

Для проекта, над которым я работаю, я хотел иметь возможность представлять почти любой строковый литерал Python в качестве значения для некоторых моих параметров конфигурации и более того, что я хотел бы обрабатывать некоторые из них в качестве исходной строки литералы. (Я хочу, чтобы этот конфиг мог обрабатывать такие вещи, как \n,\x1b и т.д.).

В этом случае я использовал что-то вроде:

def EvalStr(s, raw=False):
    r'''Attempt to evaluate a value as a Python string literal or
       return s unchanged.

       Attempts are made to wrap the value in one, then the 
       form of triple quote.  If the target contains both forms
       of triple quote, we'll just punt and return the original
       argument unmodified.

       Examples: (But note that this docstring is raw!)
       >>> EvalStr(r'this\t is a test\n and only a \x5c test')
       'this\t is a test\n and only a \\ test'

       >>> EvalStr(r'this\t is a test\n and only a \x5c test', 'raw')
       'this\\t is a test\\n and only a \\x5c test'
    '''

    results = s  ## Default returns s unchanged
    if raw:
       tmplate1 = 'r"""%s"""'
       tmplate2 = "r'''%s'''"
    else:
       tmplate1 = '"""%s"""'
       tmplate2 = "'''%s'''"

    try:
       results = eval(tmplate1 % s)
     except SyntaxError:
    try:
        results = eval(tmplate2 %s)
    except SyntaxError:
        pass
    return results

..., который, я думаю, будет обрабатывать все, что не содержит как тройных, так и тройных двойных кавычек.

(Этот один из угловых случаев превосходит мои требования).

Здесь есть странность этого кода на SO; подсветка синтаксиса, похоже, путается тот факт, что моя docstring является необработанной строкой. Это было необходимо, чтобы сделать доктрину счастливой для этой конкретной функции).

Ответ 6

Мне пришлось столкнуться с той же проблемой. Вместо объекта configparser я предпочитаю работать с обычными словарями. Итак, сначала я читаю файл .ini, затем преобразую объект configparser в dict и, наконец, удаляю кавычки (или апострофы) из строковых значений. Вот мое решение:

preferences.ini

[GENERAL]
onekey = "value in some words"

[SETTINGS]
resolution = '1024 x 768'

example.py

#!/usr/bin/env python3

from pprint import pprint
import preferences

prefs = preferences.Preferences("preferences.ini")
d = prefs.as_dict()
pprint(d)

preferences.py

import sys
import configparser
import json
from pprint import pprint

def remove_quotes(original):
    d = original.copy()
    for key, value in d.items():
        if isinstance(value, str):
            s = d[key]
            if s.startswith(('"', "'")):
                s = s[1:]
            if s.endswith(('"', "'")):
                s = s[:-1]
            d[key] = s
            # print(f"string found: {s}")
        if isinstance(value, dict):
            d[key] = remove_quotes(value)
    #
    return d

class Preferences:
    def __init__(self, preferences_ini):
        self.preferences_ini = preferences_ini

        self.config = configparser.ConfigParser()
        self.config.read(preferences_ini)

        self.d = self.to_dict(self.config._sections)

    def as_dict(self):
        return self.d

    def to_dict(self, config):
        """
        Nested OrderedDict to normal dict.
        Also, remove the annoying quotes (apostrophes) from around string values.
        """
        d = json.loads(json.dumps(config))
        d = remove_quotes(d)
        return d

Строка d = remove_quotes(d) отвечает за удаление кавычек. Комментарий/раскомментируйте эту строку, чтобы увидеть разницу.

Выход:

$ ./example.py

{'GENERAL': {'onekey': 'value in some words'},
 'SETTINGS': {'resolution': '1024 x 768'}}

Ответ 7

может написать функцию чтения конфигурации следующим образом, которая возвращает конфигурацию в виде словаря.

def config_reader():
"""
Reads configuration from configuration file.
"""
configuration = ConfigParser.ConfigParser()
configuration.read(__file__.split('.')[0] + '.cfg')
config = {}
for section in configuration.sections():
    config[section] = {}
    for option in configuration.options(section):
        config[section][option] = (configuration.get(section, option)).strip('"').strip("'")
return config

Ответ 8

В этой ситуации самым простым решением является "eval()".

Однако вы можете беспокоиться о безопасности. Но вы все равно можете это сделать:

def literal_eval(node_or_string):
    """
    Safely evaluate an expression node or a string containing a Python
    expression.  The string or node provided may only consist of the following
    Python literal structures: strings, numbers, tuples, lists, dicts,booleans,
    and None.
    """

в качестве образца:

import ast
config = ConfigParser()
config.read(["example.cfg"])
print ast.literal_eval(config.get('GENERAL', 'onekey'))
# value in some words