问题
I'm trying to use Pyinstaller to bundle a server written in Python3. Part of the server code was written in a way that some modules are dynamically loaded like this:
mod_files = [f for f in os.listdir(path)]:
for f in mod_files:
mod = importlib.import_module(mod_name)
How do I handle these files with Pyinstaller?
回答1:
Pyinstaller (currently v 3.4) can't detect imports like importlib.import_module()
. The issue and solutions are detailed in Pyinstaller's documentation, which I pasted below as an entry point.
Some Python scripts import modules in ways that PyInstaller cannot detect: for example, by using the
__import__()
function with variable data, usingimp.find_module()
, or manipulating thesys.path
value at run time. If your script requires files that PyInstaller does not know about, you must help it:
- You can give additional files on the
pyinstaller
command line.- You can give additional import paths on the command line.
- You can edit the
myscript.spec
file that PyInstaller writes the first time you run it for your script. In the spec file you can tell PyInstaller about code modules that are unique to your script. You can write “hook” files that inform PyInstaller of hidden imports. If you create a “hook” for a package that other users might also use, you can contribute your hook file to PyInstaller.If your program depends on access to certain data files, you can tell PyInstaller to include them in the bundle as well. You do this by modifying the spec file, an advanced topic that is covered under Using Spec Files.
In order to locate included files at run time, your program needs to be able to learn its path at run time in a way that works regardless of whether or not it is running from a bundle. This is covered under Run-time Information.
回答2:
I am not sure the value of the mod_name
, but turns out that the private module can not be imported after freezed by the PyInstaller. i.e.
mod = importlib.import_module("module.__somename__")
will cause ModuleNotFoundError
after package, although it might work fine with the script with packaging.
Non-private package should be imported fine with the import_module, e.g.
mod = importlib.import_module("module.somename")
And of course the prerequisite is to make sure the --hidden-import
is set correctly for any dynamically importing modules, per doc Listing Hidden Imports.
来源:https://stackoverflow.com/questions/46399311/pyinstaller-adding-dynamically-loaded-modules