44 keyword to make code in one module available in another. Imports in Python are important for structuring your code effectively. Using imports properly will make you more productive, allowing you to reuse code while keeping your projects maintainable
44 của Python và cách thức hoạt động của nó. The import system is powerful, and you’ll learn how to harness this power. Mặc dù bạn sẽ đề cập đến nhiều khái niệm đằng sau hệ thống nhập của Python, hướng dẫn này chủ yếu dựa trên ví dụ. Bạn sẽ học được từ một số ví dụ mã trong suốt
Trong hướng dẫn này, bạn sẽ học cách
Sử dụng các mô-đun, gói và gói không gian tên
Xử lý các tệp tài nguyên và dữ liệu bên trong các gói của bạn
Nhập mô-đun động khi chạy
Tùy chỉnh hệ thống nhập của Python
Xuyên suốt hướng dẫn, bạn sẽ thấy các ví dụ về cách sử dụng bộ máy nhập Python để hoạt động hiệu quả nhất. Mặc dù tất cả mã được hiển thị trong hướng dẫn, nhưng bạn cũng có thể tải xuống bằng cách nhấp vào hộp bên dưới
Lấy mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để tìm hiểu về hệ thống nhập Python trong hướng dẫn này
Python code is organized into both modules and packages. This section will explain how they differ and how you can work with them
Later in the tutorial, you’ll see some advanced and lesser-known uses of Python’s import system. However, let’s get started with the basics. importing modules and packages
Remove ads
Modules
The Python. org glossary defines module as follows
An object that serves as an organizational unit of Python code. Modules have a namespace containing arbitrary Python objects. Modules are loaded into Python by the process of importing. (Source)
49 acts as a namespace that keeps all the attributes of the module together. Namespaces are useful for keeping your code readable and organized. In the words of Tim Peters
Namespaces are one honking great idea—let’s do more of those. (Source)
Note that a package is still a module. As a user, you usually don’t need to worry about whether you’re importing a module or a package
In practice, a package typically corresponds to a file directory containing Python files and other directories. To create a Python package yourself, you create a directory and a file named
66 file are still treated as packages by Python. However, these won’t be regular packages, but something called namespace packages. You’ll learn more about them later
In general, submodules and subpackages aren’t imported when you import a package. However, you can use
Remember, importing a module both loads the contents and creates a namespace containing the contents. The last few examples show that it’s possible for the same module to be part of different namespaces
Chi tiết kỹ thuật. Không gian tên mô-đun được triển khai dưới dạng từ điển Python và có sẵn tại thuộc tính
92 và vị trí bạn đang nhập phải bắt đầu bằng dấu chấm
Hướng dẫn kiểu PEP 8 khuyến nghị sử dụng nhập khẩu tuyệt đối nói chung. Tuy nhiên, nhập khẩu tương đối là một giải pháp thay thế để tổ chức phân cấp gói. Để biết thêm thông tin, hãy xem Nhập tuyệt đối và tương đối trong Python
Đường dẫn nhập của Python
Làm cách nào để Python tìm thấy các mô-đun và gói mà nó nhập? . Hiện tại, chỉ cần biết rằng Python tìm kiếm các mô-đun và gói trong đường dẫn nhập của nó. Đây là danh sách các vị trí được tìm kiếm các mô-đun để nhập
Thông thường, Python sẽ bắt đầu ở đầu danh sách các vị trí và tìm kiếm một mô-đun nhất định ở mỗi vị trí cho đến khi khớp đầu tiên. Vì thư mục tập lệnh hoặc thư mục hiện tại luôn ở vị trí đầu tiên trong danh sách này, nên bạn có thể đảm bảo rằng các tập lệnh của mình tìm thấy các mô-đun và gói tự tạo bằng cách tổ chức các thư mục của bạn và cẩn thận về việc bạn chạy Python từ thư mục nào
Tuy nhiên, bạn cũng nên cẩn thận rằng bạn không tạo các mô-đun che khuất hoặc ẩn các mô-đun quan trọng khác. Ví dụ, giả sử bạn xác định mô-đun
To avoid these kinds of issues, you should be careful with the names of your modules and packages. Cụ thể, tên gói và mô-đun cấp cao nhất của bạn phải là duy nhất. Nếu
113 is a library module with a few functions for dealing with files. The following is an example of output from the app, in this case by running it in the
In lines 12 to 16, you read a root path from the command line. In the above example you use a dot, which means the current directory. This path will be used as the
128 trong đường dẫn nhập để quá trình nhập hoạt động
Luckily, the directory containing the current script is always in Python’s import path, so this works fine for now. However, if your project gains some traction, then it may be used in other ways
For example, someone might want to import the script into a Jupyter Notebook and run it from there. Or they may want to reuse the
128 library in another project. They may even create an executable with PyInstaller to more easily distribute it. Unfortunately, any of these scenarios can create issues with the import of
To see an example, you can follow the PyInstaller guide and create an entry point to your application. Add an extra directory outside your application directory
113. Vấn đề với phương pháp này là đường dẫn nhập của bạn có thể rất lộn xộn và khó hiểu
In practice, you’re re-creating a feature of early Python versions called implicit relative imports. These were removed from the language by PEP 328 with the following rationale
In Python 2. 4 and earlier, if you’re reading a module located inside a package, it is not clear whether
151 refers to a top-level module or to another module inside the package. As Python’s library expands, more and more existing package internal modules suddenly shadow standard library modules by accident. It’s a particularly difficult problem inside packages because there’s no way to specify which module is meant. (Source)
Another solution is to use a relative import instead. Change the import in
Vấn đề là các lần nhập tương đối được giải quyết khác nhau trong các tập lệnh so với các mô-đun đã nhập. Of course, you could go back and restore the absolute import before running the script directly, or you could even do some
When you install a package from PyPI, that package is available to all scripts in your environment. However, you can also install packages from your local computer, and they’ll also be made available in the same way
Creating a local package doesn’t involve much overhead. First, create minimal
114 will then be found on Python’s import path, meaning you can use it anywhere without having to worry about the script directory, relative imports, or other complications. The
166 option stands for editable, which is important because it allows you to change the source code of your package without reinstalling it
Note. Loại tệp thiết lập này hoạt động rất tốt khi bạn tự làm việc với các dự án. Tuy nhiên, nếu bạn định chia sẻ mã với người khác thì bạn nên thêm một số thông tin khác vào tệp thiết lập của mình
For more details on setup files, check out How to Publish an Open-Source Python Package to PyPI
This will work no matter how you end up calling your application
Tip. Trong mã của riêng bạn, bạn nên tách biệt các tập lệnh và thư viện một cách có ý thức. Here’s a good rule of thumb
Một kịch bản có nghĩa là để được chạy
A library is meant to be imported
You might have code that you want to both run on its own and import from other scripts. In that case, it’s usually worthwhile to refactor your code so that you split the common part into a library module
Mặc dù nên tách biệt các tập lệnh và thư viện, nhưng tất cả các tệp Python đều có thể được thực thi và nhập. In a later section, you’ll learn more about how to create modules that handle both well
Namespace Packages
Python modules and packages are very closely related to files and directories. This sets Python apart from many other programming languages in which packages merely act as namespaces without enforcing how the source code is organized. See the discussion in PEP 402 for examples
Namespace packages have been available in Python since version 3. 3. These are less dependent on the underlying file hierarchy. In particular, namespace packages can be split across multiple directories. A namespace package is created automatically if you have a directory containing a
Note. To be precise, implicit namespace packages were introduced in Python 3. 3. Trong các phiên bản trước của Python, bạn có thể tạo thủ công các gói không gian tên theo một số cách không tương thích khác nhau. PEP 420 unifies and simplifies these earlier approaches
To get a better understanding of why namespace packages can be useful, let’s try to implement one. As a motivating example, you’ll have another go at the problem solved in The Factory Method Pattern and Its Implementation in Python. được cung cấp một đối tượng
Let’s assume that you’re lucky and come across a third-party implementation of several of the formats that you need to serialize to, and it’s organized as a namespace package
181 isn’t in your Python import path. You’ll soon see how to solve that
So far, so good. However, now you realize that you also need to convert your songs to a YAML representation, which is not supported in the third-party library. Enter the magic of namespace packages. you can add your own
Just like regular modules and packages, namespace packages must be found on the Python import path. If you were following along with the previous examples, then you might have had issues with Python not finding
155 to install the third-party library, so it would be in your path automatically
Note. In the original example, the choice of serializer was made more dynamically. You’ll see how to use namespace packages in a proper factory method pattern later
You should also make sure that your local library is available like a normal package. As explained above, you can do this either by running Python from the proper directory or by using
You can now use all serializers without worrying about whether they’re defined in the third-party package or locally
Remove ads
Imports Style Guide
PEP 8, the Python style guide, has a couple of recommendations about imports. As always with Python, keeping your code both readable and maintainable is an important consideration. Here are a few general rules of thumb for how to style your imports
Keep imports at the top of the file
Write imports on separate lines
Organize imports into groups. first standard library imports, then third-party imports, and finally local application or library imports
412 need to be installed on the system. You can generally assume that the standard library is available. Separating imports from within your package gives you some overview over the internal dependencies of your code
There are cases in which it makes sense to bend these rules a little. You’ve already seen that relative imports can be an alternative to organizing package hierarchies. Later, you’ll see how in some cases you can move imports into a function definition to break import cycles
Resource Imports
Sometimes you’ll have code that depends on data files or other resources. In small scripts, this isn’t a problem—you can specify the path to your data file and carry on
However, if the resource file is important for your package and you want to distribute your package to other users, then a few challenges will arise
You won’t have control over the path to the resource since that will depend on your user’s setup as well as on how the package is distributed and installed. You can try to figure out the resource path based on your package’s
417 gives access to resources within packages. In this context, a resource is any file located within an importable package. The file may or may not correspond to a physical file on the file system
This has a couple of advantages. By reusing the import system, you get a more consistent way of dealing with the files inside your packages. Nó cũng cho phép bạn truy cập dễ dàng hơn vào các tệp tài nguyên trong các gói khác. The documentation sums it up nicely
If you can import a package, you can access resources within that package. (Source)
417. your resource files must be available inside a regular package. Namespace packages aren’t supported. In practice, this means that the file must be in a directory containing an
Each line contains the population of a country for a given year and a given variant, which indicates what kind of scenario is used for the projection. The file contains population projections until the year 2100
The following function reads this file and picks out the total population of each country for a given
You can do any number of interesting things with this population dictionary, including analysis and visualizations. Here, you’ll create a quiz game that asks users to identify which country in a set is most populous. Playing the game will look something like this
The details of the implementation are too far outside the topic of this tutorial, so they won’t be discussed here. However, you can expand the section below to see the complete source code
Source Code of Population QuizShow/Hide
The population quiz consists of two functions, one that reads the population data like you did above and one that runs the actual quiz
When building graphical user interfaces (GUIs), you often need to include resource files like icons. The following example shows how you can do that using
417. The final app will look quite basic, but it’ll have a custom icon as well as an illustration on the Goodbye button
The example uses Tkinter, which is a GUI package available in the standard library. It’s based on the Tk windowing system, originally developed for the Tcl programming language. There are many other GUI packages available for Python. If you’re using a different one, then you should be able add icons to your app using ideas similar to the ones presented here
If you want to try the example yourself, then you can download these files along with the rest of the source code used in this tutorial by clicking the link below
Lấy mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để tìm hiểu về hệ thống nhập Python trong hướng dẫn này
The code is stored in a file with the special name
If you want to learn more about building GUIs with Tkinter, then check out Python GUI Programming With Tkinter. The official documentation also has a nice list of resources to start with, and the tutorial at TkDocs is another great resource that shows how to use Tk in other languages
Note. One source of confusion and frustration when working with images in Tkinter is that you must make sure the images aren’t garbage collected. Due to the way Python and Tk interact, the garbage collector in Python (at least in CPython) doesn’t register that images are used by
To make sure that the images are kept around, you should manually add a reference to them. You can see examples of this in the code above on lines 18 and 31
Remove ads
Dynamic Imports
One of Python’s defining features is that it’s a very dynamic language. Although it’s sometimes a bad idea, you can do many things to a Python program when it’s running, including adding attributes to a class, redefining methods, or changing the docstring of a module. For instance, you can change
469 package, and this allows you to do your imports more dynamically. The following script asks the user for the name of a module, imports that module, and prints its docstring
472 returns a module object that you can bind to any variable. Then you can treat that variable as a regularly imported module. You can use the script like this
181 được triển khai dưới dạng gói không gian tên, bạn có khả năng thêm các bộ nối tiếp tùy chỉnh. In the original example from a previous tutorial, the serializers were made available through a serializer factory. Using
Nhà máy đưa ra một số giả định mạnh mẽ về cách đặt tên của cả mô-đun và lớp chứa các bộ nối tiếp riêng lẻ. In the next section, you’ll learn about a plugin architecture that allows more flexibility
You can now re-create the earlier example as follows
>>>
>>> importmath>>> math.pi3.141592653589793
31
In this case, you no longer need to explicitly import each serializer. Thay vào đó, bạn chỉ định tên của bộ nối tiếp bằng một chuỗi. The string could even be chosen by your user at runtime
Note. Trong một gói thông thường, bạn có thể đã triển khai
66, vì vậy bạn cần triển khai các chức năng này trong một mô-đun riêng thay thế
Ví dụ cuối cùng cho thấy rằng bạn cũng nhận được một thông báo lỗi phù hợp nếu bạn cố gắng tuần tự hóa thành một định dạng chưa được triển khai
Remove ads
Thí dụ. Một gói plugin
Let’s look at another example of using dynamic imports. Bạn có thể sử dụng mô-đun sau để thiết lập kiến trúc plugin linh hoạt trong mã của mình. Điều này tương tự như ví dụ trước, trong đó bạn có thể cắm các bộ nối tiếp cho các định dạng khác nhau bằng cách thêm các mô-đun mới
Một ứng dụng sử dụng plugin hiệu quả là công cụ trực quan hóa khám phá Keo. Keo có thể đọc được nhiều định dạng dữ liệu khác nhau. Tuy nhiên, nếu định dạng dữ liệu của bạn không được hỗ trợ thì bạn có thể viết trình tải dữ liệu tùy chỉnh của riêng mình
Bạn làm điều này bằng cách thêm một chức năng mà bạn trang trí và đặt ở một vị trí đặc biệt để Keo dễ dàng tìm thấy. Bạn không cần thay đổi bất kỳ phần nào của mã nguồn Keo. Xem tài liệu để biết tất cả các chi tiết
You can set up a similar plugin architecture that you can use in your own projects. Trong kiến trúc, có hai cấp độ
Gói plugin là tập hợp các plugin có liên quan tương ứng với gói Python
Plugin là một hành vi tùy chỉnh có sẵn trong mô-đun Python
487 hiển thị kiến trúc plugin có các chức năng sau
>>> importmath>>> math.pi3.141592653589793
32
Các chức năng của nhà máy được sử dụng để thêm chức năng vào các gói plugin một cách thuận tiện. Bạn sẽ thấy một số ví dụ về cách chúng được sử dụng trong thời gian ngắn
Xem xét tất cả các chi tiết của mã này nằm ngoài phạm vi của hướng dẫn này. Nếu quan tâm, bạn có thể xem cách triển khai bằng cách mở rộng phần bên dưới
Việc triển khai này được đơn giản hóa một chút. Đặc biệt, nó không thực hiện bất kỳ xử lý lỗi rõ ràng nào. Kiểm tra dự án PyPlugs để triển khai đầy đủ hơn
493 mà bạn có thể sử dụng để thêm nhiều lời chào khác nhau vào ứng dụng của mình. Kiến trúc plugin đầy đủ chắc chắn là quá mức cần thiết cho ví dụ này, nhưng nó cho thấy cách thức hoạt động của các plugin
Để tìm hiểu thêm về các công cụ trang trí và cách chúng được sử dụng, hãy xem Primer on Python Decorators
Ghi chú. Để đơn giản hóa việc khám phá và nhập plugin, tên của mỗi plugin dựa trên tên của mô-đun chứa nó thay vì tên chức năng. Điều này hạn chế bạn chỉ có một plugin cho mỗi tệp
101 tự động phát hiện tất cả các plugin có sẵn trong gói
Bạn cũng có thể linh hoạt hơn trong việc chọn plugin để gọi. Trong ví dụ sau, bạn chọn ngẫu nhiên plugin. Tuy nhiên, bạn cũng có thể chọn plugin dựa trên tệp cấu hình hoặc đầu vào của người dùng
>>>
>>> importmath>>> math.pi3.141592653589793
38
Để khám phá và gọi các plugin khác nhau, bạn cần nhập chúng. Hãy xem nhanh cách
117 vì điều đó sẽ tự động khởi tạo từng bộ nối tiếp. Với việc tái cấu trúc này, các bộ tuần tự hóa hoạt động giống như trước đó. Tuy nhiên, bạn có thể linh hoạt hơn trong việc đặt tên cho các lớp serializer của mình
Để biết thêm thông tin về cách sử dụng plugin, hãy xem PyPlugs trên PyPI và các Trình cắm. Thêm tính linh hoạt vào bản trình bày Ứng dụng của bạn từ PyCon 2019
Remove ads
Hệ thống nhập Python
Bạn đã thấy nhiều cách để tận dụng hệ thống nhập của Python. Trong phần này, bạn sẽ tìm hiểu thêm một chút về những gì diễn ra ở hậu trường khi các mô-đun và gói được nhập
Như với hầu hết các phần của Python, hệ thống nhập có thể được tùy chỉnh. Bạn sẽ thấy một số cách mà bạn có thể thay đổi hệ thống nhập, bao gồm tự động tải xuống các gói bị thiếu từ PyPI và nhập các tệp dữ liệu như thể chúng là các mô-đun
Nhập nội bộ
Chi tiết về hệ thống nhập Python được mô tả trong tài liệu chính thức. Ở cấp độ cao, có ba điều xảy ra khi bạn nhập một mô-đun (hoặc gói). mô-đun là
Tìm kiếm
Nạp vào
Bị ràng buộc vào một không gian tên
Đối với các thao tác nhập thông thường—những thao tác được thực hiện với câu lệnh
Tất nhiên, trong mã bình thường, bạn nên chọn cái trước
Một điều cần lưu ý là, ngay cả khi bạn chỉ nhập một thuộc tính từ mô-đun, toàn bộ mô-đun sẽ được tải và thực thi. Phần còn lại của nội dung mô-đun không bị ràng buộc với không gian tên hiện tại. Một cách để chứng minh điều này là xem cái được gọi là bộ đệm mô-đun
121. Nếu một mô-đun đã có sẵn, thì nó sẽ không được tải lại
Đây là một tối ưu hóa tuyệt vời, nhưng nó cũng là một điều cần thiết. Nếu các mô-đun được tải lại mỗi khi chúng được nhập, thì bạn có thể gặp phải tình trạng không nhất quán trong một số trường hợp nhất định, chẳng hạn như khi mã nguồn cơ bản thay đổi trong khi tập lệnh đang chạy
Nhớ lại đường dẫn nhập mà bạn đã thấy trước đó. Về cơ bản, nó cho Python biết nơi tìm kiếm các mô-đun. Tuy nhiên, nếu Python tìm thấy một mô-đun trong bộ đệm mô-đun, thì nó sẽ không bận tâm tìm kiếm đường dẫn nhập cho mô-đun
Thí dụ. Singletons như các mô-đun
Trong lập trình hướng đối tượng, một singleton là một lớp có nhiều nhất một thể hiện. Mặc dù có thể triển khai các singleton trong Python, nhưng thay vào đó, hầu hết các cách sử dụng tốt các singleton có thể được xử lý bởi các mô-đun. Bạn có thể tin tưởng bộ đệm mô-đun để khởi tạo một lớp chỉ một lần
Ví dụ: hãy quay lại dữ liệu dân số của Liên hợp quốc mà bạn đã xem trước đó. Mô-đun sau định nghĩa một lớp bao bọc dữ liệu dân số
>>> importmath>>> math.pi3.141592653589793
74
Đọc dữ liệu từ đĩa mất một thời gian. Vì bạn không muốn tệp dữ liệu thay đổi, nên bạn khởi tạo lớp khi bạn tải mô-đun. Tên của lớp bắt đầu bằng dấu gạch dưới để cho người dùng biết rằng họ không nên sử dụng nó
123 để tạo biểu đồ Matplotlib hiển thị dự báo dân số cho các quốc gia đông dân nhất
>>>
>>> importmath>>> math.pi3.141592653589793
75
Điều này tạo ra một biểu đồ như sau
Lưu ý rằng việc tải dữ liệu tại thời điểm nhập là một loại phản mẫu. Lý tưởng nhất là bạn muốn hàng nhập khẩu của mình không có tác dụng phụ nhất có thể. Cách tiếp cận tốt hơn là tải dữ liệu một cách lười biếng khi bạn cần. Bạn có thể làm điều này khá tao nhã bằng cách sử dụng các thuộc tính. Mở rộng phần sau để xem ví dụ
127. Để biết thêm thông tin về các thuộc tính và khái niệm tổng quát hơn về bộ mô tả, hãy xem Bộ mô tả Python. Một lời giới thiệuRemove ads
Tải lại mô-đun
Bộ đệm mô-đun có thể hơi khó chịu khi bạn đang làm việc trong trình thông dịch tương tác. Tải lại một mô-đun sau khi bạn thay đổi nó không phải là chuyện nhỏ. Ví dụ: hãy xem mô-đun sau
>>> importmath>>> math.pi3.141592653589793
77
Là một phần của quá trình thử nghiệm và gỡ lỗi mô-đun này, bạn nhập nó vào bảng điều khiển Python
>>>
>>> importmath>>> math.pi3.141592653589793
78
Giả sử bạn nhận ra rằng bạn có một lỗi trong mã của mình, vì vậy bạn cập nhật tệp
130 trước đó, nên không có lý do gì để tải lại mô-đun mặc dù bạn vừa thay đổi nó
Giải pháp đơn giản nhất cho vấn đề này là thoát khỏi bảng điều khiển Python và khởi động lại nó. Điều này buộc Python cũng phải xóa bộ đệm mô-đun của nó
Tuy nhiên, khởi động lại trình thông dịch không phải lúc nào cũng khả thi. Bạn có thể đang ở trong một phiên phức tạp hơn khiến bạn mất nhiều thời gian để thiết lập. Nếu đúng như vậy, bạn có thể sử dụng
132 có một số lưu ý. Cụ thể, các biến tham chiếu đến các đối tượng trong một mô-đun không bị ràng buộc lại với các đối tượng mới khi mô-đun đó được tải lại. Xem tài liệu để biết thêm chi tiết
Trình tìm và Trình tải
Bạn đã thấy trước đó rằng việc tạo các mô-đun có cùng tên với các thư viện tiêu chuẩn có thể gây ra sự cố. Ví dụ: nếu bạn có một tệp có tên
Hãy tìm hiểu sâu hơn về hệ thống nhập của Python. Điều này cũng sẽ cho thấy lý do tại sao các mô-đun tích hợp không bị che khuất bởi các mô-đun cục bộ. Có một số bước liên quan khi nhập một mô-đun
Python kiểm tra xem mô-đun có sẵn trong bộ đệm mô-đun không. Nếu
121 chứa tên của mô-đun, thì mô-đun đó đã có sẵn và quá trình nhập kết thúc
Python bắt đầu tìm kiếm mô-đun bằng một số công cụ tìm. Một công cụ tìm sẽ tìm kiếm mô-đun bằng một chiến lược nhất định. Công cụ tìm mặc định có thể nhập các mô-đun tích hợp, mô-đun cố định và mô-đun trên đường dẫn nhập
Python tải mô-đun bằng trình tải. Trình tải nào Python sử dụng được xác định bởi công cụ tìm định vị mô-đun và được chỉ định trong một thứ gọi là thông số mô-đun
Bạn có thể mở rộng hệ thống nhập Python bằng cách triển khai công cụ tìm của riêng bạn và, nếu cần, trình tải của riêng bạn. Bạn sẽ thấy một ví dụ hữu ích hơn về công cụ tìm sau. Hiện tại, bạn sẽ học cách thực hiện các tùy chỉnh cơ bản (và có thể ngớ ngẩn) của hệ thống nhập
Đầu tiên, lưu ý rằng điều này trả lời câu hỏi từ trước đó. các mô-đun tích hợp không bị che khuất bởi các mô-đun cục bộ vì công cụ tìm tích hợp được gọi trước công cụ tìm đường dẫn nhập, tìm các mô-đun cục bộ. Thứ hai, lưu ý rằng bạn có thể tùy chỉnh
Vì không có công cụ tìm, Python không thể tìm hoặc nhập các mô-đun mới. Tuy nhiên, Python vẫn có thể nhập các mô-đun đã có trong bộ đệm mô-đun vì nó tìm ở đó trước khi gọi bất kỳ công cụ tìm nào
469 đã được tải ngầm trước khi bạn xóa danh sách công cụ tìm. Nếu bạn thực sự muốn làm cho phiên Python của mình hoàn toàn không sử dụng được, thì bạn cũng có thể xóa bộ đệm mô-đun,
Sau đây là một ví dụ hữu ích hơn một chút. Bạn sẽ viết một công cụ tìm in thông báo tới bảng điều khiển xác định mô-đun đang được nhập. Ví dụ này cho thấy cách thêm công cụ tìm của riêng bạn, mặc dù nó không thực sự cố gắng tìm một mô-đun
164, cung cấp thông tin tương tự và nhiều, nhiều hơn nữa
Ví dụ khác, giả sử bạn đang thực hiện nhiệm vụ loại bỏ thế giới của các biểu thức thông thường. (Bây giờ, tại sao bạn lại muốn một thứ như vậy? Cụm từ thông dụng thật tuyệt. ) Bạn có thể triển khai công cụ tìm sau cấm mô-đun biểu thức chính quy
183 đảm bảo rằng không có công cụ tìm nào sau này trong danh sách công cụ tìm sẽ được thực thi. Điều này thực sự ngăn bạn sử dụng các biểu thức thông thường trong Python
Vì hệ thống nhập của Python đã khá mạnh mẽ và hữu ích, nên có nhiều cách để làm rối tung nó hơn là mở rộng nó theo cách hữu ích. Tuy nhiên, ví dụ sau có thể hữu ích trong một số trường hợp
Chỉ mục gói Python (PyPI) là cửa hàng pho mát duy nhất của bạn để tìm các gói và mô-đun của bên thứ ba. Đây cũng là nơi mà các gói tải xuống của
170 để cài đặt các mô-đun và gói của bên thứ ba mà bạn cần để làm theo cùng với các ví dụ. Sẽ thật tuyệt nếu Python tự động cài đặt các mô-đun còn thiếu cho bạn phải không?
Cảnh báo. Trong hầu hết các trường hợp, sẽ không tuyệt lắm nếu Python tự động cài đặt các mô-đun. Chẳng hạn, trong hầu hết các cài đặt sản xuất, bạn muốn kiểm soát môi trường của mình. Hơn nữa, tài liệu cảnh báo không nên sử dụng
So với các công cụ tìm bạn đã thấy trước đó, công cụ này phức tạp hơn một chút. Bằng cách đặt công cụ tìm này cuối cùng trong danh sách công cụ tìm, bạn biết rằng nếu bạn gọi
173 dường như hoạt động, có một số thách thức với cách tiếp cận này. Một vấn đề lớn là tên nhập của một mô-đun không phải lúc nào cũng tương ứng với tên của nó trên PyPI. Ví dụ: trình đọc nguồn cấp Python thực được gọi là
Điều này có thể gây hậu quả tai hại cho dự án của bạn
Một tình huống trong đó cài đặt tự động có thể khá hữu ích là khi bạn đang chạy Python trên đám mây với quyền kiểm soát hạn chế hơn đối với môi trường của bạn, chẳng hạn như khi bạn đang chạy sổ ghi chép kiểu Jupyter tại Google Colaboratory. Môi trường sổ ghi chép Colab rất phù hợp để thực hiện khám phá dữ liệu hợp tác
Một sổ ghi chép điển hình đi kèm với nhiều gói khoa học dữ liệu được cài đặt, bao gồm NumPy, Pandas và Matplotlib và bạn có thể thêm các gói mới bằng
186 không có sẵn cục bộ trên máy chủ Colab nên mã này được sao chép vào ô đầu tiên của sổ ghi chép
Thí dụ. Nhập tệp dữ liệu
Ví dụ cuối cùng trong phần này được lấy cảm hứng từ bài đăng trên blog tuyệt vời của Aleksey Bilogur Nhập hầu hết mọi thứ bằng Python. Giới thiệu về Trình tải và Trình tìm mô-đun. Bạn đã biết cách sử dụng
Dòng đầu tiên là tiêu đề đặt tên cho ba trường và hai hàng dữ liệu tiếp theo, mỗi hàng chứa thông tin về một nhân viên. Để biết thêm thông tin về cách làm việc với tệp CSV, hãy xem Đọc và ghi tệp CSV bằng Python
Mục tiêu của bạn trong phần này là viết một công cụ tìm và một trình tải cho phép bạn nhập tệp CSV trực tiếp để bạn có thể viết mã như sau
Công việc của công cụ tìm sẽ là tìm kiếm và nhận dạng các tệp CSV. Công việc của trình tải sẽ là nhập dữ liệu CSV. Thông thường, bạn có thể triển khai các trình tìm và trình tải tương ứng trong một lớp chung. Đó là cách tiếp cận bạn sẽ thực hiện ở đây
153. Trong trường hợp đó, bạn tìm tệp CSV trong đường dẫn nhập đầy đủ, đường dẫn này sẽ bao gồm thư mục làm việc hiện tại. Nếu bạn đang nhập tệp CSV trong một gói, thì
198 sẽ được đặt thành đường dẫn hoặc nhiều đường dẫn của gói. Nếu bạn tìm thấy tệp CSV phù hợp, thì thông số mô-đun sẽ được trả về. Thông số mô-đun này yêu cầu Python tải mô-đun bằng cách sử dụng
303 từ thư viện chuẩn để thực hiện phân tích cú pháp tệp thực tế. Giống như hầu hết mọi thứ trong Python, các mô-đun được hỗ trợ bởi từ điển. Bằng cách thêm dữ liệu CSV vào
Nói chung, tên trường CSV có thể chứa khoảng trắng và các ký tự khác không được phép trong tên thuộc tính Python. Trước khi thêm các trường làm thuộc tính trên mô-đun, bạn làm sạch tên trường bằng biểu thức chính quy. Điều này được thực hiện trong
301 này vào hệ thống nhập Python, bạn sẽ nhận được khá nhiều chức năng miễn phí. Ví dụ: bộ đệm mô-đun sẽ đảm bảo rằng tệp dữ liệu chỉ được tải một lần
Mẹo và thủ thuật nhập khẩu
Để hoàn thiện hướng dẫn này, bạn sẽ thấy một số mẹo về cách xử lý các tình huống nhất định thỉnh thoảng xảy ra. Bạn sẽ thấy cách xử lý các gói bị thiếu, nhập theo chu kỳ và thậm chí cả các gói được lưu trữ bên trong tệp ZIP
Xử lý các gói trên các phiên bản Python
Đôi khi bạn cần xử lý các gói có tên khác nhau tùy thuộc vào phiên bản Python. Bạn đã thấy một ví dụ về điều này.
153 để tìm ra phiên bản nào sẽ sử dụng. Một tùy chọn khác là kiểm tra phiên bản của trình thông dịch Python. Tuy nhiên, điều này có thể thêm một số chi phí bảo trì nếu bạn cần cập nhật số phiên bản
319 để có lời khuyên hữu ích và phù hợp với tương lai về cách kiểm tra phiên bản Python nào đang chạy
Xử lý các gói bị thiếu. Sử dụng một thay thế
Trường hợp sử dụng sau có liên quan chặt chẽ với ví dụ trước. Giả sử có một gói triển khai lại tương thích. Việc triển khai lại được tối ưu hóa tốt hơn, vì vậy bạn muốn sử dụng nó nếu có sẵn. Tuy nhiên, gói ban đầu có sẵn dễ dàng hơn và cũng mang lại hiệu suất chấp nhận được
196, bạn không phải lo lắng về gói hàng nào thực sự được nhập khẩu
Xử lý các gói bị thiếu. Sử dụng Mock thay thế
Ví dụ thứ ba, có liên quan là thêm một gói cung cấp một tính năng tuyệt vời không thực sự cần thiết cho ứng dụng của bạn. Một lần nữa, điều này có thể được giải quyết bằng cách thêm
153 vào mục nhập của bạn. Thử thách bổ sung là bạn sẽ thay thế gói tùy chọn như thế nào nếu không có sẵn
Ví dụ cụ thể, giả sử bạn đang sử dụng Colorama để thêm văn bản màu trong bảng điều khiển. Colorama chủ yếu bao gồm các hằng số chuỗi đặc biệt có thêm màu khi in
338 cung cấp mã để kiểm soát vị trí của con trỏ. Bạn có thể sử dụng nó để hiển thị tiến trình hoặc trạng thái của tập lệnh đang chạy. Ví dụ sau hiển thị đếm ngược từ
Lưu ý cách bộ đếm giữ nguyên vị trí thay vì in trên các dòng riêng biệt như bình thường
Hãy quay lại với nhiệm vụ hiện tại. Đối với nhiều ứng dụng, việc thêm màu vào đầu ra bảng điều khiển của bạn rất thú vị nhưng không quan trọng. Để tránh thêm một phần phụ thuộc khác vào ứng dụng của mình, bạn chỉ muốn sử dụng Colorama nếu ứng dụng này có sẵn trên hệ thống và không phá vỡ ứng dụng nếu ứng dụng không có
Để làm điều này, bạn có thể lấy cảm hứng từ thử nghiệm và việc sử dụng mô phỏng. Một mô hình có thể thay thế cho một đối tượng khác đồng thời cho phép bạn kiểm soát hành vi của nó. Đây là một nỗ lực ngây thơ để chế giễu Colorama
343 là một chuỗi rỗng cũng sẽ trả về chuỗi rỗng khi nó được gọi. Điều này giúp chúng tôi triển khai lại Colorama một cách hiệu quả, chỉ cần không có màu sắc
Nếu bạn chạy tập lệnh này trên hệ thống không có Colorama thì tập lệnh vẫn hoạt động nhưng có thể trông không đẹp bằng
Khi cài đặt Colorama, bạn sẽ thấy kết quả giống như trước đó
Nhập tập lệnh dưới dạng mô-đun
Một điểm khác biệt giữa tập lệnh và mô-đun thư viện là tập lệnh thường làm một việc gì đó, trong khi thư viện cung cấp chức năng. Cả tập lệnh và thư viện đều nằm trong các tệp Python thông thường và đối với Python, không có sự khác biệt nào giữa chúng
Thay vào đó, sự khác biệt là ở chỗ tệp được sử dụng như thế nào. nó nên được thực thi với
Vì JSON thường chỉ được đọc bởi máy móc nên nhiều tệp JSON không được định dạng theo kiểu có thể đọc được. Trên thực tế, việc các tệp JSON bao gồm một dòng văn bản rất dài là điều khá phổ biến.
Mặc dù việc chia nhỏ tập lệnh và thư viện là một phương pháp hay, nhưng Python có một thành ngữ giúp có thể coi một mô-đun vừa là tập lệnh vừa là thư viện cùng một lúc. Như đã lưu ý trước đó, giá trị của biến mô-đun
Một tính năng hơi khó hiểu của Python là nó có thể chạy các tập lệnh được đóng gói thành các tệp ZIP. Ưu điểm chính của điều này là bạn có thể phân phối một gói đầy đủ dưới dạng một tệp
Tuy nhiên, lưu ý rằng điều này vẫn yêu cầu cài đặt Python trên hệ thống. Nếu bạn muốn phân phối ứng dụng Python của mình dưới dạng tệp thực thi độc lập, hãy xem Sử dụng PyInstaller để dễ dàng phân phối ứng dụng Python
Nếu bạn cung cấp cho trình thông dịch Python một tệp ZIP, thì nó sẽ tìm tệp có tên
Trên Windows, thay vào đó, bạn có thể sử dụng trỏ và nhấp. Chọn tệp trong File Explorer, sau đó nhấp chuột phải và chọn Gửi đến → thư mục đã nén (zipped)
394 trước tên tệp. Đây là một thủ thuật điển hình trên Mac và Linux để chạy các tệp thực thi trong thư mục hiện tại. Nếu bạn di chuyển tệp vào một thư mục trên
305. Lý do điều này không kết thúc trong đệ quy vô tận là người bạn cũ của chúng tôi bộ đệm mô-đun
Khi bạn nhập
>>> importmath>>> math.pi3.141592653589793
315, một tham chiếu đến
>>> importmath>>> math.pi3.141592653589793
305 sẽ được thêm vào bộ nhớ cache của mô-đun ngay cả trước khi tải
>>> importmath>>> math.pi3.141592653589793
305. Khi
>>> importmath>>> math.pi3.141592653589793
307 cố gắng nhập
>>> importmath>>> math.pi3.141592653589793
305 sau đó, nó chỉ cần sử dụng tham chiếu trong bộ đệm mô-đun
Bạn cũng có thể có các mô-đun làm điều gì đó hữu ích hơn một chút. Nếu bạn xác định các thuộc tính và chức năng trong các mô-đun của mình, thì tất cả vẫn hoạt động
Các sự cố liên quan đến nhập đệ quy bắt đầu xuất hiện khi bạn thực sự sử dụng mô-đun khác tại thời điểm nhập thay vì chỉ xác định các hàm sẽ sử dụng mô-đun khác sau này. Thêm một dòng vào
Vậy làm thế nào bạn có thể tránh bị sa lầy và bối rối bởi việc nhập khẩu theo chu kỳ?
Thông thường, thời gian dễ dàng nhất để khắc phục các lần nhập theo chu kỳ là trước khi bạn triển khai chúng. Nếu bạn thấy các chu kỳ trong bản phác thảo kiến trúc của mình, hãy xem xét kỹ hơn và cố gắng phá vỡ các chu kỳ đó
Tuy nhiên, đôi khi việc giới thiệu một chu kỳ nhập khẩu là hợp lý. Như bạn đã thấy ở trên, đây không phải là vấn đề miễn là các mô-đun của bạn chỉ định nghĩa các thuộc tính, hàm, lớp, v.v. Mẹo thứ hai—cũng là một phương pháp thiết kế tốt—là giữ cho các mô-đun của bạn không có tác dụng phụ khi nhập
Nếu bạn thực sự cần các mô-đun có chu kỳ nhập và tác dụng phụ, thì vẫn còn một cách khác. thực hiện nhập cục bộ của bạn bên trong các chức năng
Lưu ý rằng trong đoạn mã sau,
>>> importmath>>> math.pi3.141592653589793
306 được thực hiện bên trong
>>> importmath>>> math.pi3.141592653589793
328. Điều này có hai hậu quả. Đầu tiên,
>>> importmath>>> math.pi3.141592653589793
307 chỉ khả dụng bên trong hàm
>>> importmath>>> math.pi3.141592653589793
328. Quan trọng hơn, quá trình nhập không xảy ra cho đến khi bạn gọi
328. Để có một góc nhìn khác về nhập khẩu theo chu kỳ, hãy xem ghi chú kinh điển của Fredrik Lundh
Nhập hồ sơ
Một mối quan tâm khi nhập một số mô-đun và gói là nó sẽ thêm vào thời gian khởi động tập lệnh của bạn. Tùy thuộc vào ứng dụng của bạn, điều này có thể hoặc không quan trọng
Kể từ khi phát hành Python 3. 7, bạn đã có một cách nhanh chóng để biết cần bao nhiêu thời gian để nhập các gói và mô-đun. Trăn 3. 7 hỗ trợ tùy chọn dòng lệnh
>>> importmath>>> math.pi3.141592653589793
344, đo lường và in lượng thời gian mỗi mô-đun cần để nhập
124, trong đó khoảng 1. 6 giây được sử dụng trong chính mô-đun, chủ yếu để tải tệp dữ liệu
>>> importmath>>> math.pi3.141592653589793
344 là một công cụ tuyệt vời để tối ưu hóa quá trình nhập của bạn. Nếu bạn cần thực hiện giám sát và tối ưu hóa tổng quát hơn cho mã của mình, hãy xem Hàm hẹn giờ Python. Ba cách để theo dõi mã của bạn
Sự kết luận
Trong hướng dẫn này, bạn đã biết hệ thống nhập Python. Giống như nhiều thứ trong Python, nó khá đơn giản để sử dụng cho các tác vụ cơ bản như nhập mô-đun và gói. Đồng thời, hệ thống nhập khẩu khá phức tạp, linh hoạt và có thể mở rộng. Bạn đã học được một số thủ thuật liên quan đến nhập mà bạn có thể tận dụng trong mã của riêng mình
Trong hướng dẫn này, bạn đã học cách
Tạo các gói không gian tên
Nhập tài nguyên và tệp dữ liệu
Quyết định những gì cần nhập động trong thời gian chạy
Mở rộng hệ thống nhập của Python
Xử lý các phiên bản khác nhau của gói
Trong suốt hướng dẫn, bạn đã thấy nhiều liên kết đến thông tin thêm. Nguồn có thẩm quyền nhất trên hệ thống nhập Python là tài liệu chính thức
You can put your knowledge of Python imports to use by following along with the examples in this tutorial. Nhấp vào liên kết bên dưới để truy cập vào mã nguồn
Lấy mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để tìm hiểu về hệ thống nhập Python trong hướng dẫn này
Mark as Completed
🐍 Thủ thuật Python 💌
Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Hủy đăng ký bất cứ lúc nào. Curated by the Real Python team
Send Me Python Tricks »
About Geir Arne Hjelle
Geir Arne is an avid Pythonista and a member of the Real Python tutorial team
» Thông tin thêm về Geir Arne
Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are
Aldren
Brad
Dan
Joanna
Jacob
Master Real-World Python Skills With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas
Level Up Your Python Skills »
Master Real-World Python Skills With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas
Level Up Your Python Skills »
What Do You Think?
Đánh giá bài viết này
Tweet Chia sẻ Chia sẻ Email
Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?
Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi