Đối số getattr trong python

The

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
82 method returns the value of the named attribute of an object. If not found, it returns the default value provided to the function

Example

class Student:
  marks = 88
  name = 'Sheeran'

person = Student()

name = getattr(person, 'name')

print(name)

marks = getattr(person, 'marks')

print(marks) # Output: Sheeran # 88

getattr() Syntax

The syntax of

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
82 method is

getattr(object, name[, default])

The above syntax is equivalent to

object.name

getattr() Parameters

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
82 method takes multiple parameters

  • object - object whose named attribute's value is to be returned
  • name - string that contains the attribute's name
  • default (Optional) - value that is returned when the named attribute is not found

getattr() Return Value

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
82 method returns

  • value of the named attribute of the given object
  • getattr(object, name[, default])
    1, if no named attribute is found
  • getattr(object, name[, default])
    2 exception, if named attribute is not found and
    getattr(object, name[, default])
    1 is not defined

Example 1. How getattr() works in Python?

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)

Output

The age is: 23
The age is: 23

Example 2. getattr() when named attribute is not found

class Person:
    age = 23
    name = "Adam"

person = Person()

# when default value is provided

print('The sex is:', getattr(person, 'sex', 'Male'))

# when no default value is provided

print('The sex is:', getattr(person, 'sex'))

Output

The sex is: Male
AttributeError: 'Person' object has no attribute 'sex'

The named attribute sex is not present in the class Person. So, when calling

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
82 method with a default value
getattr(object, name[, default])
5, it returns Male

But, if we don't provide any default value, when the named attribute sex is not found, it raises an

getattr(object, name[, default])
2 saying the object has no sex attribute

In Python, you use the

getattr(object, name[, default])
244 keyword to make code in one module available in another. Imports in Python are important for structuring your code effectively. Using imports properly will make you more productive, allowing you to reuse code while keeping your projects maintainable

This tutorial will provide a thorough overview of Python’s

getattr(object, name[, default])
244 statement and how it works. The import system is powerful, and you’ll learn how to harness this power. While you’ll cover many of the concepts behind Python’s import system, this tutorial is mostly example driven. You’ll learn from several code examples throughout

In this tutorial, you’ll learn how to

  • Use modules, packages, and namespace packages
  • Handle resources and data files inside your packages
  • Import modules dynamically at runtime
  • Customize Python’s import system

Throughout the tutorial, you’ll see examples of how to play with the Python import machinery in order to work most efficiently. While all the code is shown in the tutorial, you can also download it by clicking the box below

Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial

Python cơ bản getattr(object, name[, default])244

Python code is organized into both modules and packages. 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. Modules have a namespace containing arbitrary Python objects. 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

getattr(object, name[, default])
247 chứa mã Python

The true power of modules is that they can be imported and reused in other code. Consider the following example

>>>

getattr(object, name[, default])
6

In the first line,

getattr(object, name[, default])
248, you import the code in the
getattr(object, name[, default])
249 module and make it available to use. In the second line, you access the
getattr(object, name[, default])
250 variable within the
getattr(object, name[, default])
249 module.
getattr(object, name[, default])
249 is part of Python’s standard library, which means that it’s always available to import when you’re running Python

Note that you write

getattr(object, name[, default])
253 and not just simply
getattr(object, name[, default])
250. In addition to being a module,
getattr(object, name[, default])
249 acts as a namespace that keeps all the attributes of the module together. Namespaces are useful for keeping your code readable and organized. In the words of Tim Peters

Namespaces are one honking great idea—let’s do more of those. (Source)

You can list the contents of a namespace with

getattr(object, name[, default])
256

>>>

getattr(object, name[, default])
2

Using

getattr(object, name[, default])
256 without any argument shows what’s in the global namespace. To see the contents of the
getattr(object, name[, default])
249 namespace, you use
getattr(object, name[, default])
259

You’ve already seen the most straightforward use of

getattr(object, name[, default])
244. However, there are other ways to use it that allow you to import specific parts of a module and to rename the module as you import it

The following code imports only the

getattr(object, name[, default])
250 variable from the
getattr(object, name[, default])
249 module

>>>

getattr(object, name[, default])
3

Note that this places

getattr(object, name[, default])
250 in the global namespace and not within a
getattr(object, name[, default])
249 namespace

You can also rename modules and attributes as they’re imported

>>>

getattr(object, name[, default])
6

For more details about the syntax for importing modules, check out Python Modules and Packages – An Introduction

Packages

You can use a package to further organize your modules. The Python. org glossary defines package as follows

A Python module which can contain submodules or recursively, subpackages. Technically, a package is a Python module with an

getattr(object, name[, default])
265 attribute. (Nguồn)

Note that a package is still a module. As a user, you usually don’t need to worry about whether you’re importing a module or a package

In practice, a package typically corresponds to a file directory containing Python files and other directories. To create a Python package yourself, you create a directory and a file named

getattr(object, name[, default])
266 inside it. The
getattr(object, name[, default])
266 file contains the contents of the package when it’s treated as a module. It can be left empty

Ghi chú. Directories without an

getattr(object, name[, default])
266 file are still treated as packages by Python. However, these won’t be regular packages, but something called namespace packages. You’ll learn more about them later

In general, submodules and subpackages aren’t imported when you import a package. However, you can use

getattr(object, name[, default])
266 to include any or all submodules and subpackages if you want. To show a few examples of this behavior, you’ll create a package for saying
getattr(object, name[, default])
270 in a few different languages. The package will consist of the following directories and files

getattr(object, name[, default])
3

Each country file prints out a greeting, while the

getattr(object, name[, default])
266 files selectively import some of the subpackages and submodules. The exact contents of the files are as follows

getattr(object, name[, default])
5

Note that

getattr(object, name[, default])
272 imports only
getattr(object, name[, default])
273 and not
getattr(object, name[, default])
274. Similarly,
getattr(object, name[, default])
275 doesn’t import anything, while
getattr(object, name[, default])
276 imports
getattr(object, name[, default])
277 and
getattr(object, name[, default])
278 but not
getattr(object, name[, default])
279. Each country module will print a greeting when it’s imported

Let’s play with the

getattr(object, name[, default])
280 package at the interactive prompt to get a better understanding of how the subpackages and submodules behave

>>>

getattr(object, name[, default])
5

When

getattr(object, name[, default])
274 is imported, the
getattr(object, name[, default])
282 and
getattr(object, name[, default])
283 modules are imported as well. You can see this because the country modules print a greeting when they’re imported

>>>

getattr(object, name[, default])
9

The

getattr(object, name[, default])
275 file is empty. This means that importing the
getattr(object, name[, default])
285 package creates the namespace but has no other effect

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
2

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

getattr(object, name[, default])
286 attribute

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
4

You rarely need to interact with

getattr(object, name[, default])
286 directly

Similarly, Python’s global namespace is also a dictionary. You can access it through

getattr(object, name[, default])
288

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

getattr(object, name[, default])
266 file to make them more readily available to your users. You can see one example of this in the popular
getattr(object, name[, default])
290 package

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

Absolute and Relative Imports

Recall the source code of

getattr(object, name[, default])
272 in the earlier example

getattr(object, name[, default])
20

You’ve already seen

getattr(object, name[, default])
292 statements such as
getattr(object, name[, default])
293, but what does the dot (
getattr(object, name[, default])
294) in
getattr(object, name[, default])
295 mean?

The dot refers to the current package, and the statement is an example of a relative import. You can read it as “From the current package, import the subpackage

getattr(object, name[, default])
273. ”

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

getattr(object, name[, default])
21

In fact, all imports in

getattr(object, name[, default])
280 could have been done explicitly with similar absolute imports

Relative imports must be in the form

getattr(object, name[, default])
292, 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. Hiện tại, chỉ cần biết rằng Python tìm kiếm các mô-đun và gói trong đường dẫn nhập của nó. This is a list of locations that are searched for modules to import

Note. When you type

getattr(object, name[, default])
299, Python will look for
getattr(object, name[, default])
300 a few different places before searching the import path

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

getattr(object, name[, default])
300 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

getattr(object, name[, default])
302. 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. Nội dung của biến môi trường
    getattr(object, name[, default])
    303
  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. Ví dụ: giả sử bạn xác định mô-đun

getattr(object, name[, default])
249 sau

getattr(object, name[, default])
22

Using this module works as expected

>>>

getattr(object, name[, default])
23

Nhưng mô-đun này cũng phủ bóng mô-đun

getattr(object, name[, default])
249 có trong thư viện chuẩn. Thật không may, điều đó có nghĩa là ví dụ tra cứu giá trị của π trước đây của chúng tôi không còn hoạt động nữa

>>>

getattr(object, name[, default])
24

Vấn đề là Python hiện tìm kiếm mô-đun

getattr(object, name[, default])
249 mới của bạn cho
getattr(object, name[, default])
250 thay vì tìm kiếm mô-đun
getattr(object, name[, default])
249 trong thư viện chuẩn

Để tránh những loại sự cố này, bạn nên cẩn thận với tên của các mô-đun và gói của mình. Cụ thể, tên gói và mô-đun cấp cao nhất của bạn phải là duy nhất. Nếu

getattr(object, name[, default])
249 đượ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

