Cách khắc phục lỗi “ImportError: No module name…” trong Python?


115

Cách chính xác để sửa lỗi ImportError này là gì?

Tôi có cấu trúc thư mục sau:

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

Và tôi đang ở trong danh bạ

/home/bodacydo/work/project

Bây giờ nếu tôi gõ

python ./programs/my_python_program.py

Tôi ngay lập tức nhận được

ImportError: No module named foo.tasks

Nội ./programs/my_python_program.pydung có dòng sau:

from foo.tasks import my_function

Tôi không thể hiểu tại sao python không tìm thấy ./foo/tasks.py- nó ở đó.

Nếu tôi làm điều đó từ trình bao Python, thì nó hoạt động:

python
>>> from foo.tasks import my_function

Nó chỉ không hoạt động nếu tôi gọi nó qua python ./programs/my_python_program.pyscript.

Câu trả lời:


121

Python không thêm thư mục hiện tại vào sys.pathmà thay vào đó là thư mục chứa tập lệnh. Thêm /home/bodacydo/work/projectvào một trong hai sys.pathhoặc $PYTHONPATH.


9
Vậy có ích lợi gì khi có init .py trong thư mục gốc? Nó dường như không có mục đích gì nếu bạn chỉnh sửa sys.path hoặc pythonpath.

11
@Editor: __init__.pychỉ cho biết rằng thư mục nên được coi như một gói, khi cha của nó nằm trong sys.pathhoặc chính nó là một gói.
Ignacio Vazquez-Abrams

3
Ngoài ra, hãy kiểm tra các quyền trên thư mục. Đó là vấn đề trong trường hợp của tôi.
SidJ

15
Để thêm dir hiện tại vào đường dẫn python, hãy sử dụngexport PYTHONPATH=`pwd`
rodorgas

1
Có gì làm việc cho tôi là để thêm vào $ PYTHONPATH thư mục cha của dự án, trong trường hợp của bạn sẽ là: /home/bodacydo/work... xem câu trả lời này
maledr53

33

Bạn có một tập tin được gọi __init__.pytrong thư mục foo? Nếu không thì python sẽ không nhận ra foo là một gói python.

Xem phần về các gói trong hướng dẫn python để biết thêm thông tin.


Cảm ơn và vâng, tôi đã có __init__.py. Vấn đề lần này là với $PYTHONPATH. Giải pháp của Ignacio đã phát huy tác dụng.
bodacydo

1
Các tệp .py init là bắt buộc để Python coi các thư mục là chứa các gói; điều này được thực hiện để ngăn các thư mục có tên chung, chẳng hạn như chuỗi, vô tình ẩn các mô-đun hợp lệ xảy ra sau này trên đường dẫn tìm kiếm mô-đun. Trong trường hợp đơn giản nhất, init py chỉ có thể là một tập tin rỗng
panofish

Cảm ơn vì đã cứu tôi một lúc nào đó.
cpu_meltdown

9

Đây là một giải pháp từng bước:

  1. Thêm một tập lệnh được gọi run.pyvào /home/bodacydo/work/projectvà chỉnh sửa nó như thế này:

    import programs.my_python_program
    programs.my_python_program.main()

    (thay thế main()bằng phương thức tương đương của bạn trong my_python_program.)

  2. Đi đến /home/bodacydo/work/project
  3. Chạy run.py

Giải thích: Vì python gắn vào PYTHONPATH đường dẫn của tập lệnh mà nó chạy , nên việc chạy run.pysẽ nối thêm /home/bodacydo/work/project. Và voilà , import foo.taskssẽ được tìm thấy.


8

Giải pháp ví dụ để thêm thư viện vào PYTHONPATH của bạn.

  1. Thêm dòng sau vào ~ / .bashrc của bạn hoặc chỉ cần chạy trực tiếp:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. Sau đó liên kết thư viện yêu cầu của bạn vào thư mục ~ / .python của bạn, ví dụ:

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

6

Cách khắc phục tốt hơn so với cài đặt PYTHONPATHlà sử dụngpython -m module.path

Điều này sẽ thiết lập chính xác sys.path[0]và là một cách đáng tin cậy hơn để thực thi các mô-đun.

Tôi có một writeup nhanh chóng về vấn đề này, như người trả lời khác đã đề cập đến lý do cho điều này là python path/to/file.pyputs path/totrên đầu PYTHONPATH( sys.path).


2

Trong tâm trí của tôi, tôi phải coi rằng foothư mục là một thư viện độc lập. Tôi có thể muốn xem xét việc di chuyển nó vào Lib\site-packagesthư mục trong cài đặt python. Tôi có thể muốn xem xét thêm một foo.pthtệp ở đó.

Tôi biết đó là một thư viện vì nó ./programs/my_python_program.pychứa dòng sau:

from foo.tasks import my_function

Vì vậy, nó không quan trọng đó ./programslà một thư mục anh chị em với ./foo. Thực tế là nó my_python_program.pyđược chạy như một tập lệnh như thế này:

python ./programs/my_python_program.py


0

Nếu bạn gặp sự cố này khi sử dụng phiên bản cài sẵn, khi sử dụng setup.py, hãy đảm bảo rằng mô-đun của bạn được bao gồm bên trongpackages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.