Hướng dẫn is not a package python - không phải là một gói python

Tôi đã xem xét vấn đề này, và mặc dù nó không chính xác là cùng một lỗi mà tôi gặp phải, nhưng nó đã giúp tôi giải quyết nó. Tôi sẽ giải thích tình huống tôi có, vì tôi nghĩ một số người dùng có thể thấy điều này tiện dụng. Vì vậy, tôi đã nhận được nhật ký lỗi sau:

    Traceback (most recent call last):
  File "/home/kemal/Programming/Python/Preference_Articulation/LocalSearch/LS_apriori.py", line 1, in 
    from LocalSearch.LocalSearch import LocalSearch
ModuleNotFoundError: No module named 'LocalSearch.LocalSearch'; 'LocalSearch' is not a package

Cấu trúc của dự án của tôi là như sau (sử dụng pycharm): Chế độ xem cấu trúc dự án

Điều quan trọng cần chú ý là tôi đã tách mã của mình thành một số thư mục, vì nó làm cho nó dễ đọc hơn. Bây giờ, trong thư mục có tên LocalSearch, tôi có 4 tệp, LocalSearch, LS_APRIORI và một số tệp thử nghiệm (không liên quan). Khi cố gắng chạy tệp ls_apriori (sử dụng các phương thức và lớp từ tệp localsearch), tôi đã nhận được lỗi được cung cấp ở trên. Mã cụ thể không quan trọng và cách tôi xử lý nhập khẩu là như sau:LocalSearch I have 4 files, LocalSearch, LS_apriori and some 2 tests files (not relevant). When trying to run the file LS_apriori (which uses methods and classes from file LocalSearch) I was getting the error provided above. The code specifically is not important, and the way I handled the imports was the following:

from LocalSearch.LocalSearch import LocalSearch

Việc sửa chữa rất đơn giản. Tôi đã đổi tên PY-File LocalSearch thành Local_Search (chỉ cần thêm một dấu gạch dưới). Sau đó, lỗi đã biến mất.LocalSearch to Local_Search (just added an underscore). Afterwards, the error was gone.

Vì vậy, vấn đề của tôi là sở hữu một thư mục (gói) có cùng tên với một tệp (mô -đun) bên trong nó, có một lớp bên trong nó có cùng tên. Python không thích điều đó. Có các mô -đun có cùng tên với các gói bên trong chúng là tốt, tuy nhiên tôi đoán lớp chỉ thêm sự nhầm lẫn.

Cách sửa lỗi ModulenotFounderror và nhà nhập khẩu

Thực hiện nhập khẩu mô -đun thích hợp và làm cho cuộc sống của bạn dễ dàng hơn

Ảnh của Leone Venter trên unplash.com

