Tôi có cần nhập vào mọi tệp python không?

Đối với hầu hết các lập trình viên mới bắt đầu và trung cấp, đôi khi làm việc với nhiều thư mục trong các dự án Python có thể gây khó chịu. Là một lập trình viên Python, cách tốt nhất là trừu tượng hóa mã ứng dụng thành các tệp và thư mục khác nhau và theo các yêu cầu dữ liệu và chức năng liên quan của chúng. Hơn nữa, bạn sẽ không có tùy chọn nào ngoài việc sử dụng các gói và mô-đun hiện có mà người khác đã viết. Điều này sẽ yêu cầu khả năng làm việc hiệu quả trong nhiều gói thư mục trong dự án của bạn

Tầm quan trọng của việc làm việc với các thư mục đa cấp trong mã dự án của bạn

  1. Tính mô đun của mã. Để viết giải pháp cho các vấn đề lớn hơn, điều quan trọng là phải chia dự án của bạn thành các phần nhỏ hơn, trong đó mỗi vấn đề nhỏ hơn được triển khai trong một thư mục con riêng biệt trong dự án của bạn. Điều này sẽ cho phép bạn tập trung vào các bài toán con nhỏ hơn, ít gây choáng ngợp hơn và dễ giải quyết hơn.
  2. Khả năng sử dụng lại mã. Điều quan trọng là mã dự án của bạn phải tuân theo nguyên tắc DRY [Don't Repeat Yourself]. Khi bạn tìm thấy nhiều phần mã về cơ bản đang cố gắng làm điều tương tự, có điều gì đó không đúng. Khi bạn trừu tượng hóa mã của mình bằng cách triển khai logic đơn lẻ hoặc có liên quan vào các mô-đun và gói con riêng lẻ, thì bạn có thể sử dụng chúng ở bất kỳ đâu trong dự án của mình bằng cách chỉ nhập chúng thay vì cố gắng viết lại chúng ở nơi khác trong dự án của bạn
  3. Khả năng bảo trì của mã. Đây có lẽ là lý do quan trọng nhất để thực hiện trừu tượng hóa mã. Điều rất quan trọng là các phần mã dự án của bạn phải được kết hợp lỏng lẻo với nhau. Khi bạn phải sửa đổi một số phần trong mã dự án của mình chỉ vì bạn đã thay đổi một phần nhỏ trong dự án của mình, thì chắc chắn có điều gì đó không ổn. Mã dự án của bạn không cần quá phụ thuộc lẫn nhau. Sự phụ thuộc lẫn nhau nên được giữ ở mức tối thiểu nhất. Mã dự án tốt sẽ cho phép bất kỳ ai không có kiến ​​thức bên ngoài dự án dễ dàng thực hiện các thay đổi đối với nó. Điều này sẽ giúp ích trong quá trình hợp tác nhóm. Khi bạn sử dụng tốt các gói con và mô-đun, bạn chỉ phải thay đổi mô-đun cụ thể mà bạn cần thay đổi

Tuy nhiên, làm việc với nhiều cấp thư mục trong một dự án có thể gây khó khăn cho các lập trình viên mới bắt đầu và sử dụng các gói hoặc mô-đun của bên thứ ba trong các chương trình của riêng họ. Trong bài viết này, tôi cung cấp một cách đơn giản để dễ dàng xử lý việc nhập tệp trong mã dự án thư mục đa cấp. [Để biết cách cấu trúc các dự án Python, hãy tham khảo tài liệu Python ở cuối bài này. ]

Nhập tệp trong cấu trúc thư mục đa cấp

Theo cú pháp Python, dấu chấm ở đầu biểu thị thư mục hiện tại. Mỗi dấu chấm bổ sung sẽ đưa bạn lên một thư mục hoặc gói cao hơn. Thông thường, nên sử dụng nhập tuyệt đối thay vì nhập tương đối trong mã của bạn

Hãy sử dụng một dự án Python có cấu trúc thư mục [như hình bên dưới] để chứng minh việc nhập từ một thư mục đa cấp dễ dàng như thế nào bằng cách sử dụng cả nhập tuyệt đối và tương đối

Ghi chú. Trong Python, mỗi thư mục hoặc thư mục con phải được khởi tạo bằng __init__. py để nó được công nhận là gói hoặc gói con. Nếu không, bạn có thể gặp lỗi không tìm thấy mô-đun khi cố gắng nhập

Khi ở trong thư mục myPackage và để truy cập bảo mật. tệp py trong __init__. py của myPackage trong cùng thư mục

import security   #absolute import   
from . import  security #relative import

Tuy nhiên, đối với tệp sâu hơn một cấp, khi ở trong __init__. py của myPackage và nhập mục. py trong thư mục con1

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import

Đối với tệp sâu hơn hai cấp độ, khi ở trong __init__. py của myPackage và nhập người dùng. py từ thư mục con2

import folder1.folder2.user     #absolute import
from folder1.folder2 import user #absolute import

Khía cạnh khó khăn nhất là phải nhập ngược một tệp—tức là, từ cấp cao hơn vào một tệp trong thư mục cấp thấp hơn. Nhập tuyệt đối làm cho điều này dễ dàng hơn

Để truy cập bảo mật. py từ sinh viên. py của thư mục con2

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import

Để truy cập tài khoản. py trong thư mục con3 từ người dùng. py trong thư mục con2

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import

Để truy cập người dùng. py từ sinh viên. py trong cùng thư mục con2, chỉ cần

import user  # python3
from . import user # any python version

Tóm tắt mã của bạn thành các gói con hoặc mô-đun sẽ giúp bạn viết mã dễ bảo trì. Tôi hy vọng điều này sẽ giúp giảm đau đầu khi làm việc trong gói hoặc mô-đun thư mục đa cấp

Trước khi chúng tôi bắt đầu, hãy hiểu sự khác biệt giữa gói và mô-đun vì chúng tôi sẽ tạo một số tài liệu tham khảo về những điều này trong suốt bài viết

mô-đun. Một kịch bản python duy nhất

Bưu kiện. Bộ sưu tập các mô-đun

Hãy bắt đầu nào

Cấu trúc thư mục trong hình trên trông hơi phức tạp và tôi sẽ không yêu cầu bạn tạo tất cả cùng một lúc

Để đơn giản hóa mọi thứ, trước tiên hãy tạo một thư mục duy nhất

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
3 trong thư mục dự án của chúng ta và thêm hai mô-đun vào đó —
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4 và
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5

Ý tưởng là có bất kỳ chức năng/biến/lớp nào được xác định trong

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4 để có thể truy cập được trong
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5. Nội dung của mô-đun như sau

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
1

Để nhập những mặt hàng này trong vòng

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
3

Đầu ra từ việc chạy ví dụ2. py

Chỉ cần lặp lại những gì rõ ràng đáng chú ý, các mục trong mô-đun đã nhập có thể được truy cập bằng cách sử dụng ký hiệu dấu chấm — ví dụ:

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
9 hoặc
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
50. Nếu bạn từng cảm thấy việc viết
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
51 mỗi lần có vẻ hơi dài, chúng ta có thể sử dụng bí danh bằng cách sử dụng
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
52 và viết lại
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5 như sau. Như bạn đã đoán đúng, đầu ra sẽ vẫn giữ nguyên

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]

