我正在尝试使用 StringIO 来提供 ConfigObj。我想在我的单元测试中这样做,以便我可以根据我想在配置对象中测试的内容即时模拟配置“文件”。
我在配置模块中处理了一大堆事情(我正在阅读几个 conf 文件,为其余的应用程序聚合和“格式化”信息)。但是,在测试中,我面临着来自hell的 unicode 错误。我想我已经将我的问题归结为最小的功能代码,为了这个问题的目的,我已经提取并过度简化了这些代码。
我正在执行以下操作:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import configobj
import io
def main():
"""Main stuff"""
input_config = """
[Header]
author = PloucPlouc
description = Test config
[Study]
name_of_study = Testing
version = 9999
"""
# Just not to trust my default encoding
input_config = unicode(input_config, "utf-8")
test_config_fileio = io.StringIO(input_config)
print configobj.ConfigObj(infile=test_config_fileio, encoding="UTF8")
if __name__ == "__main__":
main()
它产生以下回溯:
Traceback (most recent call last):
File "test_configobj.py", line 101, in <module>
main()
File "test_configobj.py", line 98, in main
print configobj.ConfigObj(infile=test_config_fileio, encoding='UTF8')
File "/work/irlin168_1/USER/Apps/python272/lib/python2.7/site-packages/configobj-4.7.2-py2.7.egg/configobj.py", line 1242, in __init__
self._load(infile, configspec)
File "/work/irlin168_1/USER/Apps/python272/lib/python2.7/site-packages/configobj-4.7.2-py2.7.egg/configobj.py", line 1302, in _load
infile = self._handle_bom(infile)
File "/work/irlin168_1/USER/Apps/python272/lib/python2.7/site-packages/configobj-4.7.2-py2.7.egg/configobj.py", line 1442, in _handle_bom
if not line.startswith(BOM):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)
我在 Linux 上使用 Python-2.7.2(32 位)。我的控制台和编辑器 (Kile) 的语言环境设置为 fr_FR.utf8。
我以为我可以做到这一点。
从io.StringIO 文档中,我得到了这个:
StringIO 对象可以接受 Unicode 或 8 位字符串,但混合使用两者可能需要一些注意。
从ConfigObj 文档中,我可以这样做:
>>> config = ConfigObj('config.ini', encoding='UTF8') >>> config['name'] u'Michael Foord'
这:_
文件:无
您无需指定 infile。如果省略它,将创建一个空的 ConfigObj。infile 可以是:
[...] A StringIO instance or file object, or any object with a read method. The filename attribute of your ConfigObj will be None [5].
“编码”:无
默认情况下,ConfigObj 不会将您传递的文件/字符串解码为 Unicode [8]。如果您希望您的配置文件为 Unicode(键和成员),您需要提供一个编码来解码文件。此编码也将用于在写入时对配置文件进行编码。
我的问题是它为什么会产生这个?从(简单的)Unicode处理中我还有什么不明白的?...
通过查看这个答案,我改变了:
input_config = unicode(input_config, "utf8")
到(预先导入编解码器模块):
input_config = unicode(input_config, "utf8").strip(codecs.BOM_UTF8.decode("utf8", "strict"))
为了摆脱可能包含的字节顺序标记,但这并没有帮助。
非常感谢
注意:如果我使用 StringIO.StringIO 而不是 io.StringIO,我有相同的回溯。