Làm cách nào để Python tìm kiếm các gói hoặc mô-đun khi quá trình nhập được diễn giải?
Chuyển đến nội dung chính
Show
Python trung cấpNâng cao kỹ năng khoa học dữ liệu của bạn bằng cách tạo trực quan hóa bằng Matplotlib và thao tác với DataFrames bằng gấu trúcCó liên quan Dữ liệu văn bản trong Python Cheat SheetChào mừng bạn đến với bảng gian lận của chúng tôi để làm việc với dữ liệu văn bản trong Python. Chúng tôi đã biên soạn một danh sách các hàm và gói hữu ích nhất để dọn dẹp, xử lý và phân tích dữ liệu văn bản trong Python, cùng với các ví dụ và giải thích rõ ràng, vì vậy bạn sẽ có mọi thứ cần biết về cách làm việc với dữ liệu văn bản trong Python.Hướng dẫn về tập hợp và lý thuyết tập hợp trong PythonTìm hiểu về bộ Python. chúng là gì, cách tạo chúng, khi nào sử dụng chúng, các chức năng tích hợp và mối quan hệ của chúng với các hoạt động lý thuyết thiết lậpHướng dẫn về gấu trúc. Khung dữ liệu trong PythonKhám phá phân tích dữ liệu với Python. Pandas DataFrames giúp thao tác dữ liệu của bạn dễ dàng, từ việc chọn hoặc thay thế các cột và chỉ mục để định hình lại dữ liệu của bạnXem ThêmXem ThêmBạn có thích đọc hay nghĩ rằng nó có thể được cải thiện? . Nếu bạn thích bài viết này, vui lòng chia sẻ nó với bạn bè của bạn và đọc thêm một số 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 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 Về bản chất, để đơ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 string3 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 string4 và #example2.pyimport example1 as e1# imported string5 Ý 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 string4 để có thể truy cập được trong #example2.pyimport example1 as e1# imported string5. Nội dung của mô-đun như sau #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int): Để nhập những mặt hàng này trong vòng #example2.pyimport example1 as e1# imported string5 #example2.pyimport example1# imported stringĐầ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 string9 hoặc #example2.py# import example10. Nếu bạn từng cảm thấy việc viết #example2.py# import example11 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 #example2.py# import example12và viết lại #example2.pyimport example1 as e1# imported string5 như sau. Như bạn đã đoán đúng, đầu ra sẽ vẫn giữ nguyên #example2.pyimport example1 as e1# imported string 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 #example2.py# import example14. Đó 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 string5) #example2.py# import example1Đầ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 #example2.py# import example14 trỏ tới thư mục #example2.py# import example17, là nơi chứa mô-đun i đã nhập của chúng tôi. e. #example2.pyimport example1 as e1# imported string4 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 #example2.py# import example14
Đâ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 string4. 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 #example2.pyimport example1 as e1# imported string4 một chút #example2.pyimport example1 as e1# imported string4 Và bây giờ hãy thử chạy #example2.pyimport example1 as e1# imported string5. Bạn sẽ thấy rằng câu lệnh in cùng với đầu ra từ #example2.pyimport example1 as e1# imported string44 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 #example2.pyimport example1 as e1# imported string7 Mã bên trong câu lệnh #example2.pyimport example1 as e1# imported string45 sẽ không chạy khi được nhập, nhưng #example2.pyimport example1 as e1# imported string46 và #example2.pyimport example1 as e1# imported string47 đượ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 string4 như một mô-đun độc lập, mã trong câu lệnh #example2.pyimport example1 as e1# imported string49 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 #example2.pyimport example1 as e1# imported string70), 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 string5bằng cách chỉ nhập hàm #example2.pyimport example1 as e1# imported string72 từ #example2.pyimport example1 as e1# imported string4. Đ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 #example2.pyimport example1 as e1# imported string72 nguyên trạng #example2.pyimport example1 as e1# imported string8 Tương tự, chúng ta có thể thực hiện #example2.pyimport example1 as e1# imported string75 để nhập cả hai đối tượng từ #example2.pyimport example1 as e1# imported string4 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ư #example2.pyimport example1 as e1# imported string77. Đ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 chú ý đế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 #example2.pyimport example1 as e1# imported string78 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 #example2.pyimport example1 as e1# imported string78 sẽ chứa ba mô-đun — #example2.pyimport example1 as e1# imported string80, #example2.pyimport example1 as e1# imported string81 và #example2.pyimport example1 as e1# imported string82 để 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 #example2.pyimport example1 as e1# imported string83 ở 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 #example2.pyimport example1 as e1# imported string84 Nội dung của ba mô-đun như sau #example2.pyimport example1 as e1# imported string9 Bây giờ, nếu chúng ta phải nhập mô-đun #example2.pyimport example1 as e1# imported string80 trong #example2.pyimport example1 as e1# imported string83, đây là cách chúng ta thường làm #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):2 Điều quan trọng cần lưu ý là nếu bạn thực hiện #example2.pyimport example1 as e1# imported string87 thay vì #example2.pyimport example1 as e1# imported string88, bạn sẽ nhận được #example2.pyimport example1 as e1# imported string89. Điều này là do danh sách #example2.py# import example14 không chứa (chưa) thư mục #example2.pyimport example1 as e1# imported string91 cần thiết để tìm mô-đun #example2.pyimport example1 as e1# imported string80. Hãy xem cách chúng ta có thể thêm nó vào danh sách #example2.py# import example14 Có hai cách để làm điều này Phương pháp 1. sử dụng #example2.pyimport example1 as e1# imported string94 #example2.pyimport example1 as e1# imported string1 Vài điều cần xem xét
Phương pháp 2. sử dụng biến môi trường #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):26 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
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 #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):27 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 #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):26, được phân tách bằng dấu hai chấm ( #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):29) 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 #example2.py# import example14in #example2.pyimport example1 as e1# imported string83 nữa (Tôi đã nhận xét chúng trong đoạn trích bên dưới cho rõ ràng) #example2.pyimport example1# imported string0 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 string12, hãy thêm lệnh xuất ( #example2.pyimport example1 as e1# imported string13) vào #example2.pyimport example1 as e1# imported string14 của bạn. (Xem cuộc thảo luận về StackOverflow này) Cuối cùng, khi đã xác định cả hai phương thức, hãy chọn một phương thức (dựa trên sở thích/trường hợp sử dụng của bạn) để nhập hai mô-đun còn lại — #example2.pyimport example1 as e1# imported string82 và #example2.pyimport example1 as e1# imported string81 trong #example2.pyimport example1 as e1# imported string83. (P. S. Tôi đang đi với Phương pháp 1 chỉ để giải trí. ) #example2.pyimport example1# imported string1 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 string18 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 #example2.pyimport example1 as e1# imported string78 trong #example2.pyimport example1 as e1# imported string83 (sau khi nhận xét tất cả mã hiện có) #example2.pyimport example1# imported string2 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 #example2.py# import example14 và nó sẽ tìm thấy thư mục hiện tại #example2.pyimport example1# imported string02 tại chỉ mục 0. Đây là tất cả những gì nó cần để tìm thư mục #example2.pyimport example1 as e1# imported string78 Bây giờ, hãy thử truy cập mô-đun #example2.pyimport example1 as e1# imported string80 từ #example2.pyimport example1 as e1# imported string78 #example2.pyimport example1# imported string3 Khi bạn cố chạy tập lệnh này, bạn sẽ thấy một thông báo #example2.pyimport example1# imported string06. 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 #example2.pyimport example1 as e1# imported string78đơ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 #example2.pyimport example1# imported string08 trong thư mục #example2.pyimport example1 as e1# imported string78 Trong vòng #example2.pyimport example1# imported string08, 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 #example2.pyimport example1# imported string4 Và hãy gọi nó trong vòng #example2.pyimport example1 as e1# imported string83 #example2.pyimport example1# imported string5 Đợi chút. Tại sao chúng tôi thấy lỗi khi chạy #example2.pyimport example1# imported string12? Trả lời. Cách chúng tôi đã nhập các mô-đun trong #example2.pyimport example1# imported string08 ở trên có vẻ hợp lý với bạn — xét cho cùng thì #example2.pyimport example1# imported string08 và #example2.pyimport example1 as e1# imported string80 (hoặc #example2.pyimport example1 as e1# imported string81, #example2.pyimport example1 as e1# imported string82) đều ở cùng cấp độ nên không có lý do gì mà #example2.pyimport example1# imported string18 không hoạt động. Trên thực tế, nếu bạn tự chạy tệp #example2.pyimport example1# imported string19 này, nó sẽ thực thi hoàn hảo (nó sẽ không có đầu ra 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ù #example2.pyimport example1 as e1# imported string80 và #example2.pyimport example1 as e1# imported string81 ở cùng cấp độ với #example2.pyimport example1# imported string08 nhưng đây không phải là cấp độ mà từ đó #example2.pyimport example1# imported string19 sẽ được gọi. Trên thực tế, chúng tôi đang thực hiện cuộc gọi từ #example2.pyimport example1 as e1# imported string83 nên #example2.py# import example14 sẽ chỉ có thư mục hiện tại của #example2.pyimport example1 as e1# imported string83 i. e. #example2.pyimport example1# imported string02 để tìm kiếm bên trong cho 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 string18 trong #example2.pyimport example1 as e1# imported string83, mặc dù nó di chuyển đến #example2.pyimport example1# imported string08 bên trong thư mục #example2.pyimport example1 as e1# imported string78, thì #example2.py# import example14 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 #example2.pyimport example1# imported string33 ở đâu. Bằng cách nào đó chúng ta phải trỏ đến vị trí của thư mục #example2.pyimport example1 as e1# imported string78. Để 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 #example2.pyimport example1# imported string08 (hoặc đặt biến #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):26 như được mô tả ở trên)
#example2.pyimport example1# imported string6 Chúng tôi sử dụng ký hiệu dấu chấm ( #example2.pyimport example1# imported string37 hoặc #example2.pyimport example1# imported string38) để 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 #example2.pyimport example1# imported string39 từ #example2.pyimport example1# imported string40. 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
#example2.pyimport example1# imported string7 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, #example2.py# import example14 có quyền truy cập vào thư mục gốc của dự án i. e. #example2.pyimport example1# imported string02 như đã giải thích ở trên và từ đó có thể dễ dàng tìm kiếm thư mục #example2.pyimport example1 as e1# imported string78. (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ó xác định #example2.pyimport example1# imported string44? . 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ụ #example2.pyimport example1# imported string8 Thật tuyệt vời. Bây giờ chúng tôi đã chuyển đổi thư mục #example2.pyimport example1 as e1# imported string78 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 string3. Hãy tiếp tục và tạo một tệp mới có tên là #example2.pyimport example1# imported string47 trong #example2.pyimport example1 as e1# imported string3 #example2.pyimport example1# imported string9 Vài điều cần xem xét
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 #example2.pyimport example1# imported string08 của chúng tôi. Chẳng hạn, hãy mang vào #example2.pyimport example1# imported string59 được xác định trong #example2.pyimport example1# imported string60 #example2.pyimport example1 as e1# imported string0 Gọi chức năng này trong #example2.pyimport example1# imported string47 #example2.pyimport example1 as e1# imported string1 Phần kết luận Thành thật mà nói, ban đầu các lỗi nhập khẩu từng thực sự khiến tôi phát hoảng 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 thủ thuật 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 #example2.pyimport example1# imported string62, 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 #example2.py# import example14 hoặc thậm chí tốt hơn là thêm thư mục có liên quan vào biến #example1.pyMY_EX1_STRING = 'Welcome to Example1 module!'def yolo(x: int):26 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 Làm cách nào để Python biết nơi tìm kiếm các mô-đun và gói được nhập?Sau đó, python sẽ tìm kiếm nó trong PYTHONPATH là danh sách tên thư mục, với cùng cú pháp với biến trình bao PATH . Để biết các thư mục trong PYTHONPATH, chúng ta chỉ cần lấy chúng bằng mô-đun sys.
Làm cách nào bạn có thể cho trình thông dịch Python biết vị trí tìm kiếm các mô-đun trong quá trình nhập?Vì vậy, để đảm bảo rằng mô-đun của bạn được tìm thấy, bạn cần thực hiện một trong các thao tác sau. . Đặt chế độ. py trong thư mục chứa tập lệnh đầu vào hoặc thư mục hiện tại nếu tương tác Sửa đổi biến môi trường PYTHONPATH để chứa thư mục mà mod. py được đặt trước khi bắt đầu trình thông dịch Làm cách nào để Python biết nơi tìm các gói đã cài đặt?Việc nhập Python hoạt động bằng cách tìm kiếm các thư mục được liệt kê trong sys. đường dẫn . Vì vậy, Python sẽ tìm thấy bất kỳ gói nào đã được cài đặt vào các vị trí đó.
Trình thông dịch Python định vị một mô-đun như thế nào?Khi chúng tôi nhập mô-đun, trình thông dịch Python sẽ tìm kiếm mô-đun theo cách sau. Đầu tiên, nó tìm kiếm mô-đun trong thư mục hiện tại. Nếu không tìm thấy mô-đun trong thư mục hiện tại, thì Python sẽ tìm kiếm từng thư mục trong biến trình bao PYTHONPATH . |