Chính xác thì điều gì sẽ xảy ra khi chúng ta viết một câu lệnh 'nhập khẩu'?

Trình thông dịch python cố gắng tìm thư mục chứa mô-đun mà chúng tôi đang cố gắng nhập vào

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54. Đó là danh sách các thư mục mà Python sẽ tìm kiếm sau khi tìm kiếm xong các mô-đun được lưu trong bộ nhớ cache và các mô-đun thư viện chuẩn của Python

Hãy xem đường dẫn hệ thống của chúng ta chứa gì tại thời điểm này [bằng cách nhận xét các dòng mã trước đó trong

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5]

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
5

Đầu ra từ sys. con đường

Như bạn có thể thấy, phần tử đầu tiên trong danh sách được trả về bởi

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 trỏ tới thư mục
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
57, là nơi chứa mô-đun i đã nhập của chúng tôi. e.
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4 cư trú. Bây giờ xin lưu ý bạn, không phải ngẫu nhiên mà thư mục này có mặt một cách kỳ diệu trong
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54

Đầu ra từ

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 sẽ luôn chứa thư mục hiện tại ở chỉ mục 0. Thư mục hiện tại là thư mục chứa tập lệnh đang chạy

Đây là lý do việc nhập khá đơn giản khi cả mô-đun người gọi và mô-đun callee nằm trong cùng một thư mục

Điều gì xảy ra nếu tôi chỉ muốn nhập một số mục chứ không phải tất cả các mục từ mô-đun đã nhập?

