2013-02-07 30 views
16

Khi một người cố gắng nhập mô-đun foo trong khi đang ở trong thư mục nguồn, người nhận được thông báo ImportError khá khó hiểu: ImportError: No module named foo.Bắt python 'ImportError' nếu nhập từ thư mục nguồn

Làm cách nào tôi có thể dễ dàng nắm bắt trường hợp này và trả lại một thông báo mang tính thông tin hơn, ví dụ: 'Xin vui lòng không tải module foo từ thư mục nguồn'?

__init__.py, tôi sẽ bắt đầu với:

try: 
    from _foo import * 
except ImportError: 
    ## check whether in the source directory... 

Vì vậy, tôi muốn phân biệt các nguyên nhân khác nhau cho một ImportError (ví dụ vì một module có tên foo không được cài đặt tại tất cả), và phát hiện các trường hợp trong đó setup.py nằm trong thư mục hiện tại. Điều gì sẽ là một cách thanh lịch để làm điều này?

Trả lời

22

ImportError: No module named foo thực sự có nghĩa là mô-đun foo.py hoặc gói foo/__init__.py không thể tìm thấy trong bất kỳ thư mục nào trong đường dẫn tìm kiếm (danh sách sys.path).

sys.path thường chứa . (thư mục hiện tại), đó có thể là ý của bạn là nằm trong thư mục nguồn. Bạn đang ở trong thư mục cấp cao nhất của gói foo (trong đó tệp __init__.py) nên rõ ràng bạn không thể tìm thấy foo/__init__.py.

Cuối cùng, bạn đã trả lời câu hỏi của riêng bạn, nhiều hơn hoặc ít hơn:

try: 
    from _foo import * 
except ImportError: 
    raise ImportError('<any message you want here>') 

Ngoài ra, bạn có thể kiểm tra các nội dung của sys.path, thư mục hiện hành và, nếu biết, thư mục gói mong đợi và tạo ra một thậm chí thông báo chi tiết và ngữ cảnh.

Hoặc thêm .. vào biến môi trường PYTHONPATH (trên Unix) để cho phép bạn chạy từ thư mục nguồn của mình. Thậm chí có thể làm việc trên Windows, nhưng tôi sẽ không biết.

+0

Cảm ơn câu trả lời nhanh. Tôi đang tìm kiếm một cách để kiểm tra xem 'ImportError' được nâng lên bởi' setup.py' được đặt trong thư mục hiện tại và phân biệt nó với các trường hợp khác. – Julian

+0

Vì vậy, hãy sử dụng tùy chọn thứ hai mà tôi đã đề cập. Bạn biết bạn đang cố gắng nhập gói nào (như một phương sách cuối cùng, trích xuất nó từ thông báo 'ImportError') và bạn có thể lấy tên thư mục hiện tại. Điều kiện bạn đang tìm kiếm tương ứng với gói và tên thư mục giống nhau, phải không? – isedev