Ví dụ. Cấu trúc nhập khẩu của bạn

Mặc dù có thể sắp xếp 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

getattr(object, name[, default])
303 và thậm chí là
getattr(object, name[, default])
302, nhưng quy trình này thường không theo quy tắc và dễ xảy ra lỗi. Để xem một ví dụ điển hình, hãy xem xét ứng dụng sau

getattr(object, name[, default])
25

Ứng dụng sẽ tạo lại cấu trúc tệp đã cho bằng cách tạo thư mục và tệp trống. Tệp

getattr(object, name[, default])
312 chứa tập lệnh chính và
getattr(object, name[, default])
313 là một 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
getattr(object, name[, default])
314

getattr(object, name[, default])
26

The two source code files as well as the automatically created

getattr(object, name[, default])
315 file are re-created inside a new directory named
getattr(object, name[, default])
316

Now take a look at the source code. The main functionality of the app is defined in

getattr(object, name[, default])
312

getattr(object, name[, default])
27

Trong các dòng 12 đến 16, bạn đọc đường dẫn gốc từ dòng lệnh. Trong ví dụ trên bạn sử dụng dấu chấm, có nghĩa là thư mục hiện tại. Đường dẫn này sẽ được sử dụng làm

getattr(object, name[, default])
318 của hệ thống phân cấp tệp mà bạn sẽ tạo lại

Công việc thực tế xảy ra ở dòng 19 đến 23. Đầu tiên, bạn tạo một đường dẫn duy nhất,

getattr(object, name[, default])
319, đó sẽ là gốc của hệ thống phân cấp tệp mới của bạn. Sau đó, bạn lặp qua tất cả các đường dẫn bên dưới bản gốc
getattr(object, name[, default])
318 và tạo lại chúng dưới dạng các tệp trống bên trong hệ thống phân cấp tệp mới

Để thao tác với các đường dẫn như thế này,

getattr(object, name[, default])
321 trong thư viện tiêu chuẩn khá hữu ích. Để biết thêm chi tiết về cách nó được sử dụng, hãy xem Mô-đun
getattr(object, name[, default])
321 của Python 3. Thuần hóa hệ thống tập tin

Trên dòng 26, bạn gọi

getattr(object, name[, default])
323. Bạn sẽ tìm hiểu thêm về bài kiểm tra
getattr(object, name[, default])
324 ở dòng 25 sau. Bây giờ, bạn nên biết rằng biến đặc biệt
getattr(object, name[, default])
325 có giá trị
getattr(object, name[, default])
326 bên trong các tập lệnh, nhưng nó lấy tên của mô-đun bên trong các mô-đun đã nhập. Để biết thêm thông tin về
getattr(object, name[, default])
325, hãy xem Xác định hàm chính trong Python và What Does if name == “main” Do in Python?

Lưu ý rằng bạn nhập

getattr(object, name[, default])
328 trên dòng 8. Mô-đun thư viện này chứa hai chức năng tiện ích

getattr(object, name[, default])
28

getattr(object, name[, default])
329 sử dụng bộ đếm để tìm đường dẫn chưa tồn tại. Trong ứng dụng, bạn sử dụng nó để tìm một thư mục con duy nhất để sử dụng làm
getattr(object, name[, default])
319 của hệ thống phân cấp tệp được tạo lại. Tiếp theo,
getattr(object, name[, default])
331 đả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
getattr(object, name[, default])
332

Hãy xem lại việc nhập

getattr(object, name[, default])
328

getattr(object, name[, default])
29

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

getattr(object, name[, default])
328 từ dự án
getattr(object, name[, default])
314, 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
getattr(object, name[, default])
328 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. Tuy nhiên, nếu dự án của bạn đạt được một số lực kéo, thì nó có thể được sử dụng theo những cách khác

Ví dụ: ai đó có thể muốn nhập tập lệnh vào Jupyter Notebook và chạy tập lệnh từ đó. Hoặc họ có thể muốn sử dụng lại thư viện

getattr(object, name[, default])
328 trong một dự án khác. Họ thậm chí có thể tạo một tệp thực thi bằng PyInstaller để phân phối dễ dàng hơn. Thật không may, bất kỳ tình huống nào trong số này đều có thể tạo ra sự cố khi nhập
getattr(object, name[, default])
328

Để xem ví dụ, bạn có thể làm theo hướng dẫn PyInstaller và tạo một điểm vào cho ứng dụng của mình. Thêm một thư mục bổ sung bên ngoài thư mục ứng dụng của bạn

getattr(object, name[, default])
30

Trong thư mục bên ngoài, tạo tập lệnh điểm vào,

getattr(object, name[, default])
339

getattr(object, name[, default])
31

Tập lệnh này sẽ nhập

getattr(object, name[, default])
323 từ tập lệnh gốc của bạn và chạy nó. Lưu ý rằng
getattr(object, name[, default])
323 không chạy khi
getattr(object, name[, default])
314 được nhập vì thử nghiệm
getattr(object, name[, default])
324 trên dòng 25 trong
getattr(object, name[, default])
312. Điều đó có nghĩa là bạn cần chạy
getattr(object, name[, default])
323 một cách rõ ràng

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

getattr(object, name[, default])
32

Tại sao nó không hoạt động?

Vấn đề là khi khởi động ứng dụng bằng

getattr(object, name[, default])
339, bạn đã thay đổi vị trí của tập lệnh hiện tại, do đó thay đổi đường dẫn nhập.
getattr(object, name[, default])
328 không còn trên đường dẫn nhập, vì vậy không thể nhập hoàn toàn

Một giải pháp khả thi là thay đổi đường dẫn nhập của Python

getattr(object, name[, default])
33

Điều này hoạt động vì đường dẫn nhập bao gồm thư mục chứa

getattr(object, name[, default])
312 và
getattr(object, name[, default])
313. Vấn đề với phương pháp này là đường dẫn nhập của bạn có thể rất lộn xộn và khó hiểu

In practice, you’re re-creating a feature of early Python versions called implicit relative imports. Chúng đã bị xóa khỏi ngôn ngữ bởi PEP 328 với lý do sau

Trong Python 2. 4 trở về trước, nếu bạn đang đọc một mô-đun nằm bên trong một gói, thì không rõ liệu

getattr(object, name[, default])
351 đề cập đến một mô-đun cấp cao nhất hay một mô-đun khác bên trong gói. Khi thư viện của Python mở rộng, ngày càng có nhiều mô-đun bên trong gói hiện có đột nhiên che khuất các mô-đun thư viện tiêu chuẩn một cách tình cờ. Đây là một vấn đề đặc biệt khó khăn bên trong các gói vì không có cách nào để chỉ định mô-đun nào có nghĩa là. (Nguồn)

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

getattr(object, name[, default])
312 như sau

getattr(object, name[, default])
34

Giờ đây, bạn có thể bắt đầu ứng dụng của mình thông qua tập lệnh nhập cảnh

getattr(object, name[, default])
35

Thật không may, bạn không còn có thể gọi ứng dụng trực tiếp

getattr(object, name[, default])
36

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. Tất nhiên, bạn có thể quay lại và khôi phục quá trình nhập tuyệt đối trước khi chạy tập lệnh trực tiếp hoặc thậm chí bạn có thể thực hiện một số động tác nhào lộn

getattr(object, name[, default])
353 để nhập tệp hoàn toàn hoặc tương đối tùy thuộc vào những gì hoạt động

Thậm chí còn có một bản hack bị xử phạt chính thức để làm cho hoạt động nhập tương đối trong các tập lệnh. Thật không may, điều này cũng buộc bạn phải thay đổi

getattr(object, name[, default])
302 trong hầu hết các trường hợp. Trích lời Raymond Hettinger

Phải có cách tốt hơn. (Nguồn)

Thật vậy, một giải pháp tốt hơn—và ổn định hơn—là sử dụng cùng với hệ thống nhập và đóng gói của Python và cài đặt dự án của bạn dưới dạng gói cục bộ bằng cách sử dụng

getattr(object, name[, default])
355

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

Tạo và cài đặt gói cục bộ

Khi bạn cài đặt một gói từ PyPI, gói đó có sẵn cho tất cả các tập lệnh trong môi trường của bạn. Tuy nhiên, bạn cũng có thể cài đặt các gói từ máy tính cục bộ của mình và chúng cũng sẽ được cung cấp theo cách tương tự

Tạo một gói cục bộ không liên quan đến nhiều chi phí. Đầu tiên, tạo các tệp

getattr(object, name[, default])
356 và
getattr(object, name[, default])
357 tối thiểu trong thư mục
getattr(object, name[, default])
314 bên ngoài

getattr(object, name[, default])
37

Về lý thuyết,

getattr(object, name[, default])
359 và
getattr(object, name[, default])
360 có thể là bất cứ thứ gì bạn thích. Tuy nhiên, chúng sẽ được sử dụng bởi
getattr(object, name[, default])
355 khi đề cập đến gói của bạn, vì vậy bạn nên chọn các giá trị dễ nhận biết và không xung đột với các gói khác mà bạn sử dụng

Một mẹo là cung cấp cho tất cả các gói cục bộ như vậy một tiền tố chung như

