“ ImportError: ไม่มีโมดูลชื่อ” เมื่อพยายามเรียกใช้สคริปต์ Python


144

ฉันกำลังพยายามเรียกใช้สคริปต์ที่เปิดตัวในหมู่สิ่งอื่น ๆ สคริปต์หลาม ฉันได้รับ ImportError: ไม่มีโมดูลชื่อ ... แต่ถ้าฉันเรียกใช้ ipython และนำเข้าโมดูลเดียวกันด้วยวิธีเดียวกันผ่านล่ามก็จะยอมรับโมดูลนั้น

เกิดอะไรขึ้นและฉันจะแก้ไขได้อย่างไร ฉันพยายามเข้าใจว่าหลามใช้ PYTHONPATH อย่างไร แต่ฉันก็สับสนอย่างมาก ความช่วยเหลือใด ๆ ที่จะชื่นชมอย่างมาก


4
คุณต้องให้ข้อมูลเพิ่มเติม เมื่อคุณพูดว่า "run a script" คุณหมายถึง shell script หรือไม่ โมดูลใดที่คุณไม่สามารถนำเข้าได้ โมดูลนั้นอยู่ที่ไหน สคริปต์ของคุณอยู่ที่ไหน
BrenBarn

2
หากคุณต้องการคำตอบที่ชัดเจนสำหรับ "สิ่งที่เกิดขึ้น" ให้เริ่มต้นด้วย-vตัวเลือกของหลามและคุณจะเห็นว่าหลามอยู่ที่ไหน (หรือไม่) ในการค้นหาโมดูลที่คุณนำเข้า
FatalError

คุณพยายามนำเข้าอะไร สคริปต์ python สองตัวในไดเรกทอรีเดียวกันหรือไม่
pynovice

2
โปรดให้รหัสที่คุณใช้กับเราข้อความทั้งหมดของการติดตามสแต็กและขั้นตอนที่แน่นอนที่คุณใช้ในการสร้างข้อผิดพลาด มันค่อนข้างยากที่จะช่วยเหลือเมื่อเราไม่รู้ว่าปัญหาที่แท้จริงคืออะไร
MattDMo

5
ฉันคิดว่ามันเป็นปัญหาของผู้ใช้จำนวนมากประสบการณ์แม้กระทั่ง 4 ปีหลังจากคำถามถูกถามครั้งแรก
CodeOcelot

คำตอบ:


183

ปัญหานี้เกิดขึ้นเนื่องจากวิธีการที่ล่ามบรรทัดคำสั่ง IPython ใช้เส้นทางปัจจุบันของคุณเทียบกับวิธีการที่กระบวนการแยกต่างหากทำ ( ไม่ว่าจะเป็นโน้ตบุ๊ก IPython กระบวนการภายนอก ฯลฯ ) IPython จะค้นหาโมดูลที่จะนำเข้าที่ไม่เพียง แต่พบใน sys.path ของคุณ แต่ยังอยู่ในไดเรกทอรีการทำงานปัจจุบันของคุณ เมื่อเริ่มต้นล่ามจากบรรทัดคำสั่งไดเรกทอรีปัจจุบันที่คุณใช้อยู่นั้นเป็นไดเรกทอรีเดียวกับที่คุณเริ่มใช้ ipython หากคุณเรียกใช้

import os
os.getcwd() 

คุณจะเห็นว่านี่เป็นเรื่องจริง

อย่างไรก็ตามสมมติว่าคุณกำลังใช้สมุดบันทึก ipython ให้รันos.getcwd()และไดเรกทอรีการทำงานปัจจุบันของคุณแทนที่จะเป็นโฟลเดอร์ที่คุณบอกให้สมุดบันทึกทำงานในไฟล์ ipython_notebook_config.py ของคุณ (โดยทั่วไปจะใช้การc.NotebookManager.notebook_dirตั้งค่า)

วิธีการแก้ปัญหาคือการให้ล่ามหลามกับเส้นทางไปยังโมดูลของคุณ ทางออกที่ง่ายที่สุดคือการผนวกเส้นทางนั้นไปยังรายการ sys.path ของคุณ ในสมุดบันทึกของคุณลองแรก:

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

import module-of-interest

หากวิธีนี้ใช้ไม่ได้แสดงว่าคุณมีปัญหาที่แตกต่างจากมือของคุณที่ไม่เกี่ยวข้องกับเส้นทางสู่การนำเข้าและคุณควรให้ข้อมูลเพิ่มเติมเกี่ยวกับปัญหาของคุณ

