【问题标题】:Read list from text file从文本文件中读取列表
【发布时间】:2014-10-03 18:42:10
【问题描述】:

我一直在尝试将我的 python 项目中的一些变量存储在用户可读/可编辑的文本文件中的方法。文本文件的布局如下:

a = "hello"
b = 123
c = [4,5,6]

如您所见,a 表示字符串,b 表示整数,c 表示列表。我到目前为止的代码如下:

for line in file:
    name = line.split('=')[0]
    value = line.split('=')[1]
    vars()[name] = value

它在“=”处拆分行并将第一部分设置为变量名,将第二部分设置为该变量的值。

但是,当程序运行时,b (123) 和 c ([4,5,6]) 都保存为字符串,而不是整数和列表。

有什么方法可以将字符串转换为正确的类型?或者他们是一种更好(但仍然简单)的方式来做我想做的事情?

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 你可以使用eval,但是有一堆安全隐患。
  • 看看ast.literal_eval。不像eval,使用起来很安全。
  • 也许只是做一个函数说“嘿,这是一个列表吗?”使用 line.startswith('[') 之类的东西(甚至像老板一样的正则表达式),然后使用字符串 manip 对其进行排序,并最终在字符串 int 上使用 int() 来最终转换它们......会比 eval/exec 更安全,但实际上需要工作
  • 你会想要 exec 而不是 eval 我相信

标签: python


【解决方案1】:

“或者他们是一种更好(但仍然简单)的方式来做我想做的事情?”

选项 1 一种简单而好的方法是在 python 文件中使用字典,只需执行导入即可。

myConfig.py

cfg={'a':"hello", 'b':123, 'c':[4,5,6]}

在您的代码中:

from myConfig import *
print cfg['a']

您也可以使用单个变量而不是字典并执行相同的操作。

选项 2

如果您不想要 python 文件,您可以读取任何其他文件并使用exec 逐行执行命令行。文档在这里:https://docs.python.org/2/reference/simple_stmts.html#exec

您可以使用execfile,但我相信它已在此处的 versoin 3.x 文档中停止使用:https://docs.python.org/2/library/functions.html#execfile

选项 3

您还可以使用其他方式:

  1. Python 配置解析器:https://docs.python.org/2/library/configparser.html
  2. YAML 文件:http://pyyaml.org/wiki/PyYAMLDocumentation
  3. XML 文件:请参阅此示例: parsing XML configuration file using Etree in python

【讨论】:

    【解决方案2】:

    这是一种方法,使用ast.literal_eval

    import ast
    def config_file(filename):
        result = {}
        with open(filename) as f:
            for line in f:
                line = line.split('=',1)
                result[line[0]] = ast.literal_eval(line[1].strip())
        return result
    
    print config_file('cfg.txt')
    

    您可能希望在for 循环中添加更多内容,例如忽略空行、删除 cmets 等。

    另请注意,这会将数据放在dict 中,而不是放在vars() 字典中。你应该keep data out of your variable names。如果您确实想将配置变量添加到命名空间,您仍然可以像这样使用我的函数:

    vars().update(config_file('cfg.txt'))
    

    【讨论】:

      【解决方案3】:

      除了下面的答案,对于简单的数据结构,您可以使用json 格式和字典或命名元组:

      import json
      from ast import literal_eval
      from collections import namedtuple
      
      json_vars = """{
          'a' : "hello",
          'b' : 123,
          'c' : [4,5,6]
      }"""
      
      
      print json_vars
      from_json = literal_eval(json_vars)
      # or:
      # from_json = json.loads(json_vars)
      
      variables = namedtuple('Vars', from_json.keys())(*from_json.values())
      
      print variables
      print variables.a
      print variables.b
      print variables.c
      
      print variables._asdict()
      d = dict(variables._asdict())
      print d
      
      print d['a']
      print d.items()
      
      
      as_json_again = json.dumps(d, indent=2)
      
      print as_json_again
      

      有关更高级的对象,请参阅pickle 模块。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-18
        • 1970-01-01
        • 2023-03-04
        • 2014-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多