Trong ví dụ của chúng tôi, chúng tôi chỉ có một chuỗi và một hàm được xác định trong mô-đun

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4. Một điều quan trọng cần nhớ là bất cứ khi nào một câu lệnh nhập được thực hiện, toàn bộ mô-đun sẽ được chạy. Để chứng minh điều này, hãy sửa đổi một chút
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
0

Và bây giờ hãy thử chạy

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5. Bạn sẽ thấy rằng câu lệnh in cùng với đầu ra từ
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
04 cũng sẽ được in [ngoài các đầu ra trước đó]

Ghi chú. Có một giải pháp thay thế trong đó chúng ta có thể kiểm soát xem câu lệnh có được chạy hay không khi được nhập. Ví dụ: xem đoạn mã bên dưới

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
3

Mã bên trong câu lệnh

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
05 sẽ không chạy khi được nhập, nhưng
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
06 và
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
07 được xác định bên ngoài sẵn sàng để sử dụng thông qua một lần nhập. Phải nói rằng, nếu chúng ta chạy
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4 như một mô-đun độc lập, mã trong câu lệnh
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
09 sẽ được thực thi

Đầu ra từ việc chạy ví dụ1. py

Dù sao đi nữa, bây giờ tôi đã chứng minh rằng việc nhập một mô-đun sẽ chạy tất cả nội dung của nó [nếu không sử dụng

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
30], chắc hẳn khá trực quan rằng tại sao chỉ nhập các mục quan tâm lại có ý nghĩa. Hãy xem cách thực hiện việc này trong
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
5 bằng cách chỉ nhập hàm
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
32 từ
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4. Điều này cũng giúp chúng tôi loại bỏ ký hiệu dấu chấm và chúng tôi chỉ có thể sử dụng hàm
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
32 nguyên trạng

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
4

Tương tự, chúng ta có thể thực hiện

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
35 để nhập cả hai đối tượng từ
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
4

Ghi chú. Thông thường, tồn tại các mã bao gồm các câu lệnh nhập chẳng hạn như

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
37. Điều này về cơ bản có nghĩa là nhập mọi thứ, tuy nhiên, đây được coi là cách làm không tốt vì nó tác động tiêu cực đến khả năng đọc mã

Nhu cầu về PYTHONPATH là gì?

Nếu bạn từng để ý đến cấu trúc thư mục cho các dự án trên Github, thì thường có một thư mục

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38 chứa một số tập lệnh tiện ích cho các tác vụ phổ biến như tiền xử lý, dọn dẹp dữ liệu, v.v. Chúng được giữ tách biệt với các tập lệnh chính và có nghĩa là được sử dụng lại

Hãy tiếp tục và tạo một cái cho dự án của chúng ta. Gói

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38 sẽ chứa ba mô-đun —
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
40,
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
41 và
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
42 để trả về độ dài, chữ thường và chữ hoa của đầu vào chuỗi, tương ứng

Chúng tôi cũng sẽ tạo mô-đun

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43 ở thư mục gốc của dự án. Đây là nơi chúng tôi sẽ nhập các mô-đun trong gói
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
44

Nội dung của ba mô-đun như sau

import user  # python3
from . import user # any python version
5

Bây giờ, nếu chúng ta phải nhập mô-đun

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
40 vào
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43, đây là cách chúng ta thường làm

import user  # python3
from . import user # any python version
8

Điều quan trọng cần lưu ý là nếu bạn thực hiện ________ 447 thay vì ________ 448, bạn sẽ nhận được ________ 449. Điều này là do danh sách

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 không chứa [chưa] thư mục
import user  # python3
from . import user # any python version
51 cần thiết để tìm mô-đun
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
40. Hãy xem cách chúng ta có thể thêm nó vào danh sách
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54

Có hai cách để làm điều này

Phương pháp 1. sử dụng

import user  # python3
from . import user # any python version
54

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
7

