„ImportError: No module named” podczas próby uruchomienia skryptu w języku Python

144

Próbuję uruchomić skrypt, który uruchamia między innymi skrypt w języku Python. Otrzymuję ImportError: Brak modułu o nazwie ..., jednak jeśli uruchomię ipython i zaimportuję ten sam moduł w ten sam sposób przez interpreter, moduł zostanie zaakceptowany.

Co się dzieje i jak mogę to naprawić? Próbowałem zrozumieć, w jaki sposób python używa PYTHONPATH, ale jestem całkowicie zdezorientowany. Każda pomoc byłaby bardzo mile widziana.

CodeOcelot
źródło
4
Musisz podać więcej informacji. Kiedy mówisz „uruchom skrypt”, masz na myśli skrypt powłoki? Jakiego modułu nie możesz zaimportować? Gdzie znajduje się ten moduł? Gdzie znajduje się twój skrypt?
BrenBarn
2
Jeśli chcesz uzyskać ostateczną odpowiedź na pytanie „co się dzieje”, uruchom Pythona z -vopcją, a zobaczysz, gdzie python znajduje (lub nie) znajduje moduły, które importujesz.
FatalError
Co próbujesz zaimportować? Czy oba skrypty Pythona znajdują się w tym samym katalogu?
pynovice
2
Podaj nam kod, który używasz, pełny tekst śladu stosu i dokładne kroki, które wykonujesz, aby wygenerować błąd. Trudno jest pomóc, gdy nie wiemy, na czym dokładnie polega problem.
MattDMo
5
Wydaje mi się, że jest to problem, którego doświadcza wielu użytkowników, nawet 4 lata po pierwszym zadaniu pytania.
CodeOcelot

Odpowiedzi:

183

Ten problem wynika ze sposobu, w jaki interpreter IPython w wierszu poleceń używa bieżącej ścieżki w porównaniu ze sposobem, w jaki działa oddzielny proces (czy to notatnik IPython, proces zewnętrzny itp.). IPython będzie szukał modułów do zaimportowania, które znajdują się nie tylko w sys.path, ale także w bieżącym katalogu roboczym. Kiedy uruchamiasz interpreter z wiersza poleceń, bieżący katalog, w którym pracujesz, jest tym samym, w którym uruchomiłeś ipython. Jeśli uruchomisz

import os
os.getcwd() 

zobaczysz, że to prawda.

Załóżmy jednak, że używasz notatnika ipython, uruchom, os.getcwd()a Twoim bieżącym katalogiem roboczym jest folder, w którym kazałeś działać notebookowi w pliku ipython_notebook_config.py (zwykle przy użyciu tego c.NotebookManager.notebook_dirustawienia).

Rozwiązaniem jest dostarczenie interpreterowi Pythona ścieżki do twojego modułu. Najprostszym rozwiązaniem jest dodanie tej ścieżki do listy sys.path. W swoim notatniku najpierw spróbuj:

import sys
sys.path.append('my/path/to/module/folder')

import module-of-interest

Jeśli to nie zadziała, masz inny problem niezwiązany ze ścieżką do importu i powinieneś podać więcej informacji o swoim problemie.

Lepszym (i trwalszym) sposobem rozwiązania tego problemu jest ustawienie PYTHONPATH , która zapewnia interpreterowi dodatkowe katalogi wyszukujące pakiety / moduły Pythona. Edytowanie lub ustawianie PYTHONPATH jako zmiennej globalnej zależy od systemu operacyjnego i jest szczegółowo omówione tutaj dla systemów Unix lub Windows .