getattr(object, name[, default])
362 hoặc tên người dùng của bạn.
getattr(object, name[, default])
363 nên liệt kê thư mục hoặc các thư mục chứa mã nguồn của bạn. Sau đó, bạn có thể cài đặt gói cục bộ bằng cách sử dụng
getattr(object, name[, default])
355

getattr(object, name[, default])
38

Lệnh này sẽ cài đặt gói vào hệ thống của bạn.

getattr(object, name[, default])
314 sau đó sẽ được tìm thấy trên đường dẫn nhập của Python, nghĩa là bạn có thể sử dụng nó ở bất cứ đâu mà không phải lo lắng về thư mục tập lệnh, quá trình nhập tương đối hoặc các biến chứng khác. Tùy chọn
getattr(object, name[, default])
366 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ú. Loại tệp thiết lập này hoạt động rất tốt khi bạn tự làm việc với các dự án. Tuy nhiên, nếu bạn định chia sẻ mã với người khác thì bạn nên thêm một số thông tin khác vào tệp thiết lập của mình

Để biết thêm chi tiết về các tệp thiết lập, hãy xem Cách xuất bản Gói Python mã nguồn mở lên PyPI

Giờ đây,

getattr(object, name[, default])
314 đã đượ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

getattr(object, name[, default])
39

Điều này sẽ hoạt động bất kể bạn kết thúc cuộc gọi ứng dụng của mình như thế nào

Mẹo. Trong mã của riêng bạn, bạn nên tách biệt các tập lệnh và thư viện một cách có ý thức. Đây là một quy tắc tốt

  • Một kịch bản có nghĩa là để được chạy
  • Một thư viện có nghĩa là được nhập khẩu

Bạn có thể có mã mà bạn muốn tự chạy và nhập từ các tập lệnh khác. Trong trường hợp đó, thường đáng để cấu trúc lại mã của bạn để bạn chia phần chung thành một mô-đun thư viện

Mặc dù nên tách biệt các tập lệnh và thư viện, nhưng tất cả các tệp Python đều có thể được thực thi và nhập. Trong phần sau, bạn sẽ tìm hiểu thêm về cách tạo các mô-đun xử lý tốt cả hai

Gói không gian tên

Các mô-đun và gói Python có liên quan rất chặt chẽ với các tệp và thư mục. Điều này khiến Python khác biệt với nhiều ngôn ngữ lập trình khác, trong đó các gói chỉ hoạt động như các không gian tên mà không thực thi cách tổ chức mã nguồn. Xem các cuộc thảo luận trong PEP 402 để biết ví dụ

Các gói không gian tên đã có sẵn trong Python kể từ phiên bản 3. 3. Chúng ít phụ thuộc vào hệ thống phân cấp tệp cơ bản. In particular, namespace packages can be split across multiple directories. Gói không gian tên được tạo tự động nếu bạn có một thư mục chứa tệp

getattr(object, name[, default])
247 nhưng không có tệp
getattr(object, name[, default])
266. Xem PEP 420 để được giải thích chi tiết

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 thống nhất và đơn giản hóa các phương pháp trước đó

Để hiểu rõ hơn về lý do tại sao các gói không gian tên có thể hữu ích, hãy thử triển khai một. Như một ví dụ thúc đẩy, bạn sẽ có một cách khác để giải quyết vấn đề trong Mẫu phương thức xuất xưởng và triển khai của nó trong Python. được cung cấp một đối tượng

getattr(object, name[, default])
370, 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
getattr(object, name[, default])
370

Để cụ thể hơn, bạn muốn triển khai mã hoạt động giống như thế này

>>>

getattr(object, name[, default])
60

Giả sử rằng bạn may mắn và bắt gặp một triển khai của bên thứ ba cho một số định dạng mà bạn cần sắp xếp theo thứ tự và nó được tổ chức dưới dạng gói không gian tên

getattr(object, name[, default])
61

Tệp

getattr(object, name[, default])
372 chứa mã có thể tuần tự hóa một đối tượng thành định dạng JSON

getattr(object, name[, default])
62

Giao diện bộ nối tiếp này có một chút hạn chế, nhưng nó sẽ đủ để chứng minh cách các gói không gian tên hoạt động

Tệp

getattr(object, name[, default])
373 chứa một
getattr(object, name[, default])
374 tương tự có thể chuyển đổi một đối tượng thành XML

getattr(object, name[, default])
63

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

getattr(object, name[, default])
375,
getattr(object, name[, default])
376 và
getattr(object, name[, default])
377

Sau đó, bạn tạo một lớp

getattr(object, name[, default])
370 có thể sử dụng các bộ nối tiếp này

getattr(object, name[, default])
64

Một

getattr(object, name[, default])
370 được xác định bởi ID, tiêu đề và nghệ sĩ của nó. Lưu ý rằng
getattr(object, name[, default])
380 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

getattr(object, name[, default])
381 của bên thứ ba, bạn có thể sử dụng nó như sau

>>>

getattr(object, name[, default])
65

Bằng cách cung cấp các đối tượng nối tiếp khác nhau cho

getattr(object, name[, default])
380, bạn sẽ nhận được các bản trình bày khác nhau cho bài hát của mình

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

getattr(object, name[, default])
383 hoặc một
getattr(object, name[, default])
384 khi tự chạy mã. Điều này là do
getattr(object, name[, default])
381 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

getattr(object, name[, default])
386 của riêng mình vào gói
getattr(object, name[, default])
381 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à

getattr(object, name[, default])
381. Đ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

getattr(object, name[, default])
66

Trong tệp

getattr(object, name[, default])
389, bạn xác định
getattr(object, name[, default])
386 của riêng mình. Bạn căn cứ vào gói
getattr(object, name[, default])
391, gói này phải được cài đặt từ PyPI

getattr(object, name[, default])
67

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

getattr(object, name[, default])
392

getattr(object, name[, default])
68

Lưu ý rằng

getattr(object, name[, default])
386 dựa trên
getattr(object, name[, default])
392, được nhập từ chính
getattr(object, name[, default])
381. Vì cả
getattr(object, name[, default])
396 và
getattr(object, name[, default])
397 đề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 lệnh nhập tương đối.
getattr(object, name[, default])
398

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

>>>

getattr(object, name[, default])
69

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

getattr(object, name[, default])
381. In actual code, you would have used
getattr(object, name[, default])
355 to install the third-party library, so it would be in your path automatically

Note. In the original example, the choice of serializer was made more dynamically. You’ll see how to use namespace packages in a proper factory method pattern later

You should also make sure that your local library is available like a normal package. As explained above, you can do this either by running Python from the proper directory or by using

getattr(object, name[, default])
355 to install the local library as well

In this example, you’re testing how to integrate a fake third-party package with your local package. If

getattr(object, name[, default])
602 were a real package, then you would download it from PyPI using
getattr(object, name[, default])
355. Since this isn’t possible, you can simulate it by installing
getattr(object, name[, default])
602 locally like you did in the
getattr(object, name[, default])
314 example earlier

Alternatively, you can mess with your import path. Put the

getattr(object, name[, default])
602 and
getattr(object, name[, default])
607 directories inside the same folder, then customize your Python path as follows

>>>

getattr(object, name[, default])
30

You can now use all serializers without worrying about whether they’re defined in the third-party package or locally

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

Imports Style Guide

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

  • Keep imports at the top of the file
  • Write imports on separate lines
  • Organize imports into groups. first standard library imports, then third-party imports, and finally local application or library imports
  • Order imports alphabetically within each group
  • Prefer absolute imports over relative imports
  • Avoid wildcard imports like
    getattr(object, name[, default])
    608

getattr(object, name[, default])
609 and
getattr(object, name[, default])
610 are great tools for enforcing a consistent style on your imports

Here’s an example of an import section inside the Real Python feed reader package

getattr(object, name[, default])
31

Note how this grouping makes the dependencies of this module clear.

getattr(object, name[, default])
611 and
getattr(object, name[, default])
612 need to be installed on the system. You can generally assume that the standard library is available. Separating imports from within your package gives you some overview over the internal dependencies of your code

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

Resource Imports

Sometimes you’ll have code that depends on data files or other resources. In small scripts, this isn’t a problem—you can specify the path to your data file and carry on

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

  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

    getattr(object, name[, default])
    613 or
    getattr(object, name[, default])
    265 attributes, but this may not always work as expected

  2. Your package may reside inside a ZIP file or an old

    getattr(object, name[, default])
    615 file, in which case the resource won’t even be a physical file on the user’s system

There have been several attempts at solving these challenges, including

getattr(object, name[, default])
616. However, with the introduction of
getattr(object, name[, default])
617 into the standard library in Python 3. 7, there’s now one standard way of dealing with resource files

Introducing getattr(object, name[, default])617

getattr(object, name[, default])
617 gives access to resources within packages. In this context, a resource is any file located within an importable package. The file may or may not correspond to a physical file on the file system

This has a couple of advantages. By reusing the import system, you get a more consistent way of dealing with the files inside your packages. 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. (Source)

getattr(object, name[, default])
617 became part of the standard library in Python 3. 7. However, on older versions of Python, a backport is available as
getattr(object, name[, default])
621. To use the backport, install it from PyPI

getattr(object, name[, default])
32

The backport is compatible with Python 2. 7 as well as Python 3. 4 and later versions

