The 82 method returns the value of the named attribute of an object. If not found, it returns the default value provided to the functionExample
getattr() SyntaxThe syntax of 82 method isgetattr(object, name[, default]) The above syntax is equivalent to object.name getattr() Parameters 82 method takes multiple parameters
getattr() Return Value 82 method returns
Example 1. How getattr() works in Python?
Output The age is: 23 The age is: 23 Example 2. getattr() when named attribute is not found
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 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
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])244Python 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áomô-đuncon trăn. thuật ngữ org định nghĩa mô-đun như sau
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
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 PackagesYou can use a package to further organize your modules. The Python. org glossary defines package as follows
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 >>> 2Remember, 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 >>> 4You 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 packageLoại bỏ các quảng cáo Absolute and Relative ImportsRecall 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 PathHow 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
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ợpLoại bỏ các quảng cáo Ví dụ. Cấu trúc nhập khẩu của bạnMặ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
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
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])355Loạ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
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ênCá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áoImports Style GuidePEP 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
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 ImportsSometimes 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
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])617getattr(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
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áoVí dụ. Sử dụng tệp dữ liệuLà 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 TkinterKhi 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 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áoDynamic ImportsOne 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])669So 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 PackagesThink 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áoExample. A Package of PluginsLet’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
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
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
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áoThe Python Import SystemBạ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à
Đố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ô-đunTrong 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 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ệuLoại bỏ các quảng cáo Tải lại mô-đunBộ đệ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ó >>> 21However, 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 >>> 22Lư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ảiBạ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 23Next, open a Python interpreter and import this new module >>> 24Something 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? >>> 25You 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
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 >>> 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 >>> 27Vì 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 28Tấ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
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 >>> 29Ví 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 40Raising 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 >>> 41Mặ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 PyPIVì 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 42Compared 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 >>> 43Thô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 >>> 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 Vì 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 FilesVí 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 45Dò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 >>> 46Cô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 47Có 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 >>> 48Nó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 VersionsSometimes 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 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 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 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ô-đunMộ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 ZIPMộ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) Vì 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 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ậnTrong 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
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
Bạn có thể sử dụng kiến thức về nhập Python của mình bằng cách làm theo các ví dụ trong hướng dẫn này. Nhấp vào liên kết bên dưới để truy cập vào mã nguồn Get the Source Code. Click here to get the source code you’ll use to learn about the Python import system in this tutorial Đánh dấu là đã hoàn thành 🐍 Thủ thuật Python 💌 Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python Gửi cho tôi thủ thuật Python » Giới thiệu về Geir Arne Hjelle Geir Arne là một Pythonista cuồng nhiệt và là thành viên của nhóm hướng dẫn Real Python » Thông tin thêm về Geir ArneMỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là Aldren Brad Đan Joanna Gia-cốp Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bậc thầy Kỹ năng Python trong thế giới thực Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bạn nghĩ sao? Đánh giá bài viết này Tweet Chia sẻ Chia sẻ EmailBài học số 1 hoặc điều yêu thích mà bạn đã học được là gì? Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Get tips for asking good questions and get answers to common questions in our support portal |