Python ConfigParser - значения между кавычками - PullRequest
11 голосов
/ 21 августа 2009

При использовании модуля 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"'. Как это возможно? Спасибо.

Ответы [ 8 ]

10 голосов
/ 21 августа 2009

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

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

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

6 голосов
/ 01 февраля 2010
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 голосов
/ 07 декабря 2012

Вопрос уже довольно старый, но, по крайней мере, в 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, поскольку у вас будет огромная дыра в безопасности.

3 голосов
/ 21 августа 2009

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

0 голосов
/ 12 июня 2019

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

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
0 голосов
/ 09 июня 2018

Мне пришлось столкнуться с той же проблемой. Вместо объекта 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'}}
0 голосов
/ 16 ноября 2015

В этой ситуации наиболее простым решением является "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
0 голосов
/ 22 августа 2009

Davey,

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

Для проекта, над которым я работаю, я хотел иметь возможность представлять почти любой строковый литерал 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; подсветка синтаксиса, кажется, смущена тот факт, что моя строка документации - это строка raw . Это было необходимо, чтобы осчастливить doctest этой конкретной функцией).

...