วิธีแก้ไขข้อผิดพลาด“ ImportError: No module named …” ใน Python


115

วิธีที่ถูกต้องในการแก้ไขข้อผิดพลาด ImportError นี้คืออะไร?

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

/home/bodacydo
/home/bodacydo/work
/home/bodacydo/work/project
/home/bodacydo/work/project/programs
/home/bodacydo/work/project/foo

และฉันอยู่ในไดเร็กทอรี

/home/bodacydo/work/project

ตอนนี้ถ้าฉันพิมพ์

python ./programs/my_python_program.py

ฉันได้รับทันที

ImportError: No module named foo.tasks

./programs/my_python_program.pyมีบรรทัดต่อไปนี้:

from foo.tasks import my_function

ฉันไม่เข้าใจว่าทำไม python ไม่พบ./foo/tasks.pyมันอยู่ที่นั่น

ถ้าฉันทำจาก Python shell มันก็ใช้ได้:

python
>>> from foo.tasks import my_function

มันใช้ไม่ได้ถ้าฉันเรียกมันผ่านpython ./programs/my_python_program.pyสคริปต์

คำตอบ:


121

งูหลามไม่เพิ่มไดเรกทอรีปัจจุบันไปsys.pathแต่ไดเรกทอรีที่สคริปต์ที่อยู่ใน. เพิ่ม/home/bodacydo/work/projectอย่างใดอย่างหนึ่งหรือsys.path$PYTHONPATH


9
แล้วจุดเริ่มต้นของการมีinit. py ในโฟลเดอร์รูทคืออะไร? ดูเหมือนว่าจะไม่มีจุดประสงค์ใด ๆ หากคุณแก้ไข sys.path หรือ pythonpath

11
@Editor: __init__.pyระบุว่าไดเร็กทอรีควรถือเป็นแพ็กเกจเมื่อพาเรนต์อยู่ในsys.pathหรือเป็นแพ็กเกจ
Ignacio Vazquez-Abrams

3
นอกจากนี้ตรวจสอบสิทธิ์ในโฟลเดอร์ นั่นคือปัญหาในกรณีของฉัน
SidJ

15
หากต้องการเพิ่ม dir ปัจจุบันไปยัง python path ให้ใช้export PYTHONPATH=`pwd`
rodorgas

1
สิ่งที่ได้ผลสำหรับฉันคือการเพิ่ม $ PYTHONPATH ในไดเรกทอรีหลักของโครงการในกรณีของคุณจะเป็น: /home/bodacydo/work... ดูคำตอบนี้
maledr53

33

คุณมีไฟล์ที่เรียก__init__.pyในไดเร็กทอรี foo หรือไม่? ถ้าไม่เช่นนั้น python จะไม่รู้จัก foo เป็นแพ็คเกจ python

ดูหัวข้อแพ็คเกจในบทช่วยสอน python สำหรับข้อมูลเพิ่มเติม


__init__.pyขอขอบคุณและใช่ฉันมี $PYTHONPATHปัญหาที่เกิดขึ้นในครั้งนี้เป็นไปด้วยความ โซลูชันของอิกนาซิโอได้ผล
bodacydo

1
initไฟล์ .py จะต้องทำให้งูหลามรักษาไดเรกทอรีที่เป็นแพคเกจที่มี; สิ่งนี้ทำเพื่อป้องกันไม่ให้ไดเร็กทอรีที่มีชื่อสามัญเช่นสตริงจากการซ่อนโมดูลที่ถูกต้องโดยไม่ได้ตั้งใจซึ่งเกิดขึ้นในภายหลังบนพา ธ การค้นหาโมดูล ในกรณีที่ง่ายที่สุดinit. py อาจเป็นไฟล์เปล่า
panofish

ขอบคุณที่ช่วยฉันในบางครั้ง
cpu_meltdown

9

นี่คือวิธีแก้ปัญหาทีละขั้นตอน:

  1. เพิ่มสคริปต์ที่เรียกrun.pyเข้า/home/bodacydo/work/projectและแก้ไขดังนี้:

    import programs.my_python_program
    programs.my_python_program.main()

    (แทนที่main()ด้วยวิธีการเทียบเท่าของคุณในmy_python_program)

  2. ไปที่ /home/bodacydo/work/project
  3. วิ่ง run.py

คำอธิบาย: ตั้งแต่หลามท้าย PYTHONPATH เส้นทางของสคริปต์จากที่ที่มันวิ่งวิ่งจะผนวกrun.py /home/bodacydo/work/projectและVoila , import foo.tasksจะพบ


8

ตัวอย่างวิธีการเพิ่มไลบรารีใน PYTHONPATH ของคุณ

  1. เพิ่มบรรทัดต่อไปนี้ใน ~ / .bashrc ของคุณหรือเรียกใช้โดยตรง:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. จากนั้นเชื่อมโยงไลบรารีที่คุณต้องการเข้ากับโฟลเดอร์ ~ / .python ของคุณเช่น

    ln -s /home/user/work/project/foo ~/.python/

6

การแก้ไขที่ดีกว่าการตั้งค่าPYTHONPATHคือการใช้python -m module.path

สิ่งนี้จะตั้งค่าได้อย่างถูกต้องsys.path[0]และเป็นวิธีที่เชื่อถือได้มากขึ้นในการเรียกใช้โมดูล

ฉันมีเขียนขึ้นอย่างรวดเร็วเกี่ยวกับปัญหานี้เป็น answerers อื่น ๆ ได้กล่าวถึงเหตุผลที่เป็นเช่นนี้ก็python path/to/file.pyทำให้path/toในจุดเริ่มต้นของPYTHONPATH( sys.path)


2

ในใจของฉันฉันต้องพิจารณาว่าfooโฟลเดอร์นั้นเป็นไลบรารีแบบสแตนด์อะโลน ฉันอาจต้องการพิจารณาย้ายไปยังLib\site-packagesโฟลเดอร์ภายในการติดตั้ง python ฉันอาจต้องการพิจารณาเพิ่มfoo.pthไฟล์ที่นั่น

ฉันรู้ว่าเป็นห้องสมุดเนื่องจาก./programs/my_python_program.pyมีบรรทัดต่อไปนี้:

from foo.tasks import my_function

ดังนั้นมันไม่สำคัญว่าเป็นโฟลเดอร์ที่พี่น้องไป./programs ./fooเป็นความจริงที่my_python_program.pyเรียกใช้เป็นสคริปต์ดังนี้:

python ./programs/my_python_program.py


0

หากคุณมีปัญหานี้เมื่อใช้เวอร์ชันที่ติดตั้งเมื่อใช้setup.pyงานตรวจสอบให้แน่ใจว่าโมดูลของคุณรวมอยู่ภายในpackages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.