วิธีที่ดีกว่า (และถาวรมากขึ้น) ในการแก้ปัญหานี้คือการตั้งค่าPYTHONPATHของคุณซึ่งจะให้ล่ามที่มีไดเรกทอรีเพิ่มเติมมองหาแพ็คเกจ / โมดูลหลาม การแก้ไขหรือการตั้งค่า PYTHONPATH เป็น var ทั่วโลกขึ้นอยู่กับระบบปฏิบัติการและมีการหารือในรายละเอียดที่นี่สำหรับUnixหรือของ Windows


1
PSA: ถ้าคุณได้มาถึงคำถาม SO นี้เพราะคุณได้รับข้อผิดพลาดใน jupyter โน้ตบุ๊คแล้วเห็นด้านล่างstackoverflow.com/a/27944947/127971 แต่น่าเสียดายที่คำถามคือไม่เพียงพอที่เฉพาะเจาะจงสำหรับคำตอบเดียว
ไมเคิล

@ ไมเคิลคำตอบนั้นเกี่ยวกับการนำเข้าโมดูล Python ในกรณีทั่วไป จำเป็นต้องใช้ไฟล์ dunder init.py เมื่อล่ามค้นหาไดเรกทอรีสำหรับโมดูลที่จะนำเข้าสมุดบันทึกหรือไม่ คำตอบข้างต้นเกี่ยวกับไดเรกทอรีทำงานของล่ามและการตั้งค่า PYTHONPATH นั้นถูกต้อง
BoltzmannBrain

ฉันบอกว่าจะมีคำตอบที่ถูกต้องหลายคำเนื่องจากถ้อยคำของคำถาม ฉันไม่ได้หมายความว่าคำตอบนี้ไม่ถูกต้อง แต่ถ้าใช้ jupyter-notebook คุณแค่แตะไฟล์__init_.pyใช่มั้ย ... และจะไม่ต้องการแก้ไขPYTHONPATHหรือโทรsys.path.appendแม้ว่าพวกเขาจะยังถูกต้อง (ถูกต้อง?) ฉันหมายถึงฉันมีไดเรกทอรีหลายสิบรายการที่มีโค้ดอยู่ในนั้นและฉันจะไม่เพิ่มพวกเขาทั้งหมดลงในพา ธ - หรือคาดว่าผู้ใช้รายอื่นจะเข้าสู่ไฟล์กำหนดค่า jupyter แม้ว่ามันจะเป็นไดเรกทอรีเดียวก็ตาม
ไมเคิล

16

เพียงสร้างไฟล์ไพ ธ อนที่ว่างเปล่าด้วยชื่อ__init__.pyภายใต้โฟลเดอร์ที่แสดงข้อผิดพลาดขณะที่คุณรันโปรเจ็กต์หลาม


1
โดย ' init.py ' คุณหมายถึง '_ init_ .py ' ใช่ไหม ฉันสร้าง _ init_ .pyเป็นไฟล์ว่างและมันใช้ได้กับฉัน ขอบคุณมาก. แต่ทำไมถึงจำเป็น ก่อนที่ฉันจะมีสคริปต์ไพ ธ อนในไดเรกทอรีเดียวกับโน๊ตบุ๊ก ipython ของฉันและการนำเข้าทำงานได้ดี
Eduardo Reis

3
อันที่จริงinit .py จะใช้เพื่อระบุว่าหลามเพื่อระบุว่ามีบางแพคเกจที่มีอยู่ในตำแหน่งที่สอดคล้องกันนั้น จากนั้นจะพบเฉพาะโมดูลย่อยที่คุณสร้างขึ้น หากคุณไม่ได้สร้าง ' init .py' หมายความว่า python ไม่ทราบว่ามีบางแพ็คเกจอยู่ ตัวอย่างเช่นจาก "Myfolder.Mypackage import Mymodules" สำหรับสิ่งนี้เช่นคุณควรเริ่มต้นinit .py เพื่อระบุว่า python บอกว่ามีแพ็คเกจอยู่ที่นี่ มิฉะนั้นก็ไม่รู้
Mohideen bin Mohammed

1
ใช่คำตอบที่สมบูรณ์แบบ จำเป็นต้องใช้ใน python 2.7 แต่ทราบใน 3
Agape Gal'lo

นี้แก้ไขปัญหาในหลาม 3 สำหรับฉัน
Rick สนับสนุนโมนิก้า

แก้ไขปัญหาสำหรับฉันเช่นกัน - การใช้โน๊ตบุ๊ค jupyter กับแหล่งหลามในไดเรกทอรีย่อยของไฟล์ ipynb; เช่นfoo.ipynbใช้bar/baz.pyเพิ่มbar/__init__.pyไฟล์เปล่าเพื่อให้สมุดบันทึกสามารถใช้from bar.baz import MyClass
michael

13

ตรวจสอบให้แน่ใจว่าทั้งคู่ใช้ล่ามเดียวกัน สิ่งนี้เกิดขึ้นกับฉันบน 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]