tl;dr

  • Sử dụng nhập khẩu tuyệt đốiabsolute imports
  • Chuẩn bị thư mục gốc của dự án của bạn vào
    from LocalSearch.LocalSearch import LocalSearch
    
    4 - trong bất kỳ môi trường nào bạn muốn chạy ứng dụng Python của mình như Docker, Vagrant hoặc môi trường ảo của bạn, tức là trong Bin/Active, Run (hoặc ví dụ: Thêm vào
    from LocalSearch.LocalSearch import LocalSearch
    
    5 trong trường hợp bạn đang sử dụng ảo :
    from LocalSearch.LocalSearch import LocalSearch
    
    4 — In any environment you wish to run your Python application such as Docker, vagrant or your virtual environment i.e. in bin/activate, run (or e.g. add to
    from LocalSearch.LocalSearch import LocalSearch
    
    5 in case you are using virtualenv) the below command:
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
  • *Tránh sử dụng
    from LocalSearch.LocalSearch import LocalSearch
    
    6

Nhập khẩu 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 đối với Python. Vì tôi tiếp tục thấy các câu hỏi liên quan trên Stackoverflow hàng ngày, tôi quyết định viết một bài viết ở đây trên phương tiện để thử và mô tả cách nhập hoạt động đằng sau hậu trường và cách tiếp cận bạn cần làm theo để thực hiện cuộc sống của bạn dễ dàng hơn.

Thuật ngữ

Đầu 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ột pythonmodule là một tệp duy nhất có phần mở rộng .py.python module is a single file with a .py extension.
  • Pythonpackage 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 tệp __init__.pypython package is a folder that contains at least one python module. For python2, a package requires a __init__.py file
  • Gói Python có thể chứa bất kỳ số lượng gói phụ lồng nhau nào, tức là các gói có chứa các gói khác xuống phân cấp của cấu trúc dự án.sub-packages, i.e. packages that contain other packages down the hierarchy of the project structure.
  • 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 (ví dụ: hàm hoặc lớp) được viết trong một mô-đun khác (cùng hoặc một gói hoặc gói phụ khác) are useful when a module needs to use some piece of functionality (e.g. a function or a class) written in another module (of the same or a different package or sub-package)

Ví dụ, hãy xem xét cấu trúc dự án sau:

└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py

Dự án

from LocalSearch.LocalSearch import LocalSearch
7 chứa hai gói,
from LocalSearch.LocalSearch import LocalSearch
8 và
from LocalSearch.LocalSearch import LocalSearch
9 mỗi gói chứa một số mô-đun Python, trong khi cái sau cũng chứa một gói phụ gọi là
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
0, 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ờ, hãy để 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ư được hiển thị bên dưới:

import a

Python sẽ thực thi câu lệnh trên trong hai bước:

  • Định vị, tải và khởi tạo (nếu được yêu cầu) mô -đun được yêu cầu
  • Xác định tên cần thiết trong không gian tên địa phương và phạm vi tương ứng

Bây giờ thông dịch viên Python sẽ làm theo các bước tiếp theo trong nỗ lực giải quyết

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
1.

Bước 1: Tra cứu Sys.Modules

Ban đầu, Python sẽ cố gắng tìm kiếm tên mô -đun trong ____22, đây là một từ điển ánh xạ tên mô -đun thành 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ó) sau đó sẽ được cung cấp cho không gian tên cục bộ nếu không, hãy nhảy vào Bước 2.

Bước 2: Tra cứu thư viện tiêu chuẩn Python

Thư viện tiêu 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 như tệp I/O mà không thể truy cập được đối với các lập trình viên Python, cũng như các mô-đun được viết bằng Python cung cấp các giải pháp tiêu chuẩn cho nhiều vấn đề xảy ra trong lập trình hàng ngày. Một số trong các mô-đun này được thiết kế rõ ràng để khuyến khích và tăng cường 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 tính năng đặc trưng của nền tảng thành API trung lập nền tảng.

Nếu tên không thể được tìm thấy trong

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
2 thì Python sẽ tìm kiếm nó trong Thư viện tiêu 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 Bước 3 cần phải được tuân thủ.

Bước 3: Tra cứu sys.path

Bây giờ nếu tên mô -đun không được tìm thấy trong

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
2 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ó theo
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
5. Và đây là điểm mà mọi thứ chắc chắn có thể đi sai. Tôi tin rằng hầu hết các chương trình Python khá quen thuộc với
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
6And this is the point where things can certainly go wrong. I believe most Python programmes are quite familiar with
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
6

import aModuleNotFoundError: No module named 'a'

hoặc

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
7:

from . import aImportError: cannot import name 'a'

Nhập khẩu tuyệt đối vs 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ôiabsolute imports, we specify the explicit path starting from the project’s root directory. In our example

└── 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

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
1 trong mô -đun
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
9, chúng tôi sẽ phải chỉ định

import mypackage.a

Các ví dụ hợp lệ khác là các nhập khẩu sau:

# in module a.py
import anotherpackage.mysubpackage.d
# in module b
import anotherpackage.c

Bây giờ mặt khác, trong nhập khẩu tương đối, chúng tôi chỉ định đường dẫn đến mô -đun tương đối 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à:relative imports we specify the path to the module relatively to the location of the current module. A few examples in our example could be:

from LocalSearch.LocalSearch import LocalSearch
0

Cá nhân tôi không khuyến khích việc sử dụng nhập khẩu tương đối vì chúng không thể đọc được như nhập khẩu tuyệt đối và PEP-8 cũng cho thấy 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 khẩu tương đối để tránh những con đường dài không cần thiết. Ví dụ,

from LocalSearch.LocalSearch import LocalSearch
1

Làm thế nào để sửa chữa modulenotfounderror và nhà nhập khẩu?

Bây giờ, chúng tôi đã tăng tốc với cách thực hiện tuyên bố nhập khẩu cơ bản và sự khác biệt giữa nhập khẩu tuyệt đối và tương đối bây giờ chúng tôi 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 thất bại với

