Nhập tất cả các chức năng từ tệp python

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ình

Hướ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ốt

Trong hướng dẫn này, bạn sẽ học cách

  • Sử dụng các mô-đun, gói và gói không gian tên
  • Xử lý các tệp tài nguyên và dữ liệu bên trong các gói của bạn
  • Nhập mô-đun động khi chạy
  • Tùy chỉnh hệ thống nhập của Python

Xuyên suốt hướng dẫn, bạn sẽ thấy các ví dụ về cách chơi với bộ máy nhập Python để hoạt động hiệu quả nhất. Mặc dù tất cả mã được hiển thị trong hướng dẫn, nhưng bạn cũng có thể tải xuống bằng cách nhấp vào hộp bên dưới

Lấy mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để tìm hiểu về hệ thống nhập Python trong hướng dẫn này

Python cơ bản
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44

Mã Python được tổ chức thành cả mô-đun và gói. Phần này sẽ giải thích chúng khác nhau như thế nào và bạn có thể làm việc với chúng như thế nào

Ở phần sau của hướng dẫn, bạn sẽ thấy một số cách sử dụng nâng cao và ít được biết đến của hệ thống nhập của Python. Tuy nhiên, hãy bắt đầu với những điều cơ bản. nhập mô-đun và gói

Loại bỏ các quảng cáo

mô-đun

con trăn. thuật ngữ org định nghĩa mô-đun như sau

Một đối tượng phục vụ như một đơn vị tổ chức của mã Python. Các mô-đun có một không gian tên chứa các đối tượng Python tùy ý. Các mô-đun được tải vào Python bằng quá trình nhập. [Nguồn]

Trong thực tế, một mô-đun thường tương ứng với một tệp

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
47 chứa mã Python

Sức mạnh thực sự của các mô-đun là chúng có thể được nhập và sử dụng lại trong mã khác. Xem xét ví dụ sau

>>>

>>> import math
>>> math.pi
3.141592653589793

Trong dòng đầu tiên,

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
48, bạn nhập mã trong mô-đun
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 và cung cấp mã đó để sử dụng. Ở dòng thứ hai, bạn truy cập biến
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 trong mô-đun
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 là một phần của thư viện chuẩn của Python, có nghĩa là nó luôn có sẵn để nhập khi bạn chạy Python

Lưu ý rằng bạn viết

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
53 và không chỉ đơn giản là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50. Ngoài vai trò là một mô-đun,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 hoạt động như một không gian tên giữ tất cả các thuộc tính của mô-đun lại với nhau. Không gian tên rất hữu ích để giữ cho mã của bạn dễ đọc và có tổ chức. Theo lời của Tim Peters

Không gian tên là một ý tưởng tuyệt vời—hãy làm nhiều hơn thế nữa. [Nguồn]

Bạn có thể liệt kê nội dung của một không gian tên với

>>> 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', ...]

Sử dụng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
56 mà không có bất kỳ đối số nào sẽ hiển thị những gì trong không gian tên chung. Để xem nội dung của không gian tên
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49, bạn sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
59

Bạn đã thấy cách sử dụng đơn giản nhất của

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44. Tuy nhiên, có nhiều cách khác để sử dụng nó cho phép bạn nhập các phần cụ thể của mô-đun và đổi tên mô-đun khi bạn nhập mô-đun đó

Đoạn mã sau chỉ nhập biến

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 từ mô-đun
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
1

Lưu ý rằng nơi này đặt

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 trong không gian tên chung chứ không phải trong không gian tên
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49

Bạn cũng có thể đổi tên các mô-đun và thuộc tính khi chúng được nhập

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
4

Để biết thêm chi tiết về cú pháp nhập mô-đun, hãy xem Mô-đun và Gói Python – Giới thiệu

gói

Bạn có thể sử dụng một gói để tổ chức thêm các mô-đun của mình. con trăn. thuật ngữ org định nghĩa gói như sau

Một mô-đun Python có thể chứa các mô-đun con hoặc đệ quy, các gói con. Về mặt kỹ thuật, một gói là một mô-đun Python có thuộc tính

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
65. [Nguồn]

Lưu ý rằng một gói vẫn là một mô-đun. Là người dùng, bạn thường không cần phải lo lắng về việc bạn đang nhập mô-đun hay gói

Trong thực tế, một gói thường tương ứng với một thư mục tệp chứa các tệp Python và các thư mục khác. Để tự tạo một gói Python, bạn tạo một thư mục và một tệp có tên

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 bên trong nó. Tệp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 chứa nội dung của gói khi được coi là mô-đun. Nó có thể để trống

Ghi chú. Các thư mục không có tệp

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 vẫn được Python coi là gói. 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 sau

Nó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', ...]
1

Mỗ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', ...]
3

Lư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ập

Hã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
3

Khi

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

Tệ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', ...]
0

Remember, importing a module both loads the contents and creates a namespace containing the contents. The last few examples show that it’s possible for the same module to be part of different namespaces

Technical Detail. The module namespace is implemented as a Python dictionary and is available at the

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
86 attribute

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
2

You rarely need to interact with

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
86 directly

Tương tự, không gian tên toàn cục của Python cũng là một từ điển. You can access it through

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
88

It’s fairly common to import subpackages and submodules in an

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 file to make them more readily available to your users. You can see one example of this in the popular
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
90 package

Loại bỏ các quảng cáo

Absolute and Relative Imports

Recall the source code of

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
72 in the earlier example

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
0

Bạ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. ”

There’s an equivalent absolute import statement in which you explicitly name the current package

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
1

In fact, all imports in

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
80 could have been done explicitly with similar absolute imports

Relative imports must be in the form

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
92, and the location you’re importing from must start with a dot

The PEP 8 style guide recommends using absolute imports in general. However, relative imports are an alternative for organizing package hierarchies. For more information, see Absolute vs Relative Imports in Python

Python’s Import Path

How does Python find the modules and packages it imports? You’ll see more details about the mechanics of the Python import system later. For now, just know that Python looks for modules and packages in its import path. This is a list of locations that are searched for modules to import

