Python configparser从zip加载配置文件

Python configparser从zip加载配置文件,python,zipfile,configparser,Python,Zipfile,Configparser,我正在创建一个从压缩文件加载和运行python脚本的程序。除了这些python脚本之外,我还有一个配置文件,我以前使用configparser在程序的未压缩版本中加载信息 是否可以使用configparser直接读取zip文件中的配置文件?或者我必须将其解压缩到临时文件夹中并从那里加载它吗 我已尝试直接给出路径: >>> sysconf = configparser.ConfigParser() >>> sysconf.read_file("compresse

我正在创建一个从压缩文件加载和运行python脚本的程序。除了这些python脚本之外,我还有一个配置文件,我以前使用configparser在程序的未压缩版本中加载信息

是否可以使用configparser直接读取zip文件中的配置文件?或者我必须将其解压缩到临时文件夹中并从那里加载它吗

我已尝试直接给出路径:

>>> sysconf = configparser.ConfigParser()
>>> sysconf.read_file("compressed.zip/config_data.conf")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/configparser.py", line 691, in read_file
    self._read(f, source)
  File "/usr/local/lib/python3.4/configparser.py", line 1058, in _read
    raise MissingSectionHeaderError(fpname, lineno, line)
configparser.MissingSectionHeaderError: File contains no section headers.
file: '<???>', line: 1
sysconf=configparser.configparser() >>>sysconf.read_文件(“compressed.zip/config_data.conf”) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/usr/local/lib/python3.4/configparser.py”,第691行,在read_文件中 自读(f,源) 文件“/usr/local/lib/python3.4/configparser.py”,第1058行,已读 升起缺失节头错误(fpname、lineno、line) configparser.MissingSectionHeaderError:文件不包含节头。 文件:“”,第1行 没用。这并不奇怪

然后我试着用zipfile

 >>> zf = zipfile.ZipFile("compressed.zip")
 >>> data = zf.read("config_data.conf")
 >>> sysconf = configparser.ConfigParser()
 >>> sysconf.read_file(data)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/configparser.py", line 691, in read_file
    self._read(f, source)
  File "/usr/local/lib/python3.4/configparser.py", line 1009, in _read
    if line.strip().startswith(prefix):
AttributeError: 'int' object has no attribute 'strip'
zf=zipfile.zipfile(“compressed.zip”) >>>data=zf.read(“config_data.conf”) >>>sysconf=configparser.configparser() >>>sysconf.read_文件(数据) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/usr/local/lib/python3.4/configparser.py”,第691行,在read_文件中 自读(f,源) 文件“/usr/local/lib/python3.4/configparser.py”,第1009行,已读 如果line.strip().startswith(前缀): AttributeError:“int”对象没有属性“strip” 发现它也不起作用

所以我求助于创建一个临时文件夹,解压缩到它,然后在那里读取conf文件。如果可能的话,我真的希望避免这种情况,因为conf文件是唯一的限制因素。此时,我可以(并且正在)从zip文件加载python模块

如果有办法直接将原始文本传递给configparser,我可以获取文件的原始文本,但是搜索我空手而来的文档

更新: 我尝试使用stringIO作为文件对象,它似乎有点工作。 configparser不会拒绝它,但它也不喜欢它

>>> zf = zipfile.ZipFile("compressed.zip")
>>> data = zf.read(config_data.conf)
>>> confdata = io.StringIO(str(data))
>>> sysconf = configparser.ConfigParser()
>>> sysconf.readfp(confdata)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/configparser.py", line 736, in readfp
    self.read_file(fp, source=filename)
  File "/usr/local/lib/python3.4/configparser.py", line 691, in read_file
    self._read(f, source)
  File "/usr/local/lib/python3.4/configparser.py", line 1058, in _read
    raise MissingSectionHeaderError(fpname, lineno, line)
configparser.MissingSectionHeaderError: File contains no section headers.
file: '<???>', line: 1
(continues to spit out the entire contents of the file)
zf=zipfile.zipfile(“compressed.zip”) >>>data=zf.read(config_data.conf) >>>confdata=io.StringIO(str(数据)) >>>sysconf=configparser.configparser() >>>sysconf.readfp(confdata) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 readfp中的文件“/usr/local/lib/python3.4/configparser.py”,第736行 self.read_文件(fp,source=filename) 文件“/usr/local/lib/python3.4/configparser.py”,第691行,在read_文件中 自读(f,源) 文件“/usr/local/lib/python3.4/configparser.py”,第1058行,已读 升起缺失节头错误(fpname、lineno、line) configparser.MissingSectionHeaderError:文件不包含节头。 文件:“”,第1行 (继续吐出文件的全部内容) 如果改用read_文件,它不会出错,但也不会加载任何内容

>>> zf = zipfile.ZipFile("compressed.zip")
>>> data = zf.read(config_data.conf)
>>> confdata = io.StringIO(str(data))
>>> sysconf = configparser.ConfigParser()
>>> sysconf.read_file(confdata)
>>> sysconf.items("General") #(this is the main section in the file)
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/configparser.py", line 824, in items
    d.update(self._sections[section])
KeyError: 'General'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/configparser.py", line 827, in items
    raise NoSectionError(section)
configparser.NoSectionError: No section: 'General'
zf=zipfile.zipfile(“compressed.zip”) >>>data=zf.read(config_data.conf) >>>confdata=io.StringIO(str(数据)) >>>sysconf=configparser.configparser() >>>sysconf.read_文件(confdata) >>>sysconf.items(“General”)#(这是文件的主要部分) 回溯(最近一次呼叫最后一次): 文件“/usr/local/lib/python3.4/configparser.py”,第824行,在items中 d、 更新(自身部分[部分]) KeyError:“常规” 在处理上述异常期间,发生了另一个异常: 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/usr/local/lib/python3.4/configparser.py”,第827行,在items中 上升方向错误(第节) configparser.NoSectionError:没有节:“常规” 如果有办法将原始文本直接传递给configparser,则可以获取该文件的原始文本

试一试

当与适当的ZIP文件结合使用时,此代码适用于我:

import zipfile
import configparser

zf = zipfile.ZipFile("compressed.zip")
zf_config = zf.open("config_data.conf", "rU")
zf_config_data = zf_config.read().decode('ascii')

config = configparser.ConfigParser()
config.read_string(zf_config_data)
assert config['today']['lunch']=='cheeseburger'
经过思考,以下内容可能更合适:

import zipfile
import configparser
import io

zf = zipfile.ZipFile("compressed.zip")
zf_config = zf.open("config_data.conf", "rU")
zf_config = io.TextIOWrapper(zf_config)

config = configparser.ConfigParser()
config.read_file(zf_config)
assert config['today']['lunch']=='cheeseburger'

ZipFile
不仅支持
read
,还支持
open
,后者返回类似文件的对象。所以,你可以这样做:

zf = zipfile.ZipFile("compressed.zip")
config_file = zf.open("config_data.conf")
sysconfig = configparser.ConfigParser()
sysconfig.readfp(config_file)

正如在评论中所写,@matthewatabetanswer不能与Python3.4(以及更新的vesions)一起使用。这是因为
ZipFile.open
现在返回“类似字节”的对象,而不再是“类似文件”的对象。您可以使用:

codecs.getreader("utf-8")(config_file)
使用UTF-8编码将
config\u文件
字节类对象转换为文件类对象。代码现在是:

import zipfile, configparser, codecs

with zipfile.ZipFile("compressed.zip") as zf:
    config_file = zf.open("config_data.conf")
    sysconfig = configparser.ConfigParser()
    sysconfig.read_file(codecs.getreader("utf-8")(config_file))

这似乎比创建一个
字符串更令人满意,但我不知道它是否更有效…

您测试过吗?我无法让
configparser
喜欢
open
返回的类似文件的对象。对它进行了更多的测试,它似乎工作正常。您是否遇到错误?Ubuntu 14.04上的Python 3.4.0运行您的代码时会产生错误
TypeError:startswith first arg必须是字节或字节元组,而不是str
对不起,没有运行3.4。对于最近的编辑,请将
str(数据)
替换为
data.decode()