Trong Python, bạn sử dụng từ khóa
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44 để tạo mã trong một mô-đun có sẵn trong một mô-đun khác. Nhập trong Python rất quan trọng để cấu trúc mã của bạn một cách hiệu quả. Sử dụng nhập đúng cách sẽ giúp bạn làm việc hiệu quả hơn, cho phép bạn sử dụng lại mã trong khi vẫn duy trì dự án của mìnhHướng dẫn này sẽ cung cấp một cái nhìn tổng quan về câu lệnh
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44 của Python và cách thức hoạt động của nó. Hệ thống nhập rất mạnh và bạn sẽ học cách khai thác sức mạnh này. 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ốtTrong 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. While all the code is shown in the tutorial, you can also download it by clicking the box below
Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial
Basic Python >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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 adsModules
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]
In practice, a module usually corresponds to one
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
47 file containing Python codeThe true power of modules is that they can be imported and reused in other code. Consider the following example
>>>
>>> import math
>>> math.pi
3.141592653589793
In the first line,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
48, you import the code in the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 module and make it available to use. In the second line, you access the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 variable within the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 module. >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 is part of Python’s standard library, which means that it’s always available to import when you’re running PythonNote that you write
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
53 and not just simply >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50. In addition to being a module, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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 PetersNamespaces are one honking great idea—let’s do more of those. [Source]
You can list the contents of a namespace with
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
56>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
Using
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
56 without any argument shows what’s in the global namespace. To see the contents of the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 namespace, you use >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
59You’ve already seen the most straightforward use of
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44. However, there are other ways to use it that allow you to import specific parts of a module and to rename the module as you import itThe following code imports only the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 variable from the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 module>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
1Note that this places
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 in the global namespace and not within a >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 namespaceYou can also rename modules and attributes as they’re imported
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
4For more details about the syntax for importing modules, check out Python Modules and Packages – An Introduction
gói
You can use a package to further organize your modules. The Python. org glossary defines package as follows
A Python module which can contain submodules or recursively, subpackages. Technically, a package is a Python module with an
65 attribute. [Source]>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 inside it. The >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 file contains the contents of the package when it’s treated as a module. It can be left emptyNote. Directories without an
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 file are still treated as packages by Python. Tuy nhiên, đây sẽ không phải là các gói thông thường, mà là một thứ gọi là gói không gian tên. Bạn sẽ tìm hiểu thêm về chúng sauNói chung, các mô-đun con và gói con không được nhập khi bạn nhập một gói. Tuy nhiên, bạn có thể sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 để bao gồm bất kỳ hoặc tất cả các mô hình con và gói con nếu bạn muốn. Để hiển thị một vài ví dụ về hành vi này, bạn sẽ tạo một gói để nói >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
70 bằng một vài ngôn ngữ khác nhau. Gói này sẽ bao gồm các thư mục và tệp sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
1Mỗi tệp quốc gia in ra một lời chào, trong khi tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 nhập có chọn lọc một số gói con và mô hình con. Nội dung chính xác của các tập tin như sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
3Lưu ý rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
72 chỉ nhập khẩu >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
73 chứ không phải >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
74. Tương tự, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
75 không nhập bất cứ thứ gì, trong khi >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
76 nhập >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
77 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
78 nhưng không nhập >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
79. Mỗi mô-đun quốc gia sẽ in lời chào khi được nhậpHãy chơi với gói
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
80 tại dấu nhắc tương tác để hiểu rõ hơn về cách hoạt động của các gói con và mô-đun con>>>
>>> import math
>>> math.pi
3.141592653589793
3Khi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
74 được nhập, các mô-đun >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
82 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
83 cũng được nhập. Bạn có thể thấy điều này vì các mô-đun quốc gia in lời chào khi chúng được nhập>>>
>>> import math
>>> math.pi
3.141592653589793
7Tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
75 trống. Điều này có nghĩa là việc nhập gói >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
85 sẽ tạo không gian tên nhưng không có tác dụng nào khác>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
0Hãy nhớ rằng, nhập một mô-đun vừa tải nội dung vừa tạo một không gian tên chứa nội dung. Một vài ví dụ cuối cùng cho thấy rằng cùng một mô-đun có thể là một phần của các không gian tên khác nhau
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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
86>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
2Bạn hiếm khi cần tương tác trực tiếp với
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
86Tương tự, không gian tên chung của Python cũng là một từ điển. Bạn có thể truy cập nó thông qua
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
88Việc nhập các gói con và mô-đun con trong tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 là khá phổ biến để cung cấp chúng dễ dàng hơn cho người dùng của bạn. Bạn có thể xem một ví dụ về điều này trong gói >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
90 phổ biếnRemove adsNhập khẩu tuyệt đối và tương đối
Nhớ lại mã nguồn của
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
72 trong ví dụ trước>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
0Bạn đã từng thấy các câu lệnh của
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
92 chẳng hạn như >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
93, nhưng dấu chấm [>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
94] trong >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
95 có nghĩa là gì?Dấu chấm đề cập đến gói hiện tại và câu lệnh là một ví dụ về nhập tương đối. Bạn có thể đọc nó là “Từ gói hiện tại, nhập gói phụ
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
73. ”Có một câu lệnh nhập tuyệt đối tương đương trong đó bạn đặt tên rõ ràng cho gói hiện tại
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
1Trên thực tế, tất cả các lần nhập trong
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
80 có thể đã được thực hiện rõ ràng với các lần nhập tuyệt đối tương tựNhập tương đối phải ở dạng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
92 và vị trí bạn đang nhập phải bắt đầu bằng dấu chấmHướng dẫn kiểu PEP 8 khuyến nghị sử dụng nhập khẩu tuyệt đối nói chung. However, relative imports are an alternative for organizing package hierarchies. Để 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 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
Ghi chú. Khi bạn nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
99, Python sẽ tìm kiếm >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
100 ở một số vị trí khác nhau trước khi tìm kiếm đường dẫn nhậpCụ thể, nó sẽ tìm kiếm trong bộ đệm mô-đun để xem liệu
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
100 đã được nhập chưa và nó sẽ tìm kiếm trong số các mô-đun tích hợpBạn sẽ tìm hiểu thêm về bộ máy nhập Python đầy đủ trong phần sau
Bạn có thể kiểm tra đường dẫn nhập Python bằng cách in
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
102. Nói chung, danh sách này sẽ chứa ba loại địa điểm khác nhau- Thư mục của tập lệnh hiện tại [hoặc thư mục hiện tại nếu không có tập lệnh nào, chẳng hạn như khi Python đang chạy tương tác]
- Nội dung của biến môi trường
103>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
- Các thư mục phụ thuộc vào cài đặt khác
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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
2Sử dụng mô-đun này hoạt động như mong đợi
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
3Nhưng mô-đun này cũng phủ bóng mô-đun
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 có trong thư viện chuẩn. Thật không may, điều đó có nghĩa là ví dụ tra cứu giá trị của π trước đây của chúng tôi không còn hoạt động nữa>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
4Vấn đề là Python hiện tìm kiếm mô-đun
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 mới của bạn cho >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 thay vì tìm kiếm mô-đun >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 trong thư viện chuẩnĐể tránh những loại sự cố này, bạn nên cẩn thận với tên của các mô-đun và gói của mình. 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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 được định nghĩa là một mô-đun con trong một gói, thì nó sẽ không che khuất mô-đun tích hợpRemove adsThí dụ. Cấu trúc nhập khẩu của bạn
Mặc dù có thể tổ chức quá trình nhập của bạn bằng cách sử dụng thư mục hiện tại cũng như bằng cách thao tác với
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
103 và thậm chí là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
102, quá trình này thường không theo quy tắc và dễ xảy ra lỗi. Để xem một ví dụ điển hình, hãy xem xét ứng dụng sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
5Ứng dụng sẽ tạo lại cấu trúc tệp đã cho bằng cách tạo thư mục và tệp trống. Tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
112 chứa tập lệnh chính và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
113 là mô-đun thư viện có một số chức năng để xử lý tệp. Sau đây là một ví dụ về đầu ra từ ứng dụng, trong trường hợp này bằng cách chạy nó trong thư mục >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
6Hai tệp mã nguồn cũng như tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
115 được tạo tự động được tạo lại bên trong một thư mục mới có tên là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
116Bây giờ hãy xem mã nguồn. Chức năng chính của ứng dụng được xác định trong
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
112>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
7Trong các dòng 12 đến 16, bạn đọc đường dẫn gốc từ dòng lệnh. Trong ví dụ trên bạn sử dụng dấu chấm, có nghĩa là thư mục hiện tại. Đường dẫn này sẽ được sử dụng làm
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
118 của hệ thống phân cấp tệp mà bạn sẽ tạo lạiCông việc thực tế xảy ra ở dòng 19 đến 23. Trước tiên, bạn tạo một đường dẫn duy nhất,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
119, đây sẽ là gốc của hệ thống phân cấp tệp mới của bạn. Sau đó, bạn lặp qua tất cả các đường dẫn bên dưới bản gốc >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
118 và tạo lại chúng dưới dạng các tệp trống bên trong hệ thống phân cấp tệp mớiĐể thao tác với các đường dẫn như thế này,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121 trong thư viện tiêu chuẩn khá hữu ích. Để biết thêm chi tiết về cách nó được sử dụng, hãy xem Mô-đun >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121 của Python 3. Thuần hóa hệ thống tập tinTrên dòng 26, bạn gọi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123. Bạn sẽ tìm hiểu thêm về bài kiểm tra trực tuyến ________ 2124 25 sau. Bây giờ, bạn nên biết rằng biến đặc biệt >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125 có giá trị >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
126 bên trong các tập lệnh, nhưng nó lấy tên của mô-đun bên trong các mô-đun đã nhập. Để biết thêm thông tin về >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125, hãy xem Xác định hàm chính trong Python và Điều gì sẽ xảy ra nếu tên == “chính” Làm trong Python?Lưu ý rằng bạn nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 trên dòng 8. Mô-đun thư viện này chứa hai chức năng tiện ích>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
8>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
129 sử dụng bộ đếm để tìm đường dẫn chưa tồn tại. Trong ứng dụng, bạn sử dụng nó để tìm một thư mục con duy nhất để sử dụng làm >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
119 của hệ thống phân cấp tệp được tạo lại. Tiếp theo, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
131 đảm bảo rằng tất cả các thư mục cần thiết đã được tạo trước khi tạo một tệp trống bằng cách sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
132Hãy xem lại việc nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
9Nó trông khá ngây thơ. Tuy nhiên, khi dự án phát triển, dòng này sẽ khiến bạn đau đầu. Mặc dù bạn nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 từ dự án >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114, việc nhập là tuyệt đối. nó không bắt đầu bằng dấu chấm. Điều này có nghĩa là phải tìm thấy >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 trong đường dẫn nhập để quá trình nhập hoạt độngMay mắn thay, thư mục chứa tập lệnh hiện tại luôn nằm trong đường dẫn nhập của Python, vì vậy hiện tại nó hoạt động tốt. Tuy nhiên, nếu dự án của bạn đạt được một số lực kéo, thì nó có thể được sử dụng theo những cách khác
Ví dụ: ai đó có thể muốn nhập tập lệnh vào Jupyter Notebook và chạy tập lệnh từ đó. Hoặc họ có thể muốn sử dụng lại thư viện
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 trong một dự án khác. Họ thậm chí có thể tạo một tệp thực thi bằng PyInstaller để phân phối dễ dàng hơn. Thật không may, bất kỳ tình huống nào trong số này đều có thể tạo ra sự cố khi nhập >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128Để xem ví dụ, bạn có thể làm theo hướng dẫn PyInstaller và tạo một điểm vào cho ứng dụng của mình. Thêm một thư mục bổ sung bên ngoài thư mục ứng dụng của bạn
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
10Trong thư mục bên ngoài, tạo tập lệnh điểm vào,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
139>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
11Tập lệnh này sẽ nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 từ tập lệnh gốc của bạn và chạy nó. Lưu ý rằng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 không chạy khi >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 được nhập vì thử nghiệm >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 trên dòng 25 trong >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
112. Điều đó có nghĩa là bạn cần chạy >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 một cách rõ ràngVề lý thuyết, điều này sẽ hoạt động tương tự như chạy ứng dụng trực tiếp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
12Tại sao nó không hoạt động?
Vấn đề là khi khởi động ứng dụng bằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
139, bạn đã thay đổi vị trí của tập lệnh hiện tại, do đó sẽ thay đổi đường dẫn nhập. >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 không còn trên đường dẫn nhập nên không thể nhập hoàn toànOne possible solution is to change Python’s import path
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
13Điều này hoạt động vì đường dẫn nhập bao gồm thư mục chứa
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
112 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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ểuTrong thực tế, bạn đang tạo lại một tính năng của các phiên bản Python đầu tiên được gọi là nhập tương đối ngầm định. Chúng đã bị xóa khỏi ngôn ngữ bởi PEP 328 với lý do sau
Trong Python 2. 4 trở về trước, nếu bạn đang đọc một mô-đun nằm bên trong một gói, thì không rõ liệu
151 đề cập đến một mô-đun cấp cao nhất hay một mô-đun khác bên trong gói. Khi thư viện của Python mở rộng, ngày càng có nhiều mô-đun bên trong gói hiện có đột nhiên che khuất các mô-đun thư viện tiêu chuẩn một cách tình cờ. Đây là một vấn đề đặc biệt khó khăn bên trong các gói vì không có cách nào để chỉ định mô-đun nào có nghĩa là. [Nguồn]>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
Một giải pháp khác là sử dụng nhập tương đối thay thế. Thay đổi quá trình nhập trong
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
112 như sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
14Giờ đây, bạn có thể bắt đầu ứng dụng của mình thông qua tập lệnh nhập cảnh
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
15Thật không may, bạn không còn có thể gọi ứng dụng trực tiếp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
16Vấ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. Tất nhiên, bạn có thể quay lại và khôi phục quá trình nhập tuyệt đối trước khi chạy tập lệnh trực tiếp hoặc thậm chí bạn có thể thực hiện một số động tác nhào lộn
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
153 để nhập tệp hoàn toàn hoặc tương đối tùy thuộc vào những gì hoạt độngThậm chí còn có một bản hack bị xử phạt chính thức để làm cho hoạt động nhập tương đối trong các tập lệnh. Thật không may, điều này cũng buộc bạn phải thay đổi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
102 trong hầu hết các trường hợp. Trích lời Raymond HettingerThere must be a better way. [Nguồn]
Thật vậy, một giải pháp tốt hơn—và ổn định hơn—là sử dụng cùng với hệ thống nhập và đóng gói của Python và cài đặt dự án của bạn dưới dạng gói cục bộ bằng cách sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155Remove adsTạo và cài đặt gói cục bộ
Khi bạn cài đặt một gói từ PyPI, gói đó có sẵn cho tất cả các tập lệnh trong môi trường của bạn. Tuy nhiên, bạn cũng có thể cài đặt các gói từ máy tính cục bộ của mình và chúng cũng sẽ được cung cấp theo cách tương tự
Tạo một gói cục bộ không liên quan nhiều đến chi phí. Đầu tiên, tạo các tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
156 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
157 tối thiểu trong thư mục >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 bên ngoài>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
17Về lý thuyết,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
160 có thể là bất cứ thứ gì bạn thích. Tuy nhiên, chúng sẽ được sử dụng bởi >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 khi đề cập đến gói của bạn, vì vậy bạn nên chọn các giá trị dễ nhận biết và không xung đột với các gói khác mà bạn sử dụngMột mẹo là cung cấp cho tất cả các gói cục bộ như vậy một tiền tố chung như
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162 hoặc tên người dùng của bạn. >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
163 nên liệt kê thư mục hoặc các thư mục chứa mã nguồn của bạn. Sau đó, bạn có thể cài đặt gói cục bộ bằng cách sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
18Lệnh này sẽ cài đặt gói vào hệ thống của bạn. Sau đó,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 sẽ được tìm thấy trên đường dẫn nhập của Python, nghĩa là bạn có thể sử dụng nó ở bất cứ đâu mà không phải lo lắng về thư mục tập lệnh, quá trình nhập tương đối hoặc các vấn đề phức tạp khác. Tùy chọn >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
166 có nghĩa là có thể chỉnh sửa, tùy chọn này rất quan trọng vì tùy chọn này cho phép bạn thay đổi mã nguồn của gói mà không cần cài đặt lạiGhi chú. 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
Để biết thêm chi tiết về các tệp thiết lập, hãy xem Cách xuất bản Gói Python mã nguồn mở lên PyPI
Giờ đây,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 đã được cài đặt trên hệ thống của bạn, bạn có thể sử dụng câu lệnh nhập sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
19Điều này sẽ hoạt động bất kể bạn kết thúc cuộc gọi ứng dụng của mình như thế nào
Mẹo. 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. Đây là một quy tắc tốt
- Một kịch bản có nghĩa là để được chạy
- Một thư viện có nghĩa là được nhập khẩu
Bạn có thể có mã mà bạn muốn tự chạy và nhập từ các tập lệnh khác. Trong trường hợp đó, thường đáng để cấu trúc lại mã của bạn để bạn chia phần chung thành một mô-đun thư viện
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. Trong phần sau, bạn sẽ tìm hiểu thêm về cách tạo các mô-đun xử lý tốt cả hai
Namespace Packages
Các mô-đun và gói Python có liên quan rất chặt chẽ với các tệp và thư mục. Điều này khiến Python khác biệt với nhiều ngôn ngữ lập trình khác, trong đó các gói chỉ hoạt động như các không gian tên mà không thực thi cách tổ chức mã nguồn. See the discussion in PEP 402 for examples
Các gói không gian tên đã có sẵn trong Python kể từ phiên bản 3. 3. Chúng ít phụ thuộc vào hệ thống phân cấp tệp cơ bản. Đặc biệt, các gói không gian tên có thể được chia thành nhiều thư mục. Gói không gian tên được tạo tự động nếu bạn có một thư mục chứa tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
47 nhưng không có tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66. Xem PEP 420 để được giải thích chi tiếtGhi chú. Nói chính xác, các gói không gian tên ẩn đã được giới thiệu trong 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 thống nhất và đơn giản hóa các phương pháp trước đó
Để hiểu rõ hơn về lý do tại sao các gói không gian tên có thể hữu ích, hãy thử triển khai một. Như một ví dụ thúc đẩy, bạn sẽ có một cách khác để giải quyết vấn đề trong Mẫu phương pháp xuất xưởng và triển khai của nó trong Python. được cung cấp một đối tượng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
170, bạn muốn chuyển đổi nó thành một trong số các biểu diễn chuỗi. Nói cách khác, bạn muốn tuần tự hóa các đối tượng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
170Để cụ thể hơn, bạn muốn triển khai mã hoạt động giống như thế này
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
40Giả sử rằng bạn may mắn và bắt gặp một triển khai của bên thứ ba cho một số định dạng mà bạn cần sắp xếp theo thứ tự và nó được tổ chức dưới dạng gói không gian tên
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
41Tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
172 chứa mã có thể tuần tự hóa một đối tượng thành định dạng JSON>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
42Giao diện bộ tuần tự hóa này có một chút hạn chế, nhưng nó sẽ đủ để chứng minh cách thức hoạt động của các gói không gian tên
Tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
173 chứa một >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
174 tương tự có thể chuyển đổi một đối tượng thành XML>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
43Lưu ý rằng cả hai lớp này đều triển khai cùng một giao diện với các phương thức
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
175, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
176 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
177Sau đó, bạn tạo một lớp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
170 có thể sử dụng các bộ nối tiếp này>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44Một
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
170 được xác định bởi ID, tiêu đề và nghệ sĩ của nó. Lưu ý rằng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
180 không cần biết nó chuyển đổi sang định dạng nào vì nó sử dụng giao diện chung được xác định trước đóGiả sử rằng bạn đã cài đặt gói
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 của bên thứ ba, bạn có thể sử dụng nó như sau>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
45Bằng cách cung cấp các đối tượng nối tiếp khác nhau cho
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
180, bạn sẽ nhận được các bản trình bày khác nhau cho bài hát của mìnhGhi chú. Bạn có thể nhận được một ________ 2183 hoặc một ________ 2184 khi tự chạy mã. Điều này là do
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 không có trong đường dẫn nhập Python của bạn. Bạn sẽ sớm biết cách giải quyết vấn đề đóCàng xa càng tốt. Tuy nhiên, bây giờ bạn nhận ra rằng bạn cũng cần chuyển đổi các bài hát của mình sang biểu diễn YAML, không được hỗ trợ trong thư viện của bên thứ ba. Nhập sự kỳ diệu của các gói không gian tên. bạn có thể thêm
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
186 của riêng mình vào gói >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 mà không cần chạm vào thư viện của bên thứ baĐầu tiên, tạo một thư mục trên hệ thống tệp cục bộ của bạn có tên là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181. Điều quan trọng là tên của thư mục phải khớp với tên của gói không gian tên mà bạn đang tùy chỉnh>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
46Trong tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
189, bạn xác định >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
186 của riêng mình. Bạn căn cứ vào gói >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
191, gói này phải được cài đặt từ PyPI>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
47Vì YAML và JSON có các định dạng khá giống nhau nên bạn có thể sử dụng lại hầu hết việc triển khai của
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
192>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
48Lưu ý rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
186 dựa trên >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
192, được nhập từ chính >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181. Vì cả >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
197 đều là một phần của cùng một gói không gian tên, bạn thậm chí có thể sử dụng nhập tương đối. >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
198Tiếp tục ví dụ trên, bây giờ bạn cũng có thể chuyển đổi bài hát sang YAML
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49Cũng giống như các gói và mô-đun thông thường, các gói không gian tên phải được tìm thấy trên đường dẫn nhập Python. If you were following along with the previous examples, then you might have had issues with Python not finding
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181. Trong mã thực tế, bạn sẽ sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 để cài đặt thư viện của bên thứ ba, do đó, nó sẽ tự động nằm trong đường dẫn của bạnGhi chú. Trong ví dụ ban đầu, việc lựa chọn bộ nối tiếp được thực hiện linh hoạt hơn. Bạn sẽ thấy cách sử dụng các gói không gian tên theo mẫu phương thức xuất xưởng thích hợp sau này
Bạn cũng nên đảm bảo rằng thư viện cục bộ của mình có sẵn như một gói thông thường. Như đã giải thích ở trên, bạn có thể thực hiện việc này bằng cách chạy Python từ thư mục thích hợp hoặc bằng cách sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 để cài đặt thư viện cục bộ.Trong ví dụ này, bạn đang kiểm tra cách tích hợp gói bên thứ ba giả mạo với gói cục bộ của mình. Nếu
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
402 là một gói thực, thì bạn sẽ tải xuống từ PyPI bằng cách sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155. Vì điều này là không thể, bạn có thể mô phỏng nó bằng cách cài đặt >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
402 cục bộ giống như bạn đã làm trong ví dụ >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 trước đóNgoài ra, bạn có thể gây rối với đường dẫn nhập của mình. Put the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
402 and >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
407 directories inside the same folder, then customize your Python path as follows>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
10Giờ đây, bạn có thể sử dụng tất cả các bộ nối tiếp mà không cần lo lắng về việc chúng được xác định trong gói của bên thứ ba hay cục bộ
Remove adsHướng dẫn phong cách nhập khẩu
PEP 8, hướng dẫn kiểu Python, có một số đề xuất về nhập. Như mọi khi với Python, giữ cho mã của bạn vừa có thể đọc được vừa có thể bảo trì là một điều quan trọng cần cân nhắc. Dưới đây là một số quy tắc chung về cách tạo kiểu cho hàng nhập của bạn
- Giữ nhập ở đầu tệp
- Viết nhập trên các dòng riêng biệt
- Organize imports into groups. nhập thư viện tiêu chuẩn đầu tiên, sau đó nhập của bên thứ ba và cuối cùng là nhập thư viện hoặc ứng dụng cục bộ
- Đặt hàng nhập khẩu theo thứ tự bảng chữ cái trong mỗi nhóm
- Thích nhập khẩu tuyệt đối hơn nhập khẩu tương đối
- Tránh nhập ký tự đại diện như
408>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
409 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
410 là những công cụ tuyệt vời để thực thi một phong cách nhất quán đối với hàng nhập của bạnĐây là một ví dụ về phần nhập bên trong gói trình đọc nguồn cấp Python thực
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
11Lưu ý cách nhóm này làm cho các phụ thuộc của mô-đun này rõ ràng.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
411 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
412 cần được cài đặt trên hệ thống. Nói chung, bạn có thể cho rằng thư viện tiêu chuẩn có sẵn. Việc tách các mục nhập từ bên trong gói cung cấp cho bạn một số tổng quan về các phụ thuộc nội bộ của mã của bạnCó những trường hợp nên bẻ cong các quy tắc này một chút. Bạn đã thấy rằng nhập tương đối có thể là một giải pháp thay thế cho việc tổ chức phân cấp gói. Sau này, bạn sẽ thấy trong một số trường hợp, bạn có thể di chuyển quá trình nhập vào một định nghĩa hàm như thế nào để phá vỡ các chu kỳ nhập
Nhập tài nguyên
Đôi khi, bạn sẽ có mã phụ thuộc vào tệp dữ liệu hoặc các tài nguyên khác. Trong các tập lệnh nhỏ, đây không phải là vấn đề—bạn có thể chỉ định đường dẫn đến tệp dữ liệu của mình và tiếp tục
Tuy nhiên, nếu tệp tài nguyên quan trọng đối với gói của bạn và bạn muốn phân phối gói của mình cho những người dùng khác, thì một số thách thức sẽ phát sinh
Bạn sẽ không có quyền kiểm soát đường dẫn đến tài nguyên vì điều đó sẽ phụ thuộc vào thiết lập của người dùng cũng như cách gói được phân phối và cài đặt. Bạn có thể cố gắng tìm ra đường dẫn tài nguyên dựa trên các thuộc tính
413 hoặc>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
65 của gói, nhưng điều này có thể không phải lúc nào cũng hoạt động như mong đợi>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
Gói của bạn có thể nằm trong tệp ZIP hoặc tệp
415 cũ, trong trường hợp đó, tài nguyên thậm chí sẽ không phải là tệp vật lý trên hệ thống của người dùng>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
Đã có một số nỗ lực giải quyết những thách thức này, bao gồm cả
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
416. Tuy nhiên, với việc đưa >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 vào thư viện chuẩn trong Python 3. 7, hiện có một cách tiêu chuẩn để xử lý các tệp tài nguyênGiới thiệu >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 quyền truy cập vào tài nguyên trong các gói được cung cấp. Trong ngữ cảnh này, tài nguyên là bất kỳ tệp nào nằm trong gói có thể nhập. Tệp có thể tương ứng hoặc không tương ứng với tệp vật lý trên hệ thống tệpĐiều này có một vài lợi thế. Bằng cách sử dụng lại hệ thống nhập, bạn sẽ có cách xử lý nhất quán hơn với các tệp bên trong các gói của mình. 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. Các tài liệu tổng hợp nó độc đáo
Nếu bạn có thể nhập một gói, bạn có thể truy cập các tài nguyên trong gói đó. [Nguồn]
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 đã trở thành một phần của thư viện chuẩn trong Python 3. 7. Tuy nhiên, trên các phiên bản Python cũ hơn, một cổng sau có sẵn dưới dạng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
421. To use the backport, install it from PyPI>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
12Backport tương thích với Python 2. 7 cũng như Python 3. 4 và các phiên bản mới hơn
Có một yêu cầu khi sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417. các tệp tài nguyên của bạn phải có sẵn bên trong một gói thông thường. Gói không gian tên không được hỗ trợ. Trong thực tế, điều này có nghĩa là tệp phải nằm trong thư mục chứa tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66As a first example, assume you have resources inside a package like this
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
13>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 chỉ là một tệp trống cần thiết để chỉ định >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
425 như một gói thông thườngSau đó, bạn có thể sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
426 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
427 để mở tệp văn bản và tệp nhị phân tương ứng>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
14>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
426 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
427 tương đương với >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
430 tích hợp sẵn với tham số >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
431 được đặt lần lượt là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
432 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
433. Các chức năng thuận tiện để đọc văn bản hoặc tệp nhị phân trực tiếp cũng có sẵn như >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
434 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
435. Xem tài liệu chính thức để biết thêm thông tinGhi chú. Để liên tục quay lại sử dụng backport trên các phiên bản Python cũ hơn, bạn có thể nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 như sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
15Xem phần mẹo và thủ thuật của hướng dẫn này để biết thêm thông tin
Phần còn lại của phần này sẽ hiển thị một số ví dụ phức tạp về việc sử dụng tệp tài nguyên trong thực tế
Remove adsThí dụ. Sử dụng tệp dữ liệu
Là một ví dụ đầy đủ hơn về việc sử dụng các tệp dữ liệu, bạn sẽ thấy cách triển khai chương trình đố vui dựa trên dữ liệu dân số của Liên hợp quốc. Đầu tiên, tạo gói
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
437 và tải xuống >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
438 từ trang web của Liên hợp quốc>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
16Mở tệp CSV và xem dữ liệu
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
17Mỗi dòng chứa dân số của một quốc gia trong một năm nhất định và một biến thể nhất định, cho biết loại kịch bản nào được sử dụng để chiếu. Tệp chứa dự báo dân số cho đến năm 2100
Hàm sau đọc tệp này và chọn ra tổng dân số của mỗi quốc gia cho một
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
439 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
440 nhất định>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
18Các dòng được đánh dấu cho biết cách sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 để mở tệp dữ liệu. Để 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 PythonHàm trên trả về một từ điển có số dân
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
19Bạn có thể thực hiện bất kỳ điều thú vị nào với từ điển dân số này, bao gồm phân tích và trực quan hóa. Tại đây, bạn sẽ tạo một trò chơi đố vui yêu cầu người dùng xác định quốc gia nào trong nhóm đông dân nhất. Chơi trò chơi sẽ giống như thế này
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
30Các chi tiết của việc triển khai nằm quá xa chủ đề của hướng dẫn này, vì vậy chúng sẽ không được thảo luận ở đây. Tuy nhiên, bạn có thể mở rộng phần bên dưới để xem mã nguồn hoàn chỉnh
Source Code of Population QuizShow/Hide
Bài kiểm tra dân số bao gồm hai chức năng, một chức năng đọc dữ liệu dân số như bạn đã làm ở trên và một chức năng chạy bài kiểm tra thực tế
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
31Note that on line 24, you also check that the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
442 is less than >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
443. Locations with a >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
442 of >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
443 and above are not proper countries, but aggregates like >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
446, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
447, and so onExample. Add Icons to Tkinter GUIs
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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417. The final app will look quite basic, but it’ll have a custom icon as well as an illustration on the Goodbye buttonThe 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
In Tkinter, images are handled by the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
449 class. To create a >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
449, you pass in a path to an image fileRemember, when distributing your package, you’re not even guaranteed that resource files will exist as physical files on the file system.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 solves this by providing >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
452. This function will return a path to the resource file, creating a temporary file if necessaryTo make sure any temporary files are cleaned up properly, you should use
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
452 as a context manager using the keyword >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
454>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
32For the full example, assume you have the following file hierarchy
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
33Nếu bạn muốn tự mình thử ví dụ, thì bạn có thể tải xuống các tệp này cùng với phần còn lại của mã nguồn được sử dụng trong hướng dẫn này bằng cách nhấp vào liên kết bên dưới
Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial
Mã được lưu trữ trong một tệp có tên đặc biệt
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455. This name indicates that the file is the entry point for the package. Có tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 cho phép gói của bạn được thực thi với >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
457>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
34Để biết thêm thông tin về cách gọi gói bằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
458, hãy xem Cách xuất bản Gói Python nguồn mở lên PyPIGUI được định nghĩa trong một lớp có tên là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
459. Lưu ý rằng bạn sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 để lấy đường dẫn của tệp hình ảnh>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
35Nếu bạn muốn tìm hiểu thêm về cách xây dựng GUI với Tkinter, hãy xem Lập trình GUI Python với Tkinter. Tài liệu chính thức cũng có một danh sách tài nguyên hay để bắt đầu và hướng dẫn tại TkDocs là một tài nguyên tuyệt vời khác cho biết cách sử dụng Tk trong các ngôn ngữ khác
Ghi chú. Một nguyên nhân gây nhầm lẫn và thất vọng khi làm việc với hình ảnh trong Tkinter là bạn phải đảm bảo hình ảnh không được thu gom rác. Do cách Python và Tk tương tác, trình thu gom rác trong Python [ít nhất là trong CPython] không đăng ký rằng hình ảnh được sử dụng bởi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
461 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
462Để đảm bảo rằng hình ảnh được lưu giữ xung quanh, bạn nên thêm tham chiếu đến chúng theo cách thủ công. Bạn có thể xem các ví dụ về điều này trong đoạn mã trên ở dòng 18 và 31
Remove adsNhập động
Một trong những tính năng xác định của Python là nó là một ngôn ngữ rất năng động. Mặc dù đôi khi đó là một ý tưởng tồi, nhưng bạn có thể thực hiện nhiều việc với chương trình Python khi nó đang chạy, bao gồm thêm thuộc tính vào lớp, xác định lại phương thức hoặc thay đổi chuỗi tài liệu của mô-đun. Chẳng hạn, bạn có thể thay đổi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
463 để nó không làm gì cả>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
36Về mặt kỹ thuật, bạn không định nghĩa lại
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
463. Thay vào đó, bạn đang xác định một >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
463 khác che khuất cái tích hợp sẵn. Để quay lại sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
463 ban đầu, bạn có thể xóa tùy chỉnh của mình bằng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
467. Nếu muốn, bạn có thể tạo bóng cho bất kỳ đối tượng Python nào được tích hợp trong trình thông dịchGhi chú. Trong ví dụ trên, bạn xác định lại
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
463 bằng hàm lambda. Bạn cũng có thể đã sử dụng một định nghĩa chức năng bình thường>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
37Để tìm hiểu thêm về các hàm lambda, hãy xem Cách sử dụng các hàm Lambda của Python
Trong phần này, bạn sẽ học cách nhập động trong Python. Với chúng, bạn sẽ không phải quyết định nhập nội dung gì cho đến khi chương trình của bạn đang chạy
Sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
Cho đến giờ, bạn đã sử dụng từ khóa
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44 của Python để nhập các mô-đun và gói một cách rõ ràng. Tuy nhiên, toàn bộ máy móc nhập khẩu có sẵn trong gói >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469 và điều này cho phép bạn thực hiện việc nhập khẩu của mình linh hoạt hơn. Đoạn script sau hỏi người dùng tên của một mô-đun, nhập mô-đun đó và in chuỗi tài liệu của nó>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
38>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
472 trả về một đối tượng mô-đun mà bạn có thể liên kết với bất kỳ biến nào. Sau đó, bạn có thể coi biến đó là một mô-đun được nhập thường xuyên. Bạn có thể sử dụng kịch bản như thế này>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
39Trong mỗi trường hợp, mô-đun được nhập động bởi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
472Thí dụ. Phương thức xuất xưởng với các gói không gian tên
Nghĩ lại ví dụ serializer từ trước đó. Với
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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. Trong ví dụ ban đầu từ hướng dẫn trước, các bộ nối tiếp được cung cấp thông qua một nhà máy sản xuất bộ nối tiếp. Sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469, bạn có thể làm điều gì đó tương tựThêm mã sau vào gói không gian tên
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 cục bộ của bạn>>> import math
>>> math.pi
3.141592653589793
30Nhà máy
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 có thể tự động tạo bộ nối tiếp dựa trên tham số >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
478 và sau đó, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
479 có thể áp dụng bộ nối tiếp cho bất kỳ đối tượng nào triển khai phương thức >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
180Nhà 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ẻ. Trong phần tiếp theo, bạn sẽ tìm hiểu về kiến trúc plugin cho phép linh hoạt hơn
Bây giờ bạn có thể tạo lại ví dụ trước đó như sau
>>>
>>> import math
>>> math.pi
3.141592653589793
31Trong trường hợp này, bạn không cần phải nhập rõ ràng từng bộ nối tiếp nữa. Thay vào đó, bạn chỉ định tên của bộ nối tiếp bằng một chuỗi. Chuỗi thậm chí có thể được chọn bởi người dùng của bạn khi chạy
Ghi chú. Trong một gói thông thường, bạn có thể đã triển khai
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
479 trong tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66. Điều đó sẽ cho phép bạn chỉ cần nhập >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 và sau đó gọi >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
485Tuy nhiên, các gói không gian tên không được phép sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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 khá rõ ràng 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 adsThí dụ. Một gói plugin
Hãy xem một ví dụ khác về việc sử dụng nhập động. 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
Bạn có thể thiết lập kiến trúc plugin tương tự mà bạn có thể sử dụng trong các dự án của riêng mình. 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
Mô-đun
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
487 hiển thị kiến trúc plugin có các chức năng sau>>> import math
>>> math.pi
3.141592653589793
32Cá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 triển khai bằng cách mở rộng phần bên dưới
Mã nguồn hoàn chỉnh của plugin. pyHiện/Ẩn
Đoạn mã sau cho thấy việc triển khai
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
488 được mô tả ở trên>>> import math
>>> math.pi
3.141592653589793
33Việ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
Bạn có thể thấy rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
489 sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
490 để tải động các plugin. Ngoài ra, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
491 sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
492 để liệt kê tất cả các plugin có sẵn trong một gói nhất địnhLet’s look at some examples of how to use plugins. The first example is a
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
493 package that you can use to add many different greetings to your app. A full plugin architecture is definitely overkill for this example, but it shows how the plugins workAssume you have the following
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
493 package>>> import math
>>> math.pi
3.141592653589793
34Each
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
493 module defines a function that takes one >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 argument. Note how they’re all registered as plugins using the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
497 decorator>>> import math
>>> math.pi
3.141592653589793
35To learn more about decorators and how they’re used, check out Primer on Python Decorators
Note. To simplify the discovery and import of plugins, each plugin’s name is based on the name of the module that contains it instead of the function name. This restricts you to having only one plugin per file
To finish setting up
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
493 as a plugin package, you can use the factory functions in >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
487 to add functionality to the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
493 package itself>>> import math
>>> math.pi
3.141592653589793
36You can now use
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
101 and >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
102 as follows>>>
>>> import math
>>> math.pi
3.141592653589793
37Note that
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
101 automatically discovers all the plugins that are available in the packageYou can also more dynamically choose which plugin to call. In the following example, you choose a plugin at random. However, you could also select a plugin based on a configuration file or user input
>>>
>>> import math
>>> math.pi
3.141592653589793
38To discover and call the different plugins, you need to import them. Let’s have a quick look at how
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
487 handles imports. The main work is done in the following two functions inside >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
488>>> import math
>>> math.pi
3.141592653589793
39>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
489 looks deceptively straightforward. It uses >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469 to import a module. But there are a couple of things also happening in the background- Python’s import system ensures that each plugin is imported only once
497 decorators defined inside each plugin module register each imported plugin>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
- In a full implementation, there would also be some error handling to deal with missing plugins
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
491 discovers all the plugins within a package. Here’s how it works
110 from>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 lists all the files inside a package>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
- The results are filtered to find potential plugins
- Each Python file not starting with an underscore is imported
- Plugins in any of the files are discovered and registered
Let’s end this section with a final version of the serializers namespace package. One outstanding issue was that the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 factory made strong assumptions about the naming of the serializer classes. You can make this more flexible using pluginsFirst, add a line registering each of the serializers. Here is an example of how it’s done in the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
197 serializer>>> import math
>>> math.pi
3.141592653589793
70Next, update
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 to use >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
487>>> import math
>>> math.pi
3.141592653589793
71You implement
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 using >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
117 since that will automatically instantiate each serializer. With this refactoring, the serializers work just the same as earlier. However, you have more flexibility in naming your serializer classesFor more information about using plugins, check out PyPlugs on PyPI and the Plug-ins. Adding Flexibility to Your Apps presentation from PyCon 2019
Remove adsThe Python Import System
You’ve seen many ways to take advantage of Python’s import system. In this section, you’ll learn a bit more about what happens behind the scenes as modules and packages are imported
As with most parts of Python, the import system can be customized. You’ll see several ways that you can change the import system, including automatically downloading missing packages from PyPI and importing data files as if they were modules
Import Internals
The details of the Python import system are described in the official documentation. At a high level, three things happen when you import a module [or package]. The module is
- Searched for
- Loaded
- Bound to a namespace
For the usual imports—those done with the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44 statement—all three steps happen automatically. When you use >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469, however, only the first two steps are automatic. You need to bind the module to a variable or namespace yourselfFor instance, the following methods of importing and renaming
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
53 are roughly equivalent>>>
>>> import math
>>> math.pi
3.141592653589793
72Of course, in normal code you should prefer the former
One thing to note is that, even when you import only one attribute from a module, the whole module is loaded and executed. The rest of the contents of the module just aren’t bound to the current namespace. One way to prove this is to have a look at what’s known as the module cache
>>>
>>> import math
>>> math.pi
3.141592653589793
73>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121 acts as a module cache. It contains references to all modules that have been importedThe module cache plays a very important role in the Python import system. The first place Python looks for modules when doing an import is in
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121. If a module is already available, then it isn’t loaded againThis is a great optimization, but it’s also a necessity. If modules were reloaded each time they were imported, then you could end up with inconsistencies in certain situations, such as when the underlying source code changes while a script is running
Recall the import path you saw earlier. It essentially tells Python where to search for modules. However, if Python finds a module in the module cache, then it won’t bother searching the import path for the module
Example. Singletons as Modules
In object-oriented programming, a singleton is a class with at most one instance. While it’s possible to implement singletons in Python, most good uses of singletons can be handled by modules instead. You can trust the module cache to instantiate a class only once
As an example, let’s return to the United Nations population data you saw earlier. The following module defines a class wrapping the population data
>>> import math
>>> math.pi
3.141592653589793
74Reading the data from disk takes some time. Since you don’t expect the data file to change, you instantiate the class when you load the module. The name of the class starts with an underscore to indicate to users that they shouldn’t use it
You can use the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 singleton to create a Matplotlib graph showing the population projection for the most populous countries>>>
>>> import math
>>> math.pi
3.141592653589793
75This creates a chart like the following
Note that loading the data at import time is a kind of antipattern. Ideally, you want your imports to be as free of side effects as possible. A better approach would be to load the data lazily when you need it. You can do this quite elegantly using properties. Expand the following section to see an example
Lazily Loading Population DataShow/Hide
The lazy implementation of
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 stores the population data in >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125 the first time it’s read. Thuộc tính >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
126 xử lý bộ đệm dữ liệu này>>> import math
>>> math.pi
3.141592653589793
76Now the data won’t be loaded at import time. Instead, it’ll be imported the first time you access the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
127 dictionary. For more information about properties and the more general concept of descriptors, see Python Descriptors. An IntroductionRemove adsTải lại mô-đun
The module cache can be a little frustrating when you’re working in the interactive interpreter. It’s not trivial to reload a module after you change it. For example, take a look at the following module
>>> import math
>>> math.pi
3.141592653589793
77As part of testing and debugging this module, you import it in a Python console
>>>
>>> import math
>>> math.pi
3.141592653589793
78Giả 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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 trong trình chỉnh sửa của mình>>> import math
>>> math.pi
3.141592653589793
79Returning to your console, you import the updated module to see the effect of your fix
>>>
>>> import math
>>> math.pi
3.141592653589793
78Why is the answer still
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
129? The module cache is doing its [now frustrating] magic. since Python imported >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
130 earlier, it sees no reason to load the module again even though you just changed itThe most straightforward solution to this is to exit the Python console and restart it. This forces Python to clear its module cache as well
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
01However, restarting the interpreter isn’t always feasible. You might be in a more complicated session that has taken you a long time to set up. If that’s the case, then you can use
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
131 to reload a module instead>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
02Note that
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
132 requires a module object, not a string like >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
472 does. Also, be aware that >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
132 has some caveats. In particular, variables referring to objects within a module are not re-bound to new objects when that module is reloaded. See the documentation for more detailsFinders and Loaders
You saw earlier that creating modules with the same name as standard libraries can create problems. For example, if you have a file named
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
135 in Python’s import path, then you won’t be able to import >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 from the standard libraryThis isn’t always the case, though. Create a file named
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
137 with the following content>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
03Next, open a Python interpreter and import this new module
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
04Something weird happened. It doesn’t seem like Python imported your new
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
138 module. Instead, it imported the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
138 module from the standard library. Why are the standard library modules behaving inconsistently? You can get a hint by inspecting the modules>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
05You can see that
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 is imported from a file, whereas >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
138 is some kind of built-in module. It seems that built-in modules aren’t shadowed by local onesNote. The built-in modules are compiled into the Python interpreter. Typically, they’re foundational modules like
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
142, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
143, and >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
138. Which modules are built in depends on your Python interpreter, but you can find their names in >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
145Let’s dig even deeper into Python’s import system. This will also show why built-in modules aren’t shadowed by local ones. There are several steps involved when importing a module
Python checks if the module is available in the module cache. If
121 contains the name of the module, then the module is already available, and the import process ends>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
Python starts looking for the module using several finders. A finder will search for the module using a given strategy. The default finders can import built-in modules, frozen modules, and modules on the import path
Python loads the module using a loader. Which loader Python uses is determined by the finder that located the module and is specified in something called a module spec
You can extend the Python import system by implementing your own finder and, if necessary, your own loader. You’ll see a more useful example of a finder later. For now, you’ll learn how to do basic [and possibly silly] customizations of the import system
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
147 controls which finders are called during the import process>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
06First, note that this answers the question from earlier. built-in modules aren’t shadowed by local modules because the built-in finder is called before the import path finder, which finds local modules. Second, note that you can customize
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
147 to your likingTo quickly mess up your Python session, you can remove all finders
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
07Since there are no finders, Python can’t find or import new modules. However, Python can still import modules that are already in the module cache since it looks there before calling any finders
In the example above,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469 was already loaded under the hood before you cleared the list of finders. If you really want to make your Python session completely unusable, then you can also clear the module cache, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121The following is a slightly more useful example. You’ll write a finder that prints a message to the console identifying the module being imported. The example shows how to add your own finder, although it doesn’t actually attempt to find a module
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
08All finders must implement a
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 class method, which should try to find a given module. There are three ways that >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 can terminate- By returning
153 if it doesn’t know how to find and load the module>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
- By returning a module spec specifying how to load the module
- By raising a
183 to indicate that the module can’t be imported>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
The
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 prints a message to the console and then explicitly returns >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
153 to indicate that other finders should figure out how to actually import the moduleNote. Since Python implicitly returns
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
153 from any function or method without an explicit >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
158, you can leave out line 9. However, in this case it’s good to include >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 to make it clear that >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 doesn’t find a moduleBy inserting
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 first in the list of finders, you get a running list of all modules being imported>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
09You can, for instance, see that importing
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162 triggers the import of several other modules that >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162 depends on. Note that the verbose option to the Python interpreter, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
164, gives the same information and much, much moreFor another example, say that you’re on a quest to rid the world of regular expressions. [Now, why would you want such a thing? Regular expressions are great. ] You could implement the following finder that bans the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
165 regular expressions module>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
20Raising a
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
183 ensures that no finder later in the list of finders will be executed. This effectively stops you from using regular expressions in Python>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
21Even though you’re importing only
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162, that module is importing >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
165 behind the scenes, so an error is raisedExample. Automatically Install From PyPI
Because the Python import system is already quite powerful and useful, there are many more ways to mess it up than there are to extend it in a useful way. However, the following example can be useful in certain situations
The Python Package Index [PyPI] is your one-stop cheese shop for finding third-party modules and packages. It’s also the place from which
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 downloads packagesIn other Real Python tutorials, you may have seen instructions to use
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
170 to install the third-party modules and packages you need for following along with examples. Wouldn’t it be great to have Python automatically install missing modules for you?Warning. In most cases, it really wouldn’t be great to have Python install modules automatically. For instance, in most production settings you want to stay in control of your environment. Furthermore, the documentation cautions against using
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 this wayTo avoid messing up your Python installation, you should play with this code only in environments that you wouldn’t mind deleting or reinstalling
The following finder attempts to install modules using
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
22Compared to the finders you saw earlier, this one is slightly more complicated. By putting this finder last in the list of finders, you know that if you call
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
173, then the module won’t be found on your system. The job of >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 is therefore just to do the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
175. If the installation works, then the module spec will be created and returnedTry to use the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
176 library without installing it yourself>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
23Normally,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
177 would’ve raised a >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
183, but in this case >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
176 is installed and importedWhile the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
173 seemingly works, there are some challenges with this approach. One major problem is that the import name of a module doesn’t always correspond to its name on PyPI. For example, the Real Python feed reader is called >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 on PyPI, but the import name is simply >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
182Using
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
173 to import and install >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
182 ends up installing the wrong package>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
24This could have disastrous consequences for your project
One situation in which automatic installations can be quite helpful is when you’re running Python in the cloud with more limited control over your environment, such as when you’re running Jupyter-style notebooks at Google Colaboratory. The Colab notebook environment is great for doing cooperative data exploration
A typical notebook comes with many data science packages installed, including NumPy, Pandas, and Matplotlib, and you can add new packages with
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155. Nhưng bạn cũng có thể kích hoạt cài đặt tự độngSince
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
186 isn’t available locally on the Colab server, the code is copied into the first cell of the notebookThí dụ. Import Data Files
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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 để nhập tệp dữ liệu. Tại đây, thay vào đó, bạn sẽ triển khai trình tải tùy chỉnh có thể nhập trực tiếp tệp CSVTrước đó, bạn đã làm việc với một tệp CSV khổng lồ chứa dữ liệu dân số. Để làm cho ví dụ về trình tải tùy chỉnh dễ quản lý hơn, hãy xem xét tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
188 nhỏ hơn sau đây>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
25Dò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
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
26Cô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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
27Có khá nhiều mã trong ví dụ này. May mắn thay, hầu hết công việc được thực hiện trong
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
190. Hãy xem xét chúng chi tiết hơnNhư bạn đã thấy trước đó,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 chịu trách nhiệm tìm mô-đun. Trong trường hợp này, bạn đang tìm tệp CSV, vì vậy bạn tạo tên tệp có hậu tố >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
192. >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 chứa tên đầy đủ của mô-đun được nhập. Ví dụ: nếu bạn sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
194, thì >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 sẽ là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196. Trong trường hợp này, tên tệp sẽ là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
188Đối với nhập cấp cao nhất,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
198 sẽ là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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ì >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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 >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
301Dữ liệu CSV được tải bởi
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
190. Bạn có thể sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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 >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
304, bạn cung cấp dữ liệu đó dưới dạng thuộc tính của mô-đunChẳng hạn, thêm
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
305 vào từ điển mô-đun ở dòng 44 cho phép bạn liệt kê các tên trường trong tệp CSV như sau>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
28Nó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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
306 bắt đầu từ dòng 51Bạn có thể xem ví dụ về hiệu ứng này trong tên trường
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
307 ở trên. Nếu bạn xem tệp CSV gốc thì bạn sẽ thấy tiêu đề có nội dung >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
308 với dấu cách thay vì dấu gạch dướiBằng cách kết nối
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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ầnMẹ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.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 chỉ khả dụng kể từ Python 3. 7. Trong các phiên bản Python cũ hơn, bạn cần cài đặt và sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
421 để thay thếMiễn là các phiên bản khác nhau của gói tương thích, bạn có thể xử lý vấn đề này bằng cách đổi tên gói thành
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
312>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
15Trong phần còn lại của mã, bạn có thể tham khảo
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
313 và không cần lo lắng về việc bạn đang sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 hay >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
421Thông thường, cách dễ nhất là sử dụng câu lệnh
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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ảnBạn có thể viết lại ví dụ trước như sau
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
00Điều này sẽ sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 trên Python 3. 7 trở lên trong khi quay lại >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
421 trên các phiên bản Python cũ hơn. See the >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
319 project for good and future-proof advice on how to check which Python version is runningMua 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
Một ví dụ như vậy là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
320, đây là phiên bản được tối ưu hóa của >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
321 từ thư viện chuẩn. Bạn có thể xử lý các tùy chọn này giống như cách bạn đã xử lý các tên gói khác nhau trước đó>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
01Điều này sẽ sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
320 nếu nó có sẵn và quay trở lại >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
321 nếu khôngMột ví dụ tương tự khác là gói UltraJSON, một bộ mã hóa và giải mã JSON cực nhanh có thể được sử dụng để thay thế cho
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196 trong thư viện chuẩn>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
02Bằng cách đổi tên
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
325 thành >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196, bạn không phải lo lắng về gói hàng nào thực sự được nhập khẩuMua 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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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ẵnVí dụ cụ thể, giả sử bạn đang sử dụng Colorama để thêm văn bản có 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
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
03Thật không may, màu sắc không hiển thị trong ví dụ trên. Trong thiết bị đầu cuối của bạn, nó sẽ trông giống như thế này
Trước khi bắt đầu sử dụng màu Colorama, bạn nên gọi cho
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
328. Đặt >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
329 thành >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
330 có nghĩa là các chỉ thị màu sẽ tự động được đặt lại ở cuối chuỗi. Đây là một cài đặt hữu ích nếu bạn chỉ muốn tô màu một dòng tại một thời điểmNếu bạn muốn tất cả đầu ra của mình [ví dụ] có màu xanh lam, thì bạn có thể để
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
329 là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
332 và thêm >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
333 vào đầu tập lệnh của mình. Các màu sau đây có sẵn>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
04Bạn cũng có thể sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
334 để kiểm soát phong cách văn bản của mình. Bạn có thể chọn giữa >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
335, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
336 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
337Cuối cùng,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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ừ >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
339>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
05Lư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 trở lại với nhiệm vụ trong tầm tay. Đố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 làm hỏng ứ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ế nhạo Colorama
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
06Điều này không thực sự hiệu quả, vì
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
340 được biểu thị bằng một chuỗi làm rối đầu ra của bạn. Thay vào đó, bạn muốn tạo một đối tượng luôn hiển thị dưới dạng chuỗi rỗngIt’s possible to change the return value of
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
177 on >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
342 objects. However, in this case, it’s more convenient to write your own mock>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
07>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
343 is an empty string that will also return the empty string when it’s called. This effectively gives us a reimplementation of Colorama, just without the colorsThe final trick is that
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
344 returns itself, so that all colors, styles, and cursor movements that are attributes on >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
345, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
346, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
347, and >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
348 are mocked as wellThe
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
349 module is designed to be a drop-in replacement for Colorama, so you can update the countdown example using search and replace>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
08Nế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
One difference between scripts and library modules is that scripts typically do something, whereas libraries provide functionality. 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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
350 hay được nhập với >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
351 bên trong một tập lệnh khác?Đôi khi bạn sẽ có một mô-đun hoạt động như cả tập lệnh và thư viện. Bạn có thể thử cấu trúc lại mô-đun của mình thành hai tệp khác nhau
Một ví dụ về điều này trong thư viện tiêu chuẩn là gói
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196. Bạn thường sử dụng nó như một thư viện, nhưng nó cũng đi kèm với một tập lệnh có thể chỉnh sửa các tệp JSON. Giả sử bạn có tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
353 sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
09Vì 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.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
354 là tập lệnh sử dụng thư viện >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196 để định dạng JSON theo cách dễ đọc hơn>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
10Bây giờ cấu trúc của tệp JSON trở nên dễ nắm bắt hơn nhiều. Bạn có thể sử dụng tùy chọn
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
356 để sắp xếp các khóa theo thứ tự bảng chữ cáiMặc dù việc chia nhỏ tập lệnh và thư viện là một cách thực hành tốt, 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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125 đặc biệt được đặt trong thời gian chạy dựa trên việc mô-đun được nhập hay chạy dưới dạng tập lệnhHãy thử nghiệm nó. Tạo tập tin sau
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
11Nếu bạn chạy tệp này, thì bạn sẽ thấy rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125 được đặt thành giá trị đặc biệt >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
126>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
12Tuy nhiên, nếu bạn nhập mô-đun, thì
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125 được đặt thành tên của mô-đun>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
13Hành vi này được tận dụng trong mẫu sau
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
14Hãy sử dụng điều này trong một ví dụ lớn hơn. Với nỗ lực giúp bạn luôn trẻ trung, tập lệnh sau sẽ thay thế bất kỳ độ tuổi “già” nào [
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
361 trở lên] bằng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
129>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
15Bạn có thể chạy tập lệnh này dưới dạng tập lệnh và nó sẽ tương tác làm cho độ tuổi bạn nhập trẻ hơn
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
16Bạn cũng có thể sử dụng mô-đun làm thư viện có thể nhập. Bài kiểm tra
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 ở dòng 12 đảm bảo rằng không có tác dụng phụ khi bạn nhập thư viện. Chỉ các chức năng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
364 và >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
365 được xác định. Ví dụ, bạn có thể sử dụng thư viện này như sau>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
17Nếu không có sự bảo vệ của thử nghiệm
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124, quá trình nhập sẽ kích hoạt >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
367 tương tác và khiến cho việc sử dụng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
368 làm thư viện trở nên rất khó khănChạy tập lệnh Python từ tệp ZIP
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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 bên trong kho lưu trữ ZIP, giải nén và chạy tệp đó. Như một ví dụ cơ bản, tạo tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
18Điều này sẽ in một tin nhắn khi bạn chạy nó
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
19Bây giờ hãy thêm nó vào kho lưu trữ ZIP. Bạn có thể làm điều này trên dòng lệnh
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
20On Windows, you can instead use point and click. 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]
Vì
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
126 không phải là một cái tên mang tính mô tả nhiều nên bạn đã đặt tên cho tệp ZIP là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
372. Bây giờ bạn có thể gọi nó trực tiếp bằng Python>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
21Lưu ý rằng tập lệnh của bạn biết rằng nó nằm bên trong
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
372. Hơn nữa, gốc của tệp ZIP của bạn được thêm vào đường dẫn nhập của Python để tập lệnh của bạn có thể nhập các mô-đun khác trong cùng một tệp ZIPNghĩ lại ví dụ trước đó mà bạn đã tạo một bài kiểm tra dựa trên dữ liệu dân số. Có thể phân phối toàn bộ ứng dụng này dưới dạng một tệp ZIP.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 sẽ đảm bảo tệp dữ liệu được trích xuất từ kho lưu trữ ZIP khi cầnỨng dụng bao gồm các tệp sau
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
22Bạn có thể thêm chúng vào tệp ZIP giống như cách bạn đã làm ở trên. Tuy nhiên, Python đi kèm với một công cụ có tên là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 hợp lý hóa quy trình đóng gói các ứng dụng vào kho lưu trữ ZIP. Bạn sử dụng nó như sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
23Lệnh này về cơ bản thực hiện hai việc. nó tạo ra một điểm vào và đóng gói ứng dụng của bạn
Hãy nhớ rằng bạn cần tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 làm điểm vào bên trong kho lưu trữ ZIP của mình. Nếu bạn cung cấp cho tùy chọn >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
458 thông tin về cách bắt đầu ứng dụng của bạn, thì >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 sẽ tạo tệp này cho bạn. Trong ví dụ này, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 được tạo trông như thế này>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
24>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 này được đóng gói, cùng với nội dung của thư mục >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
381, vào một kho lưu trữ ZIP có tên là >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
382. Hậu tố >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
383 báo hiệu rằng đây là tệp Python được gói trong kho lưu trữ ZIPGhi chú. Theo mặc định,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 không nén bất kỳ tệp nào. Nó chỉ đóng gói chúng thành một tệp duy nhất. Bạn cũng có thể yêu cầu >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 nén các tệp bằng cách thêm tùy chọn >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
386Tuy nhiên, tính năng này chỉ khả dụng trong Python 3. 7 trở lên. Xem tài liệu
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 để biết thêm thông tinTrên Windows, các tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
383 đã được đăng ký dưới dạng tệp Python. Trên Mac và Linux, bạn có thể yêu cầu >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 tạo các tệp thực thi bằng cách sử dụng tùy chọn trình thông dịch >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
390 và chỉ định trình thông dịch nào sẽ sử dụng>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
25Tùy chọn
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
390 thêm một shebang [>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
392] cho hệ điều hành biết cách chạy tệp. Ngoài ra, nó làm cho tệp >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
383 có thể thực thi được để bạn có thể chạy tệp chỉ bằng cách nhập tên của nó>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
26Lưu ý
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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 >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
395 của mình hoặc nếu bạn đang sử dụng Windows thì bạn chỉ có thể sử dụng tên tệp. >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
382Ghi chú. Trên Python 3. 6 trở lên, lệnh trước đó sẽ thất bại với thông báo nói rằng nó không thể tìm thấy tài nguyên dữ liệu dân số trong thư mục
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
437. Điều này là do một giới hạn trong >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
398Một cách giải quyết khác là cung cấp đường dẫn tuyệt đối tới
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
382. Trên Mac và Linux, bạn có thể làm điều này bằng thủ thuật sau>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
27Lệnh
>>> import math
>>> math.pi
3.141592653589793
300 mở rộng đến đường dẫn của thư mục hiện tạiHãy kết thúc phần này bằng cách xem xét một hiệu ứng tuyệt vời khi sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417. Hãy nhớ rằng bạn đã sử dụng đoạn mã sau để mở tệp dữ liệu>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
28Một cách phổ biến hơn để mở tệp dữ liệu là xác định vị trí của chúng dựa trên thuộc tính
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
413 của mô-đun của bạn>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
29Cách tiếp cận này thường hoạt động tốt. Tuy nhiên, nó sẽ bị hỏng khi ứng dụng của bạn được đóng gói thành tệp ZIP
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
30Tệp dữ liệu của bạn nằm trong kho lưu trữ ZIP nên
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
430 không thể mở tệp đó. Mặt khác, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 sẽ trích xuất dữ liệu của bạn thành một tệp tạm thời trước khi mở tệp đóNhập khẩu theo chu kỳ thương mại
Nhập theo chu kỳ xảy ra khi bạn có hai hoặc nhiều mô-đun nhập lẫn nhau. Cụ thể hơn, hãy tưởng tượng rằng mô-đun
>>> import math
>>> math.pi
3.141592653589793
305 sử dụng >>> import math
>>> math.pi
3.141592653589793
306 và mô-đun >>> import math
>>> math.pi
3.141592653589793
307 nhập khẩu tương tự >>> import math
>>> math.pi
3.141592653589793
305Hệ thống nhập Python ở một mức độ nào đó được thiết kế để xử lý các chu kỳ nhập. Chẳng hạn, đoạn mã sau—mặc dù không hữu dụng lắm—chạy tốt
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
31Cố gắng nhập
>>> import math
>>> math.pi
3.141592653589793
305 trong trình thông dịch tương tác cũng nhập >>> import math
>>> math.pi
3.141592653589793
307>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
32Lưu ý rằng
>>> import math
>>> math.pi
3.141592653589793
307 được nhập vào giữa quá trình nhập của >>> import math
>>> math.pi
3.141592653589793
305, chính xác tại câu lệnh >>> import math
>>> math.pi
3.141592653589793
306 trong mã nguồn của >>> import math
>>> math.pi
3.141592653589793
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ô-đunKhi bạn nhập
>>> import math
>>> math.pi
3.141592653589793
315, một tham chiếu đến >>> import math
>>> math.pi
3.141592653589793
305 sẽ được thêm vào bộ nhớ cache của mô-đun ngay cả trước khi tải >>> import math
>>> math.pi
3.141592653589793
305. Khi >>> import math
>>> math.pi
3.141592653589793
307 cố gắng nhập >>> import math
>>> math.pi
3.141592653589793
305 sau đó, nó chỉ cần sử dụng tham chiếu trong bộ đệm mô-đunBạ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
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
33Nhập
>>> import math
>>> math.pi
3.141592653589793
305 hoạt động giống như trước đây>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
32Cá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
>>> import math
>>> math.pi
3.141592653589793
321>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
35Bây giờ Python bị nhầm lẫn khi nhập
>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
36Thông báo lỗi lúc đầu có vẻ hơi khó hiểu. Nhìn lại mã nguồn, bạn có thể xác nhận rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
130 được định nghĩa trong mô-đun >>> import math
>>> math.pi
3.141592653589793
305Vấn đề là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
130 không được xác định trong >>> import math
>>> math.pi
3.141592653589793
305 tại thời điểm >>> import math
>>> math.pi
3.141592653589793
307 được nhập. Do đó, >>> import math
>>> math.pi
3.141592653589793
327 được sử dụng bởi lệnh gọi tới >>> import math
>>> math.pi
3.141592653589793
328Thêm vào sự nhầm lẫn, bạn sẽ không gặp vấn đề gì khi nhập
>>> import math
>>> math.pi
3.141592653589793
307>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
37Vào thời điểm
>>> import math
>>> math.pi
3.141592653589793
307 gọi >>> import math
>>> math.pi
3.141592653589793
328, >>> import math
>>> math.pi
3.141592653589793
305 được nhập đầy đủ và >>> import math
>>> math.pi
3.141592653589793
327 được xác định rõ. Cuối cùng, do bộ đệm mô-đun mà bạn đã thấy trước đó, >>> import math
>>> math.pi
3.141592653589793
315 có thể hoạt động nếu bạn thực hiện một số thao tác nhập khác trước>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
38Vậ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 đưa ra 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 lối thoát 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,
>>> import math
>>> math.pi
3.141592653589793
306 được thực hiện bên trong >>> import math
>>> math.pi
3.141592653589793
328. Điều này có hai hậu quả. Đầu tiên, >>> import math
>>> math.pi
3.141592653589793
307 chỉ khả dụng bên trong hàm >>> import math
>>> math.pi
3.141592653589793
328. Quan trọng hơn, quá trình nhập không diễn ra cho đến khi bạn gọi >>> import math
>>> math.pi
3.141592653589793
328 sau khi >>> import math
>>> math.pi
3.141592653589793
305 đã được nhập hoàn toàn>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
39Bây giờ không có vấn đề gì khi nhập và sử dụng
>>> import math
>>> math.pi
3.141592653589793
305>>>
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
40Lưu ý rằng trên thực tế,
>>> import math
>>> math.pi
3.141592653589793
307 không được nhập cho đến khi bạn gọi >>> import math
>>> math.pi
3.141592653589793
328. Để có 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 LundhNhậ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
>>> import math
>>> math.pi
3.141592653589793
344, đo lường và in lượng thời gian mỗi mô-đun cần để nhập>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
41Cột
>>> import math
>>> math.pi
3.141592653589793
345 hiển thị thời gian nhập tích lũy [tính bằng micrô giây] trên cơ sở từng gói. Bạn có thể đọc danh sách như sau. Python đã dành >>> import math
>>> math.pi
3.141592653589793
346 micro giây để nhập đầy đủ >>> import math
>>> math.pi
3.141592653589793
347, bao gồm cả việc nhập >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
138, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 và triển khai C >>> import math
>>> math.pi
3.141592653589793
350Cột
>>> import math
>>> math.pi
3.141592653589793
351 hiển thị thời gian cần thiết để chỉ nhập mô-đun đã cho, không bao gồm mọi lần nhập đệ quy. Bạn có thể thấy rằng >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
138 mất >>> import math
>>> math.pi
3.141592653589793
353 micro giây để nhập, >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 mất >>> import math
>>> math.pi
3.141592653589793
355, >>> import math
>>> math.pi
3.141592653589793
350 mất >>> import math
>>> math.pi
3.141592653589793
357 và bản thân việc nhập >>> import math
>>> math.pi
3.141592653589793
347 mất >>> import math
>>> math.pi
3.141592653589793
359 micro giây. Nói chung, điều này làm tăng thêm thời gian tích lũy là >>> import math
>>> math.pi
3.141592653589793
346 micro giây [trong phạm vi lỗi làm tròn]Hãy xem ví dụ về
>>> import math
>>> math.pi
3.141592653589793
361 từ phần Colorama>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
42Trong ví dụ này, việc nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
349 mất gần 0. 013 giây. Hầu hết thời gian đó được dành để nhập Colorama và các phụ thuộc của nó. Cột >>> import math
>>> math.pi
3.141592653589793
351 hiển thị thời gian nhập không bao gồm nhập lồng nhauĐối với một ví dụ cực đoan, hãy xem xét đơn lẻ
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 từ trước đó. Vì nó đang tải một tệp dữ liệu lớn nên nhập cực kỳ chậm. Để kiểm tra điều này, bạn có thể chạy >>> import math
>>> math.pi
3.141592653589793
365 dưới dạng tập lệnh với tùy chọn >>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
386>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
43Trong trường hợp này, mất gần 2 giây để nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']
>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
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>>> import math
>>> math.pi
3.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ạnSự kết luận
Trong hướng dẫn này, bạn đã biết về 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 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
- Hệ thống nhập khẩu
- Gói
469>>> import math >>> dir[] ['__annotations__', '__builtins__', ..., 'math'] >>> dir[math] ['__doc__', ..., 'nan', 'pi', 'pow', ...]
- PEP 420. Gói không gian tên ẩn
- Nhập mô-đun
Bạn có thể sử dụng kiến thức về nhập Python của mình bằng cách làm theo các ví dụ trong hướng dẫn này. Nhấp vào liên kết bên dưới để truy cập vào mã nguồn
Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial
Đánh dấu là đã hoàn thành
🐍 Thủ thuật Python 💌
Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python
Gửi cho tôi thủ thuật Python »
Giới thiệu về Geir Arne Hjelle
Geir Arne là một Pythonista cuồng nhiệt và là thành viên của nhóm hướng dẫn Real Python
» Thông tin thêm về Geir ArneMỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là
Tuổi tác
Brad
Đan
Joanna
Jacob
Master Real-World Python Skills With Unlimited Access to Real Python
Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia
Nâng cao kỹ năng Python của bạn »
Bậc thầy Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực
Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia
Nâng cao kỹ năng Python của bạn »
Bạn nghĩ sao?
Đánh giá bài viết này
Tweet Chia sẻ Chia sẻ EmailBà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