Note. When you type

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
99, Python will look for
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
100 a few different places before searching the import path

In particular, it’ll look in a module cache to see if

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
100 has already been imported, and it’ll search among the built-in modules

You’ll learn more about the full Python import machinery in a later section

You can inspect Python’s import path by printing

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
102. Broadly speaking, this list will contain three different kinds of locations

  1. The directory of the current script [or the current directory if there’s no script, such as when Python is running interactively]
  2. The contents of the
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    103 environment variable
  3. Other, installation-dependent directories

Typically, Python will start at the beginning of the list of locations and look for a given module in each location until the first match. Since the script directory or the current directory is always first in this list, you can make sure that your scripts find your self-made modules and packages by organizing your directories and being careful about which directory you run Python from

However, you should also be careful that you don’t create modules that shadow, or hide, other important modules. As an example, say that you define the following

>>> 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', ...]
2

Sử dụng mô-đun này hoạt động như mong đợi

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
3

But this module also shadows the

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 module that’s included in the standard library. 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', ...]
4

The problem is that Python now searches your new

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 module for
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
50 instead of searching the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 module in the standard library

Để 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. In particular, your top-level module and package names should be unique. 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ợp

Loại bỏ các quảng cáo

Thí dụ. Structure Your Imports

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, nhưng quá trình này thường không theo quy tắc và dễ xảy ra lỗi. To see a typical example, consider the following application

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
5

The app will re-create a given file structure by creating directories and empty files. 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', ...]
6

The two source code files as well as the automatically created

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
115 file are re-created inside a new directory named
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
116

Now take a look at the source code. 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', ...]
7

Trong các dòng 12 đến 16, bạn đọc đường dẫn gốc từ dòng lệnh. In the above example you use a dot, which means the current directory. This path will be used as the

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
118 of the file hierarchy that you’ll re-create

Cô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. Then you loop through all paths below the original
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
118 and re-create them as empty files inside the new file hierarchy

For manipulating paths like this,

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121 in the standard library is quite useful. Để 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 tin

On line 26, you call

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123. You’ll learn more about the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 test on line 25 later. 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. For more information on
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125, check out Defining Main Functions in Python and What Does if name == “main” Do in Python?

Note that you import

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 on line 8. This library module contains two utility functions

>>> 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 uses a counter to find a path that doesn’t already exist. In the app, you use it to find a unique subdirectory to use as the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
119 of the re-created file hierarchy. 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', ...]
132

Hã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', ...]
9

Nó 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 động

May 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. However, if your project gains some traction, then it may be used in other ways

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. Unfortunately, any of these scenarios can create issues with the import of
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128

To see an example, you can follow the PyInstaller guide and create an entry point to your application. 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', ...]
10

Trong 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', ...]
11

This script will import

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 from your original script and run it. Note that
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 isn’t run when
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 is imported because of the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 test on line 25 in
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
112. That means you need to run
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 explicitly

Về 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', ...]
12

Why didn’t that work? Suddenly, the import of

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
128 raises an error

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 đó, 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, vì vậy không thể nhập hoàn toàn

One 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ểu

Trên 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. These were removed from the language by PEP 328 with the following rationale

In Python 2. 4 and earlier, if you’re reading a module located inside a package, it is not clear whether

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 refers to a top-level module or to another module inside the package. 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ờ. It’s a particularly difficult problem inside packages because there’s no way to specify which module is meant. [Nguồn]

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', ...]
14

You can now start your app through the entry point script

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
15

Unfortunately, you can no longer call the app directly

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
16

Vấn đề là các lần nhập tương đối được giải quyết khác nhau trong các tập lệnh so với các mô-đun đã nhập. Of course, you could go back and restore the absolute import before running the script directly, or you could even do some

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
153 acrobatics to import files absolutely or relatively depending on what works

There’s even an officially sanctioned hack to make relative imports work in scripts. 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. To quote Raymond Hettinger

There must be a better way. [Source]

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', ...]
155

Loại bỏ các quảng cáo

Create and Install a Local Package

When you install a package from PyPI, that package is available to all scripts in your environment. 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ự

Creating a local package doesn’t involve much overhead. Đầ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', ...]
17

Về 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. However, they’ll be used by
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 when referring to your package, so you should choose values that are recognizable and don’t collide with other packages you use

One tip is to give all such local packages a common prefix like

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162 or your username.
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
163 should list the directory or directories containing your source code. 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', ...]
18

This command will install the package to your system.

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 will then be found on Python’s import path, meaning you can use it anywhere without having to worry about the script directory, relative imports, or other complications. 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ại

Ghi chú. This kind of setup file works great when you’re working with projects on your own. However, if you plan to share the code with others, then you should add some more information to your setup file

Để 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. In your own code, you should consciously separate scripts and libraries. Đây là một quy tắc tốt

  • A script is meant to be run
  • A library is meant to be imported

You might have code that you want to both run on its own and import from other scripts. 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

While it’s a good idea to separate scripts and libraries, all Python files can be both executed and imported. 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

Gói không gian tên

Python modules and packages are very closely related to files and directories. Đ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

Namespace packages have been available in Python since version 3. 3. These are less dependent on the underlying file hierarchy. In particular, namespace packages can be split across multiple directories. A namespace package is created automatically if you have a directory containing a

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
47 file but no
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66. See PEP 420 for a detailed explanation

Ghi 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 unifies and simplifies these earlier approaches

Để 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. As a motivating example, you’ll have another go at the problem solved in The Factory Method Pattern and Its Implementation in Python. được cung cấp một đối tượng

>>> 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', ...]
40

Let’s assume that you’re lucky and come across a third-party implementation of several of the formats that you need to serialize to, and it’s organized as a namespace package

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
41

The file

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
172 contains code that can serialize an object to the JSON format

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
42

This serializer interface is a bit limited, but it’ll be enough to demonstrate how namespace packages work

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', ...]
43

Lư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', ...]
177

Sau đó, 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', ...]
44

Mộ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', ...]
45

By providing different serializer objects to

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
180, you get different representations of your song

