使用ConfigParser从ini文件读取数组 [英] Use ConfigParser to read an array from ini file

查看:51
本文介绍了使用ConfigParser从ini文件读取数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读 post ,并在subscriber.ini中定义了一个数组

I have read this post, and defined an array in subscriber.ini

[smtp]
subscriber[] = aaa@hotmail.com
subscriber[] = bbb@XX.webmail
subscriber[] = ccc@test.org

然后我尝试使用ConfigParser读取数组

Then I try to use ConfigParser to read the array

#!/usr/bin/python
import ConfigParser

CONFIG_FILE = 'subscriber.ini'

config = ConfigParser.ConfigParser()
config.read( CONFIG_FILE )

subscriber = config.get('smtp' , 'subscriber[]' )
print subscriber 

它将输出最后一个元素ccc@test.org。但是我希望有完整的订户列表。

It will output the last element, ccc@test.org. But I expect a full subscriber list.

如何从ini文件中获取数组?

How do I get the array from ini file ?

推荐答案

此语法,其中 subscriber [] 自动使 subscriber 成为多个值的列表,通常不是.ini文件的功能,也不是 ConfigParser 的功能;它是 Zend_Config_Ini

This syntax, where subscriber[] automatically makes subscriber into a list of multiple values, is not a feature of .ini files in general, nor of ConfigParser; it's a feature of Zend_Config_Ini.

在Python中, ConfigParser ini文件会创建字典映射每个价值的关键。如果您有多个值,它将覆盖先前的值。神奇的后缀 [] 毫无意义。

In Python, a ConfigParser ini file creates a dict mapping each key to its value. If you have more than one value, it will just override previous values. The magic [] suffix means nothing.

不过, ConfigParser 构造函数使您可以指定自定义词典类型或工厂,以代替默认的 OrderedDict

However, the ConfigParser constructor lets you specify a custom dictionary type or factory, in place of the default OrderedDict.

一个简单的解决方案是使用 defaultdict(list)(或OrderedDefaultDict,其中有一些用于在文档中)作为基础存储,具有 __ setitem __(self,key,value) self.dd [key] .append(value),然后正常委派其他所有内容。 (或者,如果愿意,可以从 defaultdict 继承,重写构造函数以将 list 传递给超级对象,然后除了 __ setitem __ 之外,不要覆盖其他任何内容。)这会将 all 个值全部放入列表中。

One simple solution would be to use a defaultdict(list) (or an OrderedDefaultDict, which there are recipes for in the docs) for the underlying storage, have __setitem__(self, key, value) do self.dd[key].append(value), and delegate everything else normally. (Or, if you prefer, inherit from defaultdict, override the constructor to pass list to the super, and then just don't override anything but __setitem__.) That will make all of your values into lists.

您甚至可以做一些骇人听闻的事情,其中​​只有一次看到的值是单个值,但是如果再次看到相同的名称,它将成为一个列表。我认为这将是一个糟糕的主意(您是否真的要检查 config.get('smtp','subscriber []')的类型,以确定是否您是否要对其进行迭代?),但是如果您想如何配置一个文件,为一个相同的键保留多个值?显示了如何。

You could even do something hacky where a value that's only seen once is a single value, but if you see the same name again it becomes a list. I think that would be a terrible idea (do you really want to check the type of config.get('smtp', 'subscriber[]') to decide whether or not you want to iterate over it?), but if you want to, How to ConfigParse a file keeping multiple values for identical keys? shows how.

但是,重现精确值并不难您正在寻找的魔术,所有以 [] 结尾的键都是列表(无论它们出现一次还是多次),其他所有内容都像正常一样(仅保留最后一个)值(如果出现多次)。像这样的东西:

However, it's not at all hard to reproduce the exact magic you're looking for, where all keys ending in [] are lists (whether they appear once or multiple times), and everything else works like normal (keeps only the last value if it appears multiple times). Something like this:

class MultiDict(collections.OrderedDict):
    def __setitem__(self, key, value):
        if key.endswith('[]'):
            super(MultiDict, self).setdefault(key, []).append(value)
        else:
            super(MultiDict, self).__setitem__(key, value)






这显然不会提供 all 的所有扩展功能,这些扩展功能是 Zend_Config_Ini 在普通.ini文件之上添加的。例如, [group:subgroup:subsub] 作为组名将没有任何特殊含义, key.subkey.subsub 作为键名。 PHP值 TRUE FALSE NULL 不会转换为Python值 True False True False 。数字不会神奇地变成数字。 (实际上,这不是 Zend_Config_Ini 的功能,而是PHP泄漏类型的错误特征。)您必须使用注释,而不是随意混合; // 。等等。您想要添加的任何这些功能,都必须像执行此操作一样手动添加。


This obviously won't provide all of the extended features that Zend_Config_Ini adds on top of normal .ini files. For example, [group : subgroup : subsub] won't have any special meaning as a group name, nor will key.subkey.subsub as a key name. PHP values TRUE, FALSE, yes, no, and NULL won't get converted to Python values True, False, True, False, and None. Numbers won't magically become numbers. (Actually, this isn't a feature of Zend_Config_Ini, but a misfeature of PHP's leaky typing.) You have to use # comments, rather than freely mixing #, ;, and //. And so on. Any of those features that you want to add, you'll have to add manually, just as you did this one.

正如我在评论中建议的那样,如果您确实如果希望具有两个以上的层次结构,则最好使用自然无限的层次结构格式,其中任何值都可以是其他值的列表或字典。

As I suggested in a comment, if you really want to have more than two levels of hierarchy, you may be better off with a naturally infinitely-hierarchical format, where any value can be a list or dict of other values.

JSON 如今无处不在。它可能不像INI那样可人工编辑,但我认为它比2014年的INI熟悉的人更多。它具有标准格式以及Python(2.6+)和PHP(5.2)的巨大优势。 +)在其标准库中随附解析器和漂亮打印机。

JSON is ubiquitous nowadays. It may not be quite as human-editable as INI, but I think more people are familiar with it than INI in 2014. And it has the huge advantage that it's a standardized format, and that both Python (2.6+) and PHP (5.2+) come with parsers and pretty-printers for in their standard libraries.

YAML 是一种更灵活且可人工修改的格式。但是您将需要两种语言的第三方模块(请参见YAML网站上的列表)。如果您不小心,它也会带来一些安全隐患。 (请参见 中的 safe_load 和朋友。 PyYAML 文档;大多数其他库具有类似的功能。)

YAML is a more flexible and human-editable format. But you will need third-party modules in both languages (see the list at the YAML site). And it can also bring in some security concerns if you're not careful. (See safe_load and friends in the PyYAML docs; most other libraries have similar features.)

这篇关于使用ConfigParser从ini文件读取数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