2013-06-18 11 views
18

Sto lavorando per l'adozione di Python come parte della suite di strumenti di sviluppo del mio team. Con gli altri linguaggi/strumenti che utilizziamo, sviluppiamo molte funzioni riutilizzabili e classi specifiche per il lavoro che facciamo. Questo standardizza il modo in cui facciamo le cose e risparmia molte ruote reinventando.Qual è il modo corretto di lavorare con i moduli condivisi nello sviluppo di Python?

Non riesco a trovare alcun esempio di come questo viene in genere gestito con Python. In questo momento ho una cartella di sviluppo su un'unità locale, con più cartelle di progetto al di sotto di quella e un'ulteriore cartella "comune" contenente pacchetti e moduli con classi e funzioni riutilizzabili. Questi moduli "comuni" vengono importati dai moduli all'interno di più progetti.

Development/ 
    Common/ 
     Package_a/ 
     Package_b/ 
    Project1/ 
     Package1_1/ 
     Package1_2/ 
    Project2/ 
     Package2_1/ 
     Package2_2/ 

Nel cercare di imparare come distribuire un'applicazione Python, sembra che ci sia un presupposto che tutti i pacchetti di riferimento sono al di sotto della cartella di progetto di primo livello, non è garanzia ad essa. Mi è anche venuto in mente che forse l'approccio corretto è quello di sviluppare moduli comuni/framework in un progetto separato e, una volta testato, distribuirli all'ambiente di ogni sviluppatore installando la cartella dei pacchetti del sito. Tuttavia, ciò solleva anche questioni di nuova distribuzione.

Qualcuno può far luce su questo o indirizzarmi a una risorsa che discute questo problema?

+0

sguardo al 'sys.path' –

+1

Come vuoi che i pacchetti siano presentati al programma python? Sono Package_a - Pacchetto2_1 tutti i pacchetti di primo livello, o stai provando a fare qualche namespacing/gerarchia? –

+0

Hmmm ... non sono sicuro di cosa intendi per pacchetti "di primo livello". Nel caso dei pacchetti in "Comune", sono un modo per distinguere classi e funzioni che sono estensioni di librerie standard e/o wrapper e decoratori di classi di librerie standard, e quelle classi e funzioni che sono specifiche "aziendali", vale a dire che fornisce funzionalità riutilizzabili specifiche per il nostro ambiente. Ciascun pacchetto contiene più moduli al suo interno che organizzano ulteriormente le routine riutilizzabili all'interno di tali spazi dei nomi. Non sono sicuro se sto rispondendo alla domanda. –

risposta

2

Penso che questo è il miglior riferimento per la creazione di un pacchetto python distribuibile:

collegamento rimosso in quanto porta a un sito hackerato.

Inoltre, non pensare di dover annidare tutto sotto un'unica directory. Si può fare cose come

platform/ 
    core/ 
     coremodule 
    api/ 
     apimodule 

e poi fare le cose come from platform.core import coremodule, ecc

5

Il must-read-prima su questo genere di cose è qui:

What is the best project structure for a Python application?

nel caso in cui non l'hai visto (e segui il link nella seconda risposta).

La chiave è che ogni pacchetto principale può essere importato come se "." era la directory di primo livello, il che significa che funzionerà correttamente anche se installata in un pacchetto di siti. Ciò che questo comporta è che i principali pacchetti dovrebbero essere tutti piatta all'interno della directory principale, come in:

myproject-0.1/ 
    myproject/ 
     framework/ 
    packageA/ 
     sub_package_in_A/ 
      module.py 
    packageB/ 
     ... 

Quindi sia per voi (entro gli altri pacchetti) e gli utenti possono importare come:

import myproject 
import packageA.sub_package_in_A.module 

ecc

Il che significa che dovresti riflettere sul commento di @ MattAnderson, ma se vuoi che appaia come un pacchetto distribuibile separatamente, deve essere nella directory principale.

Nota che questa non è (o gli utenti) si ferma dal fare un:

import packageA.sub_package_in_A as sub_package_in_A 

ma non si ferma da consentire:

import sub_package_in_A 

direttamente.

+0

Buona discussione in quel collegamento. Grazie. –

1

... sembra che ci sia un presupposto che tutti i pacchetti si fa riferimento sono al di sotto della cartella di progetto di primo livello, non è garanzia ad essa.

Questo è soprattutto perché la directory di lavoro corrente è la prima voce nella sys.path di default, il che lo rende molto comodo per importare i moduli e pacchetti di sotto di tale directory.

Se si rimuove, non si può nemmeno importare roba dalla directory di lavoro corrente ...

$ touch foo.py 
$ python 
>>> import sys 
>>> del sys.path[0] 
>>> import foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named foo 

Il pensiero anche venuto in mente che forse l'approccio corretto è per sviluppare comuni/moduli framework in un progetto separato e, una volta testato , distribuirli a ciascun ambiente dello sviluppatore installando su la cartella dei pacchetti del sito.

Non è davvero un grosso problema per lo sviluppo. Se stai usando il controllo di versione e tutti gli sviluppatori controllano l'albero dei sorgenti nella stessa struttura, puoi facilmente utilizzare relative path hacks per assicurarti che il codice funzioni correttamente, senza doversi preoccupare di variabili d'ambiente o collegamenti simbolici.

Tuttavia, ciò solleva anche questioni di distribuzione.

Qui è dove le cose possono essere un po 'più complicate, ma solo se hai intenzione di rilasciare librerie indipendentemente dai progetti che le usano e/o avere più installatori di progetti condividono le stesse librerie. È così, dai uno sguardo allo distutils.

In caso contrario, è possibile utilizzare semplicemente gli stessi hack relativi al percorso utilizzati nello sviluppo per garantire che il progetto funzioni "immediatamente".

+0

No: nessuna intenzione di rilasciare librerie al di fuori del nostro team. –

3

Se si dispone di codice comune da condividere su più progetti, può valere la pena di pensare di archiviare questo codice in un progetto fisicamente separato, che viene quindi importato come dipendenza negli altri progetti. Ciò si ottiene facilmente se si ospita il progetto di codice comune in github o bitbucket, in cui è possibile utilizzare pip per installarlo in qualsiasi altro progetto. Questo approccio non solo ti aiuta a condividere facilmente codice comune su più progetti, ma ti aiuta anche a proteggerti dal creare inavvertitamente cattive dipendenze (ad esempio quelle dirette dal tuo codice comune al tuo codice non comune).

Il link qui sotto fornisce una buona introduzione all'uso pip e virtualenv per gestire le dipendenze, sicuramente vale la pena una lettura se voi e il vostro team sono abbastanza nuovo a lavorare con Python come questo è un toolchain molto comune utilizzato proprio per questo tipo di problema :

http://dabapps.com/blog/introduction-to-pip-and-virtualenv-python/

E sul link qui sotto mostra come tirare in dipendenze da github con pip:

How to use Python Pip install software, to pull packages from Github?

+0

Grazie - Avevo bisogno di guardare in un sistema di controllo di versione/sorgente, e questo potrebbe uccidere due uccelli ... –

+0

Nessun problema - anche se non è necessario andare per il controllo del codice sorgente, virtualenv e pip vengono _idamente_ consigliati. Buona fortuna – robjohncox

+0

>> importato come dipendenza negli altri tuoi progetti << In realtà, questo è quello che sto facendo attualmente e funziona perfettamente con l'IDE, ma distribuire un'applicazione che usa il codice comune è ciò che mi ha impressionato. –

Problemi correlati