2010-02-24 100 views
77

Cách chính xác để khắc phục lỗi ImportError này là gì?Cách khắc phục lỗi "ImportError: No module named ..." trong Python?

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 trong thư mục

/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 có được

ImportError: No module named foo.tasks 

Các ./programs/my_python_program.py chứa các dòng sau:

from foo.tasks import my_function 

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

Nếu tôi làm điều đó từ vỏ Python, sau đó 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.py kịch bản.

Trả lời

81

Python không thêm thư mục hiện hành để sys.path, mà đúng hơn là thư mục mà kịch bản đang ở trong. Thêm /home/bodacydo/work/project hoặc là sys.path hoặc $PYTHONPATH.

+1

Vì vậy, sau đó làm thế nào để có __init__.py trong thư mục gốc? Nó dường như không phục vụ mục đích gì nếu bạn chỉnh sửa sys.path hoặc pythonpath. –

+7

@Editor: '__init __. Py' chỉ cho biết thư mục nên được coi là một gói, khi cha mẹ của nó nằm trong' sys.path' hoặc chính nó là một gói. –

+1

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

31

Bạn có tệp có tên là __init__.py trong thư mục foo không? Nếu không thì python sẽ không nhận ra foo như là một gói python.

Xem section on packages trong hướng dẫn trăn để biết thêm thông tin.

+0

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 đã hoạt động. – bodacydo

+1

Các tập tin __init__.py được yêu cầu để làm cho Python xử lý các thư mục 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, từ 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 rỗng – panofish

+0

Cảm ơn bạn đã tiết kiệm cho tôi đôi khi. –

2

Trong suy nghĩ của tôi, tôi phải xem xét rằng thư mục foo là thư viện độc lập. Tôi có thể muốn xem xét di chuyển nó vào thư mục Lib\site-packages trong một cài đặt python. Tôi có thể muốn xem xét thêm một tệp foo.pth tại đó.

Tôi biết đó là một thư viện kể từ khi ./programs/my_python_program.py chứa các dòng sau:

from foo.tasks import my_function

Vì vậy, nó không quan trọng mà ./programs là một thư mục anh chị em để ./foo. Đó là một thực tế rằng my_python_program.py được chạy như một kịch bản như thế này:

python ./programs/my_python_program.py

7

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

  1. Thêm một kịch bản gọi là run.py trong /home/bodacydo/work/project và 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 pháp tương đương của bạn trong my_python_program.)

  2. Đến /home/bodacydo/work/project
  3. Run run.py

Giải thích: Từ trăn gắn thêm để PYTHONPATH con đường kịch bản từ đó nó chạy, chạy run.py sẽ nối /home/bodacydo/work/project. Và voilà, import foo.tasks sẽ được tìm thấy.

7

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

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

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

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

Một sửa chữa tốt hơn so với thiết PYTHONPATH là sử dụng python -m module.path

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

Tôi có một quick writeup 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.py đặt path/to trên đầu PYTHONPATH (sys.path).

Các vấn đề liên quan