2012-01-25 10 views
16

Ho un semplice script python, che importa vari altri moduli che ho scritto (e così via). A causa del mio ambiente, il mio PYTHONPATH è piuttosto lungo. Sto anche usando Python 2.4.Come creare un singolo file python da più script

Quello che devo fare è in qualche modo impacchettare il mio script e tutte le dipendenze che non fanno parte del python standard, in modo da poter inviare un singolo file a un altro sistema dove voglio eseguirlo. So che la versione di destinazione di Python è la stessa, ma è su Linux dove sono su Windows. Altrimenti userei py2exe.

Idealmente, mi piacerebbe inviare un file .py che in qualche modo incorpori tutti i moduli richiesti, ma mi accontento di creare automaticamente un file zip che posso semplicemente decomprimere, con i moduli richiesti il ​​tutto in un'unica directory.

Ho dato un'occhiata a varie soluzioni di packaging, ma non riesco a trovare un modo adeguato per farlo. Ho perso qualcosa?

[modifica] Mi sembra abbastanza poco chiaro in quello che sto cercando. Praticamente sto cercando qualcosa come py2exe che produrrà un singolo file (o 2 file) da un determinato script python, includendo automaticamente tutti i moduli importati.

Per esempio, se ho i seguenti due file:

[\foo\module.py] 
def example(): 
    print "Hello" 

[\bar\program.py] 
import module 
module.example() 

e corro:

cd \bar 
set PYTHONPATH=\foo 
program.py 

allora funzionerà. Quello che voglio è essere in grado di dire:

magic program.py 

e finire con un singolo file, o forse un file e una zip, che posso quindi copiare per linux ed eseguire. Non voglio installare i miei moduli sul sistema Linux di destinazione.

+0