Note. Bạn có thể nhận được một

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
183 hoặc một
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
184 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', ...]
46

Trong 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', ...]
47

Vì 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', ...]
48

Lư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', ...]
198

Tiế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', ...]
49

Cũ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. Nếu bạn đang làm theo các ví dụ trước, thì bạn có thể đã gặp sự cố với việc Python không tìm thấy

>>> 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ạn

Ghi 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. Đặt các thư mục

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
402 và
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
407 trong cùng một thư mục, sau đó tùy chỉnh đường dẫn Python của bạn như sau

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
10

Giờ đây, bạn có thể sử dụng tất cả các bộ nối tiếp mà không phải 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ộ

Loại bỏ các quảng cáo

Hướng dẫn phong cách nhập khẩu

PEP 8, the Python style guide, has a couple of recommendations about imports. As always with Python, keeping your code both readable and maintainable is an important consideration. Here are a few general rules of thumb for how to style your imports

  • Giữ nhập ở đầu tệp
  • Write imports on separate lines
  • 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ộ
  • Order imports alphabetically within each group
  • Prefer absolute imports over relative imports
  • Tránh nhập ký tự đại diện như
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    408

>>> 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', ...]
11

Lư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 and
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
412 need to be installed on the system. You can generally assume that the standard library is available. Việc tách nhập khẩu từ bên trong gói của bạn 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ạn

There are cases in which it makes sense to bend these rules a little. You’ve already seen that relative imports can be an alternative to organizing package hierarchies. Later, you’ll see how in some cases you can move imports into a function definition to break import cycles

Resource Imports

Đô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. In small scripts, this isn’t a problem—you can specify the path to your data file and carry on

However, if the resource file is important for your package and you want to distribute your package to other users, then a few challenges will arise

  1. You won’t have control over the path to the resource since that will depend on your user’s setup as well as on how the package is distributed and installed. You can try to figure out the resource path based on your package’s

    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    413 or
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    65 attributes, but this may not always work as expected

  2. Gói của bạn có thể nằm trong tệp ZIP hoặc tệp

    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    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

There have been several attempts at solving these challenges, including

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
416. However, with the introduction of
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 into the standard library in Python 3. 7, there’s now one standard way of dealing with resource files

Giớ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', ...]
417 cấp quyền truy cập vào tài nguyên trong các gói. In this context, a resource is any file located within an importable package. The file may or may not correspond to a physical file on the file system

Điều này có một vài lợi thế. By reusing the import system, you get a more consistent way of dealing with the files inside your packages. It also gives you easier access to resource files in other packages. The documentation sums it up nicely

If you can import a package, you can access resources within that package. [Nguồn]

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 became part of the standard library in Python 3. 7. However, on older versions of Python, a backport is available as
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
421. Để sử dụng backport, hãy cài đặt nó từ PyPI

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
12

Backport tương thích với Python 2. 7 cũng như Python 3. 4 and later versions

There’s one requirement when using

>>> 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', ...]
66

As 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ường

Sau đó, 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 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 tin

Ghi 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', ...]
15

Xem 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ế

Loại bỏ các quảng cáo

Thí dụ. Sử dụng tệp dữ liệu

Là một ví dụ đầy đủ hơn về việc sử dụng 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', ...]
16

Mở tệp CSV và xem dữ liệu

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
17

Mỗ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', ...]
18

Cá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 Python

Hà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', ...]
19

Bạ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', ...]
30

Cá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

Mã nguồn của bài kiểm tra dân sốHiển thị/Ẩn

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', ...]
31

Lưu ý rằng ở dòng 24, bạn cũng kiểm tra xem ________ 2442 có nhỏ hơn ________ 2443 không. Các vị trí có

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
442 trong số
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
443 trở lên không phải là quốc gia thích hợp, mà là các tập hợp như
>>> 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, v.v.

Thí dụ. Thêm biểu tượng vào GUI Tkinter

Khi xây dựng giao diện người dùng đồ họa [GUI], bạn thường cần bao gồm các tệp tài nguyên như biểu tượng. Ví dụ sau đây cho thấy cách bạn có thể làm điều đó bằng cách sử dụng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417. Ứng dụng cuối cùng sẽ trông khá cơ bản, nhưng nó sẽ có biểu tượng tùy chỉnh cũng như hình minh họa trên nút Tạm biệt

Ví dụ sử dụng Tkinter, một gói GUI có sẵn trong thư viện chuẩn. Nó dựa trên hệ thống cửa sổ Tk, ban đầu được phát triển cho ngôn ngữ lập trình Tcl. Có nhiều gói GUI khác có sẵn cho Python. Nếu bạn đang sử dụng một ứng dụng khác, thì bạn có thể thêm các biểu tượng vào ứng dụng của mình bằng các ý tưởng tương tự như những ý tưởng được trình bày ở đây

Trong Tkinter, hình ảnh được xử lý bởi lớp

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
449. Để tạo một
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
449, bạn chuyển vào một đường dẫn đến một tệp hình ảnh

Hãy nhớ rằng, khi phân phối gói của bạn, bạn thậm chí không đảm bảo rằng các tệp tài nguyên sẽ tồn tại dưới dạng tệp vật lý trên hệ thống tệp.

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 giải quyết vấn đề này bằng cách cung cấp
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
452. Hàm này sẽ trả về đường dẫn đến tệp tài nguyên, tạo tệp tạm thời nếu cần

Để đảm bảo mọi tệp tạm thời được dọn sạch đúng cách, bạn nên sử dụng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
452 làm trình quản lý ngữ cảnh bằng từ khóa
>>> 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', ...]
32

Đối với ví dụ đầy đủ, giả sử bạn có hệ thống phân cấp tệp sau

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
33

Nế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

Lấy mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để tìm hiểu về hệ thống nhập Python trong hướng dẫn này

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. Tên này chỉ ra rằng tệp là điểm vào cho gói. 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 PyPI

GUI đượ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', ...]
35

Nế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 bị 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

Loại bỏ các quảng cáo

Nhậ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', ...]
36

