将 pkgutil.iter_modules 与 py2app 一起使用

Using pkgutil.iter_modules with py2app

在我的游戏中,我有很多不同的关卡,结构如下:

+ levels/
  - Level1.py
  - Level2.py
  - Level3.py
  - ...

Level1.py 包含 class Level1,其他的也一样。

我可以这样导入我的每个关卡:

from levels.Level1 import Level1

但是因为我有很多,我想将它们全部导入到同一个地方,所以我写了一个 load_levels 函数,它位于 levels/__init__.py:

def load_levels(game,window):
  levels = {}
  for loader, mod_name, ispkg in pkgutil.iter_modules(path=__path__):
    #import and initialise level
  return levels

这很好用,直到我使用 py2app 打包应用程序。然后 pkgutil.iter_modules 不包含任何内容,大概是因为它不能 运行 在 zip 目录中(__path__['/.../dist/main.app/Contents/Resources/lib/python35.zip/levels']

我可以在这里做什么?有没有办法配置 py2app 不压缩目录,或者 pkgutil 在 zip 文件中工作?

问题不是 pkgutil 不工作,而是 modulegraph 没有打包我的任何关卡文件,因为它无法在构建时 'see' 它们。

为了解决这个问题,您可以将 levels 作为一个包列在 setup.py 中,这将确保它的所有内容都被打包。但是,它们不会被编译。

如果您想实现相同的目的并确保编译文件,一种解决方法是确保 __init__.py 中的 __all__ 包含所有模块:

for f in os.listdir(__path__):
  mod = os.path.splitext(f)[0]
  if mod not in ['__init__','__pycache__','level_base']:
    __all__.append(mod)

然后将模块添加到setup.py中的includes

现在唯一的问题是这段代码不会在打包的应用程序中工作,因为__path__不再是一个真正的目录,所以你会想要将其放在 try/except 块中。