และ sys.pathแตกต่างกันระหว่างล่ามทั้งสอง เพื่อแก้ไขฉันลบ Python 3.3


ต้องใช้ miniconda เพื่อติดตั้งพวงของ python ที่เกี่ยวข้องฉันยังเจอปัญหานี้เหมือนกัน ubuntu python 2.7 ที่รวมมานั้นแตกต่างจาก miniconda python 2.7 คำตอบนี้อนุญาตให้ฉันแก้ไขปัญหา
bph

4
นี่คือปัญหาของฉัน ฉันได้อัพเกรดเป็น python 2.7.11 แต่เชลล์การโต้ตอบ iPython ของฉันยังคงใช้ 2.7.5 ฉันต้องการเรียกใช้pip install --upgrade ipythonเพื่อรับรุ่นล่าสุดจากนั้นจะใช้ 2.7.11 โดยอัตโนมัติตามค่าเริ่มต้น
Abundnce10

IPython ของฉันคือ 7.4.0 ในขณะที่ไม่มีรุ่น Python ดังกล่าวเลย
aderchox

@aderchox เรียกใช้สิ่งนี้ใน ipython เพื่อรับรุ่นล่าม:import sys; sys.version
z0r

7

สาเหตุหลักคือ sys.paths ของ Python และ IPython แตกต่างกัน

โปรดอ้างอิงถึงลิงค์ lucyparkการแก้ปัญหาทำงานในกรณีของฉัน มันเกิดขึ้นเมื่อติดตั้ง opencv โดย

conda install opencv

และได้รับข้อผิดพลาดในการนำเข้าใน iPython มีสามขั้นตอนในการแก้ไขปัญหานี้:

import cv2
ImportError: ...

1. ตรวจสอบพา ธ ใน Python และ iPython ด้วยคำสั่งดังต่อไปนี้

import sys
sys.path

คุณจะพบผลลัพธ์ที่แตกต่างจาก Python และ Jupyter ขั้นตอนที่สองเพียงใช้sys.path.append เพื่อแก้ไขเส้นทางที่ไม่ได้รับโดยลองและข้อผิดพลาด

2. การแก้ปัญหาชั่วคราว

ใน iPython:

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

ImportError:..ปัญหาแก้ไขได้

3. ทางออกถาวร

สร้างโปรไฟล์ iPython และตั้งค่าการต่อท้ายเริ่มต้น:

ใน bash shell:

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

ใน vi ต่อท้ายไฟล์:

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

DONE


'โปรไฟล์ ipython สร้าง' .... ใช่! นี่เป็นทางออกเดียว (ถาวร) ที่แก้ปัญหาสมุดบันทึก jupyter ที่ไม่ได้อ่านจากสภาพแวดล้อม PATH และ PYTHONPATH ... โดยไม่ต้องใช้คำสั่ง sys.path ที่ยุ่งเหยิงในตอนเริ่มต้นของทุกไฟล์ (yuk) ขอบคุณ @jesse
JohnL_10

6

การsys.path.append('my-path-to-module-folder')ทำงานจะทำงานได้ แต่เพื่อหลีกเลี่ยงการทำเช่นนี้ใน IPython ทุกครั้งที่คุณต้องการใช้โมดูลคุณสามารถเพิ่มไฟล์export PYTHONPATH="my-path-to-module-folder:$PYTHONPATH"ของคุณ~/.bash_profileได้


2

ก่อนการติดตั้ง ipython ฉันติดตั้งโมดูลผ่าน easy_install sudo easy_install mechanizeพูด

หลังจากติดตั้ง ipython ฉันต้องเรียกใช้ easy_install อีกครั้งเพื่อให้ ipython จดจำโมดูล



2

หากคุณใช้งานจากบรรทัดคำสั่งบางครั้งตัวแปลภาษาไพ ธ อนจะไม่ทราบเส้นทางที่จะค้นหาโมดูล

ด้านล่างเป็นโครงสร้างไดเรกทอรีของโครงการของฉัน:

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

ฉันใช้คำสั่งด้านล่าง:

>> cd project

>> python tests/my_test.py

หลังจากใช้คำสั่งข้างต้นฉันได้รับข้อผิดพลาดด้านล่าง

no module named lib

lib ถูกนำเข้าใน my_test.py

ฉันพิมพ์ sys.path และหาเส้นทางของโครงการที่ฉันกำลังทำงานอยู่นั้นไม่สามารถใช้ได้ในรายการ sys.path

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)

ฉันไม่แน่ใจว่ามันเป็นวิธีที่ดีในการแก้ไข แต่ใช่ว่ามันได้ผลสำหรับฉัน