There’s one requirement when using

getattr(object, name[, default])
617. your resource files must be available inside a regular package. Namespace packages aren’t supported. In practice, this means that the file must be in a directory containing an
getattr(object, name[, default])
266 file

As a first example, assume you have resources inside a package like this

getattr(object, name[, default])
33

getattr(object, name[, default])
266 chỉ là một tệp trống cần thiết để chỉ định
getattr(object, name[, default])
625 như một gói thông thường

You can then use

getattr(object, name[, default])
626 and
getattr(object, name[, default])
627 to open text and binary files, respectively

>>>

getattr(object, name[, default])
34

getattr(object, name[, default])
626 and
getattr(object, name[, default])
627 are equivalent to the built-in
getattr(object, name[, default])
630 with the
getattr(object, name[, default])
631 parameter set to
getattr(object, name[, default])
632 and
getattr(object, name[, default])
633, respectively. 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ư
getattr(object, name[, default])
634 và
getattr(object, name[, default])
635. 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

getattr(object, name[, default])
617 như sau

getattr(object, name[, default])
35

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

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

getattr(object, name[, default])
637 và tải xuống
getattr(object, name[, default])
638 từ trang web của Liên hợp quốc

getattr(object, name[, default])
36

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

getattr(object, name[, default])
37

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

getattr(object, name[, default])
639 và
getattr(object, name[, default])
640 nhất định

getattr(object, name[, default])
38

Các dòng được đánh dấu cho biết cách sử dụng

getattr(object, name[, default])
617 để 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

>>>

getattr(object, name[, default])
39

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

getattr(object, name[, default])
50

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ế

getattr(object, name[, default])
51

Lưu ý rằng ở dòng 24, bạn cũng kiểm tra xem

getattr(object, name[, default])
642 có nhỏ hơn
getattr(object, name[, default])
643 không. Các vị trí có
getattr(object, name[, default])
642 của
getattr(object, name[, default])
643 trở lên không phải là quốc gia thích hợp, mà là các tập hợp như
getattr(object, name[, default])
646,
getattr(object, name[, default])
647, v.v.

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

getattr(object, name[, default])
617. Ứ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

Đối số getattr trong python

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

getattr(object, name[, default])
649. Để tạo một
getattr(object, name[, default])
649, 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.

getattr(object, name[, default])
617 giải quyết vấn đề này bằng cách cung cấp
getattr(object, name[, default])
652. 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

getattr(object, name[, default])
652 làm trình quản lý ngữ cảnh bằng từ khóa
getattr(object, name[, default])
654

>>>

getattr(object, name[, default])
52

For the full example, assume you have the following file hierarchy

getattr(object, name[, default])
53

If you want to try the example yourself, then you can download these files along with the rest of the source code used in this tutorial by clicking the link below

Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial

The code is stored in a file with the special name

getattr(object, name[, default])
655. This name indicates that the file is the entry point for the package. Having a
getattr(object, name[, default])
655 file allows your package to be executed with
getattr(object, name[, default])
657

getattr(object, name[, default])
54

For more information on calling a package with

getattr(object, name[, default])
658, see How to Publish an Open-Source Python Package to PyPI

The GUI is defined in a class called

getattr(object, name[, default])
659. Note that you use
getattr(object, name[, default])
617 to obtain the path of the image files

getattr(object, name[, default])
55

If you want to learn more about building GUIs with Tkinter, then check out Python GUI Programming With Tkinter. The official documentation also has a nice list of resources to start with, and the tutorial at TkDocs is another great resource that shows how to use Tk in other languages

Note. One source of confusion and frustration when working with images in Tkinter is that you must make sure the images aren’t garbage collected. Due to the way Python and Tk interact, the garbage collector in Python (at least in CPython) doesn’t register that images are used by

getattr(object, name[, default])
661 and
getattr(object, name[, default])
662

To make sure that the images are kept around, you should manually add a reference to them. You can see examples of this in the code above on lines 18 and 31

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

Dynamic Imports

One of Python’s defining features is that it’s a very dynamic language. Although it’s sometimes a bad idea, you can do many things to a Python program when it’s running, including adding attributes to a class, redefining methods, or changing the docstring of a module. For instance, you can change

getattr(object, name[, default])
663 so that it doesn’t do anything

>>>

getattr(object, name[, default])
56

Technically, you’re not redefining

getattr(object, name[, default])
663. Instead, you’re defining another
getattr(object, name[, default])
663 that shadows the built-in one. To return to using the original
getattr(object, name[, default])
663, you can delete your custom one with
getattr(object, name[, default])
667. If you’re so inclined, you can shadow any Python object that is built into the interpreter

Note. In the above example, you redefine

getattr(object, name[, default])
663 using a lambda function. You also could have used a normal function definition

>>>

getattr(object, name[, default])
57

To learn more about lambda functions, see How to Use Python Lambda Functions

In this section, you’ll learn how to do dynamic imports in Python. With them, you won’t have to decide what to import until your program is running

Using getattr(object, name[, default])669

So far, you’ve used Python’s

getattr(object, name[, default])
244 keyword to import modules and packages explicitly. However, the whole import machinery is available in the
getattr(object, name[, default])
669 package, and this allows you to do your imports more dynamically. The following script asks the user for the name of a module, imports that module, and prints its docstring

getattr(object, name[, default])
58

getattr(object, name[, default])
672 returns a module object that you can bind to any variable. Then you can treat that variable as a regularly imported module. You can use the script like this

getattr(object, name[, default])
59

In each case, the module is imported dynamically by

getattr(object, name[, default])
672

Example. Factory Method With Namespace Packages

Think back to the serializers example from earlier. With

getattr(object, name[, default])
381 implemented as a namespace package, you had the ability to add custom serializers. In the original example from a previous tutorial, the serializers were made available through a serializer factory. Using
getattr(object, name[, default])
669, you can do something similar

Add the following code to your local

getattr(object, name[, default])
381 namespace package

getattr(object, name[, default])
50

The

getattr(object, name[, default])
677 factory can create serializers dynamically based on the
getattr(object, name[, default])
678 parameter, and
getattr(object, name[, default])
679 can then apply the serializer to any object that implements a
getattr(object, name[, default])
380 method

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

>>>

getattr(object, name[, default])
51

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

getattr(object, name[, default])
677 and
getattr(object, name[, default])
679 in an
getattr(object, name[, default])
266 file. That would have allowed you to simply import
getattr(object, name[, default])
381 and then call
getattr(object, name[, default])
685

However, namespace packages aren’t allowed to use

getattr(object, name[, default])
266, 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

getattr(object, name[, default])
687 module that exposes the plugin architecture has the following functions

getattr(object, name[, default])
52

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

Complete Source Code of plugins. pyShow/Hide

The following code shows the implementation of

getattr(object, name[, default])
688 described above

getattr(object, name[, default])
53

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

getattr(object, name[, default])
689 uses
getattr(object, name[, default])
690 to dynamically load plugins. Additionally,
getattr(object, name[, default])
691 uses
getattr(object, name[, default])
692 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

getattr(object, name[, default])
693 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

getattr(object, name[, default])
693 package

getattr(object, name[, default])
54

Each

getattr(object, name[, default])
693 module defines a function that takes one
getattr(object, name[, default])
359 argument. Note how they’re all registered as plugins using the
getattr(object, name[, default])
697 decorator

getattr(object, name[, default])
55

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

getattr(object, name[, default])
693 as a plugin package, you can use the factory functions in
getattr(object, name[, default])
687 to add functionality to the
getattr(object, name[, default])
693 package itself

getattr(object, name[, default])
56

You can now use

getattr(object, name[, default])
301 and
getattr(object, name[, default])
302 as follows

>>>

getattr(object, name[, default])
57

Note that

getattr(object, name[, default])
301 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. Tuy nhiên, bạn cũng có thể chọn plugin dựa trên tệp cấu hình hoặc đầu vào của người dùng

>>>

getattr(object, name[, default])
58

To discover and call the different plugins, you need to import them. Let’s have a quick look at how

getattr(object, name[, default])
687 handles imports. The main work is done in the following two functions inside
getattr(object, name[, default])
688

getattr(object, name[, default])
59

getattr(object, name[, default])
689 looks deceptively straightforward. Nó sử dụng
getattr(object, name[, default])
669 để nhập một mô-đun. Nhưng có một vài điều cũng xảy ra trong nền

  1. Hệ thống nhập của Python đảm bảo rằng mỗi plugin chỉ được nhập một lần
  2. getattr(object, name[, default])
    697 trình trang trí được xác định bên trong mỗi mô-đun plugin đăng ký từng plugin đã nhập
  3. In a full implementation, there would also be some error handling to deal with missing plugins

getattr(object, name[, default])
691 khám phá tất cả các plugin trong một gói. Đây là cách nó hoạt động

  1. getattr(object, name[, default])
    310 từ
    getattr(object, name[, default])
    617 liệt kê tất cả các tệp bên trong một gói
  2. The results are filtered to find potential plugins
  3. Mỗi tệp Python không bắt đầu bằng dấu gạch dưới được nhập
  4. Các plugin trong bất kỳ tệp nào được phát hiện và đăng ký

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

getattr(object, name[, default])
677 đã đư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

