【问题标题】:How to read a config file using python如何使用python读取配置文件
【发布时间】:2013-10-23 03:12:00
【问题描述】:

我有一个配置文件abc.txt,看起来有点像:

path1 = "D:\test1\first"
path2 = "D:\test2\second"
path3 = "D:\test2\third"

我想从abc.txt 中读取这些路径,以便在我的程序中使用它来避免硬编码。

【问题讨论】:

标签: python


【解决方案1】:

为了使用我的示例,您的文件“abc.txt”需要如下所示。

[your-config]
path1 = "D:\test1\first"
path2 = "D:\test2\second"
path3 = "D:\test2\third"

然后在您的代码中您可以使用配置解析器。

import ConfigParser

configParser = ConfigParser.RawConfigParser()   
configFilePath = r'c:\abc.txt'
configParser.read(configFilePath)

正如his comment 中提到的human.js,在Python 3 中,ConfigParser 已重命名为configparser。详情请见Python 3 ImportError: No module named 'ConfigParser'

【讨论】:

  • 我已经编辑了这篇文章,我的建议是使用配置文件更容易而且非常有用,这样你就可以学到一个真正能帮助你的新东西。错误MissingSectionHeaderError 是因为您需要[file] 部分
  • 当然有用;以前不知道这一点。 +1
  • @KobiK 我可以通过 os.path.abspath(os.path.dirname(sys.argv[0])) 获取当前执行的脚本文件的路径。然后我可以用我的“abc.txt”做一个 os.path.join。这解决了这个问题。非常感谢
  • 在 python 3 中,ConfigParser 被重命名为 configparser。在此处查看详细信息stackoverflow.com/questions/14087598/…
  • 您可能希望从配置文件变量内容中删除引号,因为使用 configParser.get('your-config', 'path1') 将添加另一堆(单)引号(在 python3 configparser 上测试) )
【解决方案2】:

您的文件中需要一个部分:

[My Section]
path1 = D:\test1\first
path2 = D:\test2\second
path3 = D:\test2\third

然后,读取属性:

import ConfigParser

config = ConfigParser.ConfigParser()
config.readfp(open(r'abc.txt'))
path1 = config.get('My Section', 'path1')
path2 = config.get('My Section', 'path2')
path3 = config.get('My Section', 'path3')

【讨论】:

  • readfp 已弃用。请改用 read_file:config.read_file(open(r'abc.txt'))
  • 你甚至可以使用config.read(r'abc.txt')。详情见官方doc
  • 在 Python 3 中,ConfigParser 已重命名为 configparser 以符合 PEP 8。
【解决方案3】:

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

您的config.cfg 文件布局:

[SECTION_NAME]  
key1 = value1  
key2 = value2  

你的代码:

   import configparser

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

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

details_dict 是:

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

现在获取 key1 的值: 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'] 


通用多部分方法:

[SECTION_NAME_1]  
key1 = value1  
key2 = value2  

[SECTION_NAME_2]  
key1 = value1  
key2 = value2

扩展上述方法,自动逐段读取,然后按段名后键名访问。

def get_config_section():
    if not hasattr(get_config_section, 'section_dict'):
        get_config_section.section_dict = collections.defaultdict()
        
        for section in config.sections():
            get_config_section.section_dict[section] = dict(config.items(section))
    
    return get_config_section.section_dict

访问:

config_dict = get_config_section()

port = config_dict['DB']['port'] 

(这里 'DB' 是配置文件中的部分名称 'port' 是“DB”部分下的一个键。)

【讨论】:

    【解决方案4】:

    这看起来像是有效的 Python 代码,所以如果文件在项目的类路径中(而不是在其他目录或任意位置),一种方法是将文件重命名为“abc.py”并将其导入为一个模块,使用import abc。您甚至可以稍后使用reload 函数更新这些值。然后以abc.path1 等方式访问值。

    当然,如果文件包含将要执行的其他代码,这可能是危险的。我不会在任何真正的专业项目中使用它,但对于小脚本或交互模式,这似乎是最简单的解决方案。

    只需将abc.py 放入与您的脚本相同的目录,或您打开交互式shell 的目录,然后执行import abcfrom abc import *

    【讨论】:

    • 谢谢,但我没有项目构建。我只是从命令行运行 Python 脚本。在这种情况下可以做这样的事情吗?我的意思是有没有其他方法可以将它们作为一个包或类似的东西一起制作?
    • @user2882117 当然,只需将abc.py 与您的脚本或您启动交互式shell 的目录放在同一目录中,然后执行import abc。特别是如果它只是一个小脚本,我认为这是最简单的解决方案,但我不会在“真实”项目中使用它。
    • 您需要小心字符串中的反斜杠。
    【解决方案5】:

    在您的情况下,一个方便的解决方案是将配置包含在名为的 yaml 文件中 **your_config_name.yml** 看起来像这样:

    path1: "D:\test1\first"
    path2: "D:\test2\second"
    path3: "D:\test2\third"
    

    在您的 python 代码中,您可以通过执行以下操作将配置参数加载到字典中:

    import yaml
    with open('your_config_name.yml') as stream:
        config = yaml.safe_load(stream)
    

    然后您访问例如path1 像这样从你的字典 config:

    config['path1']
    

    要导入 yaml,您首先必须将包安装为:pip install pyyaml 到您选择的虚拟环境中。

    【讨论】:

      【解决方案6】:

      由于您的配置文件是一个普通的文本文件,只需使用open 函数读取它:

      file = open("abc.txt", 'r')
      content = file.read()
      paths = content.split("\n") #split it into lines
      for path in paths:
          print path.split(" = ")[1]
      

      这将打印您的路径。您还可以使用字典列表来存储它们。

      path_list = []
      path_dict = {}
      for path in paths:
          p = path.split(" = ")
          path_list.append(p)[1]
          path_dict[p[0]] = p[1]
      

      更多关于读/写文件here。 希望这会有所帮助!

      【讨论】:

      • 记住close 文件,或者更好的是,使用with 块。还不如把它们放进字典里。
      • 另外,如果它只是一个文本文件,我建议放弃引号。
      • @tobias_k 他自己能搞定的:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2013-05-18
      • 1970-01-01
      • 2018-12-12
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      相关资源
      最近更新 更多