สิ่งนี้จะใช้งานได้หากคุณเรียกใช้สคริปต์จากตำแหน่งเดิมเสมอ มิฉะนั้นคุณจะพบปัญหานับตั้งแต่os.getcwd()รับไดเรกทอรีที่สคริปต์ทำงานไม่ใช่ไดเรกทอรีที่ไฟล์สคริปต์ใช้งานอยู่
Nathan Arthur

1

นี่คือวิธีที่ฉันแก้ไขมัน:

import os
import sys
module_path = os.path.abspath(os.getcwd() + '\\..')
if module_path not in sys.path:
    sys.path.append(module_path)

1

ฉันพบว่าวิธีแก้ไขปัญหานี้ได้รับการบันทึกอย่างกว้างขวางที่นี่:

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

โดยทั่วไปคุณต้องติดตั้งแพ็กเกจภายในสภาพแวดล้อม Jupyter โดยใช้คำสั่งเชลล์เช่น:

!{sys.executable} -m pip install numpy

โปรดตรวจสอบลิงก์ด้านบนเพื่อดูคำตอบเต็มที่เชื่อถือได้


0

ฉันพบแหล่งอื่นของความคลาดเคลื่อนนี้:

ฉันมี ipython ติดตั้งทั้งในเครื่องและโดยทั่วไปใน virtualenvs ปัญหาของฉันคือว่าใน virtualenv ที่สร้างขึ้นใหม่กับ ipython ระบบ ipython ถูกเลือกขึ้นซึ่งเป็นรุ่นที่แตกต่างจาก python และ ipython ใน virtualenv (2.7.x เทียบกับ 3.5.x) และเกิดความฮือฮา

ฉันคิดว่าสิ่งที่ชาญฉลาดที่ต้องทำเมื่อใดก็ตามที่ติดตั้งสิ่งที่จะมีไบนารีอยู่ในyourvirtualenv/binนั้นคือการทำงานในทันทีrehashหรือคล้ายกับเชลล์ที่คุณใช้งานอยู่ (ต้องตรวจสอบว่ามีpipตะขอหลังการติดตั้งที่เหมาะสม... )


0

โซลูชันที่ไม่มีสคริปต์:

  1. เปิด Spyder -> เครื่องมือ -> ตัวจัดการ PYTHONPATH
  2. เพิ่มเส้นทางของ Python โดยคลิกที่ "เพิ่มเส้นทาง" เช่น: 'C: \ Users \ User \ AppData \ Local \ Programs \ Python \ Python37 \ Lib \ site-packages'
  3. คลิก "ซิงโครไนซ์ ... " เพื่อให้โปรแกรมอื่น ๆ (เช่น Jupyter Notebook) ใช้ pythonpaths ที่ตั้งค่าในขั้นตอนที่ 2
  4. รีสตาร์ท Jupyter ถ้าเปิดอยู่

0

อาจเกิดจากงูหลามรุ่นอื่นที่ติดตั้งบนระบบของคุณเช่นpython2หรือpython3 python3

เรียกใช้คำสั่ง$ pip --versionและ$ pip3 --versionการตรวจสอบซึ่งpipจากที่งูหลาม 3x เช่นคุณควรเห็นข้อมูลรุ่นดังด้านล่าง:

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

จากนั้นเรียกใช้example.pyสคริปต์ด้วยคำสั่งด้านล่าง

$ python3 example.py

0

utilsที่เกิดขึ้นกับฉันด้วยไดเรกทอรี ฉันพยายามนำเข้าไดเรกทอรีนี้เป็น:

from utils import somefile

utilsเป็นแพ็กเกจในไพ ธ อนแล้ว เพียงแค่เปลี่ยนชื่อไดเรกทอรีของคุณเป็นชื่ออื่นและมันก็ใช้ได้ดี


0

ข้อผิดพลาดชนิดนี้เกิดขึ้นส่วนใหญ่อาจเกิดจากข้อผิดพลาดของเวอร์ชันหลาม ตัวอย่างเช่นหากแอปพลิเคชันของคุณทำงานบน python 3 เท่านั้นและคุณได้ python 2 ด้วยเช่นกันคุณควรระบุเวอร์ชันที่จะใช้ ตัวอย่างการใช้งาน

python3 .....

แทน

python

0

คำตอบนี้ใช้กับคำถามนี้ถ้า

  1. คุณไม่ต้องการเปลี่ยนรหัสของคุณ
  2. คุณไม่ต้องการเปลี่ยน PYTHONPATH อย่างถาวร

แก้ไข PYTHONPATH ชั่วคราว

เส้นทางด้านล่างสามารถเป็นญาติ

PYTHONPATH=/path/to/dir python script.py


-1

ลบpathlibและติดตั้งใหม่ ลบ pathlib ในsitepackagesโฟลเดอร์และติดตั้งแพ็คเกจ pathlib โดยใช้คำสั่ง pip:

pip install pathlib
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.