【问题标题】:Python ConfigParser - values between quotesPython ConfigParser - 引号之间的值
【发布时间】:2009-08-21 11:12:50
【问题描述】:

当使用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"'。这怎么可能?谢谢。

【问题讨论】:

    标签: python configparser


    【解决方案1】:

    我在the configparser manual 中没有看到任何内容,但您可以使用字符串的.strip 方法来去掉前导和尾随双引号。

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

    如您所见,.strip 不以指定字符串开头和结尾的字符串不会修改。

    【讨论】:

    • 注意最后一句要更新。 strip() DOES 修改字符串,如果它以指定的字符串开始或结束。例如'"bar'.strip("'") 返回 'bar 而不是 bar
    【解决方案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 只是取等号的右边。

      【讨论】:

      • 我也遇到了同样的问题,这确实是解决方案。即改为[GENERAL]onekey=value in some words
      【解决方案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】:

        可以编写如下配置读取函数,以字典形式返回配置。

        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
        

        【讨论】:

          【解决方案6】:

          戴维,

          正如你所说,你可以把引号从你的字符串中去掉。

          对于我正在处理的项目,我希望能够将几乎任何 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
          

          ...我认为它将处理不包含三单引号和三双引号字符串的任何内容。

          (那个极端情况超出了我的要求)。

          这里的代码有点奇怪;语法荧光笔似乎被 我的文档字符串是 raw 字符串的事实。这对于让 doctest 对此特定功能感到满意是必要的)。

          【讨论】:

            【解决方案7】:

            我不得不面对同样的问题。我更喜欢使用普通字典,而不是 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'}}
            

            【讨论】:

              【解决方案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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-12-11
                • 1970-01-01
                • 2018-07-02
                • 1970-01-01
                • 1970-01-01
                • 2019-06-13
                • 1970-01-01
                • 2011-05-02
                相关资源
                最近更新 更多