py2exe和文件系统

Cla*_*diu 3 python configuration file py2exe

我有一个Python应用程序.它通过执行以下操作来加载配置文件(以及各种其他文件):

_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CONFIG_DIR = os.path.join(_path, 'conf')
Run Code Online (Sandbox Code Playgroud)

这很好用.但是,当我用py2exe打包应用程序时,会发生不好的事情:

  File "proj\config.pyc", line 8, in <module>
WindowsError: [Error 3] The system cannot find the path specified: 'C:\\proj\
\dist\\library.zip\\conf'
Run Code Online (Sandbox Code Playgroud)

显然这是一条无效的道路......这样做的更有效的方法是什么?我不想在程序中指定绝对路径,因为它可以放在不同的文件夹中.我应该只说"如果它说文件夹名称是'library.zip',那么再向下一级到'dist'文件夹"?

请注意,我有非常嵌套的目录层次结构...例如,我有一个模块gui.utils.images,存储在"gui/utils/images.py"中,它使用其路径访问"gui/images/ok. png",例如.现在py2exe版本会尝试访问"proj/dist/library.zip/gui/images/ok.png",或其他东西,这是行不通的.

Pet*_*sen 10

做这种事情的常用方法(如果我理解得当)是这样的:

  1. 使用getattr(sys,'frozen','')之类的东西检查py2exe设法设置的sys.frozen
  2. 如果没有设置,请使用常用方法,因为您从源代码运行
  3. 如果已设置,请检查sys.executable,因为这将指向.exe所在的位置(而不是python.exe所在的位置,这是它通常指向的位置).使用类似os.path.dirname(sys.executable)的东西,然后将其与您的相对路径连接以查找子文件夹等

例:

frozen = getattr(sys, 'frozen', '')

if not frozen:
    # not frozen: in regular python interpreter
    approot = os.path.dirname(__file__)

elif frozen in ('dll', 'console_exe', 'windows_exe'):
    # py2exe:
    approot = os.path.dirname(sys.executable)

elif frozen in ('macosx_app',):
    # py2app:
    # Notes on how to find stuff on MAC, by an expert (Bob Ippolito):
    # http://mail.python.org/pipermail/pythonmac-sig/2004-November/012121.html
    approot = os.environ['RESOURCEPATH']
Run Code Online (Sandbox Code Playgroud)

或者它的一些变体......后者处理py2app的使用.如果需要,您可以为其他构建器扩展它.