getattr(object, name[, default])
397

getattr(object, name[, default])
90

Next, update

getattr(object, name[, default])
314 to use
getattr(object, name[, default])
687

getattr(object, name[, default])
91

Bạn triển khai

getattr(object, name[, default])
677 bằng cách sử dụng
getattr(object, name[, default])
317 vì điều đó sẽ tự động khởi tạo từng bộ nối tiếp. Với việc tái cấu trúc này, các bộ tuần tự hóa hoạt động giống như trước đó. Tuy nhiên, bạn có thể linh hoạt hơn trong việc đặt tên cho các lớp serializer của mình

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

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

The Python Import System

Bạn đã thấy nhiều cách để tận dụng hệ thống nhập của Python. In this section, you’ll learn a bit more about what happens behind the scenes as modules and packages are imported

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

Nhập nội bộ

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

  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

getattr(object, name[, default])
244—cả ba bước diễn ra tự động. Tuy nhiên, khi bạn sử dụng
getattr(object, name[, default])
669, chỉ có hai bước đầu tiên là tự động. Bạn cần tự liên kết mô-đun với một biến hoặc không gian tên

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

getattr(object, name[, default])
253 sau đây gần như tương đương

>>>

getattr(object, name[, default])
92

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. The rest of the contents of the module just aren’t bound to the current namespace. Một cách để chứng minh điều này là xem cái được gọi là bộ đệm mô-đun

>>>

getattr(object, name[, default])
93

getattr(object, name[, default])
321 hoạt động như một bộ đệm mô-đun. Nó chứa các tham chiếu đến tất cả các mô-đun đã được nhập

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

getattr(object, name[, default])
321. Nếu một mô-đun đã có sẵn, thì nó sẽ không được tải lại

Đây là một tối ưu hóa tuyệt vời, nhưng nó cũng là một điều cần thiết. Nếu các mô-đun được tải lại mỗi khi chúng được nhập, thì bạn có thể gặp phải tình trạng không nhất quán trong một số trường hợp nhất định, chẳng hạn như khi mã nguồn cơ bản thay đổi trong khi tập lệnh đang chạy

Nhớ lại đường dẫn nhập mà bạn đã thấy trước đó. Về cơ bản, nó cho Python biết nơi tìm kiếm các mô-đun. Tuy nhiên, nếu Python tìm thấy một mô-đun trong bộ đệm mô-đun, thì nó sẽ không bận tâm tìm kiếm đường dẫn nhập cho mô-đun

Example. Singletons như các mô-đun

Trong lập trình hướng đối tượng, một singleton là một lớp có nhiều nhất một thể hiện. 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ố

getattr(object, name[, default])
94

Đọc dữ liệu từ đĩa mất một thời gian. Vì bạn không muốn tệp dữ liệu thay đổi, nên bạn khởi tạo lớp khi bạn tải mô-đun. Tên của lớp bắt đầu bằng dấu gạch dưới để cho người dùng biết rằng họ không nên sử dụng nó

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

getattr(object, name[, default])
323 để 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

>>>

getattr(object, name[, default])
95

This creates a chart like the following

Đối số getattr trong python

Lưu ý rằng việc tải dữ liệu tại thời điểm nhập là một loại phản mẫu. Lý tưởng nhất là bạn muốn hàng nhập khẩu của mình không có tác dụng phụ nhất có thể. A better approach would be to load the data lazily when you need it. Bạn có thể làm điều này khá tao nhã bằng cách sử dụng các thuộc tính. Mở rộng phần sau để xem ví dụ

Tải dữ liệu dân số một cách lười biếngHiển thị/Ẩn

The lazy implementation of

getattr(object, name[, default])
324 stores the population data in
getattr(object, name[, default])
325 the first time it’s read. The
getattr(object, name[, default])
326 property handles this caching of data

getattr(object, name[, default])
96

Bây giờ dữ liệu sẽ không được tải khi nhập. Instead, it’ll be imported the first time you access the

getattr(object, name[, default])
327 dictionary. Để biết thêm thông tin về các thuộc tính và khái niệm tổng quát hơn về bộ mô tả, hãy xem Bộ mô tả Python. Một lời giới thiệu

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

Tải lại mô-đun

Bộ đệm mô-đun có thể hơi khó chịu khi bạn đang làm việc trong trình thông dịch tương tác. Tải lại một mô-đun sau khi bạn thay đổi nó không phải là chuyện nhỏ. Ví dụ: hãy xem mô-đun sau

getattr(object, name[, default])
97

As part of testing and debugging this module, you import it in a Python console

>>>

getattr(object, name[, default])
98

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

getattr(object, name[, default])
328 trong trình chỉnh sửa của mình

getattr(object, name[, default])
99

Quay trở lại bảng điều khiển của bạn, bạn nhập mô-đun đã cập nhật để xem hiệu quả của bản sửa lỗi của bạn

>>>

getattr(object, name[, default])
98

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

getattr(object, name[, default])
329? . vì Python đã nhập
getattr(object, name[, default])
330 trước đó, nên không có lý do gì để tải lại mô-đun mặc dù bạn vừa thay đổi nó

Giải pháp đơn giản nhất cho vấn đề này là thoát khỏi bảng điều khiển Python và khởi động lại nó. Điều này buộc Python cũng phải xóa bộ đệm mô-đun của nó

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
21

However, restarting the interpreter isn’t always feasible. Bạn có thể đang ở trong một phiên phức tạp hơn khiến bạn mất nhiều thời gian để thiết lập. If that’s the case, then you can use

getattr(object, name[, default])
331 to reload a module instead

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
22

Lưu ý rằng

getattr(object, name[, default])
332 yêu cầu đối tượng mô-đun, không phải chuỗi như
getattr(object, name[, default])
672. Ngoài ra, hãy lưu ý rằng
getattr(object, name[, default])
332 có một số lưu ý. Cụ thể, các biến tham chiếu đến các đối tượng trong một mô-đun không bị ràng buộc lại với các đối tượng mới khi mô-đun đó được tải lại. Xem tài liệu để biết thêm chi tiết

Trình tìm và Trình tải

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

getattr(object, name[, default])
335 trong đường dẫn nhập của Python, thì bạn sẽ không thể nhập
getattr(object, name[, default])
249 từ thư viện chuẩn

Điều này không phải luôn luôn như vậy, mặc dù. Create a file named

getattr(object, name[, default])
337 with the following content

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
23

Next, open a Python interpreter and import this new module

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
24

Something weird happened. It doesn’t seem like Python imported your new

getattr(object, name[, default])
338 module. Instead, it imported the
getattr(object, name[, default])
338 module from the standard library. Tại sao các mô-đun thư viện tiêu chuẩn hoạt động không nhất quán?

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
25

You can see that

getattr(object, name[, default])
249 is imported from a file, whereas
getattr(object, name[, default])
338 is some kind of built-in module. Có vẻ như các mô-đun tích hợp không bị che khuất bởi các mô-đun cục bộ

Ghi chú. Các mô-đun tích hợp được biên dịch thành trình thông dịch Python. Thông thường, chúng là các mô-đun nền tảng như

getattr(object, name[, default])
342,
getattr(object, name[, default])
343 và
getattr(object, name[, default])
338. Những mô-đun nào được tích hợp sẵn tùy thuộc vào trình thông dịch Python của bạn, nhưng bạn có thể tìm thấy tên của chúng trong
getattr(object, name[, default])
345

Hãy tìm hiểu sâu hơn về hệ thống nhập của Python. Điều này cũng sẽ cho thấy lý do tại sao các mô-đun tích hợp không bị che khuất bởi các mô-đun cục bộ. Có một số bước liên quan khi nhập một mô-đun

  1. Python kiểm tra xem mô-đun có sẵn trong bộ đệm mô-đun không. Nếu

    getattr(object, name[, default])
    321 chứa tên của mô-đun, thì mô-đun đó đã có sẵn và quá trình nhập kết thúc

  2. Python bắt đầu tìm kiếm mô-đun bằng một số công cụ tìm. Một công cụ tìm sẽ tìm kiếm mô-đun bằng một chiến lược nhất định. Công cụ tìm mặc định có thể nhập các mô-đun tích hợp, mô-đun cố định và mô-đun trên đường dẫn nhập

  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. You’ll see a more useful example of a finder later. 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

getattr(object, name[, default])
347 kiểm soát công cụ tìm nào được gọi trong quá trình nhập

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
26

Đầu tiên, lưu ý rằng điều này trả lời câu hỏi từ trước đó. các mô-đun tích hợp không bị che khuất bởi các mô-đun cục bộ vì công cụ tìm tích hợp được gọi trước công cụ tìm đường dẫn nhập, tìm các mô-đun cục bộ. Second, note that you can customize

getattr(object, name[, default])
347 to your liking

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

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
27

Vì không có công cụ tìm, Python không thể tìm hoặc nhập các mô-đun mới. Tuy nhiên, Python vẫn có thể nhập các mô-đun đã có trong bộ đệm mô-đun vì nó tìm ở đó trước khi gọi bất kỳ công cụ tìm nào

In the example above,

getattr(object, name[, default])
669 was already loaded under the hood before you cleared the list of finders. If you really want to make your Python session completely unusable, then you can also clear the module cache,
getattr(object, name[, default])
321