Về 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ịch

Ghi 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ẽ tìm hiểu 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

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', ...]
39

Trong 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', ...]
472

Thí dụ. Phương thức xuất xưởng với các gói không gian tên

Think back to the serializers example from earlier. 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
30

Nhà 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', ...]
180

The factory makes some strong assumptions about the naming of both the module and the class containing the individual serializers. In the next section, you’ll learn about a plugin architecture that allows more flexibility

You can now re-create the earlier example as follows

>>>

>>> import math
>>> math.pi
3.141592653589793
31

In this case, you no longer need to explicitly import each serializer. Instead, you specify the name of a serializer with a string. The string could even be chosen by your user at runtime

Note. In a regular package, you probably would have implemented

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 and
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
479 in an
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66 file. That would have allowed you to simply import
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 and then call
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
485

However, namespace packages aren’t allowed to use

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
66, so you need to implement these functions in a separate module instead

The final example shows that you also get a decent error message if you try to serialize to a format that hasn’t been implemented

Loại bỏ các quảng cáo

Example. A Package of Plugins

Let’s look at another example of using dynamic imports. You can use the following module to set up a flexible plugin architecture in your code. This is similar to the previous example, in which you could plug in serializers for different formats by adding new modules

One application that uses plugins effectively is the Glue exploratory visualization tool. Glue can read many different data formats out of the box. However, if your data format isn’t supported, then you can write your own custom data loader

You do this by adding a function that you decorate and place in a special location to make it easy for Glue to find. You don’t need to alter any part of the Glue source code. See the documentation for all the details

You can set up a similar plugin architecture that you can use in your own projects. Within the architecture, there are two levels

  1. A plugin package is a collection of related plugins corresponding to a Python package
  2. A plugin is a custom behavior made available in a Python module

The

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
487 module that exposes the plugin architecture has the following functions

>>> import math
>>> math.pi
3.141592653589793
32

The factory functions are used to conveniently add functionality to plugin packages. You’ll see some examples of how they’re used shortly

Looking at all the details of this code is outside the scope of this tutorial. If you’re interested, then you can see an implementation by expanding the section below

Mã nguồn hoàn chỉnh của plugin. pyShow/Hide

The following code shows the implementation of

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
488 described above

>>> import math
>>> math.pi
3.141592653589793
33

This implementation is a bit simplified. In particular, it doesn’t do any explicit error handling. Check out the PyPlugs project for a more complete implementation

You can see that

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
489 uses
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
490 to dynamically load plugins. Additionally,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
491 uses
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
492 to list all available plugins in a given package

Let’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 work

Assume you have the following

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
493 package

>>> import math
>>> math.pi
3.141592653589793
34

Each

>>> 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
35

To 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
36

You 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
37

Note that

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
101 automatically discovers all the plugins that are available in the package

You 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
38

To 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

  1. Python’s import system ensures that each plugin is imported only once
  2. >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    497 decorators defined inside each plugin module register each imported plugin
  3. 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

  1. >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    110 from
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    417 lists all the files inside a package
  2. The results are filtered to find potential plugins
  3. Each Python file not starting with an underscore is imported
  4. Plugins in any of the files are discovered and registered

Let’s end this section with a final version of the serializers namespace package. Một vấn đề nổi bật là nhà máy

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 đã đưa ra các giả định mạnh mẽ về việc đặt tên cho các lớp bộ nối tiếp. Bạn có thể làm cho điều này linh hoạt hơn bằng cách sử dụng plugin

Đầu tiên, thêm một dòng đăng ký từng bộ nối tiếp. Đây là một ví dụ về cách nó được thực hiện trong bộ nối tiếp

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
197

>>> import math
>>> math.pi
3.141592653589793
70

Tiếp theo, cập nhật

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
114 để sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
487

>>> import math
>>> math.pi
3.141592653589793
71

Bạn triển khai

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
477 bằng cách sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
117 vì điều đó sẽ tự động khởi tạo từng bộ nối tiếp. With this refactoring, the serializers work just the same as earlier. Tuy nhiên, bạn có thể linh hoạt hơn trong việc đặt tên cho các lớp serializer của mình

Để biết thêm thông tin về cách sử dụng plugin, hãy xem PyPlugs trên PyPI và các Trình cắm. Thêm tính linh hoạt vào bản trình bày Ứng dụng của bạn từ PyCon 2019

Loại bỏ các quảng cáo

Hệ thống nhập Python

Bạn đã thấy nhiều cách để tận dụng hệ thống nhập của Python. Trong phần này, bạn sẽ tìm hiểu thêm một chút về những gì diễn ra ở hậu trường khi các mô-đun và gói được nhập

Như với hầu hết các phần của Python, hệ thống nhập có thể được tùy chỉnh. Bạn sẽ thấy một số cách mà bạn có thể thay đổi hệ thống nhập, bao gồm tự động tải xuống các gói bị thiếu từ PyPI và nhập các tệp dữ liệu như thể chúng là các mô-đun

Nhập nội bộ

Chi tiết về hệ thống nhập Python được mô tả trong tài liệu chính thức. Ở cấp độ cao, có ba điều xảy ra khi bạn nhập một mô-đun [hoặc gói]. The module is

  1. Tìm kiếm
  2. Nạp vào
  3. Bị ràng buộc vào một không gian tên

Đối với các thao tác nhập thông thường—những thao tác được thực hiện với câu lệnh

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
44—cả ba bước diễn ra tự động. Tuy nhiên, khi bạn sử dụng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
469, chỉ có hai bước đầu tiên là tự động. You need to bind the module to a variable or namespace yourself

Chẳng hạn, các phương pháp nhập và đổi tên

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
53 sau đây gần như tương đương

>>>

>>> import math
>>> math.pi
3.141592653589793
72

Tất nhiên, trong mã bình thường, bạn nên chọn cái trước

Một điều cần lưu ý là, ngay cả khi bạn chỉ nhập một thuộc tính từ mô-đun, toàn bộ mô-đun sẽ được tải và thực thi. Phần còn lại của nội dung mô-đun không bị ràng buộc với không gian tên hiện tại. Một cách để chứng minh điều này là xem cái được gọi là bộ đệm mô-đun

