How to build a single python file from multiple scripts?

前端 未结 8 1705
终归单人心
终归单人心 2020-12-24 01:30

I have a simple python script, which imports various other modules I\'ve written (and so on). Due to my environment, my PYTHONPATH is quite long. I\'m also using Python 2.

相关标签:
8条回答
  • 2020-12-24 02:02

    Have you taken into considerations Automatic script creation of distribute the official packaging solution.

    What you do is create a setup.py for you program and provide entry points that will be turned into executables that you will be able run. This way you don't have to change your source layout while still having the possibility to easily distribute and run you program.

    You will find an example on a real app of this system in gunicorn's setup.py

    0 讨论(0)
  • 2020-12-24 02:07

    I found this useful:

    http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html

    In short, you can .zip your modules and include a __main__.py file inside, which will enable you to run it like so:

    python3 app.zip
    

    Since my app is small I made a link from my main script to __main__.py.

    Addendum:

    You can also make the zip self-executable on UNIX-like systems by adding a single line at the top of the file. This may be important for scripts using Python3.

    echo '#!/usr/bin/env python3' | cat - app.zip > app
    chmod a+x app
    

    Which can now be executed without specifying python

    ./app
    
    0 讨论(0)
  • 2020-12-24 02:08

    I've come up with a solution involving modulefinder, the compiler, and the zip function that works well. Unfortunately I can't paste a working program here as it's intermingled with other irrelevant code, but here are some snippets:

    zipfile = ZipFile(os.path.join(dest_dir, zip_name), 'w', ZIP_DEFLATED)
    sys.path.insert(0, '.')
    finder = ModuleFinder()
    finder.run_script(source_name)
    
    for name, mod in finder.modules.iteritems():
        filename = mod.__file__
        if filename is None:
            continue
        if "python" in filename.lower():
            continue
    
        subprocess.call('"%s" -OO -m py_compile "%s"' % (python_exe, filename))
    
        zipfile.write(filename, dest_path)
    
    0 讨论(0)
  • 2020-12-24 02:09

    You can try converting the script into an executable file. First, use:

    pip install pyinstaller

    After installation type ( Be sure you are in your file of interest directory):

    pyinstaller --onefile --windowed filename.py

    This will create an executable version of your script containing all the necessary modules. You can then transfer (copy and paste) this executable to the PC or machine you want to run your script.

    I hope this helps.

    0 讨论(0)
  • 2020-12-24 02:13

    The only way to send a single .py is if the code from all of the various modules were moved into the single script and they your'd have to redo everything to reference the new locations.

    A better way of doing it would be to move the modules in question into subdirectories under the same directory as your command. You can then make sure that the subdirectory containing the module has a __init__.py that imports the primary module file. At that point you can then reference things through it.

    For example:

    App Directory: /test

    Module Directory: /test/hello

    /test/hello/__init__.py contents:

    import sayhello
    

    /test/hello/sayhello.py contents:

    def print_hello():
        print 'hello!'
    

    /test/test.py contents:

    #!/usr/bin/python2.7
    
    import hello
    
    hello.sayhello.print_hello()
    

    If you run /test/test.py you will see that it runs the print_hello function from the module directory under the existing directory, no changes to your PYTHONPATH required.

    0 讨论(0)
  • 2020-12-24 02:18

    You should create an egg file. This is an archive of python files.

    See this question for guidance: How to create Python egg file

    Update: Consider wheels in 2019

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