Data & AI Training Guide 2021
Scaricate la brochure di GoDataDriven per una panoramica completa delle sessioni di formazione disponibili e dei percorsi di apprendimento di data engineering, data science, data analyst e analytics translator.
Quando usi python in modo professionale è utile impostare i tuoi progetti
in modo coerente. Questo aiuta i tuoi collaboratori a capire rapidamente la
struttura di un progetto, e rende più facile per loro impostare il progetto
sulla loro macchina. La chiave per impostare il tuo progetto è il file setup.py
.
In questo blog entrerò nei dettagli di questo file.
Da dove cominciamo
Qui assumo che tu abbia già un pacchetto che vuoi impostare.
Non è necessario che sia un pacchetto finito – idealmente dovresti creare ilsetup.py
molto prima che il tuo progetto sia finito. Potrebbe anche essere un pacchetto vuoto;
assicurati solo che la cartella del pacchetto esista
e contenga un file chiamato init.py
(che potrebbe essere vuoto).
Se segui la struttura del mio collega Henk
per il tuo progetto, la tua situazione di partenza dovrebbe assomigliare a questa:
example_project/├── exampleproject/ Python package with source code.│ ├── __init__.py Make the folder a package.│ └── example.py Example module.└── README.md README with info of the project.
Puoi avere altri file o cartelle nella tua struttura, per esempio
cartelle chiamate notebooks/
, tests/
o data/
, ma queste non sono necessarie.
Il caso di un setup.py
Una volta che hai creato un pacchetto come questo, allora è probabile che tu
utilizzi parte del codice in altri posti. Per esempio, potreste voler
fare questo in un quaderno:
from exampleproject.example import example_function
Questo funzionerebbe se la vostra directory di lavoro corrente è example_project/
, ma in
tutti gli altri casi python vi darà output come:
ModuleNotFoundError: No module named 'exampleproject'
Si potrebbe dire a python dove cercare il pacchetto impostando la variabile PYTHONPATH
ambiente o aggiungendo il percorso a sys.path
,
ma questo è lontano dall’ideale: richiederebbe azioni diverse su diverse
piattaforme, e il percorso che dovete impostare dipende dalla posizione del vostro codice.
Un modo molto migliore è installare il tuo pacchetto usando un setup.py
e pip
,
perché pip
è il modo standard per installare tutti gli altri pacchetti, ed è destinato
a funzionare allo stesso modo su tutte le piattaforme.
Un esempio minimo
Come è fatto un file setup.py
? Ecco un esempio minimo0:
from setuptools import setup, find_packagessetup( name='example', version='0.1.0', packages=find_packages(include=))
Qui specifichiamo tre cose:
- Il nome del pacchetto, che è il nome che
pip
userà per il tuo pacchetto.
Non deve essere lo stesso del nome della cartella in cui il pacchetto vive
, sebbene possa confondere se non lo è. Un esempio di dove il nome del pacchetto
e la cartella non corrispondono è Scikit-Learn: lo si installa
usandopip install scikit-learn
, mentre lo si usa importando dasklearn
. - La versione del tuo pacchetto. Questa è la versione che
pip
riporterà, ed è usata
per esempio quando pubblichi il tuo pacchetto su PyPI1. - Quali pacchetti includere; nel nostro caso questo è solo
exampleproject/
.
Qui lasciamo chesetuptools
lo capisca
automaticamente2. Mentre si potrebbe in linea di principio usarefind_packages()
senza alcun argomento, questo può potenzialmente risultare in pacchetti indesiderati da
includere. Questo può accadere, per esempio,
se hai incluso un__init__.py
nella tuatests/
directory. In alternativa, puoi anche usare l’argomentoexclude
per prevenire esplicitamente
l’inclusione di test nel pacchetto, ma questo è leggermente
meno robusto.
Ora tutto ciò che devi fare per installare il tuo pacchetto è eseguire il seguente
da dentro la example_project/
directory3:
pip install -e .
Il .
qui si riferisce alla directory di lavoro corrente, che presumo sia la directory
dove si trova il setup.py
. Il flag -e
specifica che vogliamo installare
in modalità modificabile, il che significa
che quando modifichiamo i file nel nostro pacchetto non abbiamo bisogno di reinstallare il
pacchetto prima che le modifiche abbiano effetto. Sarà necessario riavviare
python o ricaricare il pacchetto!
Quando si modificano informazioni nel setup.py
stesso sarà necessario reinstallare
il pacchetto nella maggior parte dei casi, e anche se si aggiungono nuovi (sotto)pacchetti.
In caso di dubbio, non fa mai male reinstallare. Basta eseguire di nuovo pip install -e .
.
Requisiti
La maggior parte dei progetti ha alcune dipendenze. Molto probabilmente hai usato
un file requirements.txt
prima, o un environment.yml
se stai usando conda
. Ora che stai creando un setup.py
, puoi specificare le tue
dipendenze nell’argomento install_requires
.
Per esempio, per un tipico progetto di scienza dei dati potresti avere:
setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=)
Puoi specificare i requisiti senza una versione (PyYAML
), fissare una versione (pandas==0.23.3
), specificare una versione minima ('numpy>=1.14.5
) o impostare un intervallo di versioni (matplotlib>=2.2.0,<3.0.0
). Questi
requisiti saranno automaticamente installati da pip
quando si installa il pacchetto.
Extras-require
A volte si possono avere dipendenze che sono richieste solo in certe situazioni. Come scienziato dei dati
faccio spesso pacchetti che uso per addestrare un modello. Quando lavoro su tale modello in modo interattivo
potrei aver bisogno di avere matplotlib
e jupyter
installati per lavorare in modo interattivo con i
dati e per creare visualizzazioni
delle prestazioni del modello. D’altra parte, se il modello gira in produzione non voglio installare matplotlib
né jupyter
sulla macchina (o contenitore) dove mi alleno
o faccio inferenza. Fortunatamente setuptools
permette di specificare dipendenze opzionali in extras_require
:
setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=, extras_require={ 'interactive': , })
Ora se installiamo il pacchetto normalmente (pip install example
da PyPI o pip install -e .
localmente)
installerà solo le dipendenze PyYAML
, pandas
e numpy
. Tuttavia, quando specifichiamo
che vogliamo le dipendenze interactive
opzionali (pip install example
o pip install -e .
),
allora anche matplotlib
e jupyter
saranno installate.
Scripts e entry points
Il caso d’uso principale della maggior parte dei pacchetti python che si installano da PyPI è di fornire funzionalità
che possono essere usate in altro codice python. In altre parole, è possibile import
da quei pacchetti.
Come scienziato dei dati spesso creo pacchetti che non sono destinati ad essere usati da altro codice python ma
sono destinati a fare qualcosa, per esempio addestrare un modello. Come tale, ho spesso uno script python che
voglio eseguire dalla linea di comando.
Il modo migliore4 per esporre le funzionalità del tuo pacchetto alla linea di comando è quello di definire
un entry_point
così:
setup( # ..., entry_points={ 'console_scripts': })
Ora puoi usare il comando my-command
dalla linea di comando, che a sua volta eseguirà la main
funzione dentro exampleproject/example.py
. Non dimenticare di reinstallare – altrimenti il comando
non sarà registrato.
Test
Ogni volta che scrivi del codice, ti incoraggio fortemente a scrivere anche dei test per questo codice. Per i test
con python ti suggerisco di usare pytest
. Naturalmente non vuoi aggiungere pytest
alle tue dipendenze
in install_requires
: non è richiesto dagli utenti del tuo pacchetto. Per averlo installato
automaticamente quando esegui i test puoi aggiungere quanto segue al tuo setup.py
:
setup( # ..., setup_requires=, tests_require=,)
Inoltre dovrai creare un file chiamato setup.cfg
con il seguente contenuto:
test=pytest
Ora puoi semplicemente eseguire python setup.py test
e setuptools
si assicurerà che le dipendenze necessarie
siano installate ed eseguirà pytest
per te! Dai un’occhiata qui se
vuoi fornire argomenti o impostare opzioni di configurazione per pytest
.
Se hai dei requisiti aggiuntivi per i test (per esempio pytest-flask
) puoi aggiungerli a tests_require
.
Flake8
Personalmente penso sia una buona idea eseguire Flake8 per
controllare la formattazione del tuo codice. Proprio come con pytest
, non vuoi aggiungere flake8
alleinstall_requires
dipendenze: non ha bisogno di essere installato per usare il tuo
pacchetto. Invece, puoi aggiungerlo a setup_requires
:
setup( # ..., setup_requires=)
Ora puoi semplicemente eseguire python setup.py flake8
. Naturalmente puoi anche appuntare la versione
di flake8
(o qualsiasi altro pacchetto) in setup_requires
.
Se vuoi cambiare alcuni dei parametri di configurazione di Flake8 puoi aggiungere una sezione a
il tuo setup.cfg
. Per esempio:
max-line-length=120
Dati del pacchetto
A volte potresti voler includere alcuni file non-python nel tuo pacchetto. Questi
possono essere per esempio file di schema o una piccola tabella di ricerca. Siate consapevoli che tali file
saranno impacchettati insieme al vostro codice, quindi è in generale una cattiva idea includere
qualsiasi file di grandi dimensioni.
Supponiamo di avere un schema.json
nel nostro progetto, che mettiamo in exampleproject/data/schema.json
.
Se vogliamo includerlo nel nostro pacchetto, dobbiamo usare l’argomento package_data
di setup
:
setup( # ..., package_data={'exampleproject': })
Questo farà sì che il file sia incluso nel pacchetto. Possiamo anche scegliere di includere
tutti i file sulla base di uno schema, per esempio:
setup( # ..., package_data={'': })
Questo aggiungerà tutti i file *.json
in qualsiasi pacchetto che incontra.
Non cercate di capire da soli la posizione dei file installati, perchépkg_resources
ha alcune funzioni molto utili:
-
pkg_resources.resource_stream
ti darà un flusso del file, molto simile all’oggetto
che ottieni quando chiamiopen()
, -
pkg_resources.resource_string
ti darà il contenuto del file come una stringa, -
pkg_resources.resource_filename
ti darà il nome del file (e lo estrarrà
in un file temporaneo se è incluso in un pacchetto zippato) se le due opzioni
di cui sopra non soddisfano le tue esigenze.
Per esempio, potremmo leggere il nostro schema usando:
from json import loadfrom pkg_resources import resource_streamschema = load(resource_stream('exampleproject', 'data/schema.json'))
Metadata
Se stai per pubblicare il tuo pacchetto, allora probabilmente vuoi dare ai tuoi
potenziali utenti qualche informazione in più sul tuo pacchetto, inclusa una descrizione,
il nome dell’autore o del manutentore, e l’url della pagina iniziale del pacchetto.
Puoi trovare una lista completa di tutti i metadati consentiti nei setuptools
docs.
Inoltre, se hai intenzione di pubblicare su PyPI, allora potresti voler
caricare automaticamente il contenuto del tuo README.md
nel long_description
,
e fornire dei classificatori per dire pip
ancora
di più sul tuo pacchetto.
Wrap-up
Questo blog dovrebbe essere un buon punto di partenza per impostare la maggior parte dei vostri progetti python.
Se volete leggere di più sul packaging di python date un’occhiata
alla documentazione. Ecco un esempio setup.py
che combina tutte le parti mostrate in questo blog:
from setuptools import setup, find_packagessetup( name='example', version='0.1.0', description='Setting up a python package', author='Rogier van der Geer', author_email='[email protected]', url='https://blog.godatadriven.com/setup-py', packages=find_packages(include=), install_requires=, extras_require={'plotting': }, setup_requires=, tests_require=, entry_points={ 'console_scripts': }, package_data={'exampleproject': })
e l’accompagnamento setup.cfg
:
test=pytestmax-line-length=120
Migliora le tue competenze Python, impara dagli esperti!
A GoDataDriven offriamo una serie di corsi Python da principiante a esperto, tenuti dai migliori professionisti del settore. Unisciti a noi e migliora il tuo gioco con Python:
- Python Essentials – Ottimo se hai appena iniziato con Python.
- Certified Data Science with Python Foundation – Vuoi fare il passo dall’analisi e visualizzazione dei dati alla vera scienza dei dati? Questo è il corso giusto.
- Advanced Data Science with Python – Impara a produrre i tuoi modelli come un professionista e ad usare Python per l’apprendimento automatico.
Note
0: In questo blog ho usato setuptools
per impostare il mio progetto di esempio. In alternativa
potresti anche usare distutils,
che è lo strumento standard per il packaging in python, ma manca di caratteristiche
come la funzione find_packages()
e entry_points
.
Siccome l’uso di setuptools è molto comune al giorno d’oggi e molte delle sue caratteristiche
possono essere particolarmente utili, vi suggerisco di usare setuptools.
1: Se volete che la versione del vostro pacchetto sia disponibile anche dentro python,
date un’occhiata qui.
2: Potresti anche elencare i tuoi pacchetti manualmente, ma questo è particolarmente soggetto a errori.
3: In alternativa potresti eseguire python setup.py install
, ma usare pip
ha
molti benefici, tra cui l’installazione automatica delle dipendenze e la
possibilità di disinstallare o aggiornare il tuo pacchetto.
4: Potresti anche usare l’argomento scripts
(vedi per
esempio qui)
ma siccome questo richiede la creazione di uno script di shell python potrebbe non funzionare
altrettanto bene (o affatto) su Windows.