【问题标题】:what would be a quick way to read a property file in python?在python中读取属性文件的快速方法是什么?
【发布时间】:2010-10-22 14:26:06
【问题描述】:

我有一个格式的文件

VarName=Value
.
.

我想将它读入一个散列,这样H("VarName") 将返回该值。

什么是快速的方法? (读取一组字符串,将它们全部拆分到等号所在的位置,然后放入哈希中?

我正在使用 python。

【问题讨论】:

标签: python configuration-files


【解决方案1】:

oneliner 答案:

H = dict(line.strip().split('=') for line in open('filename.txt'))

(如果值还可以包含“=”字符,则可以选择使用 .split()maxsplit=1

【讨论】:

  • 对不起,这是-1。这不遵守对属性文件有效的语法中有效的几件事。有关此答案中缺少的内容的更多详细信息,请参阅以下链接:docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/…。属性文件,和 JSON 类似,语法不是很复杂,但还是要遵守。
【解决方案2】:

也许ConfigParser可以帮到你。

【讨论】:

  • -1 除了如果没有任何节标题,ConfigParser 将抛出 NoSectionError。
【解决方案3】:
d = {}
with open('filename') as f:
    for line in f:
        key, value = line.split('=')
        d[key] = value

编辑: 按照foret的建议,您可以将其更改为

    for line in f:
        tokens = line.split('=')
        d[tokens[0]] = '='.join(tokens[1:])

这将处理值中允许使用等号的情况,但如果名称也可以包含等号,它仍然会失败——因为你需要一个真正的解析器。

【讨论】:

  • 你可以做for line in f
  • 如果值包含'='怎么办? =)
  • 那么你需要一个完整的解析器来解析像'x=y'="\"'z'=a\""这样的行,或者如果你不能引用部分文件格式是不明确的:x=y=z是指x -> y=z还是x=y -> z
  • 我不反对这一点的唯一原因是因为您在回答 for that you would need a true parser 时指出,这意味着这不是在解析属性文件。如果您明确指出这不是解析 .properties 文件语法,我仍然更喜欢它,但这至少是一个开始。
【解决方案4】:

接受@Steven 的回答并没有考虑属性文件中的 cmets 和换行符,这个可以:

H = dict(line.strip().split('=') for line in open('file.properties') if not line.startswith('#') and not line.startswith('\n'))  

【讨论】:

  • 很抱歉,这和@Steven 有同样的问题。如果这符合语法,我将删除反对票,或者如果答案至少承认这不是解析属性文件。
【解决方案5】:

【讨论】:

    【解决方案6】:

    这可能是一个愚蠢的答案,但谁知道它可以帮助你:)

    将文件的扩展名更改为 .py,并进行必要的更改,如下所示:

    文件.py

    VarName="Value"   # if it's a string
    VarName_2=1
    # and you can also assign a dict a list to a var, how cool is that ?
    

    并把它放在你的包树或sys.path中,现在你可以在脚本中这样调用它,当你想使用它时:

    >>> import file
    >>> file.VarName
    'Value'
    

    为什么我写这个答案是因为,这个文件到底是什么?我从来没有见过这样的conf文件,没有部分没有什么?为什么要创建这样的配置文件?它看起来像一个糟糕的配置文件,应该看起来像 Django 设置,我更喜欢尽可能使用类似于 django 设置的配置文件。

    现在你可以把你的 -1 放在左边:)

    【讨论】:

    • 这是一个 Java 属性文件。相当标准,如果没有任何部分,ConfigParser 会抛出 NoSectionError ,这很遗憾。我应该为此提交功能请求。
    • 我确实喜欢你跳出框框思考,但这会在VarName:value 这样的行上中断,这两个字符都在: 字符上中断,而且你的value周围没有引号。
    • 另外,@samwyse:.cfg 文件虽然不像 .properties 文件那样具有集中的形式语法,但通常与 .properties 不同地解释。 ConfigParser 是一个用于理解 .cfg 文件的库,因此如果您针对该库编写了一个不读取 .properties 的错误,他们很可能会将其踢回并拒绝它——无论如何我都会这样做。 .properties 文件不是 .cfg 解析器的责任。 .cfg 文件要求在大多数 .cfg 处理程序中存在一个部分,这就是引发该异常的原因。
    【解决方案7】:

    csv module 可以让您轻松做到这一点:

    import csv
    H = dict([(row[0], row[1]) for row in csv.reader(open('the_file', 'r'), delimiter='=' )])
    

    【讨论】:

    【解决方案8】:

    对于 python2 有一个 jproperties https://pypi.python.org/pypi/jproperties/1.0.1

    对于 python2/3 有 javaproperties http://javaproperties.readthedocs.io/en/v0.1.0/

    就这么简单:

    import os, javaproperties
    with open(file, 'rb') as f:
        properties_dict = javaproperties.load(f)
    

    【讨论】:

    • 老实说,这是这里唯一真正 100% 解决 OP 问题的完整解决方案。唯一的问题可能是使用可能受其组织限制的第三方库,这在企业界经常发生。我必须解决相同问题的解决方案也需要使用单独的库,所以我没有更好的解决方案,必然 - 只是不同。
    【解决方案9】:

    好的,答案中没有其他人提到它,所以我想我会这样做。如果您正在编写 Python,并且可以控制您的解释器,也许您可​​以强制使用 Jython 解释器。

    Jython 是一个完全用 Java 实现的 Python 解释器。所有的 Python 标准库都触手可及,还有所有可用的 Java SE 库的额外优势。

    我实际上并没有执行以下任何操作(认为它更像是没有异常处理的伪代码),但是您可以混合和匹配 Python 和 Java 库,您的代码最终可能看起来像这样:

    from java.util import Properties
    from java.io import File, FileInputStream
    import os
    javasPropertyObject = Properties()
    pathToPropFile = os.path.join('path', 'to', 'property', 'file.properties')
    if os.path.isfile(pathToPropFile):
        #this is java.io.File, not Python's file descriptor
        propFile = File(pathToPropFile )
        javasFileInputStreamObject = FileInputStream(propFile)
        javasPropertyObject.load(javasFileInputStreamObject)
    
        #now we can pull out Java properties as defined by the .property file grammar
        myProp = javasPropertyObject.getProperty('myPropName')
    

    这样的文件在哪里是有效的,而在简单的split on '=' 解决方案中却不是这样:

    myPropName1:value
    myPropName2=value
    myPropName3=\
    value
    #this is a = comment
    myPropName4:my \
    value
    myPropNameWithUnicode=\u0009
    

    不利的一面是,您失去了在各种 Python 解释器之间移植的能力,现在您被锁定在 Jython 中。如果您也尝试这种方法,您将被锁定在图书馆中。我喜欢 Jython 的原因是你增加了所有可用的 Java SE 库的灵活性。

    【讨论】:

      【解决方案10】:

      如果您需要以简单的方式从属性文件中的某个部分读取所有值:

      您的 config.properties 文件布局:

      [SECTION_NAME]  
      key1 = value1  
      key2 = value2  
      

      你的代码:

      import configparser
      
      config = configparser.RawConfigParser()
      config.read('path_to_config.properties file')
      
      details_dict = dict(config.items('SECTION_NAME'))
      

      这将为您提供一个字典,其中的键与配置文件中的键及其对应的值相同。

      details_dict becomes
      
      {'key1':'value1', 'key2':'value2'}
      

      现在获取key1的值:

      value_1 = details_dict['key1']
      

      将所有内容放在一个方法中,该方法只从配置文件中读取该部分一次(在程序运行期间第一次调用该方法)。

      def get_config_dict():
          if not hasattr(get_config_dict, 'config_dict'):
              get_config_dict.config_dict = dict(config.items('SECTION_NAME'))
          return get_config_dict.config_dict
      

      现在调用上述函数并获取所需键的值:

      config_details = get_config_dict()
      key_1_value = config_details['key1'] 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-24
        • 2016-05-13
        • 2013-01-17
        • 1970-01-01
        • 2021-12-08
        • 1970-01-01
        • 2016-12-03
        相关资源
        最近更新 更多