2012-10-19 14 views
5

Sto distribuendo un pacchetto che ha questa struttura:modo corretto per trovare la directory degli script da setup.py in distutils Python?

mymodule: 
    mymodule/__init__.py 
    mymodule/code.py 
    scripts/script1.py 
    scripts/script2.py 

La mymodule sottocartella di mymodule contiene il codice, e il subdir scripts contiene gli script che dovrebbe essere eseguibile dall'utente.

Quando si descrive un installazione del pacchetto in setup.py, io uso:

scripts=['myscripts/script1.py'] 

per specificare dove gli script dovrebbero andare. Durante l'installazione, di solito si trovano in una determinata directory specifica per piattaforma/utente bin. Il codice che ho in mymodule/mymodule deve comunque effettuare chiamate agli script. Qual è il modo corretto per trovare il percorso completo per questi script? Idealmente essi dovrebbero essere sul percorso dell'utente a quel punto, quindi, se voglio chiamare fuori dal guscio, dovrei essere in grado di fare:

os.system('script1.py args') 

ma voglio chiamare lo script con il suo percorso assoluto, e non fare affidamento sulla directory bin specifica piattaforma di essere sul PATH, come in:

# get the directory where the scripts reside in current installation 
scripts_dir = get_scripts_dir() 
script1_path = os.path.join(scripts_dir, "script1.py") 
os.system("%s args" %(script1_path)) 

come si può fare? Grazie.

EDIT rimuovere il codice al di fuori di uno script non è una soluzione pratica per me. il motivo è che distribuisco lavori a un sistema cluster e il modo in cui lo faccio di solito è così: immagina di avere una serie di attività su cui vuoi eseguire. Ho uno script che prende tutte le attività come input e quindi chiama un altro script, che viene eseguito solo sull'attività specificata. Qualcosa di simile:

main.py: 
for task in tasks: 
    cmd = "python script.py %s" %(task) 
    execute_on_system(cmd) 

così main.py bisogno di sapere dove script.py è, perché ha bisogno di essere un eseguibile comando execute_on_system.

+0

correlati: [determinare la posizione dei dati Distutils file di codice in Python?] (Http://stackoverflow.com/q/8628495/95735) –

+0

Come appare 'execute_on_system()'? –

+0

@PiotrDobrogost: 'execute_on_system' prende come input una stringa corrispondente a un comando di shell. Quindi crea un file temporaneo chiamato 'cmd.sh' e inserisce il comando, insieme ai prefissi necessari che indicano come deve essere eseguito il lavoro (specifico per il sistema cluster utilizzato sul sistema dell'utente) - es. Cosa accoda il lavoro dovrebbe entrare, ecc. Quindi prende questo script, 'cmd.sh' e lo esegue in un modo specifico del sistema, es facendo: 'os.system (" qsub cmd.sh ")' – user248237dfsf

risposta

3

Penso che dovresti strutturare il tuo codice in modo da non dover chiamare script dal tuo codice. Spostare il codice necessario dagli script al pacchetto e quindi è possibile chiamare questo codice sia dagli script che dal codice.

+0

Mi piace l'idea ma in pratica non funziona per me vedere imminente modifica – user248237dfsf

+0

Non vedo nulla nel tuo flusso di lavoro impedendo lo spostamento di alcuni codici dallo script al pacchetto. –

+0

Devo essere in grado di creare un comando che chiama uno script Python, che fa parte del mio pacchetto. Qualcosa come "python myscript.py someargs". per sapere * dove * myscript.py vive ... Persino myscript.py faceva parte del pacchetto e non nella directory degli script, avrei comunque dovuto usare un hack come '__file__' per capire dove si trova lo script. che sia preferibile da un design perspec piuttosto che cercare di scoprire dove si trova la directory degli script? Entrambe le soluzioni sembrano ineleganti – user248237dfsf

1

Il mio caso di utilizzo per questo è stato controllare che la directory in cui sono installati i miei script sia nel percorso dell'utente e dare un avviso se non (dato che spesso non si trova nel percorso se si installa con --user). Ecco la soluzione che ho trovato:

from setuptools.command.easy_install import easy_install 

class my_easy_install(easy_install): 

    # Match the call signature of the easy_install version. 
    def write_script(self, script_name, contents, mode="t", *ignored): 

     # Run the normal version 
     easy_install.write_script(self, script_name, contents, mode, *ignored) 

     # Save the script install directory in the distribution object. 
     # This is the same thing that is returned by the setup function. 
     self.distribution.script_install_dir = self.script_dir 

... 

dist = setup(..., 
      cmdclass = {'build_ext': my_builder, # I also have one of these. 
         'easy_install': my_easy_install, 
         }, 
      ) 

if dist.script_install_dir not in os.environ['PATH'].split(':'): 
    # Give a sensible warning message... 

Vorrei sottolineare che questo è per setuptools. Se si utilizza distutils, allora la soluzione è simile, ma leggermente diversa:

from distutils.command.install_scripts import install_scripts 

class my_install_scripts(install_scripts): # For distutils 
    def run(self): 
     install_scripts.run(self) 
     self.distribution.script_install_dir = self.install_dir 

dist = setup(..., 
      cmdclass = {'build_ext': my_builder, 
         'install_scripts': my_install_scripts, 
         }, 
      ) 
Problemi correlati