Dove dovrei mettere il mio modulo python in modo che possa essere importato


89

Ho il mio pacchetto in Python e lo uso molto spesso. qual è la directory più elegante o convenzionale in cui dovrei mettere il mio pacchetto in modo che venga importato senza giocare con PYTHONPATH o sys.path?

E i pacchetti del sito, ad esempio? /usr/lib/python2.7/site-packages.
È comune in Python copiare e incollare il pacchetto lì?


1
crea un setup.py che dica le dipendenze e cosa no e usalo è una pratica migliore e sarà più portabile ... ma sì tipicamente copia / incolla funzionerà bene ... anche se di solito creo una cartella extra chiamata "user / lib / "o qualcosa del genere e mettili tutti lì e assicurati che sia sul mio PYTHONPATH
Joran Beasley,

1
Risposta REALE: non mi piacciono altre risposte nemmeno per script personali semplici / pacchetti non distribuiti, come @JoranBeasley: crea una cartella per conservare i tuoi script (o collegamenti ad essi) e aggiungi quella cartella a PYTHONPATH dall'interno della tua bash albero runcom (ad es. inserisci script / link ~/foo/bar/, aggiungi export PYTHONPATH=~/foo/bar # fields separated by ":"al tuo ~/.bashrcfile). Vedi man python, questo percorso manuale precede il percorso di ricerca Python predefinito. Attento alle collisioni di nomi.

Risposte:


64

Di solito metto le cose che voglio avere pronto per l'importazione nella directory del sito dell'utente:

~/.local/lib/pythonX.X/site-packages

Per mostrare la directory giusta per la tua piattaforma, puoi usare python -m site --user-site


modifica: verrà visualizzato una sys.pathvolta creato:

mkdir -p "`python -m site --user-site`"