Sau đây là một ví dụ hữu ích hơn một chút. Bạn sẽ viết một công cụ tìm in thông báo tới bảng điều khiển xác định mô-đun đang được nhập. The example shows how to add your own finder, although it doesn’t actually attempt to find a module

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
28

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

getattr(object, name[, default])
351, phương thức này sẽ cố gắng tìm một mô-đun nhất định. Có ba cách mà
getattr(object, name[, default])
351 có thể chấm dứt

  1. Bằng cách trả lại
    getattr(object, name[, default])
    353 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
    getattr(object, name[, default])
    383 để cho biết rằng không thể nhập mô-đun

getattr(object, name[, default])
355 in một thông báo tới bảng điều khiển và sau đó trả về rõ ràng
getattr(object, name[, default])
353 để 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ề

getattr(object, name[, default])
353 từ bất kỳ hàm hoặc phương thức nào mà không có
getattr(object, name[, default])
358 rõ ràng, bạn có thể bỏ qua dòng 9. However, in this case it’s good to include
getattr(object, name[, default])
359 to make it clear that
getattr(object, name[, default])
355 doesn’t find a module

Bằng cách chèn

getattr(object, name[, default])
355 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

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
29

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

getattr(object, name[, default])
362 sẽ kích hoạt việc nhập một số mô-đun khác mà
getattr(object, name[, default])
362 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,
getattr(object, name[, default])
364, 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

getattr(object, name[, default])
365

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
40

Raising a

getattr(object, name[, default])
383 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

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
41

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

getattr(object, name[, default])
362, nhưng mô-đun đó đang nhập
getattr(object, name[, default])
365 đằng sau hậu trường, vì vậy sẽ xảy ra lỗi

Ví dụ. Automatically Install From PyPI

Vì hệ thống nhập của Python đã khá mạnh mẽ và hữu ích, nên có nhiều cách để làm rối tung nó hơn là mở rộng nó theo cách hữu ích. Tuy nhiên, ví dụ sau có thể hữu ích trong một số trường hợp

The Python Package Index (PyPI) is your one-stop cheese shop for finding third-party modules and packages. Đây cũng là nơi mà các gói tải xuống của

getattr(object, name[, default])
355

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

getattr(object, name[, default])
370 để cài đặt các mô-đun và gói của bên thứ ba mà bạn cần để làm theo cùng với các ví dụ. Sẽ thật tuyệt nếu Python tự động cài đặt các mô-đun còn thiếu cho bạn phải không?

Cảnh báo. Trong hầu hết các trường hợp, sẽ không tuyệt lắm nếu Python tự động cài đặt các mô-đun. Chẳng hạn, trong hầu hết các cài đặt sản xuất, bạn muốn kiểm soát môi trường của mình. Hơn nữa, tài liệu cảnh báo không nên sử dụng

getattr(object, name[, default])
355 theo cách này

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

Công cụ tìm sau cố gắng cài đặt các mô-đun bằng cách sử dụng

getattr(object, name[, default])
355

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
42

Compared to the finders you saw earlier, this one is slightly more complicated. Bằng cách đặt công cụ tìm này cuối cùng trong danh sách công cụ tìm, bạn biết rằng nếu bạn gọi

getattr(object, name[, default])
373, thì mô-đun đó sẽ không được tìm thấy trên hệ thống của bạn. Do đó, công việc của
getattr(object, name[, default])
351 chỉ là thực hiện
getattr(object, name[, default])
375. 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

getattr(object, name[, default])
376 mà không cần tự cài đặt

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
43

Thông thường,

getattr(object, name[, default])
377 sẽ tăng một
getattr(object, name[, default])
383, nhưng trong trường hợp này,
getattr(object, name[, default])
376 được cài đặt và nhập

Trong khi

getattr(object, name[, default])
373 dường như hoạt động, có một số thách thức với cách tiếp cận này. One major problem is that the import name of a module doesn’t always correspond to its name on PyPI. Ví dụ: trình đọc nguồn cấp dữ liệu Real Python có tên là
getattr(object, name[, default])
381 trên PyPI, nhưng tên nhập chỉ đơn giản là
getattr(object, name[, default])
382

Sử dụng

getattr(object, name[, default])
373 để nhập và cài đặt
getattr(object, name[, default])
382 kết thúc bằng việc cài đặt sai gói

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
44

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

Một tình huống trong đó cài đặt tự động có thể khá hữu ích là khi bạn đang chạy Python trên đám mây với quyền kiểm soát hạn chế hơn đối với môi trường của bạn, chẳng hạn như khi bạn đang chạy sổ ghi chép kiểu Jupyter tại Google Colaboratory. Môi trường sổ ghi chép Colab rất phù hợp để thực hiện khám phá dữ liệu hợp tác

Một sổ ghi chép thông thường đ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

getattr(object, name[, default])
355. Nhưng bạn cũng có thể kích hoạt cài đặt tự động

Đối số getattr trong python

getattr(object, name[, default])
386 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. Import Data Files

Ví dụ cuối cùng trong phần này được lấy cảm hứng từ bài đăng trên blog tuyệt vời của Aleksey Bilogur Nhập hầu hết mọi thứ bằng Python. An Intro to Module Loaders and Finders. Bạn đã biết cách sử dụng

getattr(object, name[, default])
617 để nhập tệp dữ liệu. Tại đây, thay vào đó, bạn sẽ triển khai trình tải tùy chỉnh có thể nhập trực tiếp tệp 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

getattr(object, name[, default])
388 nhỏ hơn sau đây

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
45

Dòng đầu tiên là tiêu đề đặt tên cho ba trường và hai hàng dữ liệu tiếp theo, mỗi hàng chứa thông tin về một nhân viên. Để biết thêm thông tin về cách làm việc với tệp CSV, hãy xem Đọc và ghi tệp CSV bằng Python

Mục tiêu của bạn trong phần này là viết một công cụ tìm và một trình tải cho phép bạn nhập tệp CSV trực tiếp để bạn có thể viết mã như sau

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
46

Công việc của công cụ tìm sẽ là tìm kiếm và nhận dạng các tệp CSV. Công việc của trình tải sẽ là nhập dữ liệu CSV. Thông thường, bạn có thể triển khai các trình tìm và trình tải tương ứng trong một lớp chung. That’s the approach you’ll take here

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
47

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

getattr(object, name[, default])
351 và
getattr(object, name[, default])
390. Hãy xem xét chúng chi tiết hơn

Như bạn đã thấy trước đó,

getattr(object, name[, default])
351 chịu trách nhiệm tìm mô-đun. In this case, you’re looking for CSV files, so you create a filename with a
getattr(object, name[, default])
392 suffix.
getattr(object, name[, default])
359 chứa tên đầy đủ của mô-đun được nhập. Ví dụ: nếu bạn sử dụng
getattr(object, name[, default])
394, thì
getattr(object, name[, default])
359 sẽ là
getattr(object, name[, default])
396. Trong trường hợp này, tên tệp sẽ là
getattr(object, name[, default])
388

Đối với nhập cấp cao nhất,

getattr(object, name[, default])
398 sẽ là
getattr(object, name[, default])
353. 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ì
getattr(object, name[, default])
398 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
getattr(object, name[, default])
501

Dữ liệu CSV được tải bởi

getattr(object, name[, default])
390. Bạn có thể sử dụng
getattr(object, name[, default])
503 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
getattr(object, name[, default])
504, 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

getattr(object, name[, default])
505 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

>>>

class Person:
    age = 23
    name = "Adam"

person = Person()

print('The age is:', getattr(person, "age"))

print('The age is:', person.age)
48

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

getattr(object, name[, default])
506 bắt đầu từ dòng 51

Bạn có thể xem ví dụ về hiệu ứng này trong tên trường

getattr(object, name[, default])
507 ở trên. Nếu xem tệp CSV gốc, thì bạn sẽ thấy tiêu đề có nội dung
getattr(object, name[, default])
508 với dấu cách thay vì dấu gạch dưới

By hooking this

getattr(object, name[, default])
501 into the Python import system, you get a fair bit of functionality for free. For example, the module cache will make sure that the data file is loaded only once

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

Để hoàn thiện hướng dẫn này, bạn sẽ thấy một số mẹo về cách xử lý các tình huống nhất định thỉnh thoảng xảy ra. Bạn sẽ thấy cách xử lý các gói bị thiếu, nhập theo chu kỳ và thậm chí cả các gói được lưu trữ bên trong tệp ZIP

Handle Packages Across Python Versions

Sometimes you need to deal with packages that have different names depending on the Python version. Bạn đã thấy một ví dụ về điều này.

getattr(object, name[, default])
617 has only been available since 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
getattr(object, name[, default])
621 để 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

getattr(object, name[, default])
512

getattr(object, name[, default])
35

Trong phần còn lại của mã, bạn có thể tham khảo

getattr(object, name[, default])
513 và không cần lo lắng về việc bạn đang sử dụng
getattr(object, name[, default])
617 hay
getattr(object, name[, default])
621

Thông thường, cách dễ nhất là sử dụng câu lệnh

getattr(object, name[, default])
353 để 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

Bạn có thể viết lại ví dụ trước như sau

