Nhập lỗi trong Python

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ổ sung

Là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
9

Bướ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 3

Bướ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
2

hoặ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 đối

Trong 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
8

Cá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
9

Mặ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
0

Cá 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
9

Trong 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ứ hai

Nế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
    ├── mypackage
    │ ├── a.py
    └── anotherpackage
    ├── b.py
    ├── c.py
    └── mysubpackage
    └── d.py
    28

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
1

và 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ốt

Phần kết luận

Nế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

Lỗi nào xảy ra khi nhập một mô-đun Python không xác định?

Lỗi ModuleNotFound xuất hiện khi Python không thể nhập thành công mô-đun.

Tại sao Python không thể tìm thấy lần nhập của tôi?

Điều này là do phiên bản Python mà bạn đang chạy tập lệnh không được định cấu hình để tìm kiếm các mô-đun mà bạn đã cài đặt chúng. This happens when you use the wrong installation of pip to install packages.

nhập trong ví dụ Python là gì?

Mã Python trong một mô-đun có quyền truy cập vào mã trong một mô-đun khác bằng quá trình nhập mã đó . Câu lệnh nhập khẩu là cách phổ biến nhất để gọi máy móc nhập khẩu, nhưng nó không phải là cách duy nhất. Các chức năng như importlib.

Làm cách nào để giải quyết lỗi nhập trong Django?

Để khắc phục, bạn chạy cmd-shift-p (hoặc click View -> Command Palette và chạy lệnh Python. Chọn Phiên dịch viên. VS Code sẽ hiển thị cho bạn danh sách các trình thông dịch Python được tìm thấy. Chọn một cái tương ứng với môi trường ảo của bạn, trong trường hợp này là tùy chọn cuối cùng. Lỗi sẽ biến mất