2014-11-03 17 views
14

Ho sempre creato directory di script in ogni progetto che ho creato perché sono utili per inserire script eseguibili utilizzati di rado. In Python, inserisco sempre uno __init__.py nella directory degli script in modo da poter eseguire script come pacchetti (ad esempio python -m scripts.some_scripts) e caricare i moduli dalle directory sorelle. Basato su this e su Google, sto iniziando a sentire che si tratta di un anti-pattern.Una directory di script è un anti-pattern in Python? In tal caso, qual è il modo giusto per importare?

Detto questo, data una struttura come:

project_dir/ 
    some_modules_dir/ 
     foo.py 
     bar.py 
     ... 
    scripts/ 
     some_script.py 
     other_script.py 
     ... 

Qual è il modo giusto per eseguire script e qual è il modo giusto per avere loro importazione dal loro directory sorella some_modules_dir? Quale dir dovrebbe contenere __init__.py e quale non dovrebbe? Voglio seguire PEP8 il più possibile e voglio semplificare il più possibile gli script in esecuzione. Se avere una directory di script è intrinsecamente sconsigliabile, cosa fate invece voi ragazzi?

+0

È possibile che qualcuno importi un modulo di script e ne invochi manualmente alcune parti? – Kos

+0

@Kos possibile, ma perché? Voglio solo avere alcuni script Python regolari che eseguono attività una tantum. Avere persone importare parti altrove sembra eccessivo. – Eli

risposta

2

Personalmente, avendo un __init__.py nel proprio script dir si sente un po 'fuori , ma posso anche capire perché è utile qui (e in IDE).

Detto questo, se sono già stati eseguiti come modulo Python, allora forse non sono veri script, qualunque cosa significhi anche (correlato: hai uno shebang su questi file?). Difficile da dire senza contesto, ma forse sono più vicini ai moduli degli strumenti, che fanno parte del tuo codice base Python complessivo.

In questo caso, con l'aggiunta di un __init__.py a livello di progetto (project_dir nel tuo esempio), è possibile utilizzare il normale importazione nel vostro aspiranti script:

from some_modules_dir import foo 

significa che il vostro python -m scripts.some_script marche originali assoluta (sorry) il senso ...

+1

senso "assoluto". huehuehue –

2

setuptools possono create scripts automatically se dargli un elenco dei punti di entrata (cioè main() funzioni). Se stai già usando Setuptools, è molto facile da attivare. Quindi puoi unire la tua directory scripts con gli altri tuoi pacchetti.

+0

Com'è rilevante? –

+2

@ivan: OP vuole script eseguibili. Non capisco la tua domanda. – Kevin

+0

la domanda non ha nulla a che fare con la directory 'Scripts' o con gli script di wrapping in exe. –

1

In generale, se il progetto Python contiene più pacchetti nativi per il progetto, è probabile che ci sia probabilmente un unico pacchetto di livello superiore che tutti gli altri pacchetti sono sottoinsiemi di (dopotutto fanno parte dello stesso progetto quindi ci dovrebbe essere qualche giustificazione unificante per la loro esistenza). Dal momento che una directory conta come un pacchetto solo quando ha un __init__.py, l'altro modo per dire questo è che se due directory di pari livello nel tuo progetto hanno entrambi uno __init__.py, allora anche il loro genitore dovrebbe averne uno. Quindi, supponendo che abbiate buoni motivi per avere un pacchetto "scripts" e un pacchetto "modules" direttamente all'interno della root del progetto, cosa che potreste avere, la directory root del progetto probabilmente dovrebbe essere anche un pacchetto.

Se il pacchetto di livello superiore non è la radice del progetto, di solito è considerato opportuno disporre di alcuni script Python "liberi" adiacenti al pacchetto di livello superiore. Come questo:

project_root/ 
    top_level_package/ 
     __init__.py 
     module.py 
     subpackage/ 
      __init__.py 
      anothermodule.py 
    adjacent_script.py 
    adjacent_script_2.py 

Gli script "sciolti" in grado di importare direttamente dai pacchetti e moduli, perché sono nella stessa directory come il pacchetto di livello superiore.L'ipotesi con questa costruzione è che il pacchetto di livello superiore contenga tutto il codice "interessante" del tuo progetto (il tuo "punto di vendita", o la "carne" del tuo progetto, se lo desideri), mentre gli script "liberi" adiacenti funzionano solo come punti di accesso a funzionalità specifiche a cui si potrebbe voler accedere dal pacchetto di livello superiore. Ad esempio, potresti avere uno script adiacente per avviare la suite di test, per installare il software o per avviare l'applicazione se il tuo progetto è un'applicazione.

Per quanto riguarda il vostro modello particolare, ho l'impressione che si distinguano gli "script" da "moduli" perché gli script sono intesi come un'interfaccia tra te e i moduli. Se è solo per tu come uno sviluppatore e stai usando gli "script" raramente, come hai detto, probabilmente è meglio attenersi alla tua ricetta finché la directory root ha un __init__.py. Se, tuttavia, tu (o qualcun altro) usi anche gli "script" come utente finale, o se li usi frequentemente, è più semplice fornire uno script adiacente al pacchetto di livello superiore che metta in bundle la funzionalità dal tuo directory "scripts" in un singolo comando (o forse alcuni se offrono funzionalità molto dissimili) con un sottocomando per ogni "script". Potresti voler usare il modulo standard argparse per quello script adiacente. In entrambi i casi, sarebbe probabilmente più appropriato chiamare gli "script" strumenti.

Se si dispone solo di alcuni strumenti e non contengono alcun codice diverso dalla colla tra la riga di comando e i moduli, è possibile anche considerare di spostarli nella directory superiore.


Alcune fonti:

4

Il collegamento nella domanda dice solo sull'esecuzione degli script che risiedono in una directory del pacchetto che è un potenziale problema perché ... beh ... i pacchetti non sono script e gli script non sono pacchetti. Servono a scopi diversi e vengono invocati in modi diversi, quindi se li mescoli, a un certo punto ci sarà un pasticcio.

Dal momento che Python stesso ha avuto una directory Scripts per anni e nessuno si lamenta, non è in alcun modo un anti-pattern.

Vedere How do I separate my executable files from my library files? su come ci siamo occupati di script eseguibili alla mia ultima occupazione. Non ha mai causato problemi di cui sono a conoscenza.

Problemi correlati