Wo soll ich mein eigenes Python-Modul ablegen, damit es importiert werden kann?

88

Ich habe mein eigenes Paket in Python und benutze es sehr oft. Was ist das eleganteste oder konventionellste Verzeichnis, in das ich mein Paket legen sollte, damit es importiert wird, ohne mit PYTHONPATH oder sys.path zu spielen?

Was ist zum Beispiel mit Site-Paketen? /usr/lib/python2.7/site-packages.
Ist es in Python üblich, das Paket dort zu kopieren und einzufügen?

Cobry
quelle
1
mache eine setup.py, die Abhängigkeiten und was nicht sagt und was nicht und die Verwendung ist besser und portabler ... aber ja, normalerweise funktioniert das Kopieren / Einfügen gut ... obwohl ich normalerweise einen zusätzlichen Ordner namens "user / lib /" erstelle. "oder so und setzen Sie sie alle dort und stellen Sie einfach sicher, dass es auf meinem PYTHONPATH
Joran Beasley
1
ECHTE Antwort: Ich mag auch keine anderen Antworten für persönliche einfache Skripte / nicht verteilte Pakete wie @JoranBeasley: Erstellen Sie einen Ordner, in dem Ihre Skripte gespeichert sind (oder Links zu ihnen), und fügen Sie diesen Ordner innerhalb Ihrer Bash zu PYTHONPATH hinzu Runcom-Baum (z. B. Skripte / Links einfügen ~/foo/bar/, export PYTHONPATH=~/foo/bar # fields separated by ":"zu Ihrer ~/.bashrcDatei hinzufügen ). Siehe man pythondieses Handbuch Pfad geht der Standard - Python - Suchpfad. Vorsicht vor Namenskollisionen.

Antworten:

62

Normalerweise lege ich das zu importierende Material in das Benutzer-Site-Verzeichnis:

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

Um das richtige Verzeichnis für Ihre Plattform anzuzeigen, können Sie verwenden python -m site --user-site


Bearbeiten: Es wird angezeigt, sys.pathsobald Sie es erstellt haben:

mkdir -p "`python -m site --user-site`"
mata
quelle
Wenn ich Python von einem Terminal aus öffne, gibt dies sys.path. Beachten Sie, dass es keine lokalen ['', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/ usr / gibt. 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
Wenn Sie ein Skript ausführen, erhalten Sie Folgendes: ['/ 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, aber dies ist nicht unter sys.path !!
Cobry
@ Cobry teilt python -m site --user-siteIhnen mit, welches Verzeichnis Sie erstellen sollen. Es wird erst angezeigt, sys.moduleswenn Sie es tatsächlich erstellt haben.
Aya
@mata Sie sollten wahrscheinlich ändern , mkdirum mkdir -pdie Zwischenverzeichnisse zu erstellen. Ich hatte nicht einmal eine ~/.local. ;-)
Aya
27

Wenn Sie ein Anfänger wie ich und Ihre Verzeichnisse nicht sehr gut organisiert sind, können Sie diese Methode ausprobieren.

Öffnen Sie Ihr Python-Terminal. Importieren Sie ein Modul, von dem Sie wissen, dass es in meinem Fall wie numpy funktioniert, und führen Sie die folgenden Schritte aus. Import numpy

numpy.__file__

was in ... endet

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

Das Ergebnis von numpy.__file__ist der Speicherort, an dem Sie die Python-Datei mit Ihrem Modul (mit Ausnahme des numpy/__init__.py) ablegen sollten

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

Gehen Sie dazu einfach zu Ihrem Terminal und geben Sie ein

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

Jetzt sollten Sie Ihr Modul importieren können.

arie64
quelle
Wie kommt es, dass bei meinem Python die "._file_" nicht funktioniert? >>> import re >>> re._file_ Traceback (letzter Aufruf zuletzt): Datei "<pyshell # 10>", Zeile 1, in <module> re._file_ AttributeError: Modul 're' hat kein Attribut ' file '
Urso
3
@Urso Sind Sie sicher, dass Sie zwei Unterstriche verwenden? Der Befehl re.__file__hat bei mir funktioniert.
Arie64
Vielen Dank, @ arie64 für eine so saubere Lösung. Hat auch bei mir gut funktioniert !!
Bms Bharadwaj
Danke, das hat auch bei mir funktioniert. Aber seltsamerweise kann ich das Verzeichnis / den Ordner, an das ich mein Modul gesendet habe, im Datei-Explorer nicht finden. Es scheint, dass der Ordner nicht existiert. Irgendeine Idee, warum der Ordner nicht dort angezeigt wird, wo er sollte? (Ich habe "versteckte Gegenstände
Andre
7

Dies funktioniert bei mir (ich muss häufig Python-Pakete erstellen, die in ein privates Pip-Repository hochgeladen werden). Ausarbeitung des Kommentars von @joran zu der Frage.

  1. Erstellen Sie ein "Build-Verzeichnis", das als Arbeitsbereich zum Erstellen von Paketen verwendet wird. Jedes Verzeichnis Ihrer Wahl reicht aus
  2. Kopieren Sie dort Ihr Python-Paketverzeichnis und erstellen Sie eine setup.py-Datei. Dies sollte beim korrekten Erstellen der Datei setup.py hilfreich sein.
  3. Erstellen Sie eine virtuelle Umgebung für das Projekt, an dem Sie arbeiten. virtualenvs haben eine Reihe weiterer Vorteile, auf die ich hier nicht näher eingehen möchte.
  4. Erstellen Sie ein lokales dist-Paket python setup.py sdist --format=tar. Das erstellte Paket sollte sich idealerweise im distOrdner befinden.
  5. Installieren Sie das Paket auf Ihrer virtuellen Umgebung (nachdem Sie es aktiviert haben). pip install <yourpackage>.tar

Sie können verwenden, pip install --force-reinstallwenn Sie mehr mit den Bibliotheken herumspielen und die dist-Pakete neu erstellen müssen.

Ich habe festgestellt, dass diese Methode für mich gut funktioniert. Wenn Sie die Module nicht für die Verwendung anderer Systeme anstatt nur Ihrer lokalen Systeme verpacken müssen, ist diese Methode möglicherweise ein Overkill

Viel Spaß beim Hacken.

srj
quelle
1

Auf meinem Mac habe ich eine sudo find / -name "site-packages". Das gab mir ein paar Wege , wie /Library/Python/2.6/site-packages, /Library/Python/2.7/site-packagesund /opt/X11/lib/python2.6/site-packages.

Ich wusste also, wo ich meine Module platzieren sollte, wenn ich v2.7 oder v2.6 verwendete.

Ich hoffe es hilft.

Testen123
quelle
1

Importordner können durch Hinzufügen des folgenden Quellcodes extrahiert werden:

import sys
print sys.path

Beispiel für eine automatische Symlink-Generierung wäre:

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

Anstelle von "em" können Sie auch ein anderes Paket verwenden, das Sie "gerade installiert haben, aber der Python kann es nicht sehen".

Im Folgenden werde ich näher erläutern, wie im Kommentar angefordert.

Angenommen, Sie haben das Python-Modul em oder pyserial mit dem folgenden Befehl installiert (Beispiele für Ubuntu):

sudo pip install pyserial

und die Ausgabe ist wie folgt:

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

Die Frage wäre folgende: Python kann das Modul pyserial nicht sehen, warum? da der Speicherort, an dem das Modul installiert wurde, nicht derjenige ist, nach dem Python für Ihr bestimmtes Benutzerkonto sucht.

Lösung - Wir müssen einen Symlink von dem Pfad, auf dem Pyserial angekommen ist, zu dem Pfad erstellen, nach dem Ihre Python sucht.

Der Befehl zum Erstellen eines Symlinks wäre:

ln -s <what_to_link> <where_to_link>

Anstatt den genauen Speicherort einzugeben, bitten wir pip, uns durch Ausführen des folgenden Befehls mitzuteilen, wo die Module gespeichert sind:

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

Anstatt den genauen Speicherort einzugeben, bitten wir Python, uns mitzuteilen, wo nach den zu installierenden Modulen gesucht wird, indem der Befehl ausgeführt wird:

python -m site --user-site

Beide Befehle müssen mit dem Zeichen "` "maskiert werden (normalerweise links von Ihrer 1-Taste für die US-Tastaturen).

Im Ergebnis wird der folgende Befehl für ln bereitgestellt und der fehlende Symlink wird erstellt:

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

oder ähnliches, abhängig von Ihren Standardeinstellungen für Distribution und Python / Pip.

Oleg Kokorin
quelle
Sieht aus wie ein leistungsstarker Einzeiler ... können Sie uns Linux-Neulingen etwas erklären? Die Leute könnten vorsichtig sein, etwas zu benutzen, das sie nicht verstehen :-)
pianoJames
-1

Wenn Sie ein Modul entwickeln, würde ich empfehlen, dies zu befolgen.

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

Jetzt kann jedes Modul, in dem Sie sich python-packagesbefinden, von importiert werden Python-interpreter.

AA Shakil
quelle