tyleha
źródło
1
PSA: jeśli doszedłeś do tego pytania SO, ponieważ otrzymujesz ten błąd w jupyter-notebook, zobacz poniżej, stackoverflow.com/a/27944947/127971 Niestety, pytanie nie jest wystarczająco szczegółowe, aby dać jedną odpowiedź.
michael
@michael, ta odpowiedź dotyczy importowania modułów Pythona w ogólnym przypadku; plik dunder init.py jest potrzebny, gdy interpreter przeszukuje katalogi w poszukiwaniu modułów do zaimportowania, notatnika lub nie. Powyższa odpowiedź dotycząca katalogu roboczego interpretera notebooków i ustawienia PYTHONPATH jest poprawna.
BoltzmannBrain
Powiedziałem, że będzie wiele poprawnych odpowiedzi, ze względu na brzmienie pytania. Nie sugeruję, że ta odpowiedź jest nieprawidłowa. Ale jeśli używasz jupyter-notebook, po prostu dotkniesz pliku __init_.py, prawda? ... i nie zamierzam zmieniać PYTHONPATHani dzwonić sys.path.append, nawet jeśli są również poprawne (prawda?). Mam na myśli dziesiątki katalogów z kodem w nich i nie zamierzam dodawać ich wszystkich do ścieżki - ani nie oczekuję, że inni użytkownicy do ich pliku konfiguracyjnego jupyter, nawet jeśli jest to jeden katalog.
michael
16

Po prostu utwórz pusty plik Pythona z nazwą __init__.pypod folderem, który wyświetla błąd podczas uruchamiania projektu w języku Python.

Mohideen bin Mohammed
źródło
1
Przez „ init.py ” masz na myśli „_ init_ .py”, prawda? Utworzyłem _ init_ .py jako pusty plik i zadziałał dla mnie. Wielkie dzięki. Ale dlaczego jest to potrzebne? Wcześniej miałem skrypt Pythona w tym samym katalogu co mój notatnik ipython, a import działał poprawnie.
Eduardo Reis
3
faktycznie init .py jest używany do wskazania Pythona, aby wskazać, że w tej odpowiedniej lokalizacji znajduje się jakiś pakiet. tylko wtedy znajdzie podmoduły, cokolwiek stworzyłeś pod nim. jeśli nie utworzysz „ init .py”, oznacza to, że Python nie wie, że jest w nim jakiś pakiet. Np .: z "Myfolder.Mypackage import Mymodules" w tym celu np. Powinieneś zainicjować init .py, aby wskazać Pythonowi, że jest tu jakiś pakiet. inaczej to nie wiem.
Mohideen bin Mohammed
1
Tak, doskonała odpowiedź. Jest to potrzebne w Pythonie 2.7, ale zwróć uwagę na 3
Agape Gal'lo
rozwiązało to dla mnie problem w Pythonie 3.
Rick wspiera Monikę
poprawiłem też problem dla mnie - używając notatnika jupyter, ze źródłem Pythona w podkatalogu pliku ipynb; np. foo.ipynbużywając bar/baz.py, dodaj pusty bar/__init__.pyplik, aby notebook mógł używaćfrom bar.baz import MyClass
michael
13

Upewnij się, że oboje używają tego samego tłumacza. Zdarzyło mi się to na Ubuntu:

$ ipython3 -c 'import sys; print(sys.version)'
3.4.2 (default, Jun 19 2015, 11:34:49) \n[GCC 4.9.1]

$ python3 -c 'import sys; print(sys.version)'
3.3.0 (default, Nov 27 2012, 12:11:06) \n[GCC 4.6.3]

I sys.pathbyło inaczej między dwoma tłumaczami. Aby to naprawić, usunąłem Pythona 3.3.

z0r
źródło
po użyciu minicondy do zainstalowania wielu rzeczy związanych z Pythonem, również mam dokładnie ten problem. Dołączony ubuntu python 2.7 różni się od miniconda python 2.7. Ta odpowiedź pozwoliła mi rozwiązać problem
bph,
4
To był mój problem. Zaktualizowałem Pythona do wersji 2.7.11, ale moja interaktywna powłoka iPythona nadal korzystała z wersji 2.7.5. Po prostu musiałem uruchomić, pip install --upgrade ipythonaby pobrać najnowszą wersję, a następnie automatycznie używała domyślnie 2.7.11.
Abundnce10
Mój IPython to 7.4.0, podczas gdy w ogóle nie ma takiej wersji Pythona.
aderchox
@aderchox Uruchom to w ipythonie, aby uzyskać wersję interpretera:import sys; sys.version
z0r
7

