Importing external module in single-file exe created with PyInstaller

后端 未结 2 2049
你的背包
你的背包 2020-12-08 05:55

I am using PyInstaller to create a single-file executable. Is it possible for my script to perform an import such that i) the imported module is imported from the same direc

相关标签:
2条回答
  • 2020-12-08 06:18

    Type in Pyinstaller -h. It will give you info about pyinstaller and tell you about --runtime-hook. I presume adding this to the executable should work. There's actually a whole page of documentation for this. Surprised you could not find that.

    Anyway,

    The docs say put in: pyinstaller --additional-hooks-dir=. myscript.py.

    I presume then something like pyinstaller --additional-hooks-dir=C:\pathtofolder myscript.py should work in theory. Yet to test it. Tell us how it goes and what made kinks made it work for you.

    Lastly, if you want to be hipster try integrating cython for speed and obfuscation. Fair warning, cython is not as user friendly as pyinstaller appears to be. I have yet to use it successfully.

    0 讨论(0)
  • 2020-12-08 06:41

    The following steps allow a Python module (named module_name here) outside of an executable created by PyInstaller to be imported and for that module to import modules that were bundled into the executable.

    • Add excludes=['module_name'] to the Analysis object used in the PyInstaller spec. This prevents module_name.py being bundled into the executable.
    • Add sys.path.append(os.path.dirname(sys.executable)) where module_name is imported in your application. This allows it to be imported from the directory the executable is in, which is different to the directory that the application will run in (due to being decompressed to a temporary folder).
    • Make sure any imports performed by the external module are also performed by one of the bundled modules before the external one is imported. The interpreter will not resolve the external module's imports against bundled modules, but will use ones that already exist in sys.modules.

    As an example of the final point, consider the following.

    # bundled_module1.py
    import external_module
    
    # bundled_module2.py
    # module content
    
    # external_module.py
    import bundled_module2
    

    This will fail in external_module.py because the imported module can't be found. However, the following will work:

    # bundled_module1.py
    import bundled_module2
    import external_module
    
    # bundled_module2.py
    # module content
    
    # external_module.py
    import bundled_module2
    

    This will be fine if there are a limited set of bundled modules that the external one should be able to import. It may get unwieldy for larger sets.

    Given that the documentation states that the interpreter will resolve imports against modules bundled into the executable, this feels like a possible bug. Interoperating with modules outside of the executable isn't explicitly called out though.

    0 讨论(0)
提交回复
热议问题