>>>

>>> import math
>>> math.pi
3.141592653589793
73

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121 hoạt động như một bộ đệm mô-đun. It contains references to all modules that have been imported

Bộ đệm mô-đun đóng một vai trò rất quan trọng trong hệ thống nhập Python. Nơi đầu tiên Python tìm kiếm các mô-đun khi thực hiện nhập là trong

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121. Nếu một mô-đun đã có sẵn, thì nó sẽ không được tải lại

This is a great optimization, but it’s also a necessity. Nếu các mô-đun được tải lại mỗi khi chúng được nhập, thì bạn có thể gặp phải tình trạng không nhất quán trong một số trường hợp nhất định, chẳng hạn như khi mã nguồn cơ bản thay đổi trong khi tập lệnh đang chạy

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

Thí dụ. 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

Ví dụ: hãy quay lại dữ liệu dân số của Liên hợp quốc mà bạn đã xem trước đó. Mô-đun sau định nghĩa một lớp bao bọc dữ liệu dân số

>>> import math
>>> math.pi
3.141592653589793
74

Đọc dữ liệu từ đĩa mất một thời gian. Vì bạn không muốn tệp dữ liệu thay đổi, nên bạn khởi tạo lớp khi bạn tải mô-đun. The name of the class starts with an underscore to indicate to users that they shouldn’t use it

Bạn có thể sử dụng đơn lẻ

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
123 để tạo biểu đồ Matplotlib hiển thị dự báo dân số cho các quốc gia đông dân nhất

>>>

>>> import math
>>> math.pi
3.141592653589793
75

Điều này tạo ra một biểu đồ như sau

Note that loading the data at import time is a kind of antipattern. Lý tưởng nhất là bạn muốn hàng nhập khẩu của mình không có tác dụng phụ nhất có thể. A better approach would be to load the data lazily when you need it. You can do this quite elegantly using properties. Mở rộng phần sau để xem ví dụ

Lazily Loading Population DataShow/Hide

Việc triển khai lười biếng của

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
124 lưu trữ dữ liệu dân số trong
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
125 lần đầu tiên nó được đọc. The
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
126 property handles this caching of data

>>> import math
>>> math.pi
3.141592653589793
76

Bây giờ dữ liệu sẽ không được tải khi nhập. Thay vào đó, nó sẽ được nhập vào lần đầu tiên bạn truy cập từ điển

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
127. For more information about properties and the more general concept of descriptors, see Python Descriptors. Một lời giới thiệu

Loại bỏ các quảng cáo

Tả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. Ví dụ: hãy xem mô-đun sau

>>> import math
>>> math.pi
3.141592653589793
77

Là một phần của quá trình thử nghiệm và gỡ lỗi mô-đun này, bạn nhập nó vào bảng điều khiển Python

>>>

>>> import math
>>> math.pi
3.141592653589793
78

Giả sử bạn nhận ra rằng bạn có một lỗi trong mã của mình, vì vậy bạn cập nhật tệp

>>> 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
79

Returning to your console, you import the updated module to see the effect of your fix

>>>

>>> import math
>>> math.pi
3.141592653589793
78

Tại sao câu trả lời vẫn là

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
129? . 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 it

The most straightforward solution to this is to exit the Python console and restart it. Điều này buộc Python cũng phải xóa bộ đệm mô-đun của nó

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
01

Tuy nhiên, khởi động lại trình thông dịch không phải lúc nào cũng khả thi. You might be in a more complicated session that has taken you a long time to set up. Nếu đúng như vậy, bạn có thể sử dụng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
131 để tải lại một mô-đun thay thế

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
02

Lưu ý rằng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
132 yêu cầu đối tượng mô-đun, không phải chuỗi như
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
472. Ngoài ra, hãy lưu ý rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
132 có một số lưu ý. In particular, variables referring to objects within a module are not re-bound to new objects when that module is reloaded. Xem tài liệu để biết thêm chi tiết

Finders and Loaders

Bạn đã thấy trước đó rằng việc tạo các mô-đun có cùng tên với các thư viện tiêu chuẩn có thể gây ra sự cố. Ví dụ: nếu bạn có một tệp có tên

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
135 trong đường dẫn nhập của Python, thì bạn sẽ không thể nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
49 từ thư viện chuẩn

Điều này không phải luôn luôn như vậy, mặc dù. Tạo một tệp có tên

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
137 với nội dung sau

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
03

Next, open a Python interpreter and import this new module

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
04

Something 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', ...]
05

You 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 ones

Note. 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', ...]
145

Let’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

  1. Python checks if the module is available in the module cache. If

    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    121 contains the name of the module, then the module is already available, and the import process ends

  2. Python starts looking for the module using several finders. Một công cụ tìm sẽ tìm kiếm mô-đun bằng một chiến lược nhất định. The default finders can import built-in modules, frozen modules, and modules on the import path

  3. Python loads the module using a loader. Trình tải nào Python sử dụng được xác định bởi công cụ tìm định vị mô-đun và được chỉ định trong một thứ gọi là thông số mô-đun

Bạn có thể mở rộng hệ thống nhập Python bằng cách triển khai công cụ tìm của riêng bạn và, nếu cần, trình tải của riêng bạn. Bạn sẽ thấy một ví dụ hữu ích hơn về công cụ tìm sau. Hiện tại, bạn sẽ học cách thực hiện các tùy chỉnh cơ bản [và có thể ngớ ngẩn] của hệ thống nhập

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
147 kiểm soát công cụ tìm nào được gọi trong quá trình nhập

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
06

First, 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. Thứ hai, lưu ý rằng bạn có thể tùy chỉnh

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
147 theo ý thích của mình

Để nhanh chóng làm rối phiên Python của bạn, bạn có thể xóa tất cả các công cụ tìm

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
07