Głównym powodem jest to, że sys.paths w Pythonie i IPythonie są różne.

Proszę odnieść się do linku lucypark , rozwiązanie działa w moim przypadku. Dzieje się tak, gdy instalujesz opencv przez

conda install opencv

I dostałem błąd importu w iPythonie, istnieją trzy kroki, aby rozwiązać ten problem:

import cv2
ImportError: ...

1. Sprawdź ścieżkę w Pythonie i iPythonie za pomocą następującego polecenia

import sys
sys.path

Znajdziesz inne wyniki z Pythona i Jupytera. Drugi krok, po prostu użyj, sys.path.append aby naprawić pominiętą ścieżkę przez try-and-error.

2. Rozwiązanie tymczasowe

W iPythonie:

import sys
sys.path.append('/home/osboxes/miniconda2/lib/python2.7/site-packages')
import cv2

ImportError:..problem rozwiązany

3. Trwałe rozwiązanie

Utwórz profil iPython i ustaw początkowe dołączanie:

W powłoce bash:

ipython profile create
... CHECK the path prompted , and edit the prompted config file like my case
vi /home/osboxes/.ipython/profile_default/ipython_kernel_config.py

W vi, dołącz do pliku:

c.InteractiveShellApp.exec_lines = [
 'import sys; sys.path.append("/home/osboxes/miniconda2/lib/python2.7/site-packages")'
]

GOTOWE

Jesse
źródło
„ipython profile create”… Tak! Jest to jedyne (trwałe) rozwiązanie, które rozwiązuje problem notebooka jupyter, który nie odczytuje ze środowiska PATH i PYTHONPATH ... bez uciekania się do niechlujnych instrukcji sys.path na początku każdego pliku (yuk). dziękuję @jesse.
JohnL_10
6

Robi sys.path.append('my-path-to-module-folder')będzie działać, ale aby uniknąć konieczności zrobić w ipython każdym razem chcesz użyć modułu, można dodać export PYTHONPATH="my-path-to-module-folder:$PYTHONPATH"do ~/.bash_profilepliku.

acannon828
źródło
2

Przed zainstalowaniem ipythona zainstalowałem moduły przez easy_install; powiedz sudo easy_install mechanize.

Po zainstalowaniu ipythona musiałem ponownie uruchomić easy_install, aby ipython rozpoznał moduły.

pandorabob
źródło
2

Miałem podobny problem, naprawiłem go, wywołując python3zamiast python, moje moduły były w Pythonie 3.5.

peter n
źródło
2

Jeśli uruchamiasz go z wiersza poleceń, czasami interpreter Pythona nie jest świadomy ścieżki, w której należy szukać modułów.

Poniżej znajduje się struktura katalogów mojego projektu:

/project/apps/..
/project/tests/..

Biegałem pod poleceniem:

>> cd project

>> python tests/my_test.py

Po uruchomieniu powyższego polecenia otrzymałem poniższy błąd

no module named lib

lib został zaimportowany do my_test.py

Wydrukowałem sys.path i zorientowałem się, że ścieżka projektu, nad którym pracuję, nie jest dostępna na liście sys.path

Dodałem poniższy kod na początku mojego skryptu my_test.py.

import sys
import os

module_path = os.path.abspath(os.getcwd())    

if module_path not in sys.path:       

    sys.path.append(module_path)

Nie jestem pewien, czy to dobry sposób na rozwiązanie tego problemu, ale tak, zadziałał dla mnie.

Raghav salotra
źródło
To zadziała, jeśli zawsze uruchamiasz skrypt z tej samej lokalizacji. W przeciwnym razie napotkasz problemy, ponieważ os.getcwd()pobierze katalog, w którym skrypt został uruchomiony, a nie katalog, w którym znajduje się plik skryptu.
Nathan Arthur
1