quando apro python da un terminale, questo è ciò che fornisce sys.path. notare che non esistono ['', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/ usr / lib64 / python2.7 / lib-tk ',' /usr/lib64/python2.7/lib-old ',' /usr/lib64/python2.7/lib-dynload ',' /usr/lib64/python2.7 / site-packages ',' /usr/lib64/python2.7/site-packages/PIL ',' /usr/lib64/python2.7/site-packages/gst-0.10 ',' / usr / lib64 / python2. 7 / site-packages / gtk-2.0 ',' /usr/lib/python2.7/site-packages ',' /usr/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg -info ']
Cobry

quando si esegue uno script questo è ciò che fornisce ['/ home / username / Desktop / mypackage / examples', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/ usr / lib64 /python2.7/plat-linux2 ',' /usr/lib64/python2.7/lib-tk ',' /usr/lib64/python2.7/lib-old ',' /usr/lib64/python2.7/ lib-dynload ',' /usr/lib64/python2.7/site-packages ',' /usr/lib64/python2.7/site-packages/PIL ',' /usr/lib64/python2.7/site-packages /gst-0.10 ',' /usr/lib64/python2.7/site-packages/gtk-2.0 ',' /usr/lib/python2.7/site-packages ',' /usr/lib/python2.7/ site-packages / setuptools-0.6c11-py2.7.egg-info ']
Cobry

python -m site --user-site /home/username/.local/lib/python2.7/site-packages ma questo non è tra sys.path !!
Cobry

@Cobry python -m site --user-siteti dirà quale directory dovresti creare. Non apparirà sys.modulesfinché non lo avrai effettivamente creato.
Aya

@mata Probabilmente dovresti passare mkdira mkdir -pper creare le directory intermedie. Non avevo nemmeno un file ~/.local. ;-)
Aya

27

Quindi, se sei un principiante come me e le tue directory non sono molto ben organizzate, potresti provare questo metodo.

Apri il tuo terminale Python. Importa un modulo che sai funziona come numpy nel mio caso e procedi come segue. Import numpy

numpy.__file__

che si traduce in

'/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site- packages/numpy/__init__.py'

Il risultato numpy.__file__è la posizione in cui dovresti mettere il file python con il tuo modulo (escluso il numpy/__init__.py) quindi per me sarebbe

/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site- packages

Per farlo, vai sul tuo terminale e digita

mv "location of your module" "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site- packages"

Ora dovresti essere in grado di importare il tuo modulo.


Come mai nel mio Python il "._file_" non funziona? >>> import re >>> re._file_ Traceback (chiamata più recente per ultima): File "<pyshell # 10>", riga 1, in <module> re._file_ AttributeError: il modulo 're' non ha attributo ' file '
Urso

3
@ Urso Sei sicuro di utilizzare due trattini bassi? Il comando ha re.__file__funzionato per me.
arie64

Grazie mille, @ arie64 per una soluzione così pulita. Ha funzionato bene anche per me !!
Bms bharadwaj

Grazie, questo ha funzionato anche per me. Ma stranamente non riesco a trovare la directory / cartella a cui ho inviato il mio modulo in Esplora file. Sembra che la cartella non esista. Qualche idea sul perché la cartella non viene visualizzata dove dovrebbe? (Ho abilitato "mostra oggetti nascosti" quindi non è semplicemente quello ...)
Andre

7

Questo è qualcosa che funziona per me (devo creare frequentemente pacchetti Python che vengono caricati in un repository pip privato). elaborando il commento di @joran sulla domanda.

  1. creare una "directory build" che viene utilizzata come spazio di lavoro per creare pacchetti. qualsiasi directory di tua scelta andrà bene
  2. Copia lì la directory del tuo pacchetto python e crea un file setup.py. questo dovrebbe aiutare a creare correttamente setup.py.
  3. creare un virtualenv per il progetto su cui stai lavorando. virtualenvs ha un sacco di altri vantaggi, non entrerò nei dettagli qui.
  4. creare un pacchetto dist locale python setup.py sdist --format=tar. il pacchetto creato dovrebbe idealmente essere nel filedist cartella.
  5. Installa il pacchetto sul tuo virtualenv (dopo averlo attivato). pip install <yourpackage>.tar

Puoi usare pip install --force-reinstall se hai bisogno di giocare di più con le librerie e ricreare i pacchetti dist.

Ho scoperto che questo metodo funziona alla grande per me. Se non hai bisogno di impacchettare i moduli per l'uso di altri sistemi invece che solo del tuo locale, questo metodo potrebbe essere eccessivo

Buon hacking.


1

Sul mio Mac, ho eseguito un file sudo find / -name "site-packages". Che mi ha dato un paio di percorsi come /Library/Python/2.6/site-packages, /Library/Python/2.7/site-packagese/opt/X11/lib/python2.6/site-packages .

Quindi, sapevo dove mettere i miei moduli se stavo usando v2.7 o v2.6.

Spero che sia d'aiuto.


1

le cartelle di importazione possono essere estratte aggiungendo il seguente codice sorgente:

import sys
print sys.path

Un esempio di generazione di collegamento simbolico automatico sarebbe:

ln -s \`pip show em | grep "Location"| cut -d " " -f2\` \`python -m site --user-site\`

invece di "em" puoi usare un altro pacchetto che hai "appena installato ma il python non può vederlo"

di seguito spiegherò più in dettaglio come richiesto nel commento.

supponiamo di aver installato il modulo python em o pyserial con il seguente comando (gli esempi sono per ubuntu):

sudo pip install pyserial

e l'output è come questo:

Collecting pyserial
  Downloading pyserial-3.3-py2.py3-none-any.whl (189kB)
    100% |████████████████████████████████| 194kB 2.3MB/s 
Installing collected packages: pyserial
Successfully installed pyserial-3.3

la domanda sarebbe la seguente: python non può vedere il modulo pyserial, perché? perché la posizione in cui è stato installato il modulo non è quella che Python sta cercando per il tuo account utente specifico.

soluzione: dobbiamo creare un collegamento simbolico dal percorso in cui pyserial è arrivato al percorso in cui sta cercando il tuo python.

Il comando di creazione del collegamento simbolico sarebbe:

ln -s <what_to_link> <where_to_link>

invece di digitare la posizione esatta, chiediamo a pip di dirci dove ha memorizzato i moduli eseguendo il comando:

pip show pyserial | grep "Location"| cut -d " " -f2

invece di digitare la posizione esatta, chiediamo a python di dirci dove cerca i moduli installati eseguendo il comando:

python -m site --user-site

entrambi i comandi devono essere preceduti dal carattere "` "(di solito a sinistra del tuo tasto 1 per le tastiere americane)

nel risultato verrà fornito il seguente comando per ln e verrà creato il collegamento simbolico mancante:

ln -s /usr/local/lib/python2.7/dist-packages /home/<your_username>/.local/lib/python2.7/site-packages 

o qualcosa di simile, a seconda delle impostazioni predefinite della distribuzione e di python / pip.


Sembra un potente one-liner ... puoi spiegarci un po 'per noi neofiti di Linux? Le persone potrebbero essere diffidenti nell'usare qualcosa che non capiscono :-)
pianoJames

-1

Se stai sviluppando un modulo, ti consiglio di seguire questo.

import sys
sys.path.append("/home/mylinux/python-packages")

Ora qualsiasi modulo in cui tieni python-packagesè importabile da Python-interpreter.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.