getattr(object, name[, default])
200

This would use

getattr(object, name[, default])
617 on Python 3. 7 trở lên trong khi quay lại
getattr(object, name[, default])
621 trên các phiên bản Python cũ hơn. Xem dự án
getattr(object, name[, default])
519 để có lời khuyên hữu ích và phù hợp với tương lai về cách kiểm tra phiên bản Python nào đang chạy

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

Trường hợp sử dụng sau có liên quan chặt chẽ với ví dụ trước. Assume there’s a compatible reimplementation of a package. Việc triển khai lại được tối ưu hóa tốt hơn, vì vậy bạn muốn sử dụng nó nếu có sẵn. Tuy nhiên, gói ban đầu có sẵn dễ dàng hơn và cũng mang lại hiệu suất chấp nhận được

Một ví dụ như vậy là

getattr(object, name[, default])
520, đây là phiên bản được tối ưu hóa của
getattr(object, name[, default])
521 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 đó

getattr(object, name[, default])
201

This will use

getattr(object, name[, default])
520 if it’s available and fall back to
getattr(object, name[, default])
521 if not

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

getattr(object, name[, default])
396 trong thư viện chuẩn

getattr(object, name[, default])
202

Bằng cách đổi tên

getattr(object, name[, default])
525 thành
getattr(object, name[, default])
396, bạn không phải lo lắng về gói hàng nào thực sự được nhập khẩu

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

Ví dụ thứ ba, có liên quan là thêm một gói cung cấp một tính năng tuyệt vời không thực sự cần thiết cho ứng dụng của bạn. Again, this can be solved by adding

getattr(object, name[, default])
353 to your imports. 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

For a concrete example, say that you’re using Colorama to add colored text in the console. Colorama mainly consists of special string constants that add color when printed

>>>

getattr(object, name[, default])
203

Thật không may, màu sắc không hiển thị trong ví dụ trên. In your terminal it’ll look something like this

Đối số getattr trong python

Trước khi bắt đầu sử dụng màu Colorama, bạn nên gọi cho

getattr(object, name[, default])
528. Đặt
getattr(object, name[, default])
529 thành
getattr(object, name[, default])
530 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

getattr(object, name[, default])
529 be
getattr(object, name[, default])
532 and add
getattr(object, name[, default])
533 to the beginning of your script. Các màu sau đây có sẵn

>>>

getattr(object, name[, default])
204

Bạn cũng có thể sử dụng

getattr(object, name[, default])
534 để kiểm soát phong cách văn bản của mình. You can choose between
getattr(object, name[, default])
535,
getattr(object, name[, default])
536, and
getattr(object, name[, default])
537

Cuối cùng,

getattr(object, name[, default])
538 cung cấp mã để kiểm soát vị trí của con trỏ. You can use it to display the progress or status of a running script. Ví dụ sau hiển thị đếm ngược từ
getattr(object, name[, default])
539

getattr(object, name[, default])
205

Lưu ý cách bộ đếm giữ nguyên vị trí thay vì in trên các dòng riêng biệt như bình thường

Đối số getattr trong python

Let’s get back to the task at hand. Đối với nhiều ứng dụng, việc thêm màu vào đầu ra bảng điều khiển của bạn rất thú vị nhưng không quan trọng. Để tránh thêm một phần phụ thuộc khác vào ứng dụng của mình, bạn chỉ muốn sử dụng Colorama nếu ứng dụng này có sẵn trên hệ thống và không phá vỡ ứng dụng nếu ứng dụng không có

Để làm điều này, bạn có thể lấy cảm hứng từ thử nghiệm và việc sử dụng mô phỏng. Một mô hình có thể thay thế cho một đối tượng khác đồng thời cho phép bạn kiểm soát hành vi của nó. Đây là một nỗ lực ngây thơ để chế giễu Colorama

>>>

getattr(object, name[, default])
206

Điều này không thực sự hiệu quả, vì

getattr(object, name[, default])
540 đượ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

getattr(object, name[, default])
377 trên các đối tượng
getattr(object, name[, default])
542. Tuy nhiên, trong trường hợp này, sẽ thuận tiện hơn nếu bạn viết bản mô phỏng của riêng mình

getattr(object, name[, default])
207

getattr(object, name[, default])
543 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à

getattr(object, name[, default])
544 tự trả về chính nó, do đó tất cả màu sắc, kiểu dáng và chuyển động của con trỏ là các thuộc tính trên
getattr(object, name[, default])
545,
getattr(object, name[, default])
546,
getattr(object, name[, default])
547 và
getattr(object, name[, default])
548 cũng bị giả lập

The

getattr(object, name[, default])
549 module is designed to be a drop-in replacement for Colorama, so you can update the countdown example using search and replace

getattr(object, name[, default])
208

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

Đối số getattr trong python

Khi cài đặt Colorama, bạn sẽ thấy kết quả giống như trước đó

Nhập tập lệnh dưới dạng mô-đun

Một điểm khác biệt giữa tập lệnh và mô-đun thư viện là tập lệnh thường làm một việc gì đó, trong khi thư viện cung cấp chức năng. Both scripts and libraries live inside regular Python files, and as far as Python is concerned, there’s no difference between them

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

getattr(object, name[, default])
550 or imported with
getattr(object, name[, default])
551 inside another script?

Đôi khi, bạn sẽ có một mô-đun hoạt động như cả tập lệnh và thư viện. Bạn có thể thử cấu trúc lại mô-đun của mình thành hai tệp khác nhau

Một ví dụ về điều này trong thư viện tiêu chuẩn là gói

getattr(object, name[, default])
396. 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
getattr(object, name[, default])
553 sau

getattr(object, name[, default])
209

Vì JSON thường chỉ được đọc bởi máy móc nên nhiều tệp JSON không được định dạng theo kiểu có thể đọc được. Trên thực tế, việc các tệp JSON bao gồm một dòng văn bản rất dài là điều khá phổ biến.

getattr(object, name[, default])
554 là tập lệnh sử dụng thư viện
getattr(object, name[, default])
396 để định dạng JSON theo cách dễ đọc hơn

getattr(object, name[, default])
210

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

getattr(object, name[, default])
556 để sắp xếp các khóa theo thứ tự bảng chữ cái

While it’s good practice to split scripts and libraries, Python has an idiom that makes it possible to treat a module as both a script and a library at the same time. Như đã lưu ý trước đó, giá trị của biến mô-đun

getattr(object, name[, default])
325 đặ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

Let’s test it out. Tạo tập tin sau

getattr(object, name[, default])
211

If you run this file, then you’ll see that

getattr(object, name[, default])
325 is set to the special value
getattr(object, name[, default])
326

getattr(object, name[, default])
212

Tuy nhiên, nếu bạn nhập mô-đun, thì

getattr(object, name[, default])
325 được đặt thành tên của mô-đun

>>>

getattr(object, name[, default])
213

Hành vi này được tận dụng trong mẫu sau

getattr(object, name[, default])
214

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 (

getattr(object, name[, default])
561 trở lên) bằng
getattr(object, name[, default])
329

getattr(object, name[, default])
215

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

getattr(object, name[, default])
216

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

getattr(object, name[, default])
324 ở 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
getattr(object, name[, default])
564 và
getattr(object, name[, default])
565 được xác định. Ví dụ, bạn có thể sử dụng thư viện này như sau

>>>

getattr(object, name[, default])
217

Nếu không có sự bảo vệ của thử nghiệm

getattr(object, name[, default])
324, quá trình nhập sẽ kích hoạt
getattr(object, name[, default])
567 tương tác và khiến cho việc sử dụng
getattr(object, name[, default])
568 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

Nếu bạn cung cấp cho trình thông dịch Python một tệp ZIP, thì nó sẽ tìm tệp có tên

getattr(object, name[, default])
655 bên trong kho lưu trữ ZIP, giải nén và chạy tệp đó. Như một ví dụ cơ bản, tạo tệp
getattr(object, name[, default])
655 sau

getattr(object, name[, default])
218

Điều này sẽ in một tin nhắn khi bạn chạy nó

getattr(object, name[, default])
219

Bây giờ hãy thêm nó vào kho lưu trữ ZIP. Bạn có thể làm điều này trên dòng lệnh

getattr(object, name[, default])
220

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)

getattr(object, name[, default])
326 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à
getattr(object, name[, default])
572. Bây giờ bạn có thể gọi nó trực tiếp bằng Python

getattr(object, name[, default])
221

Lưu ý rằng tập lệnh của bạn biết rằng nó nằm bên trong

getattr(object, name[, default])
572. 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.

getattr(object, name[, default])
617 sẽ đảm bảo tệp dữ liệu được trích xuất từ ​​kho lưu trữ ZIP khi cần

Ứng dụng bao gồm các tệp sau

getattr(object, name[, default])
222

Bạn có thể thêm chúng vào tệp ZIP giống như cách bạn đã làm ở trên. Tuy nhiên, Python đi kèm với một công cụ có tên là

getattr(object, name[, default])
575 hợp lý hóa quy trình đóng gói ứng dụng vào kho lưu trữ ZIP. Bạn sử dụng nó như sau

getattr(object, name[, default])
223

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 một tệp