Since there are no finders, Python can’t find or import new modules. Tuy nhiên, Python vẫn có thể nhập các mô-đun đã có trong bộ đệm mô-đun vì nó tìm ở đó trước khi gọi bất kỳ công cụ tìm nào

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. Nếu bạn thực sự muốn làm cho phiên Python của mình hoàn toàn không sử dụng được, thì bạn cũng có thể xóa bộ đệm mô-đun,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
121

The following is a slightly more useful example. You’ll write a finder that prints a message to the console identifying the module being imported. Ví dụ này cho thấy cách thêm công cụ tìm của riêng bạn, mặc dù nó không thực sự cố gắng tìm một mô-đun

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
08

Tất cả các công cụ tìm phải triển khai một phương thức lớp

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151, phương thức này sẽ cố gắng tìm một mô-đun nhất định. Có ba cách mà
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 có thể chấm dứt

  1. Bằng cách trả lại
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    153 nếu nó không biết cách tìm và tải mô-đun
  2. Bằng cách trả về thông số mô-đun chỉ định cách tải mô-đun
  3. Bằng cách tăng
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    183 để cho biết rằng không thể nhập mô-đun

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 in một thông báo tới bảng điều khiển và sau đó trả về một cách rõ ràng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
153 để chỉ ra rằng những người tìm kiếm khác nên tìm ra cách thực sự nhập mô-đun

Ghi chú. Vì Python hoàn toàn trả về

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
153 từ bất kỳ hàm hoặc phương thức nào mà không có
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
158 rõ ràng, bạn có thể bỏ qua dòng 9. Tuy nhiên, trong trường hợp này, tốt nhất là thêm vào
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 để làm rõ rằng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 không tìm thấy mô-đun

Bằng cách chèn

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155 trước vào danh sách công cụ tìm, bạn sẽ có một danh sách đang chạy gồm tất cả các mô-đun đang được nhập

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
09

Ví dụ: bạn có thể thấy rằng việc nhập

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162 sẽ kích hoạt việc nhập một số mô-đun khác mà
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162 phụ thuộc vào. Lưu ý rằng tùy chọn dài dòng cho trình thông dịch Python,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
164, cung cấp thông tin tương tự và nhiều, nhiều hơn nữa

Ví dụ khác, giả sử bạn đang thực hiện nhiệm vụ loại bỏ thế giới của các biểu thức thông thường. [Bây giờ, tại sao bạn lại muốn một thứ như vậy? Cụm từ thông dụng thật tuyệt. ] Bạn có thể triển khai công cụ tìm sau cấm mô-đun biểu thức chính quy

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
165

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
20

Raising 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. Điều này thực sự ngăn bạn sử dụng các biểu thức thông thường trong Python

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
21

Mặc dù bạn chỉ đang nhập

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
162, nhưng mô-đun đó đang nhập
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
165 ở hậu trường, do đó sẽ xảy ra lỗi

Thí dụ. Tự động cài đặt từ 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. Tuy nhiên, ví dụ sau có thể hữu ích trong một số trường hợp

Chỉ mục gói Python [PyPI] là cửa hàng pho mát duy nhất của bạn để tìm các gói và mô-đun của bên thứ ba. Đây cũng là nơi mà các gói tải xuống của

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155

Trong các hướng dẫn Real Python khác, bạn có thể đã xem hướng dẫn sử dụng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
170 để cài đặt các mô-đun và gói của bên thứ ba mà bạn cần để làm theo cùng với các ví dụ. Wouldn’t it be great to have Python automatically install missing modules for you?

Warning. Trong hầu hết các trường hợp, sẽ không tuyệt lắm nếu Python tự động cài đặt các mô-đun. 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 way

Để tránh làm rối cài đặt Python của bạn, bạn chỉ nên sử dụng mã này trong các môi trường mà bạn không ngại xóa hoặc cài đặt lại

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', ...]
22

So với các công cụ tìm bạn đã thấy trước đó, công cụ này phức tạp hơn một chút. 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. Do đó, công việc của
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
151 chỉ là thực hiện
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
175. Nếu quá trình cài đặt hoạt động, thì thông số mô-đun sẽ được tạo và trả về

Cố gắng sử dụng thư viện

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
176 mà không cần tự cài đặt

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
23

Thông thường,

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
177 sẽ tăng một
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
183, nhưng trong trường hợp này,
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
176 được cài đặt và nhập

While the

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
173 seemingly works, there are some challenges with this approach. Một vấn đề lớn là tên nhập của một mô-đun không phải lúc nào cũng tương ứng với tên của nó trên PyPI. Ví dụ: trình đọc nguồn cấp Python thực có tên là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
181 trên PyPI, nhưng tên nhập chỉ đơn giản là
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
182

Sử dụng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
173 để nhập và cài đặt
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
182 kết thúc bằng việc cài đặt sai gói

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
24

Điều này có thể gây hậu quả tai hại cho dự án của bạn

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. Môi trường sổ ghi chép Colab rất phù hợp để thực hiện khám phá dữ liệu hợp tác

Một sổ ghi chép điển hình đi kèm với nhiều gói khoa học dữ liệu được cài đặt, bao gồm NumPy, Pandas và Matplotlib và bạn có thể thêm các gói mới bằng

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
155. But you can also activate automatic installation

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
186 không có sẵn cục bộ trên máy chủ Colab nên mã này được sao chép vào ô đầu tiên của sổ ghi chép

Example. Nhập tệp dữ liệu

Ví dụ cuối cùng trong phần này được lấy cảm hứng từ bài đăng trên blog tuyệt vời của Aleksey Bilogur Nhập hầu hết mọi thứ bằng Python. Giới thiệu về Trình tải và Trình tìm mô-đun. You’ve already seen how to use

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
417 to import datafiles. 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 CSV

Trướ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', ...]
25

The first line is a header naming three fields, and the following two rows of data each contain information about an employee. Để 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', ...]
26

The job of the finder will be to search for and recognize CSV files. 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', ...]
27

Có 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ơn

Như 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. For example, if you use
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
194, then
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
159 will be
>>> 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

For top-level imports,

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
198 will be
>>> 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', ...]
301

Dữ 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ô-đun