└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
0or
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
1.or
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
1 .

Trong hầu hết các trường hợp, một trong hai lỗi xảy ra do thực tế là Python không thể giải quyết tên mô -đun trong

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
5. Hãy nhớ lại rằng khi bạn gọi
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
3 nếu tên của mô -đun không được tìm thấy trong
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
2 cũng như trong thư viện tiêu chuẩn, Python sẽ cố gắng giải quyết nó trong
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
5. 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
6 (ví dụ:
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
7), Python trước tiên sẽ cố gắng tìm và tải mô -đun. Khi không làm như vậy, Python sẽ ném
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
0 cho trường hợp đầu tiên hoặc
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
1 cho trường hợp thứ hai.

Nếu đó là trường hợp và nhớ lại ví dụ của chúng tôi dưới đây,

└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py
  • Đầu tiên hãy chắc chắn 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
    import a
    0
    import a
    0

Hầu hết các ID Python hiện đại sẽ tự động thực hiện thủ thuật nhưng nếu đây không phải là trường hợp, tôi khá chắc chắn sẽ có tùy chọn như vậy mà bạn sẽ có thể xác định

from LocalSearch.LocalSearch import LocalSearch
4 cho ứng dụng Python của bạn (í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 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 bên dưới trong bash của bạn:

from LocalSearch.LocalSearch import LocalSearch
3

Và bây giờ vì thư mục gốc của dự án của bạn đã được thêm vào

from LocalSearch.LocalSearch import LocalSearch
4 Nhập khẩu tuyệt đối của bạn sẽ hoạt động như một sự quyến rũ.

import a
3 có thể cũng có thể thực hiện thủ thuật, nhưng nó chắc chắn không phải là một thực hành tốt.

Sự kết luận

Nếu bạn chưa quen với Python, các mô -đun nhập khẩu có thể trở thành một cơn ác mộng đặc biệt nếu bạn cần đối phó với một cấu trúc dự án phức tạp. Nếu bạn tuân theo quy tắc hai bước-tức là sử dụng nhập khẩu tuyệt đối và nối thư mục gốc dự án của bạn vào PythonPath-thì bạn không nê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 rất khuyên bạn nên nhận một bản sao của việc học cuốn sách Python trên Amazon.Learning Python book on Amazon.

Trở thành một thành viên và đọc mọi câu chuyện trên Medium. Phí thành viên của bạn trực tiếp hỗ trợ tôi và các nhà văn khác mà bạn đọc. Bạn cũng sẽ có quyền truy cập đầy đủ vào mọi câu chuyện trên Medium. and read every story on Medium. Your membership fee directly supports me and other writers you read. You’ll also get full access to every story on Medium.

Gói nào trong Python?

Một gói Python thường bao gồm một số mô -đun.Về mặt vật lý, một gói là một thư mục chứa các mô -đun và có thể các thư mục khác có thể chứa nhiều thư mục và mô -đun hơn.Về mặt khái niệm, đó là một không gian tên.usually consists of several modules. Physically, a package is a folder containing modules and maybe other folders that themselves may contain more folders and modules. Conceptually, it's a namespace.

Có phải một tập tin Python là một gói?

Một gói về cơ bản là một thư mục với các tệp python và một tệp có tên __init__ .py.Điều này có nghĩa là mọi thư mục bên trong đường dẫn Python, chứa một tệp có tên __init__.PY, sẽ được Python coi là một gói. py. This means that every directory inside of the Python path, which contains a file named __init__ . py, will be treated as a package by Python.

Làm thế nào để bạn xác định một gói trong Python?

Trình thông dịch Python nhận ra một thư mục là gói nếu nó chứa tệp __init__.py.__init__.py lộ các tài nguyên được chỉ định từ các mô -đun của nó sẽ được nhập.if it contains __init__.py file. __init__.py exposes specified resources from its modules to be imported.

Làm cách nào để khắc phục lỗi không có mô -đun trong Python?

Làm thế nào để sửa chữa ModulenotFounderror trong Python..
Đảm bảo các mô -đun nhập được cài đặt.Lấy ví dụ, Numpy.....
Đảm bảo các mô -đun được đánh vần chính xác.....
Hãy chắc chắn rằng các mô -đun là trong đúng vỏ.....
Hãy chắc chắn rằng bạn sử dụng đúng đường đi ..