我有一个看起来像这样的包:
- package
-- module1.py
-- module2.py
-- __init__.py
在init.py中,我以编程方式扫描软件包并导入其中的模块。
import importlib
import pkgutil
registry = {}
def creatable(cls):
if cls.handles_type() in registry:
raise KeyError("Duplicate string representations found for string: " + cls.handles_type())
registry[cls.handles_type()] = cls
return cls
def import_submodules(package, recursive=False):
""" Import all submodules of a module, recursively, including subpackages
"""
if isinstance(package, str):
package = importlib.import_module(package)
results = {}
for loader, name, is_pkg in pkgutil.walk_packages(package.__path__):
full_name = package.__name__ + '.' + name
results[full_name] = importlib.import_module(full_name)
if recursive and is_pkg:
results.update(import_submodules(full_name))
return results
import_submodules(__name__)
在模块内部,有一些用@creatable装饰器注释的类,我在这里定义了这些装饰器。这个想法是要有一个注册表字典,其键是类名,值是类(因此我可以使用字符串表示形式创建实例)。
问题是,使用Pyinstaller时注册表为空。
更新:
问题在于package.__path__
不包含任何内容。可以通过在包路径上添加.py文件来修复此问题,即
datas=[
('package/*.py', 'package'),
]
但这似乎不是一个很好的解决方案-即,我将向最终用户发送代码。
答案 0 :(得分:1)
这不是答案,但这是我可以显示一些代码的唯一方法-这是我的包mypkg的钩子文件,位于钩子文件夹中,名为hook-mypkg.py
import os
imports = []
for root, dirs, files in os.walk(os.path.join(os.getcwd(),"mypkg" )):
print(root)
for file in files:
if file.endswith( ".py") and not file.endswith( "__init__.py"):
print( " ",file)
imports.append("mypkg."+file[:-3])
print( "........." )
print( "hi=",imports )
hiddenimports = imports
这绝对可以将其在捆绑包中找到的.py文件包括在内-它们在 init .py中的globals()['__loader__'].toc
中显示为例如"mypkg.file1"
为True时,模块mypkg \ file1.py的sys.frozen
。
注意,在编辑钩子之后,您必须删除dist并构建文件夹,然后重新运行pyinstaller