Gdzie powinienem umieścić własny moduł Pythona, aby można go było zaimportować

86

Mam swój pakiet w pythonie i często go używam. Jaki jest najbardziej elegancki lub konwencjonalny katalog, w którym powinienem umieścić pakiet, aby został zaimportowany bez korzystania z PYTHONPATH lub sys.path?

A co na przykład z pakietami witryn? /usr/lib/python2.7/site-packages.
Czy w Pythonie często kopiuje się i wkleja pakiet?

Cobry
źródło
1
stwórz plik setup.py, który mówi o zależnościach, a co nie, i użyj tego, co jest lepszą praktyką i będzie bardziej przenośne ... ale tak, zazwyczaj kopiowanie / wklejanie będzie działać dobrze ... chociaż zwykle tworzę dodatkowy folder o nazwie "user / lib / "lub coś w tym stylu i umieść je tam wszystkie i po prostu upewnij się, że jest na mojej PYTHONPATH
Joran Beasley
1
PRAWDZIWA odpowiedź: Nie lubię innych odpowiedzi ani dla osobistych prostych skryptów / nierozpowszechnionych pakietów, takich jak @JoranBeasley: Utwórz folder, w którym będą przechowywane twoje skrypty (lub linki do nich) i dodaj ten folder do PYTHONPATH z poziomu twojego basha drzewo runcom (np. umieść skrypty / linki ~/foo/bar/, dodaj export PYTHONPATH=~/foo/bar # fields separated by ":"do swojego ~/.bashrcpliku). Zobacz man python, ta ręczna ścieżka poprzedza domyślną ścieżkę wyszukiwania w Pythonie. Uważaj na kolizje nazw.

Odpowiedzi:

60

Zwykle umieszczam rzeczy, które chcę mieć gotowe do zaimportowania, w katalogu witryny użytkownika:

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

Aby pokazać właściwy katalog dla swojej platformy, możesz użyć python -m site --user-site


edycja: pojawi się sys.pathpo utworzeniu:

mkdir -p "`python -m site --user-site`"
mata
źródło
kiedy otwieram Pythona z terminala, to właśnie daje sys.path. zauważ, że nie ma lokalnego ['', '/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
to właśnie daje podczas wykonywania skryptu [„/ 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, ale to nie jest wśród sys.path !!
Cobry
@Cobry python -m site --user-sitepowie Ci, jaki katalog powinieneś utworzyć. Nie pojawi się, sys.modulesdopóki go nie utworzysz.
Aya
@mata Prawdopodobnie powinieneś zmienić mkdirna, mkdir -paby utworzyć katalogi pośrednie. Nie miałem nawet ~/.local. ;-)
Aya
27

Więc jeśli jesteś nowicjuszem, takim jak ja, i twoje katalogi nie są zbyt dobrze zorganizowane, możesz wypróbować tę metodę.

Otwórz terminal Pythona. Zaimportuj moduł, o którym wiesz, że działa taki jak numpy w moim przypadku i wykonaj następujące czynności. Import numpy

numpy.__file__

Co skutkuje w

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

Wynikiem numpy.__file__jest lokalizacja, w której należy umieścić plik Pythona z modułem (z wyłączeniem numpy/__init__.py), więc dla mnie tak byłoby

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

Aby to zrobić, przejdź do terminala i wpisz

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

Teraz powinieneś móc zaimportować swój moduł.

arie64
źródło
Dlaczego w moim Pythonie plik „._file_” nie działa? >>> import ponownie >>> re._file_ Traceback (ostatnie połączenie ostatnie): Plik „<pyshell # 10>”, wiersz 1, w <module> re._file_ AttributeError: moduł „re” nie ma atrybutu „ plik
Urso
3
@Urso Czy na pewno używasz dwóch podkreśleń? Polecenie re.__file__zadziałało dla mnie.
arie64
Wielkie dzięki @ arie64 za tak czyste rozwiązanie. U mnie też zadziałało !!
Bms bharadwaj,
Dzięki, to też zadziałało dla mnie. Ale, co dziwne, nie mogę znaleźć katalogu / folderu, do którego wysłałem mój moduł w Eksploratorze plików. Wygląda na to, że folder nie istnieje. Masz pomysł, dlaczego folder nie pojawia się tam, gdzie powinien? (Włączyłem "pokaż ukryte przedmioty", więc nie chodzi tylko o to ...)
Andre
7

To jest coś, co działa dla mnie (muszę często tworzyć pakiety Pythona, które są przesyłane do prywatnego repozytorium pip). omówienie komentarza @jorana do pytania.

  1. utwórz „katalog budowania”, który będzie używany jako obszar roboczy do tworzenia pakietów. dowolny wybrany katalog wystarczy
  2. Skopiuj tam katalog z pakietami Pythona i utwórz plik setup.py. powinno to pomóc w poprawnym utworzeniu pliku setup.py.
  3. utwórz virtualenv dla projektu, nad którym pracujesz. virtualenvs mają wiele innych zalet, nie będę tutaj wchodził w szczegóły.
  4. utwórz lokalny pakiet dist python setup.py sdist --format=tar. utworzony pakiet powinien znajdować się w distfolderze.
  5. Zainstaluj pakiet na swoim virtualenv (po aktywacji). pip install <yourpackage>.tar

możesz użyć, pip install --force-reinstalljeśli potrzebujesz więcej bawić się bibliotekami i ponownie tworzyć pakiety dist.

Odkryłem, że ta metoda działa dla mnie świetnie. Jeśli nie musisz pakować modułów do używania innych systemów zamiast tylko lokalnego, ta metoda może być przesadą

Miłego hakowania.

srj
źródło
1

Na moim Macu zrobiłem sudo find / -name "site-packages". To dało mi kilka ścieżek, jak /Library/Python/2.6/site-packages, /Library/Python/2.7/site-packagesi /opt/X11/lib/python2.6/site-packages.

Więc wiedziałem, gdzie umieścić moje moduły, jeśli używam wersji 2.7 lub 2.6.

Mam nadzieję, że to pomoże.

Testowanie 123
źródło
1

Import folderów można wyodrębnić, dodając następujący kod źródłowy:

import sys
print sys.path

Przykładem automatycznego generowania linków symbolicznych byłoby:

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

zamiast "em" możesz użyć innego pakietu, który właśnie "zainstalowałeś, ale Python go nie widzi"

poniżej wyjaśnię bardziej szczegółowo, o co proszono w komentarzu.

załóżmy, że zainstalowałeś moduł Pythona em lub pyserial za pomocą następującego polecenia (przykłady dotyczą ubuntu):

sudo pip install pyserial

a wynik wygląda tak:

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

pytanie byłoby następujące - python nie widzi pyserialu modułu, dlaczego? ponieważ lokalizacja, w której moduł został zainstalowany, nie jest tą, której Python szuka dla twojego konkretnego konta użytkownika.

rozwiązanie - musimy utworzyć dowiązanie symboliczne ze ścieżki, z której dotarł pyserial, do ścieżki, której szuka Twój python.

Polecenie tworzenia łącza symbolicznego wyglądałoby tak:

ln -s <what_to_link> <where_to_link>

zamiast wpisywać dokładną lokalizację, prosimy pip, aby powiedział nam, gdzie przechował moduły, wykonując polecenie:

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

zamiast wpisywać dokładną lokalizację, prosimy Pythona, aby powiedział nam, gdzie szuka instalowanych modułów, wykonując polecenie:

python -m site --user-site

oba polecenia muszą być poprzedzone znakiem "` "(zwykle po lewej stronie przycisku 1 w przypadku klawiatur amerykańskich)

w rezultacie dla ln zostanie dostarczone następujące polecenie i zostanie utworzony brakujący link symboliczny:

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

lub coś podobnego, w zależności od twojej dystrybucji i domyślnych ustawień python / pip.

Oleg Kokorin
źródło
Wygląda na potężny jednolinijkowy ... czy możesz trochę wyjaśnić nam, początkującym użytkownikom Linuksa? Ludzie mogą być ostrożni, jeśli chodzi o użycie czegoś, czego nie rozumieją :-)
pianoJames
-1

Jeśli tworzysz moduł, polecam to.

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

Teraz każdy moduł, który przechowujesz, python-packagesmoże być importowany przez Python-interpreter.

AA Shakil
źródło