Chẳ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', ...]
28

Nói chung, tên trường CSV có thể chứa khoảng trắng và các ký tự khác không được phép trong tên thuộc tính Python. Trước khi thêm các trường làm thuộc tính trên mô-đun, bạn làm sạch tên trường bằng biểu thức chính quy. This is done in

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
306 starting on line 51

Bạ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 xem tệp CSV gốc, 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ưới

Bằ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ần

Mẹo và thủ thuật nhập khẩu

To round out this tutorial, you’ll see a few tips about how to handle certain situations that come up from time to time. 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. You’ve already seen one example of this.

>>> 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', ...]
15

Trong 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 phải 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', ...]
421

Thô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ản

You could rewrite the previous example as follows

>>> 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 and newer while falling back to
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
421 on older versions of Python. Xem dự án
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
319 để có lời khuyên hữu ích và phù hợp với tương lai về cách kiểm tra phiên bản Python nào đang chạy

Xử lý các gói bị thiếu. Use an Alternative

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. The reimplementation is better optimized, so you want to use it if it’s available. 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ông

Mộ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', ...]
02

Bằ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ẩu

Xử lý các gói bị thiếu. Sử dụng Mock thay thế

A third, related example is adding a package that provides a nice-to-have feature that’s not strictly necessary for your app. 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ẵn

Ví dụ cụ thể, giả sử bạn đang sử dụng Colorama để thêm văn bản màu trong bảng điều khiển. Colorama chủ yếu bao gồm các hằng số chuỗi đặc biệt có thêm màu khi in

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
03

Unfortunately, the color doesn’t render in the example above. 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. Đó 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ểm

If you’d rather have all your output be [for example] blue, then you can let

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
329 be
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
332 and add
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
333 to the beginning of your script. Các màu sau đây có sẵn

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
04

You can also use

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
334 to control the style of your text. 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', ...]
337

Cuố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', ...]
05

Note how the counter stays in place instead of printing on separate lines as it normally would

Hãy quay lại với nhiệm vụ hiện tại. Đối với nhiều ứng dụng, việc thêm màu vào đầu ra bảng điều khiển của bạn rất thú vị nhưng không quan trọng. Để tránh thêm một phần phụ thuộc khác vào ứng dụng của mình, bạn chỉ muốn sử dụng Colorama nếu ứng dụng này có sẵn trên hệ thống và không 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ế giễu 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ỗng

Có thể thay đổi giá trị trả về của

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
177 trên đối tượng
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
342. 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 là một chuỗi rỗng cũng sẽ trả về chuỗi rỗng khi nó được gọi. Điều này giúp chúng tôi triển khai lại Colorama một cách hiệu quả, chỉ cần không có màu sắc

Thủ thuật cuối cùng là

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
344 tự trả về, do đó tất cả màu sắc, kiểu dáng và chuyển động con trỏ là thuộc tính trên
>>> 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 và
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
348 cũng bị giả lập

Mô-đun

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
349 được thiết kế để thay thế thả xuống cho Colorama, vì vậy bạn có thể cập nhật ví dụ đếm ngược bằng tìm kiếm và thay thế

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
08

If you run this script on a system in which Colorama isn’t available, then it’ll still work, but it may not look as nice

With Colorama installed, you should see the same results as earlier

Import Scripts as Modules

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. should it be executed with

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
350 or imported with
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
351 inside another script?

Sometimes you’ll have a module that works as both a script and a library. 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', ...]
09

Vì JSON thường chỉ được đọc bởi máy móc nên nhiều tệp JSON không được định dạng theo kiểu có thể đọc được. In fact, it’s quite common for JSON files to consist of one very long line of text

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
354 is a script that uses the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
196 library to format JSON in a more readable fashion

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
10

Bâ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ái

Mặc dù việc chia nhỏ tập lệnh và thư viện là một phương pháp hay, nhưng Python có một thành ngữ giúp có thể coi một mô-đun vừa là tập lệnh vừa là thư viện cùng một lúc. Như đã lưu ý trước đó, giá trị của biến mô-đun

>>> 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ệnh

Hãy thử nghiệm nó. Tạo tập tin sau

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
11

Nế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', ...]
12

Tuy 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', ...]
13

Hà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', ...]
14

Hã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', ...]
15

Bạ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', ...]
16

Bạ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', ...]
17

Nế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ăn

Chạ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

If you give the Python interpreter a ZIP file, then it’ll look for a file named

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 inside the ZIP archive, extract it, and run it. As a basic example, create the following
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
455 file

>>> 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', ...]
19

Now add it to a ZIP archive. 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', ...]
20

Trên Windows, thay vào đó, bạn có thể sử dụng trỏ và nhấp. Chọn tệp trong File Explorer, sau đó nhấp chuột phải và chọn Gửi đến → thư mục đã nén [zipped]

>>> 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', ...]
21

Note that your script is aware that it lives inside

>>> 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 ZIP

Nghĩ 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

The app consists of the following files

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
22

Bạn có thể thêm chúng vào tệp ZIP giống như cách bạn đã làm ở trên. However, Python comes with a tool called

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 that streamlines the process of packing applications into ZIP archives. Bạn sử dụng nó như sau

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
23

Lệ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ữ ZIP

Ghi 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', ...]
386

Tuy 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 tin

Trê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. On Mac and Linux, you can have
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
375 create executable files by using the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
390 interpreter option and specifying which interpreter to use

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
25

Tù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. Additionally, it makes the
>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
383 file executable so that you can run the file just by typing its name

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
26

Lưu ý

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
394 trước tên tệp. This is a typical trick on Mac and Linux to run executable files in the current directory. 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', ...]
382

Ghi 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', ...]
398

Mộ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', ...]
27

Lệnh

>>> import math
>>> math.pi
3.141592653589793
300 mở rộng đến đường dẫn của thư mục hiện tại

Hã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', ...]
28

Mộ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', ...]
29

Cách tiếp cận này thường hoạt động tốt. However, it falls apart when your application is packed into a ZIP file

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
30

Tệ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 đó