Vài điều cần xem xét

  • Thứ tự của
    import user  # python3
    from . import user # any python version
    55 rất quan trọng — chỉ khi bạn đã thêm đường dẫn đến thư mục
    import myPackage.security #absolute import
    from myPackage import security #absolute import
    from .. import security #relative import
    38 bằng cách sử dụng
    import user  # python3
    from . import user # any python version
    54, bạn mới có thể thực thi câu lệnh
    import myPackage.subfolder3.accounts #absolute import
    from  myPackage.subfolder3 import accounts #absolute import
    from ...subfolder3 import accounts #relative import
    47.
    Tóm lại, đừng để tất cả
    import user  # python3
    from . import user # any python version
    59,
    import user  # python3
    from . import user # any python version
    80 và
    import myPackage.subfolder3.accounts #absolute import
    from  myPackage.subfolder3 import accounts #absolute import
    from ...subfolder3 import accounts #relative import
    47 ở đầu tập lệnh chỉ vì sự gọn gàng.
  • import user  # python3
    from . import user # any python version
    82 trả về đường dẫn tuyệt đối đến thư mục làm việc hiện tại. Chúng tôi sử dụng
    import user  # python3
    from . import user # any python version
    83 để thêm thư mục
    import myPackage.security #absolute import
    from myPackage import security #absolute import
    from .. import security #relative import
    38 vào đường dẫn này
  • Như mọi khi, việc truy cập các chức năng được xác định trong mô-đun đã nhập được hỗ trợ bằng cách sử dụng ký hiệu dấu chấm i. e.
    import user  # python3
    from . import user # any python version
    85

Phương pháp 2. sử dụng biến môi trường

import user  # python3
from . import user # any python version
86

Thông thường, tôi thấy việc sửa đổi biến pythonpath dễ dàng hơn là xử lý các thư mục nối thêm bằng Phương pháp 1

PYTHONPATH là một biến môi trường mà bạn có thể đặt để thêm các thư mục bổ sung nơi python sẽ tìm kiếm các mô-đun và gói. [Nguồn]

Trước khi chúng tôi sửa đổi nó, hãy kiểm tra nội dung của nó [để đảm bảo rằng chúng tôi không ghi đè] bằng cách sử dụng

import user  # python3
from . import user # any python version
87 trong thiết bị đầu cuối

Có vẻ như hiện tại nó trống nhưng trong trường hợp không có, bạn luôn nên sửa đổi pythonpath theo cách mà bạn đang thêm vào nó và không ghi đè lên nó. Cụ thể hơn, bạn phải thêm thư mục mới của mình vào

import user  # python3
from . import user # any python version
86, được phân tách bằng dấu hai chấm [
import user  # python3
from . import user # any python version
89] từ nội dung hiện có của nó

Với bộ biến pythonpath, chúng tôi không còn cần phải thêm vào

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54in
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43 nữa [Tôi đã nhận xét chúng trong đoạn trích bên dưới cho rõ ràng]

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
30

Ghi chú. Khi bạn đóng python, danh sách sẽ trở lại các giá trị mặc định trước đó. Nếu bạn muốn thêm vĩnh viễn một thư mục vào

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
72, hãy thêm lệnh xuất [
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
73] vào
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
74 của bạn. [Xem cuộc thảo luận về StackOverflow này]

Cuối cùng, sau khi đã xác định cả hai phương thức, hãy chọn một phương thức [dựa trên tùy chọn/trường hợp sử dụng của bạn] để nhập hai mô-đun còn lại —

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
42 và
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
41in
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43.
[P. S. Tôi đang đi với Phương pháp 1 chỉ để giải trí. ]

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
31

siêu. Điều này có vẻ tuyệt vời. Tuy nhiên, sẽ không tuyệt sao nếu chúng ta chỉ có thể thực hiện

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
78 thay vì nhập tất cả các mô-đun bên trong nó một cách riêng lẻ? . Vì vậy, làm thế nào để chúng ta làm điều đó?

Khi nào chúng ta cần __init__. py?

Trước tiên, hãy thử nhập thư mục

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38 trong
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43 [sau khi nhận xét tất cả mã hiện có]

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
32

Chạy tập lệnh này sẽ không gây ra bất kỳ lỗi nào và đúng như vậy - trình thông dịch sẽ xem bên trong

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 và nó sẽ tìm thấy thư mục hiện tại
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
302 tại chỉ mục 0. Đây là tất cả những gì nó cần để tìm thư mục
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38

Bây giờ, hãy thử truy cập mô-đun

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
40 từ
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
33

Khi bạn cố chạy tập lệnh này, bạn sẽ thấy một thông báo

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
306. Theo thuật ngữ thông thường, điều này có nghĩa là chúng tôi sẽ không thể truy cập bất kỳ tập lệnh python nào bên trong
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38đơn giản vì trình thông dịch chưa biết đây là một gói

Chúng tôi có thể biến thư mục này thành một gói bằng cách giới thiệu tệp

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 trong thư mục
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38

Trong vòng

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308, chúng tôi nhập tất cả các mô-đun mà chúng tôi cho là cần thiết cho dự án của mình

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
34

Và hãy gọi nó trong vòng

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
35

