【问题标题】:Problem accessing config files within a Python egg在 Python Egg 中访问配置文件时出现问题
【发布时间】:2011-03-05 12:29:36
【问题描述】:

我有一个 Python 项目,其结构如下:

package1
  class.py
  class2.py
  ...
package2
  otherClass.py
  otherClass2.py
  ...
config
  dev_settings.ini
  prod_settings.ini

我编写了一个 setup.py 文件,将其转换为具有相同文件结构的鸡蛋。 (当我使用 zip 程序检查它时,结构似乎相同。)有趣的是,当我从 IDE 运行 Python 代码时,它工作正常并且可以访问配置文件;但是当我尝试使用egg从不同的Python脚本运行它时,它似乎无法在egg中找到配置文件。如果我将配置文件放入相对于 calling Python 脚本(在 egg 外部)的目录中,它可以工作 - 但这有点违背了拥有一个包含所有程序的功能,可以从任何地方调用。只要不使用配置文件,我就可以使用任何类/模块并从 egg 运行任何功能......但如果他们这样做,egg 找不到它们,因此这些功能不起作用。

任何帮助将不胜感激!我们对这里的彩蛋有点陌生,真的不知道从哪里开始。

【问题讨论】:

    标签: python file egg


    【解决方案1】:

    问题是,配置文件不再是文件——它们被打包在 egg 中。在文档中找到答案并不容易,但它就在那里。来自setuptools developer's guide

    通常,现有程序会操纵包的__file__ 属性以查找数据文件的位置。但是,这种操作与基于 PEP 302 的导入挂钩不兼容,包括从 zip 文件和 Python Eggs 导入。

    要访问它们,您需要关注资源管理 API 的 instructions

    在我自己的代码中,我在日志配置文件中遇到了这个问题。我像这样成功使用了 API:

    from pkg_resources import resource_stream
    
    _log_config_file = 'logging.conf'
    _log_config_location = resource_stream(__name__, _log_config_file)
    logging.config.fileConfig(_log_config_location)
    _log = logging.getLogger('package.module')
    

    【讨论】:

    • 我很困惑...我可能有点慢,因为这些概念对我来说是新的,所以请多多包涵。我必须更改使用配置文件的 Python 类中的代码以使用 pkg_resources 模块而不是对其进行硬编码?我现在要加载配置文件的行是 config = ConfigParser.RawConfigParser() config.read("..\\config\\" + environment + "_settings.ini")... 我应该把它改成什么?
    • @froadie:没错。你需要config.read(resource_stream(__name__, "..\\config\\" + environment + "_settings.ini").之类的东西,另外,你需要导入资源管理模块:from pkg_resources import resource_stream
    • 我尝试了类似的方法-config.read(pkg_resources.resource_filename(__name__, "..\\config\\" + environment + "_settings.ini"))(resource_filename 而不是 resource_stream,因为 read 需要文件名)-当我运行它时它可以工作,但在尝试从 egg 调用它时仍然出错, 虽然这次是新的 - KeyError: 'myPackageName\\..\\config\\dev_settings.ini'
    • 我可以通过将我的配置文件夹移动到使用它的实际包中来解决这个问题。这是正确的做法吗?无论如何,在包级别仍然拥有配置文件夹的同时完成同样的事情吗?
    • 你应该可以做到。做pkg_resources.resource_filename("your_base_package.config", environment + "_settings.ini") 而不是使用__name__ 作为第一个参数。然后,创建一个config/__init__.py 文件。看看这是否有效。 (your_base_package是package1/package2/config的父目录,如果父目录直接在PYTHONPATH上,资源调用的第一个参数使用“config”即可。)
    【解决方案2】:

    Setuptools' discussion of accessing pacakged data files at runtime。如果您希望脚本在鸡蛋中运行,您必须获取配置文件 a different way。此外,要使其正常工作,您可能需要通过放入一个空的 __init__.py 文件来使您的配置目录成为 Python 包。

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 2012-09-25
      • 2011-04-08
      • 1970-01-01
      • 2015-03-01
      • 2011-02-07
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多