01/10/2018, 00:23

Import từ một package khác trong Python

Giả sử mình có cấu trúc thư mục như này:

MyProj/
    scripts/
        __init__.py
        file1.py
    tests/
        __init__.py
        file2.py

Câu hỏi là làm sao để import được file1 vào file2?
Mình đã thử viết thế này trong file2 nhưng không hoạt động:

import MyProj.scripts.file1

Nó báo lỗi không tìm thấy module tên là MyProj

Pham Van Hai viết 02:36 ngày 01/10/2018

Bạn thử tạo thêm file __init__.py trong thư mục MyProj xem có đc ko?

Thành Phạm viết 02:31 ngày 01/10/2018

Để thoải mái hơn về cái tên thư mục root thì bạn có thể dùng kiểu này:

http://stackoverflow.com/questions/279237/import-a-module-from-a-relative-path

Ví dụ áp dụng trong project thực tế:

https://github.com/rg3/youtube-dl/blob/master/test/test_download.py

Người ta cũng dùng cái này:

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

Để import hàm vào trong test

Nhưng mà nếu không cần thiết thì để flat cho đơn giản

Lương Quang Mạnh viết 02:37 ngày 01/10/2018

Thực tình thì đây là Python project đầu tiên của mình. Công nhận là có quá nhiều vấn đề phát sinh mà trước đây, với những script con con chả bao giờ phải suy nghĩ .

Bạn thử tạo thêm file init.py trong thư mục MyProj xem có đc ko?

Tại vì file2.py nó đã không thể lần ngược về parent directory nên có vẻ cách này không khả quan lắm. Import subdirectories thì lúc nào cũng dễ hơn .

Để thoải mái hơn về cái tên thư mục root thì bạn có thể dùng kiểu này:

http://stackoverflow.com/questions/279237/import-a-module-from-a-relative-path

Ví dụ áp dụng trong project thực tế:

https://github.com/rg3/youtube-dl/blob/master/test/test_download.py

Người ta cũng dùng cái này:

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

Để import hàm vào trong test

Chắc là phải dùng cách này thôi . Dù mình muốn hạn chế tối đa việc động đến paths phức tạp.

Nhưng mà nếu không cần thiết thì để flat cho đơn giản

Mình cũng chả thích thú gì đâu. Nhưng xem qua nhiều projects trên Github thì người ta cũng toàn phân chia thành một số thư mục con mà. Ngoài cùng toàn những files kiểu kiểu setup.py, .gitignore, README.md,…

Khoa NTA viết 02:23 ngày 01/10/2018

Theo mình nghĩ là người ta phân chia như vậy để dễ nhìn, dễ quản lý. Người khác nhìn vào biết files nào là chính hay phụ (theo cấp). Có thể bạn không cần phải sử dụng kiểu đó nhưng bạn cũng nên thử một lần để sau này có đọc code của người khác cũng dễ hiểu hơn :3

Lương Quang Mạnh viết 02:28 ngày 01/10/2018

Ừ thì mình đang cố đây, nhưng nói chung là cực kì rắc rối

Thành Phạm viết 02:36 ngày 01/10/2018

Mình cũng chả thích thú gì đâu. Nhưng xem qua nhiều projects trên Github thì người ta cũng toàn phân chia thành một số thư mục con mà. Ngoài cùng toàn những files kiểu kiểu setup.py, .gitignore, README.md,…

Có nhiều project họ dùng 1 cái lib gì đó để test => không cần chèn cái dòng kia vào , tất nhiên như vậy bạn sẽ không thể chạy test trực tiếp bằng cách python test_abcd.py được.

Cách phân chia các thư mục con như nào bạn xem ở đây xem
https://learnpythonthehardway.org/book/ex46.html
http://docs.python-guide.org/en/latest/writing/structure/

Lương Quang Mạnh viết 02:36 ngày 01/10/2018

Mình mới biết dùng unittest thôi, còn cái ví dụ trong cái link đầu tiên của bác thì hình như người ta dùng thư viện nose thì phải?

Bài liên quan
0