Penso che tu stia cercando un [pacchetto] (http://docs.python.org/tutorial/modules.html#packages) (questo è ciò che Drahkar sta descrivendo nella sua risposta). Vedi [questo] (http://stackoverflow.com/questions/4155914/how-to-create-a-python-2-x-package-simple-case) domanda e l'eccellente risposta accettata. – Chris

+0

Possibile duplicato di [Comprimere i file Python in un singolo script .py] (http://stackoverflow.com/questions/4368040/packing-python-files-into-a-single-py-script) –

risposta

0

Ho trovato una soluzione che comprenda modulefinder, il compilatore e la funzione zip che funziona bene. Purtroppo non posso incollare un programma di lavoro qui come è mescolata con altro codice irrilevante, ma qui ci sono alcuni frammenti:

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) 
3

È necessario creare un file uovo. Questo è un archivio di file Python.

Vai a questa domanda per la guida: How to create Python egg file

+0

Non ho bisogno un pacchetto per questo? – xorsyst

+0

@xorsyst: se i file sono archiviati in posizioni pazzesche, li svuotano in un pacchetto e distribuiscono il singolo file. Qualunque cosa tu pensi, non è infatti il ​​caso che devi avere un sacco di file in posti strani. – Marcin

+0

Non lavoro nel vuoto. In effetti, è il caso che sto importando moduli da varie librerie che si trovano in una selezione di luoghi pazzi, e non c'è nulla che io possa fare al riguardo. – xorsyst

0

Avete preso in considerazione Automatic script creation di distribuire la soluzione ufficiale di confezionamento.

Quello che fai è create a setup.py per il tuo programma e fornire punti di ingresso che saranno trasformati in eseguibili che potrai eseguire. In questo modo non è necessario modificare il layout sorgente, pur avendo la possibilità di distribuire ed eseguire facilmente il programma.

Troverete un esempio su una vera e propria applicazione di questo sistema in gunicorn's setup.py

+0

Sembra interessante, ma quando ho provato l'esempio dato non funzionava. Potresti fornire un esempio su come usarlo? – xorsyst

+0

@xorsyst Ho aggiunto un esempio nella risposta. – amirouche

+0

Grazie. Ho provato questo, ma non sembra funzionare. Ha creato un file zip contenente tutto ciò che si trova nella mia directory corrente e non ha incluso i miei moduli importati. Sto usando male? – xorsyst

0

L'unico modo per inviare un singolo .py è se il codice da tutti i vari moduli sono stati spostati nel singolo script e la tua Dovrei rifare tutto per fare riferimento alle nuove posizioni.

Un modo migliore per farlo sarebbe spostare i moduli in questione in sottodirectory nella stessa directory del comando. È quindi possibile assicurarsi che la sottodirectory contenente il modulo abbia un __init__.py che importa il file del modulo primario. A quel punto puoi quindi fare riferimento alle cose attraverso di esso.

Ad esempio:

App Directory: /test

Directory Modulo: /test/hello

/test/hello/__init__.py contenuti:

import sayhello 

/test/hello/sayhello.py contenuti:

def print_hello(): 
    print 'hello!' 

/test/test.py contenuti:

#!/usr/bin/python2.7 

import hello 

hello.sayhello.print_hello() 

Se si esegue /test/test.py vedrete che esegue la funzione print_hello dalla directory del modulo sotto la directory esistente, nessuna modifica alla vostra PYTHONPATH necessari.

+0

Sfortunatamente, lo spostamento di file sorgente non è possibile. – xorsyst

+0

Sono un po 'confuso. Ora stai contraddicendo la tua precedente affermazione nella domanda in alto. Hai dichiarato che volevi spostare tutto in una singola directory/file.Se non si è in grado di spostare nessuno dei moduli in questione, non si può nemmeno fare ciò che si sta chiedendo a causa della propria politica interna, a parte tutte le limitazioni tecniche. – Drahkar

+0

Ci scusiamo per la confusione. Non riesco a spostare in modo permanente i file sul mio sistema. Quello che voglio fare è raccogliere tutti i file sorgente necessari in un singolo file che posso mettere sul sistema di destinazione per eseguire Python. Non voglio installare le librerie lì. Fondamentalmente, sto cercando py2exe, ma questo produce un archivio basato sulla fonte che è multipiattaforma. – xorsyst

0

Se si desidera impacchettare il proprio script con tutte le sue dipendenze in un singolo file (non sarà un file .py), è necessario esaminare virtualenv. Questo è uno strumento che consente di creare un ambiente sandbox per installare i pacchetti Python e gestire tutti i problemi PATH, PYTHONPATH e LD_LIBRARY_PATH per assicurarsi che la sandbox sia completamente autonoma.

Se inizi con un Python vergine senza librerie aggiuntive installate, quindi easy_install le tue dipendenze nell'ambiente virtuale, ti ritroverai con un progetto costruito nel virtualenv che richiede solo l'esecuzione di Python.

La sandbox è un albero di directory, non un singolo file, ma per la distribuzione è possibile aggiungerlo a tar/zip. Non ho mai provato a distribuire l'env quindi potrebbero esserci delle dipendenze da percorso, non ne sono sicuro.

Potrebbe essere necessario, invece, distribuire uno script di compilazione che costruisca un ambiente virtuale sul computer di destinazione. zc.buildout è uno strumento che aiuta ad automatizzare quel processo, un po 'come un "make install" che è strettamente integrato con il sistema di pacchetti Python e PyPI.

+0

Dovresti usare 'pip' con virtualenv invece di' easy_install'. – Marcin

+0

Modulo interessante - ma non credo di poterlo usare per creare un ambiente su Windows e quindi portarlo su Linux – xorsyst

+0

No, decisamente no. Potresti essere in grado di creare uno script buildout che crea e popola automaticamente un ambiente virtuale. –

3

Usa stickytape modulo

stickytape scripts/blah --add-python-path . > /tmp/blah-standalone 
+0

Sembra un'eccellente idea, grazie. – xorsyst

0

si può provare a convertire lo script in un file eseguibile. In primo luogo, l'uso:

pip install pyinstaller

Dopo tipo di installazione (Assicurarsi di essere nel file di directory interessi):

pyinstaller --onefile --windowed filename.py

Questo creerà una versione eseguibile del tuo script contenente tutti i moduli necessari. È quindi possibile trasferire (copiare e incollare) questo file eseguibile sul PC o sulla macchina su cui si desidera eseguire lo script.

Spero che questo aiuti.

Problemi correlati