Đợi chút. Tại sao chúng tôi thấy lỗi khi chạy

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
312?
Trả lời. Cách chúng tôi đã nhập các mô-đun trong
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 ở trên có vẻ hợp lý với bạn — xét cho cùng thì
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 và
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
40 [hoặc
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
41,
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
42] đều ở cùng cấp độ nên không có lý do gì mà
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
318 không hoạt động. Trên thực tế, nếu bạn tự chạy tệp
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
319 này, nó sẽ thực thi hoàn hảo [nó sẽ không đưa ra kết quả nào nhưng dù sao cũng sẽ thực thi thành công].

Phải nói rằng, chúng ta không thể sử dụng cách nhập trên vì mặc dù

import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
40 và
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
41 ở cùng cấp độ với
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 nhưng đây không phải là cấp độ mà từ đó
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
319 sẽ được gọi. Trên thực tế, chúng tôi đang thực hiện cuộc gọi từ
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43 nên
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 sẽ chỉ có thư mục hiện tại của
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43 i. e.
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
302 để tìm kiếm bên trong bất kỳ hàng nhập khẩu nào. Do đó, khi trình thông dịch gặp lệnh
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
78 trong
import myPackage.subfolder3.accounts #absolute import
from  myPackage.subfolder3 import accounts #absolute import
from ...subfolder3 import accounts #relative import
43, mặc dù nó di chuyển đến
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 bên trong thư mục
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38, thì
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 không được cập nhật tự động và trình thông dịch không có cách nào biết tìm mô-đun có tên
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
333 ở đâu. Bằng cách nào đó chúng ta phải trỏ đến vị trí của thư mục
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38. Để làm như vậy, chúng tôi có thể sử dụng nhập tương đối hoặc tuyệt đối trong
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 [hoặc đặt biến
import user  # python3
from . import user # any python version
86 như được mô tả ở trên]

Nhập khẩu tương đối [không khuyến nghị]. chỉ định đường dẫn liên quan đến đường dẫn của tập lệnh gọi

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
36

Chúng tôi sử dụng ký hiệu dấu chấm [

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
337 hoặc
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
338] để chỉ định nhập khẩu tương đối. Dấu chấm đơn trước Lower đề cập đến cùng thư mục với thư mục mà quá trình nhập được gọi. Điều này có thể được hình dung như nhập
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
339 từ
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
340. Tương tự, hai dấu chấm trước tên mô-đun có nghĩa là tăng hai cấp so với cấp hiện tại

Nhập khẩu tuyệt đối [lựa chọn tốt hơn]. chỉ định đường dẫn tuyệt đối của mô-đun đã nhập từ thư mục gốc của dự án [hoặc bất kỳ thư mục nào khác mà sys. đường dẫn có quyền truy cập vào]

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
37

Bây giờ, điều này chứa nhiều thông tin hơn so với nhập khẩu tương đối và ít bị phá vỡ hơn. Ngoài ra,

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 có quyền truy cập vào thư mục gốc của dự án i. e.
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
302 như đã giải thích ở trên và từ đó có thể dễ dàng tìm kiếm thư mục
import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38. [Tại sao? Bởi vì nó là thư mục con trực tiếp của gốc dự án]

Điều gì xảy ra khi chúng tôi nhập một gói có _____1344 được xác định? . Cho rằng chúng tôi thực hiện tất cả các nhập cần thiết ở đây, mã sạch hơn nhiều trong tập lệnh gọi. Ví dụ

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
38

Thật tuyệt vời. Bây giờ chúng tôi đã chuyển đổi thư mục

import myPackage.security #absolute import
from myPackage import security #absolute import
from .. import security #relative import
38 của mình thành một gói. Cái hay của gói này là nó có thể được nhập ở bất cứ đâu và sử dụng gần như ngay lập tức. Hãy xem cách chúng ta có thể sử dụng gói này bên trong thư mục
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
3. Hãy tiếp tục và tạo một tệp mới có tên là
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
347 trong
#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
3

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
39