Oto jak to naprawiłem:

import os
import sys
module_path = os.path.abspath(os.getcwd() + '\\..')
if module_path not in sys.path:
    sys.path.append(module_path)
pomber
źródło
1

Odkryłem, że rozwiązanie tego problemu zostało obszernie udokumentowane tutaj:

https://jakevdp.github.io/blog/2017/12/05/installing-python-packages-from-jupyter/

Zasadniczo musisz zainstalować pakiety w środowisku Jupyter, wydając polecenia powłoki, takie jak:

!{sys.executable} -m pip install numpy

Proszę sprawdzić powyższy link, aby uzyskać miarodajną pełną odpowiedź.

Rui Guerra
źródło
0

Znalazłem jeszcze jedno źródło tej rozbieżności:

Zainstalowałem ipythona zarówno lokalnie, jak i powszechnie w virtualenvach. Mój problem polegał na tym, że w nowo utworzonym virtualenvie z ipythonem odebrano system ipython, który był inną wersją niż python i ipython w virtualenv (a 2.7.x vs. 3.5.x) i nastąpiła wesołość.

Myślę, że mądrą rzeczą do zrobienia podczas instalowania czegoś, co będzie zawierało plik binarny, yourvirtualenv/binjest natychmiastowe uruchomienie rehashlub coś podobnego dla dowolnej używanej powłoki, aby wybrać poprawny Python / ipython. (Muszę sprawdzić, czy są odpowiednie piphaki po instalacji ...)

kaleissin
źródło
0

Rozwiązanie bez skryptów:

  1. Otwórz Spyder -> Narzędzia -> Menedżer PYTHONPATH
  2. Dodaj ścieżki Pythona, klikając „Dodaj ścieżkę”. Na przykład: „C: \ Users \ User \ AppData \ Local \ Programs \ Python \ Python37 \ Lib \ site-packages”
  3. Kliknij „Synchronizuj ...”, aby zezwolić innym programom (np. Jupyter Notebook) na używanie ścieżek Python ustawionych w kroku 2.
  4. Zrestartuj Jupyter, jeśli jest otwarty
Wen
źródło
0

Jest to prawdopodobnie spowodowane różnymi wersjami Pythona zainstalowanymi w twoim systemie , np. Python2 lub python3 .

Uruchom polecenie $ pip --versioni $ pip3 --versionsprawdź, z którego pip pochodzi Python 3x . Np. Powinieneś zobaczyć informacje o wersji, jak poniżej:

pip 19.0.3 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)

Następnie uruchom example.pyskrypt za pomocą poniższego polecenia

$ python3 example.py
shizhen
źródło
0

Przydarzyło mi się z katalogiem utils. Próbowałem zaimportować ten katalog jako:

from utils import somefile

utilsjest już pakietem w Pythonie. Po prostu zmień nazwę katalogu na inną i powinno działać dobrze.

subtleseeker
źródło
0

Ten rodzaj błędów występuje najprawdopodobniej z powodu konfliktów wersji Pythona. Na przykład, jeśli twoja aplikacja działa tylko na Pythonie 3 i masz również Pythona 2, lepiej jest określić, której wersji użyć. Na przykład użyj

python3 .....

zamiast

python
Nu-ONE
źródło
0

Ta odpowiedź dotyczy tego pytania, jeśli

  1. Nie chcesz zmieniać swojego kodu
  2. Nie chcesz trwale zmieniać PYTHONPATH

Tymczasowo zmodyfikuj PYTHONPATH

ścieżka poniżej może być względna

PYTHONPATH=/path/to/dir python script.py
kon psych
źródło
0

import sys sys.path.append ('/ Users / {user} /Library/Python/3.7/lib/python/site-packages') import ta

shiva kumar
źródło
-1

Usuń pathlibi zainstaluj ponownie. Usuń pathlib w sitepackagesfolderze i ponownie zainstaluj pakiet pathlib za pomocą polecenia pip:

pip install pathlib
user3233042
źródło