【问题标题】:Modifying python variables based on config file entries根据配置文件条目修改 python 变量
【发布时间】:2015-10-29 15:43:38
【问题描述】:

相对 Python 新手,我正在编写一个脚本,该脚本将 csv 文件作为其输入,将其逐行拆分为其组成字段并以另一种格式输出。到目前为止,我所拥有的通常效果很好。

每个传入的 csv 行都有特定的字段,分别读入变量“txnname”和“txnmemo”。在我写出包含这些的行之前,我需要针对特定​​的字符串序列测试它们并根据需要进行修改。目前,我将这些测试硬编码到脚本中,如下所示

if ('string1' in txnname) and ('string2' in txnmemo):
    txnname = 'string3'
if 'string4' in txnname:
    txnname = 'string5 ' + txnmemo

'stringx' 在这里被用来替换我想要使用的实际文本。

我真正想做的是从脚本中完全删除搜索字符串、变量名和修饰符字符串,并将它们放在脚本旁边已经存在的配置文件中,并包含通过 ConfigParser 读入脚本的各种参数.这样我就不必在每次想要测试新条件时修改代码。这样做的“hacky”方式似乎是在从配置文件读取的文字 Python 语句上以某种组合使用 eval/exec,但是几乎每个人都说几乎总是有一个更好的替代 eval/exec。但是,尽管进行了大量研究,但我无法想出这种替代方案。我已经读过以某种方式使用字典的提及,但无法理解这是如何工作的,尤其是在具有多个要测试的条件的“If”语句中(如上所述)

感谢您的任何建议。

【问题讨论】:

    标签: python csv configparser


    【解决方案1】:

    有几个选项。

    最简单的方法是创建一个全局config 模块,定义您的字符串变量和修饰符,并将其导入该模块。基本上,这会将所有这些变量集中到一个位置,因此当您需要修改时,只需更改 config 模块即可。

    另一个选项是使用 configparser,如您所述。在这种情况下,您需要创建一个INI file,其格式如下所示。每个部分都有不同的部分和键。

    example.ini

    [DEFAULT]
    variable_to_access = value
    
    [INPUT]
    txnname_mod = string1
    txnmemo_mod = string2
    
    [MODIFY]
    txnname_mod = string3
    txnmemo_mod = string4
    

    现在您可以读取 INI 文件并像字典一样访问变量。

    Python

    >>> import configparser
    >>> config = configparser.ConfigParser()
    >>> config.sections()
    []
    >>> config.read('example.ini')
    >>> config['INPUT']['txnname_mod']
    string1
    

    有关更多信息,请查看文档here

    【讨论】:

      【解决方案2】:

      创建配置文件并使用 configparser 非常简单易用https://docs.python.org/2/library/configparser.html。 configparser 已经为您将所有内容放入字典中。 Convert ConfigParser.items('') to dictionary

      从字典中检索值的方法非常简单,而且可能是最快的方法。

      示例用法

      renames = {"string1": "string3",
                 "string2": "string3",
                 "string4": "string5 " + txnmemo}
      
      # new_value = renames[txnname] # raises KeyError if txnname not in renames
      new_value = renames.get(txnname, txnname) # txname is the default value if txnname is not in renames
      

      如果您使用的是 configparser 方法,那么您将无法创建 "string5 " + txnmemo 作为字典结果。对于这种情况,请将您的配置文件结果设为 "string5 *unique_text*",然后替换该文本。

      new_value = renames.get(txnname, txname).replace("*unique_text*", txnmemo)
      

      我只想让配置文件尽可能简单

      [Renames]
      string1 = string3
      string2 = string3
      string4 = string5 *unique_text*
      

      配置解析器

      import configparser
      config = configparser.ConfigParser(allow_no_value=True, inline_comment_prefixes=(";"))
      config.optionxform = str # Prevents key case change
      config.read('rename.ini')
      
      with open("file.csv", "r") as file:
          for line in file:
              txnname, txnmemo = line.split(",")
              txnname = config["Renames"].get(txnname, txnname)
              txnname = txnname.replace("*unique_text*", txnmemo)
      

      【讨论】:

        【解决方案3】:

        您确实可以使用 ConfigParser 来读取 .cfg 文件。这样您就可以使用 config.get() 和 config.write() 在 .cfg 文件上读取和写入数据

        【讨论】:

        • 谢谢。我已经使用我读入脚本的其他参数来执行此操作。我无法解决的是如何格式化必要的配置文件行的最佳方式,以及我需要在脚本中读入哪些代码来精确模拟我显示的代码,同时避免使用 eval/执行。
        • 我认为 HashSplat 的回答应该对你有更多帮助
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-02
        • 1970-01-01
        • 2021-03-10
        • 1970-01-01
        • 2018-11-29
        相关资源
        最近更新 更多