Xử lý nhập khẩu theo chu kỳ

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
305

Hệ thống nhập của 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', ...]
31

Cố 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', ...]
32

Lư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ô-đun

Khi 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ô-đun

Bạn cũng có thể có các mô-đun làm điều gì đó hữu ích hơn một chút. Nếu bạn xác định các thuộc tính và chức năng trong các mô-đun của mình, thì tất cả vẫn hoạt động

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
33

Nhậ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', ...]
32

Các sự cố liên quan đến nhập đệ quy bắt đầu xuất hiện khi bạn thực sự sử dụng mô-đun khác tại thời điểm nhập thay vì chỉ xác định các hàm sẽ sử dụng mô-đun khác sau này. Thêm một dòng vào

>>> import math
>>> math.pi
3.141592653589793
321

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
35

Bây giờ Python bị nhầm lẫn khi nhập

>>>

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
36

Thô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
305

Vấ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
328

Để thê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', ...]
37

Và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', ...]
38

Vậy làm thế nào bạn có thể tránh bị sa lầy và bối rối bởi việc nhập khẩu theo chu kỳ?

Often, the easiest time to fix cyclical imports is before you implement them. Nếu bạn thấy các chu kỳ trong bản phác thảo kiến ​​trúc của mình, hãy xem xét kỹ hơn và cố gắng phá vỡ các chu kỳ đó

Tuy nhiên, đôi khi việc giới thiệu một chu kỳ nhập khẩu là hợp lý. Như bạn đã thấy ở trên, đây không phải là vấn đề miễn là các mô-đun của bạn chỉ định nghĩa các thuộc tính, hàm, lớp, v.v. Mẹo thứ hai—cũng là một phương pháp thiết kế tốt—là giữ cho các mô-đun của bạn không có tác dụng phụ khi nhập

Nếu bạn thực sự cần các mô-đun có chu kỳ nhập và tác dụng phụ, thì vẫn còn một cách khác. thực hiện nhập cục bộ của bạn bên trong các chức năng

Lưu ý rằng trong đoạn mã sau,

>>> 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 xảy 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 đầy đủ

>>> import math
>>> dir[]
['__annotations__', '__builtins__', ..., 'math']

>>> dir[math]
['__doc__', ..., 'nan', 'pi', 'pow', ...]
39

Bâ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', ...]
40

Lư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ó một góc nhìn khác về nhập khẩu theo chu kỳ, hãy xem ghi chú kinh điển của Fredrik Lundh

Nhập hồ sơ

Một mối quan tâm khi nhập một số mô-đun và gói là nó sẽ thêm vào thời gian khởi động tập lệnh của bạn. Tùy thuộc vào ứng dụng của bạn, điều này có thể hoặc không quan trọng

Since the release of 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', ...]
41

Cộ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
350

Cộ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', ...]
42

Trong 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', ...]
43

Trong 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ạn

Conclusion

Trong hướng dẫn này, bạn đã biết hệ thống nhập Python. Giống như nhiều thứ trong Python, nó khá đơn giản để sử dụng cho các tác vụ cơ bản như nhập mô-đun và gói. Đồng thời, hệ thống nhập khẩu khá phức tạp, linh hoạt và có thể mở rộng. Bạn đã học được một số thủ thuật liên quan đến nhập mà bạn có thể tận dụng trong mã của riêng mình

Trong hướng dẫn này, bạn đã học cách

  • Tạo các gói không gian tên
  • Import resources and data files
  • Quyết định những gì cần nhập động trong thời gian chạy
  • Mở rộng hệ thống nhập của Python
  • Xử lý các phiên bản khác nhau của gói

Trong suốt hướng dẫn, bạn đã thấy nhiều liên kết đến thông tin thêm. Nguồn có thẩm quyền nhất trên hệ thống nhập Python là tài liệu chính thức

  • Hệ thống nhập khẩu
  • Gói
    >>> import math
    >>> dir[]
    ['__annotations__', '__builtins__', ..., 'math']
    
    >>> dir[math]
    ['__doc__', ..., 'nan', 'pi', 'pow', ...]
    
    469
  • 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

Lấy mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để tìm hiểu về hệ thống nhập Python trong hướng dẫn này

Đá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 Arne

Mỗ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à

Aldren

Brad

Đan

Joanna

Gia-cốp

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 nghìn hướng dẫn, khóa học video thực hành và cộng đồng các 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ẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Làm cách nào để nhập tất cả các hàm từ một tệp khác trong Python?

Cách tiếp cận. Tạo tệp Python chứa các chức năng cần thiết. Tạo một tệp Python khác và nhập tệp Python trước đó vào đó. Gọi các hàm được xác định trong tệp đã nhập .

Làm cách nào bạn có thể nhập tất cả các chức năng từ tệp Python trong thư mục trước đó?

Để nhập một mô-đun, thư mục chứa mô-đun đó phải có trên PYTHONPATH . Nó là một biến môi trường chứa danh sách các gói sẽ được Python tải. Danh sách các gói có trong PYTHONPATH cũng có trong sys. đường dẫn, vì vậy sẽ thêm đường dẫn thư mục mẹ vào sys.

Các chức năng có thể được nhập bằng Python không?

Bạn có thể xác định các chức năng được sử dụng nhiều nhất trong một mô-đun và nhập nó , thay vì sao chép các định nghĩa của chúng vào các chương trình khác nhau. Một mô-đun có thể được nhập bởi một chương trình khác để sử dụng chức năng của nó. Đây là cách bạn cũng có thể sử dụng thư viện chuẩn Python.

Làm cách nào để nhập tất cả từ mô-đun Python?

Bạn có thể nhập tất cả mã từ một mô-đun bằng cách chỉ định từ khóa nhập theo sau là mô-đun bạn muốn nhập . câu lệnh nhập xuất hiện ở đầu tệp Python, bên dưới bất kỳ nhận xét nào có thể tồn tại. Điều này là do việc nhập các mô-đun hoặc gói ở đầu tệp giúp cấu trúc mã của bạn rõ ràng hơn.

Chủ Đề