Nhập mô-đun chắc chắn có thể làm mọi người thất vọng và đặc biệt là những người khá mới với Python. Vì tôi liên tục thấy các câu hỏi có liên quan trên StackOverflow hàng ngày, nên tôi quyết định viết một bài báo ở đây trên Medium để thử và mô tả cách thức hoạt động của tính năng nhập đằng sau hậu trường và cách tiếp cận bạn cần tuân theo để cuộc sống của bạn dễ dàng hơn
Thuật ngữTrước tiên, hãy bắt đầu bằng cách xác định một số thuật ngữ hữu ích sẽ giúp bạn hiểu các khái niệm được mô tả trong bài viết này
- Mô-đun python là một tệp duy nhất có. phần mở rộng py
- Gói python là một thư mục chứa ít nhất một mô-đun python. Đối với python2, một gói yêu cầu __init__. tập tin py
- Một gói python có thể chứa bất kỳ số lượng gói con lồng nhau nào, tôi. e. các gói chứa các gói khác trong hệ thống phân cấp của cấu trúc dự án
- nhập khẩu rất hữu ích khi một mô-đun cần sử dụng một số chức năng [e. g. một chức năng hoặc một lớp] được viết trong một mô-đun khác [của gói hoặc gói con giống hoặc khác]
Ví dụ, xem xét cấu trúc dự án sau
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
Dự án
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
5 chứa hai gói, └── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
6 và └── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
7, mỗi gói chứa một số mô-đun python, trong khi gói thứ hai cũng chứa một gói phụ có tên là └── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
8, gói này lần lượt chứa một mô-đun python bổ sungLàm thế nào để nhập mô-đun hoạt động đằng sau hậu trường?Bây giờ, giả sử rằng trong mô-đun hiện tại của bạn, bạn muốn nhập một mô-đun khác như hình bên dưới
import a
Python sẽ thực thi câu lệnh trên theo hai bước
- Xác định vị trí, tải và khởi tạo [nếu cần] mô-đun được yêu cầu
- Xác định các tên cần thiết trong không gian tên cục bộ và phạm vi tương ứng
Bây giờ trình thông dịch Python sẽ làm theo các bước tiếp theo trong nỗ lực giải quyết
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
9Bước 1. hệ thống. tra cứu mô-đun
Ban đầu, Python sẽ cố gắng tìm kiếm tên của mô-đun trong ______50 , đây là một từ điển ánh xạ tên mô-đun tới các mô-đun đã được tải. Nếu tên được giải quyết thành công [có nghĩa là một mô-đun khác đã tải nó] thì nó sẽ được cung cấp cho không gian tên cục bộ, nếu không, hãy chuyển sang bước 2
Bước 2. Tra cứu thư viện chuẩn Python
Thư viện chuẩn Python chứa các mô-đun tích hợp [được viết bằng C] cung cấp quyền truy cập vào chức năng hệ thống, chẳng hạn như tệp I/O mà các lập trình viên Python không thể truy cập được, cũng như các mô-đun được viết bằng Python cung cấp các giải pháp được tiêu chuẩn hóa cho nhiều sự cố xảy ra . Một số mô-đun này được thiết kế rõ ràng để khuyến khích và nâng cao tính di động của các chương trình Python bằng cách trừu tượng hóa các đặc điểm cụ thể của nền tảng thành các API trung lập với nền tảng
Nếu không tìm thấy tên trong
import a
1 thì Python sẽ tìm kiếm nó trong Thư viện chuẩn Python. Một lần nữa, nếu tên được giải quyết thì nó sẽ được xác định trong không gian tên cục bộ nếu không cần phải tuân theo bước 3Bước 3. hệ thống. tra cứu đường dẫn
Bây giờ nếu tên của mô-đun không được tìm thấy trong
import a
1 cũng như trong thư viện tiêu chuẩn, Python cuối cùng sẽ cố gắng giải quyết nó trong import a
3. Và đây là điểm mà mọi thứ chắc chắn có thể đi sai hướng. Tôi tin rằng hầu hết các chương trình Python đều khá quen thuộc với import a
4└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
2hoặc
import a
5└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
4 Nhập khẩu tuyệt đối so với nhập khẩu tương đốiTrong nhập khẩu tuyệt đối, chúng tôi chỉ định đường dẫn rõ ràng bắt đầu từ thư mục gốc của dự án. trong ví dụ của chúng tôi
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
điều này có nghĩa là nếu chúng tôi muốn nhập mô-đun
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
9 trong mô-đun import a
7, chúng tôi sẽ phải chỉ định└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
8Các ví dụ hợp lệ khác là các lần nhập sau
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
9Mặt khác, bây giờ, trong các lần nhập tương đối, chúng tôi chỉ định đường dẫn đến mô-đun tương ứng với vị trí của mô-đun hiện tại. Một vài ví dụ trong ví dụ của chúng tôi có thể là
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
0Cá nhân tôi không khuyến khích việc sử dụng nhập tương đối vì chúng không dễ đọc như nhập tuyệt đối và PEP-8 cũng đề xuất như vậy. Trong một số trường hợp hiếm hoi, bạn có thể phải sử dụng nhập tương đối để tránh các đường dẫn dài không cần thiết. Ví dụ,
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
1Làm cách nào để sửa lỗi ModuleNotFoundError và ImportError?Bây giờ chúng ta đã nắm bắt được cách thực thi câu lệnh nhập cơ bản và sự khác biệt giữa nhập tuyệt đối và tương đối là gì, bây giờ chúng ta có thể tiếp tục và thảo luận về những việc cần làm khi ứng dụng Python của bạn bị lỗi với
import a
8 hoặc import a
9Trong hầu hết các trường hợp, một trong hai lỗi xảy ra do Python không thể giải quyết tên của mô-đun trong
import a
3. Nhớ lại rằng khi bạn gọi └── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
21 nếu tên của mô-đun không được tìm thấy trong import a
1 cũng như trong thư viện chuẩn, Python sẽ cố gắng giải quyết nó trong import a
3. Tương tự như vậy, khi bạn sử dụng cú pháp └── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
24 [e. g. └── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
25 ], trước tiên Python sẽ cố gắng tìm và tải mô-đun. Khi không làm như vậy, Python sẽ ném import a
8 cho trường hợp đầu tiên hoặc import a
9 cho trường hợp thứ haiNếu đúng như vậy và nhớ lại ví dụ của chúng tôi bên dưới,
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
- trước tiên hãy đảm bảo rằng bạn đang sử dụng nhập khẩu tuyệt đối
- xuất thư mục gốc của dự án sang
└── myproject
28
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
Hầu hết các IDE Python hiện đại sẽ tự động thực hiện thủ thuật nhưng nếu không phải như vậy, tôi khá chắc chắn rằng sẽ có tùy chọn như vậy để bạn có thể xác định
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
2 cho ứng dụng Python của mình [ít nhất là PyCharm]Nếu bạn đang chạy ứng dụng Python của mình trong bất kỳ môi trường nào khác, chẳng hạn như Docker, Vagrant hoặc bên trong môi trường virutal của bạn, bạn có thể chạy lệnh dưới đây trong bash của mình
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
1và bây giờ vì thư mục gốc của dự án của bạn đã được thêm vào
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
2, quá trình nhập tuyệt đối của bạn sẽ hoạt động như một bùa mê└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
41 cũng có thể thực hiện thủ thuật này, nhưng đó chắc chắn không phải là một cách làm tốtPhần kết luậnNếu bạn chưa quen với Python, việc nhập mô-đun có thể trở thành cơn ác mộng, đặc biệt nếu bạn cần xử lý cấu trúc dự án phức tạp. Nếu bạn tuân theo quy tắc hai bước — tôi. e sử dụng nhập tuyệt đối và nối thêm thư mục gốc của dự án vào PYTHONPATH — khi đó bạn không cần thực sự lo lắng về việc nhập mô-đun trong tương lai
Nếu bạn chưa quen với Python, tôi thực sự khuyên bạn nên lấy một cuốn sách Học Python trên Amazon
Trở thành thành viên và đọc mọi câu chuyện trên Medium. Phí thành viên của bạn hỗ trợ trực tiếp cho tôi và các nhà văn khác mà bạn đọc. Bạn cũng sẽ có toàn quyền truy cập vào mọi câu chuyện trên Phương tiện