getattr(object, name[, default])
655 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 ______ 3658 thông tin về cách bắt đầu ứng dụng của bạn, thì ________ 4575 đã tạo tệp này cho bạn. Trong ví dụ này,
getattr(object, name[, default])
655 được tạo trông như thế này

getattr(object, name[, default])
224

getattr(object, name[, default])
655 này được đóng gói, cùng với nội dung của thư mục
getattr(object, name[, default])
581, vào một kho lưu trữ ZIP có tên là
getattr(object, name[, default])
582. Hậu tố
getattr(object, name[, default])
583 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,

getattr(object, name[, default])
575 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
getattr(object, name[, default])
575 nén các tệp bằng cách thêm tùy chọn
getattr(object, name[, default])
586

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

getattr(object, name[, default])
575 để biết thêm thông tin

Trên Windows, các tệp

getattr(object, name[, default])
583 đã được đăng ký dưới dạng tệp Python. Trên Mac và Linux, bạn có thể yêu cầu
getattr(object, name[, default])
575 tạo các tệp thực thi bằng cách sử dụng tùy chọn trình thông dịch
getattr(object, name[, default])
590 và chỉ định trình thông dịch nào sẽ sử dụng

getattr(object, name[, default])
225

Tùy chọn

getattr(object, name[, default])
590 thêm một shebang (
getattr(object, name[, default])
592) cho hệ điều hành biết cách chạy tệp. Ngoài ra, nó làm cho tệp
getattr(object, name[, default])
583 có thể thực thi được để bạn có thể chạy tệp chỉ bằng cách nhập tên của nó

getattr(object, name[, default])
226

Lưu ý

getattr(object, name[, default])
594 trước tên tệp. Đây là một thủ thuật điển hình trên Mac và Linux để chạy các tệp thực thi trong thư mục hiện tại. Nếu bạn di chuyển tệp vào một thư mục trên
getattr(object, name[, default])
595 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.
getattr(object, name[, default])
582

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

getattr(object, name[, default])
637. Điều này là do một giới hạn trong
getattr(object, name[, default])
598

Một cách giải quyết khác là cung cấp đường dẫn tuyệt đối tới

getattr(object, name[, default])
582. Trên Mac và Linux, bạn có thể làm điều này bằng thủ thuật sau

getattr(object, name[, default])
227

Lệnh

getattr(object, name[, default])
500 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

getattr(object, name[, default])
617. Hãy nhớ rằng bạn đã sử dụng đoạn mã sau để mở tệp dữ liệu

getattr(object, name[, default])
228

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

getattr(object, name[, default])
613 của mô-đun của bạn

getattr(object, name[, default])
229

Cách tiếp cận này thường hoạt động tốt. Tuy nhiên, nó sẽ bị hỏng khi ứng dụng của bạn được đóng gói thành tệp ZIP

getattr(object, name[, default])
230

Tệp dữ liệu của bạn nằm trong kho lưu trữ ZIP nên

getattr(object, name[, default])
630 không thể mở tệp đó. Mặt khác,
getattr(object, name[, default])
617 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

getattr(object, name[, default])
505 sử dụng
getattr(object, name[, default])
506 và mô-đun
getattr(object, name[, default])
507 nhập khẩu tương tự
getattr(object, name[, default])
505

Đối số getattr trong python

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. For instance, the following code—while not very useful—runs fine

getattr(object, name[, default])
231

Cố gắng nhập

getattr(object, name[, default])
505 trong trình thông dịch tương tác cũng nhập
getattr(object, name[, default])
507

>>>

getattr(object, name[, default])
232

Lưu ý rằng

getattr(object, name[, default])
507 được nhập vào giữa quá trình nhập của
getattr(object, name[, default])
505, chính xác tại câu lệnh
getattr(object, name[, default])
506 trong mã nguồn của
getattr(object, name[, default])
505. 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

getattr(object, name[, default])
515, một tham chiếu đến
getattr(object, name[, default])
505 sẽ được thêm vào bộ nhớ cache của mô-đun ngay cả trước khi tải
getattr(object, name[, default])
505. Khi
getattr(object, name[, default])
507 cố gắng nhập
getattr(object, name[, default])
505 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

getattr(object, name[, default])
233

Nhập

getattr(object, name[, default])
505 hoạt động giống như trước đây

>>>

getattr(object, name[, default])
232

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

getattr(object, name[, default])
521

getattr(object, name[, default])
235

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

>>>

getattr(object, name[, default])
236

Thông báo lỗi lúc đầu có vẻ hơi khó hiểu. Looking back at the source code, you can confirm that

getattr(object, name[, default])
330 is defined in the
getattr(object, name[, default])
505 module

Vấn đề là

getattr(object, name[, default])
330 không được xác định trong
getattr(object, name[, default])
505 tại thời điểm
getattr(object, name[, default])
507 được nhập. Do đó,
getattr(object, name[, default])
527 được sử dụng bởi lệnh gọi tới
getattr(object, name[, default])
528

Thêm vào sự nhầm lẫn, bạn sẽ không gặp vấn đề gì khi nhập

getattr(object, name[, default])
507

>>>

getattr(object, name[, default])
237

Vào thời điểm

getattr(object, name[, default])
507 gọi
getattr(object, name[, default])
528,
getattr(object, name[, default])
505 được nhập hoàn toàn và
getattr(object, name[, default])
527 được xác định rõ. Cuối cùng, do bộ đệm mô-đun mà bạn đã thấy trước đó,
getattr(object, name[, default])
515 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

>>>

getattr(object, name[, default])
238

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,

getattr(object, name[, default])
506 được thực hiện bên trong
getattr(object, name[, default])
528. Điều này có hai hậu quả. Đầu tiên,
getattr(object, name[, default])
507 chỉ khả dụng bên trong hàm
getattr(object, name[, default])
528. Quan trọng hơn, quá trình nhập không xảy ra cho đến khi bạn gọi
getattr(object, name[, default])
528 sau khi
getattr(object, name[, default])
505 đã được nhập đầy đủ

getattr(object, name[, default])
239

Bây giờ không có vấn đề gì khi nhập và sử dụng

getattr(object, name[, default])
505

>>>

getattr(object, name[, default])
240

Lưu ý rằng trên thực tế,

getattr(object, name[, default])
507 không được nhập cho đến khi bạn gọi
getattr(object, name[, default])
528. Để có một góc nhìn khác về nhập khẩu theo chu kỳ, hãy xem ghi chú kinh điển của Fredrik Lundh

Nhập hồ sơ

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

Kể từ khi phát hành Python 3. 7, bạn đã có một cách nhanh chóng để biết cần bao nhiêu thời gian để nhập các gói và mô-đun. Trăn 3. 7 hỗ trợ tùy chọn dòng lệnh

getattr(object, name[, default])
544, đo lường và in lượng thời gian mỗi mô-đun cần để nhập

getattr(object, name[, default])
241

Cột

getattr(object, name[, default])
545 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
getattr(object, name[, default])
546 micro giây để nhập đầy đủ
getattr(object, name[, default])
547, bao gồm cả việc nhập
getattr(object, name[, default])
338,
getattr(object, name[, default])
249 và triển khai C
getattr(object, name[, default])
550

Cột

getattr(object, name[, default])
551 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
getattr(object, name[, default])
338 mất
getattr(object, name[, default])
553 micro giây để nhập,
getattr(object, name[, default])
249 mất
getattr(object, name[, default])
555,
getattr(object, name[, default])
550 mất
getattr(object, name[, default])
557 và bản thân việc nhập
getattr(object, name[, default])
547 mất
getattr(object, name[, default])
559 micro giây. Nói chung, điều này làm tăng thêm thời gian tích lũy là
getattr(object, name[, default])
546 micro giây (trong phạm vi lỗi làm tròn)

Hãy xem ví dụ về

getattr(object, name[, default])
561 từ phần Colorama

getattr(object, name[, default])
242

Trong ví dụ này, việc nhập

getattr(object, name[, default])
549 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
getattr(object, name[, default])
551 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ẻ

getattr(object, name[, default])
324 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
getattr(object, name[, default])
565 dưới dạng tập lệnh với tùy chọn
getattr(object, name[, default])
586

getattr(object, name[, default])
243

Trong trường hợp này, mất gần 2 giây để nhập

getattr(object, name[, default])
324, 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

getattr(object, name[, default])
544 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

Phần kết luận

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

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

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

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

  • The import system
  • Gói
    getattr(object, name[, default])
    669
  • PEP 420. Gói không gian tên ẩn
  • Nhập mô-đun

Bạn có thể sử dụng kiến ​​thức về nhập Python của mình bằng cách làm theo các ví dụ trong hướng dẫn này. Nhấp vào liên kết bên dưới để truy cập vào mã nguồn

Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial

Đánh dấu là đã hoàn thành

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Đối số getattr trong python

Gửi cho tôi thủ thuật Python »

Giới thiệu về Geir Arne Hjelle

Đối số getattr trong python
Đối số getattr trong python

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à

Đối số getattr trong python

Aldren

Đối số getattr trong python

Brad

Đối số getattr trong python

Đan

Đối số getattr trong python

Joanna

Đối số getattr trong python

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

Đối số getattr trong python

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. Get tips for asking good questions and get answers to common questions in our support portal