将 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
块中。
在我的游戏中,我有很多不同的关卡,结构如下:
+ 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
块中。