Vài điều cần xem xét

  • Trước khi nhập gói
    import myPackage.security #absolute import
    from myPackage import security #absolute import
    from .. import security #relative import
    38, chúng tôi phải đảm bảo thư mục mẹ của
    import myPackage.security #absolute import
    from myPackage import security #absolute import
    from .. import security #relative import
    38 i. e. root dự án có thể truy cập được bằng trình thông dịch Python. Sẽ là thiếu thận trọng khi cho rằng nó sẽ xảy ra theo mặc định, chủ yếu là do chúng tôi hiện đang ở một cấp trong thư mục gốc của dự án [chúng tôi đang chạy tập lệnh từ
    import subfolder1.item    #absolute import
    from subfolder1 import item  #absolute import
    351],
    import subfolder1.item    #absolute import
    from subfolder1 import item  #absolute import
    54 sẽ có
    import subfolder1.item    #absolute import
    from subfolder1 import item  #absolute import
    353 ở chỉ mục 0
  • import user  # python3
    from . import user # any python version
    82 sẽ cung cấp tên của thư mục cho tập lệnh hiện tại và
    import subfolder1.item    #absolute import
    from subfolder1 import item  #absolute import
    355 sẽ cung cấp đường dẫn đến thư mục mẹ bằng ký hiệu dấu chấm i. e.
    import subfolder1.item    #absolute import
    from subfolder1 import item  #absolute import
    338. Nói chung,
    import subfolder1.item    #absolute import
    from subfolder1 import item  #absolute import
    357 sẽ cung cấp đường dẫn tuyệt đối đến thư mục gốc của dự án

Thưởng. Chúng tôi thậm chí có thể thêm các mô-đun từ các thư mục khác vào

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
308 của chúng tôi. Chẳng hạn, hãy mang vào
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
359 được xác định trong
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
360

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
0

Gọi chức năng này trong

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
347

#example2.pyimport example1 as e1# imported string
print["The imported string is: ", e1.MY_EX1_STRING]
# imported function
e1.yolo[10]
1

Phần kết luận

Thành thật mà nói, các lỗi nhập khẩu từng thực sự khiến tôi phát hoảng lúc đầu vì đây là một lĩnh vực mà tôi không bao giờ phải bận tâm. Qua nhiều năm, tôi đã học được một mẹo hữu ích — đối với bất kỳ gói/mô-đun nào bạn đang cố gắng nhập bằng cách sử dụng

import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
362, hãy đảm bảo trình thông dịch Python có quyền truy cập vào gói/mô-đun đó. Nếu không, hãy cập nhật
import subfolder1.item    #absolute import
from subfolder1 import item  #absolute import
54 hoặc thậm chí tốt hơn là thêm thư mục có liên quan vào biến
import user  # python3
from . import user # any python version
86 và tránh phải xử lý nó trong tập lệnh của bạn

Như mọi khi, nếu có một cách dễ dàng hơn để thực hiện/giải thích một số nội dung được đề cập trong bài viết này, hãy cho tôi biết. Nói chung, hãy kiềm chế những bình luận phá hoại/rác rưởi/thù địch không được yêu cầu

Cho đến lần sau ✨

Tôi thích viết hướng dẫn từng bước cho người mới bắt đầu, hướng dẫn cách thực hiện, câu hỏi phỏng vấn, giải mã thuật ngữ được sử dụng trong ML/AI, v.v. Nếu bạn muốn có toàn quyền truy cập vào tất cả các bài viết của tôi [và các tác giả khác trên Phương tiện], thì bạn có thể đăng ký bằng liên kết của tôi tại đây

Tất cả các mục nhập có nên ở đầu Python không?

Nội dung nhập phải luôn được viết ở đầu tệp, sau bất kỳ nhận xét và chuỗi tài liệu mô-đun nào . Nhập khẩu nên được chia theo những gì đang được nhập khẩu. Nhìn chung có ba nhóm. nhập thư viện tiêu chuẩn [các mô-đun tích hợp sẵn của Python]

Bạn có nên nhập chức năng Python không?

PEP 8 khuyên bạn nên đặt mục nhập ở trên cùng . Việc nhận ImportError s khi bạn chạy chương trình lần đầu tiên sẽ thuận tiện hơn là khi chương trình gọi hàm của bạn lần đầu tiên. Đặt nhập khẩu trong phạm vi chức năng có thể giúp tránh các vấn đề với nhập khẩu vòng tròn.

Thứ tự nhập khẩu có quan trọng với Python không?

Lệnh nhập không thành vấn đề . Nếu một mô-đun phụ thuộc vào các mô-đun khác, thì nó cần phải tự nhập các mô-đun đó. Python xử lý từng. py dưới dạng một đơn vị độc lập theo như nội dung hiển thị trong tệp đó.

Cách chính xác để nhập tệp Python là gì?

cách tốt nhất để nhập. py bằng cách __init__. p . điều đơn giản nhất cần làm là tạo một tệp trống có tên __init__. py trong cùng thư mục mà bạn. tập tin py nằm.

Chủ Đề