Trước tiên tôi cần phải hiểu rõ hơn về hoạt động import
. May mắn thay, điều này được giải thích rõ trong tài liệu importlib
và gãi thông qua mã nguồn cũng đã giúp.
Quá trình import
này thực sự được chia thành hai phần. Đầu tiên, một công cụ tìm kiếm phụ trách phân tích tên mô-đun [bao gồm các gói được phân tách DOT] và khởi tạo một trình tải thích hợp. Thật vậy, tích hợp không được nhập như các mô-đun cục bộ chẳng hạn. Sau đó, trình tải được gọi dựa trên những gì công cụ tìm trả lại. Trình tải này nhận được nguồn từ một tệp hoặc từ bộ đệm và thực hiện mã nếu mô -đun không được tải trước đó.
Điều này rất đơn giản. Điều này giải thích lý do tại sao tôi thực sự không cần sử dụng các lớp trừu tượng từ importutil.abc
: Tôi không muốn cung cấp quy trình nhập khẩu của riêng mình. Thay vào đó, tôi có thể tạo một lớp con được kế thừa từ một trong các lớp từ
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 và ghi đè
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py1 từ
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py2 chẳng hạn. Tuy nhiên, đây không phải là cách để đi vì trình tải được khởi tạo bởi công cụ tìm nên tôi không có tay sử dụng lớp nào. Tôi không thể chỉ định rằng lớp con của tôi nên được sử dụng.
Vì vậy, giải pháp tốt nhất là để công cụ tìm kiếm công việc của mình, và sau đó thay thế phương pháp
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py1 của bất kỳ trình tải nào đã được khởi tạo.
Thật không may, bằng cách tìm máng, nguồn mã tôi thấy rằng các trình tải cơ bản không sử dụng
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py1 [chỉ được sử dụng bởi mô -đun
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py5]. Vì vậy, toàn bộ ý tưởng của tôi không thể hoạt động.
Cuối cùng, tôi đoán
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py1 nên được gọi là thủ công, sau đó nguồn được trả về phải được sửa đổi và cuối cùng mã sẽ được thực thi. Đây là những gì Martin Valgur chi tiết trong câu trả lời của mình.
Nếu cần phải tương thích với Python 2, tôi không thấy cách nào khác ngoài việc đọc tệp nguồn:
import imp
import sys
import types
module_name = "my_module"
file, pathname, description = imp.find_module[module_name]
with open[pathname] as f:
source = f.read[]
source = source.replace['hello', 'world']
module = types.ModuleType[module_name]
exec[source, module.__dict__]
sys.modules[module_name] = module
Mã Python trong một mô -đun đạt được quyền truy cập vào mã trong một mô -đun khác bằng quá trình nhập nó. Tuyên bố
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 là cách phổ biến nhất để gọi máy móc nhập khẩu, nhưng nó không phải là cách duy nhất. Các chức năng như
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8 và
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 tích hợp cũng có thể được sử dụng để gọi máy móc nhập khẩu.module gains access to the code in another module by the process of importing it. The
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 statement is the most common way of invoking the import machinery, but it is not the only way. Functions such as
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8 and built-in
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 can also be used to invoke the import machinery.
Tuyên bố
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 kết hợp hai hoạt động; Nó tìm kiếm mô -đun được đặt tên, sau đó nó liên kết kết quả tìm kiếm đó với một tên trong phạm vi cục bộ. Hoạt động tìm kiếm của câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 được định nghĩa là một cuộc gọi đến hàm
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9, với các đối số thích hợp. Giá trị trả về của
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 được sử dụng để thực hiện hoạt động liên kết tên của câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7. Xem câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 để biết chi tiết chính xác của hoạt động ràng buộc tên đó.
Một cuộc gọi trực tiếp đến
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 chỉ thực hiện tìm kiếm mô -đun và, nếu được tìm thấy, thao tác tạo mô -đun. Mặc dù một số tác dụng phụ nhất định có thể xảy ra, chẳng hạn như nhập các gói mẹ và việc cập nhật các bộ nhớ cache khác nhau [bao gồm
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7], nhưng chỉ câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 thực hiện hoạt động ràng buộc tên.
Khi một câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 được thực thi, hàm
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 được xây dựng tiêu chuẩn được gọi. Các cơ chế khác để gọi hệ thống nhập khẩu [như
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8] có thể chọn bỏ qua
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 và sử dụng các giải pháp của riêng họ để thực hiện ngữ nghĩa nhập khẩu.
Khi một mô -đun được nhập lần đầu tiên, Python tìm kiếm mô -đun và nếu được tìm thấy, nó sẽ tạo một đối tượng mô -đun 1, khởi tạo nó. Nếu không thể tìm thấy mô -đun được đặt tên,
>>> import spam >>> spam.foo >>> spam.Foo3 sẽ được nâng lên. Python thực hiện các chiến lược khác nhau để tìm kiếm mô -đun được đặt tên khi máy móc nhập khẩu được gọi. Các chiến lược này có thể được sửa đổi và mở rộng bằng cách sử dụng các móc khác nhau được mô tả trong các phần dưới đây.
Đã thay đổi trong phiên bản 3.3: Hệ thống nhập khẩu đã được cập nhật để thực hiện đầy đủ giai đoạn thứ hai của PEP 302. Không còn bất kỳ máy móc nhập khẩu ngầm nào nữa - hệ thống nhập đầy đủ được phơi bày qua >>> import spam
>>> spam.foo
>>> spam.Foo
4. Ngoài ra, hỗ trợ gói tên gốc đã được triển khai [xem PEP 420].The import system has been updated to fully implement the second phase of
PEP 302. There is no longer any implicit import machinery - the full import system is exposed through
>>> import spam >>> spam.foo >>> spam.Foo4. In addition, native namespace package support has been implemented [see PEP 420].
5.1. ________ 35¶>>> import spam
>>> spam.foo
>>> spam.Foo
5¶
Mô -đun
>>> import spam >>> spam.foo >>> spam.Foo5 cung cấp API phong phú để tương tác với hệ thống nhập. Ví dụ:
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8 cung cấp API đơn giản, được đề xuất hơn so với
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 tích hợp để gọi máy móc nhập khẩu. Tham khảo tài liệu thư viện
>>> import spam >>> spam.foo >>> spam.Foo5 để biết thêm chi tiết.
5.2. GóiPackages¶
Python chỉ có một loại đối tượng mô -đun và tất cả các mô -đun thuộc loại này, bất kể mô -đun có được triển khai trong Python, C hay thứ gì khác không. Để giúp tổ chức các mô -đun và cung cấp một hệ thống phân cấp đặt tên, Python có một khái niệm về các gói.packages.
Bạn có thể nghĩ về các gói là các thư mục trên một hệ thống tệp và mô -đun dưới dạng các tệp trong các thư mục, nhưng don không nhận được sự tương tự này theo nghĩa đen vì các gói và mô -đun không cần phải bắt nguồn từ hệ thống tệp. Đối với mục đích của tài liệu này, chúng tôi sẽ sử dụng sự tương tự thuận tiện này về các thư mục và tệp. Giống như các thư mục hệ thống tệp, các gói được tổ chức theo cấp bậc và các gói có thể tự chứa các gói con, cũng như các mô -đun thông thường.
Nó rất quan trọng để ghi nhớ rằng tất cả các gói là các mô -đun, nhưng không phải tất cả các mô -đun đều là các gói. Hoặc đặt một cách khác, các gói chỉ là một loại mô -đun đặc biệt. Cụ thể, bất kỳ mô -đun nào chứa thuộc tính
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 đều được coi là một gói.
Tất cả các mô -đun có một tên. Tên SubPackage được tách ra khỏi tên gói cha mẹ của chúng bằng một dấu chấm, gần giống với cú pháp truy cập thuộc tính tiêu chuẩn Python. Do đó, bạn có thể có một gói gọi là
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py1, đến lượt nó có một gói con được gọi là
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py2 và một mô -đun trong gói con đó được gọi là
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py3.
5.2.1. Gói thông thườngRegular packages¶
Python xác định hai loại gói, gói thông thường và gói tên. Các gói thông thường là các gói truyền thống khi chúng tồn tại trong Python 3.2 trở lên. Một gói thông thường thường được triển khai dưới dạng thư mục chứa tệp
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4. Khi một gói thông thường được nhập, tệp
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 này được thực thi hoàn toàn và các đối tượng mà nó xác định bị ràng buộc với tên trong không gian tên gói. Tệp
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 có thể chứa cùng một mã Python mà bất kỳ mô -đun nào khác có thể chứa và Python sẽ thêm một số thuộc tính bổ sung vào mô -đun khi được nhập.regular packages and namespace packages. Regular packages are traditional packages as they existed in Python 3.2 and earlier. A regular package is typically implemented as a directory containing an
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 file. When a regular package is imported, this
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 file is implicitly executed, and the objects it defines are bound to names in the package’s namespace. The
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 file can contain the same Python code that any other module can contain, and Python will add some additional attributes to the module when it is imported.
Ví dụ: Bố cục hệ thống tệp sau đây xác định gói cấp cao nhất
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 với ba thanh toán con:
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py
Nhập
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py8 sẽ ngầm thực hiện
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py9 và
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo0. Nhập khẩu sau đó là
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo1 hoặc
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo2 sẽ thực hiện tương ứng
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo3 và
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo4.
5.2.2. Gói không gian tênNamespace packages¶
Gói không gian tên là một tổng hợp của các phần khác nhau, trong đó mỗi phần đóng góp một gói con cho gói cha mẹ. Các phần có thể nằm ở các vị trí khác nhau trên hệ thống tệp. Các phần cũng có thể được tìm thấy trong các tệp zip, trên mạng hoặc bất kỳ nơi nào khác mà Python tìm kiếm trong quá trình nhập. Các gói không gian tên có thể hoặc không thể tương ứng trực tiếp với các đối tượng trên hệ thống tệp; Chúng có thể là các mô -đun ảo không có biểu diễn cụ thể.portions, where each portion contributes a subpackage to the parent package. Portions may reside in different locations on the file system. Portions may also be found in zip files, on the network, or anywhere else that Python searches during import. Namespace packages may or may not correspond directly to objects on the file system; they may be virtual modules that have no concrete representation.
Các gói không gian tên không sử dụng danh sách thông thường cho thuộc tính
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 của họ. Thay vào đó, họ sử dụng một loại có thể lặp lại tùy chỉnh sẽ tự động thực hiện tìm kiếm mới cho các phần gói trong lần thử nhập tiếp theo trong gói đó nếu đường dẫn của gói cha mẹ của họ [hoặc
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 cho gói cấp cao nhất] thay đổi.
Với các gói không gian tên, không có tệp
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py9. Trên thực tế, có thể có nhiều thư mục
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 được tìm thấy trong quá trình tìm kiếm nhập khẩu, trong đó mỗi thư mục được cung cấp bởi một phần khác nhau. Do đó,
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo9 có thể không được định vị vật lý bên cạnh
import
0. Trong trường hợp này, Python sẽ tạo gói không gian tên cho gói package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 cấp cao nhất bất cứ khi nào hoặc một trong các thanh toán con của nó được nhập.
Xem thêm PEP 420 để biết thông số kỹ thuật của gói tên.PEP 420 for the namespace package specification.
5.3. Đang tìm kiếm¶Searching¶
Để bắt đầu tìm kiếm, Python cần tên hoàn toàn đủ điều kiện của mô -đun [hoặc gói, nhưng với mục đích của cuộc thảo luận này, sự khác biệt là không quan trọng] đang được nhập khẩu. Tên này có thể đến từ các đối số khác nhau đến câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 hoặc từ các tham số đến các hàm
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8 hoặc
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9.fully qualified name of the module [or package, but for the purposes of this discussion, the difference is immaterial] being imported. This name may come from various arguments to the
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 statement, or from the parameters to the
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8 or
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 functions.
Tên này sẽ được sử dụng trong các giai đoạn khác nhau của tìm kiếm nhập và nó có thể là đường dẫn chấm đến một mô hình con, ví dụ: import
5. Trong trường hợp này, Python trước tiên cố gắng nhập import
6, sau đó import
7, và cuối cùng là import
5. Nếu bất kỳ nhập khẩu trung gian nào thất bại,
>>> import spam >>> spam.foo >>> spam.Foo3 sẽ được nâng lên.
5.3.1. Mô -đun Cache¶The module cache¶
Nơi đầu tiên được kiểm tra trong quá trình tìm kiếm nhập khẩu là
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7. Ánh xạ này đóng vai trò là bộ đệm của tất cả các mô -đun đã được nhập trước đó, bao gồm các đường dẫn trung gian. Vì vậy, nếu
import
5 trước đây được nhập, module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 sẽ chứa các mục nhập cho
import
6, import
7 và import
5. Mỗi khóa sẽ có giá trị của nó đối tượng mô -đun tương ứng.Trong quá trình nhập, tên mô -đun được tra cứu trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 và nếu có, giá trị liên quan là mô -đun thỏa mãn nhập và quá trình hoàn thành. Tuy nhiên, nếu giá trị là
importlib
7, thì >>> import spam >>> spam.foo >>> spam.Foo3 sẽ được nâng lên. Nếu tên mô -đun bị thiếu, Python sẽ tiếp tục tìm kiếm mô -đun.
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 có thể ghi được. Việc xóa khóa có thể không phá hủy mô -đun liên quan [vì các mô -đun khác có thể chứa các tham chiếu cho nó], nhưng nó sẽ làm mất hiệu lực mục nhập bộ đệm cho mô -đun được đặt tên, khiến Python tìm kiếm lại cho mô -đun được đặt tên khi nhập tiếp theo. Khóa cũng có thể được gán cho
importlib
7, buộc việc nhập tiếp theo của mô -đun phải dẫn đến >>> import spam >>> spam.foo >>> spam.Foo3.
Mặc dù vậy, hãy coi chừng, như thể bạn giữ một tham chiếu đến đối tượng mô-đun, vô hiệu hóa mục nhập bộ đệm của nó trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7, sau đó nhập lại mô-đun được đặt tên, hai đối tượng mô-đun sẽ không giống nhau. Ngược lại,
import
3 sẽ sử dụng lại cùng một đối tượng mô -đun và chỉ cần tái tạo nội dung mô -đun bằng cách chạy lại mã mô -đun.5.3.2. Người tìm và bộ tảiFinders and loaders¶
Nếu mô -đun được đặt tên không được tìm thấy trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7, thì giao thức nhập Python, được gọi để tìm và tải mô -đun. Giao thức này bao gồm hai đối tượng khái niệm, người tìm và bộ tải. Công việc của người tìm kiếm là để xác định xem liệu nó có thể tìm thấy mô -đun được đặt tên bằng bất kỳ chiến lược nào mà nó biết hay không. Các đối tượng thực hiện cả hai giao diện này được gọi là nhà nhập khẩu - chúng tự trả lại khi thấy rằng chúng có thể tải mô -đun được yêu cầu.finders and loaders. A finder’s job is to determine whether it can find the named module using whatever strategy it knows about. Objects that implement both of these interfaces are referred to as importers - they return themselves when they find that they can load the requested module.
Python bao gồm một số công cụ tìm và nhà nhập khẩu mặc định. Cái đầu tiên biết cách định vị các mô-đun tích hợp và thứ hai biết cách xác định vị trí các mô-đun đông lạnh. Công cụ tìm mặc định thứ ba tìm kiếm một đường dẫn nhập cho các mô -đun. Đường dẫn nhập là danh sách các vị trí có thể đặt tên cho các đường dẫn hệ thống hoặc tệp zip. Nó cũng có thể được mở rộng để tìm kiếm bất kỳ tài nguyên định vị nào, chẳng hạn như những tài nguyên được xác định bởi các URL.import path for modules. The import path is a list of locations that may name file system paths or zip files. It can also be extended to search for any locatable resource, such as those identified by URLs.
Máy móc nhập khẩu có thể mở rộng, vì vậy các công cụ tìm kiếm mới có thể được thêm vào để mở rộng phạm vi và phạm vi tìm kiếm mô -đun.
Người tìm không thực sự tải mô -đun. Nếu họ có thể tìm thấy mô-đun được đặt tên, họ sẽ trả về một mô-đun thông số kỹ thuật, việc đóng gói thông tin liên quan đến mô-đun, mà máy móc nhập khẩu sau đó sử dụng khi tải mô-đun.
Các phần sau đây mô tả giao thức cho người tìm và trình tải chi tiết hơn, bao gồm cả cách bạn có thể tạo và đăng ký các sản phẩm mới để mở rộng máy móc nhập khẩu.
Đã thay đổi trong phiên bản 3.4: Trong các phiên bản trước của Python, các công cụ tìm lại đã trả về Trình tải trực tiếp, trong khi bây giờ chúng trả về các thông số kỹ thuật mô -đun có chứa trình tải. Bộ tải vẫn được sử dụng trong quá trình nhập khẩu nhưng có ít trách nhiệm hơn.In previous versions of Python, finders returned loaders directly, whereas now they return module specs which contain loaders. Loaders are still used during import but have fewer responsibilities.
5.3.3. Nhập khẩu HookImport hooks¶
Máy móc nhập khẩu được thiết kế để mở rộng; Cơ chế chính cho điều này là các móc nhập khẩu. Có hai loại móc nhập khẩu: móc meta và móc đường dẫn nhập.
Các móc meta được gọi khi bắt đầu xử lý nhập khẩu, trước khi bất kỳ xử lý nhập khẩu nào khác, ngoài bộ đệm
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 tra cứu. Điều này cho phép các móc meta ghi đè lên xử lý
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6, các mô-đun đông lạnh hoặc thậm chí các mô-đun tích hợp. Meta Hook được đăng ký bằng cách thêm các đối tượng tìm kiếm mới vào
>>> import spam >>> spam.foo >>> spam.Foo4, như được mô tả dưới đây.
Các móc đường dẫn nhập được gọi là một phần của quá trình xử lý
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 [hoặc
import
9], tại điểm gặp phải mục đường dẫn liên quan của chúng. Nhập các móc đường dẫn được đăng ký bằng cách thêm các thiết bị gọi mới vào importutil.abc
0 như được mô tả dưới đây.5.3.4. Con đường metaThe meta path¶
Khi không tìm thấy mô -đun được đặt tên trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7, Python tiếp theo tìm kiếm
>>> import spam >>> spam.foo >>> spam.Foo4, trong đó có một danh sách các đối tượng công cụ tìm đường dẫn meta. Những công cụ tìm kiếm này được truy vấn để xem liệu họ có biết cách xử lý mô -đun được đặt tên không. Trình tìm đường dẫn Meta phải thực hiện một phương thức gọi là
importutil.abc
3 có ba đối số: một tên, đường dẫn nhập và [tùy chọn] một mô -đun đích. Công cụ tìm đường dẫn Meta có thể sử dụng bất kỳ chiến lược nào mà nó muốn xác định xem liệu nó có thể xử lý mô -đun được đặt tên hay không.Nếu trình tìm đường dẫn meta biết cách xử lý mô -đun được đặt tên, nó sẽ trả về một đối tượng Spec. Nếu nó không thể xử lý mô -đun được đặt tên, nó sẽ trả về importlib
7. Nếu
>>> import spam >>> spam.foo >>> spam.Foo4 Xử lý đạt đến cuối danh sách của nó mà không trả lại thông số kỹ thuật, thì một
>>> import spam >>> spam.foo >>> spam.Foo3 sẽ được nâng lên. Bất kỳ trường hợp ngoại lệ nào khác được nêu ra chỉ đơn giản là tuyên truyền, hủy bỏ quá trình nhập khẩu.
Phương pháp importutil.abc
3 của các công cụ tìm đường dẫn meta được gọi với hai hoặc ba đối số. Đầu tiên là tên đủ điều kiện của mô -đun đang được nhập, ví dụ import
5. Đối số thứ hai là các mục đường dẫn để sử dụng cho tìm kiếm mô -đun. Đối với các mô-đun cấp cao nhất, đối số thứ hai là importlib
7, nhưng đối với các mô hình con hoặc thanh toán con, đối số thứ hai là giá trị của thuộc tính gói cha mẹ. Nếu thuộc tính
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 thích hợp không thể được truy cập, thì
>>> import spam >>> spam.foo >>> spam.Foo3 sẽ được nâng lên. Đối số thứ ba là một đối tượng mô -đun hiện có sẽ là mục tiêu tải sau. Hệ thống nhập chỉ chuyển trong mô -đun mục tiêu trong quá trình tải lại.
Đường dẫn meta có thể đi qua nhiều lần cho một yêu cầu nhập duy nhất. Ví dụ: giả sử không có mô -đun nào liên quan đã được lưu trữ, nhập import
5 trước tiên sẽ thực hiện nhập cấp cao nhất, gọi
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py04 trên mỗi công cụ tìm đường dẫn meta [
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py05]. Sau khi
import
6 đã được nhập khẩu, import
7 sẽ được nhập khẩu bằng cách đi qua đường dẫn Meta lần thứ hai, gọi parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py08. Khi
import
7 đã được nhập khẩu, lần cuối cùng sẽ gọi parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py10.
Một số công cụ tìm đường dẫn meta chỉ hỗ trợ nhập khẩu cấp cao nhất. Các nhà nhập khẩu này sẽ luôn trả lại importlib
7 khi bất cứ điều gì khác ngoài importlib
7 được thông qua như là đối số thứ hai.
Python sườn mặc định
>>> import spam >>> spam.foo >>> spam.Foo4 có ba trình tìm đường dẫn meta, một công cụ biết cách nhập các mô-đun tích hợp, một loại biết cách nhập các mô-đun đông lạnh và một người biết cách nhập các mô-đun từ đường dẫn nhập [nghĩa là trình tìm dựa trên đường dẫn].import path [i.e. the path based finder].
Đã thay đổi trong phiên bản 3.4: Phương pháp tìm đường dẫn meta importutil.abc
3 đã thay thế parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
15, hiện không bị phản đối. Mặc dù nó sẽ tiếp tục hoạt động mà không thay đổi, máy móc nhập khẩu sẽ chỉ thử nếu người tìm không triển khai importutil.abc
3.The importutil.abc
3 method of meta path finders replaced
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15, which is now deprecated. While it will continue to work without change, the import machinery will try it only if the finder does not implement
importutil.abc
3.5.4. Đang tải¶Loading¶
Nếu và khi tìm thấy thông số kỹ thuật mô -đun, bộ máy nhập sẽ sử dụng nó [và bộ tải nó chứa] khi tải mô -đun. Dưới đây là một xấp xỉ những gì xảy ra trong phần tải của nhập khẩu:
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]
Lưu ý các chi tiết sau:
Nếu có một đối tượng mô -đun hiện có với tên đã cho trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7, nhập sẽ trả lại.Mô -đun sẽ tồn tại trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 trước khi trình tải thực thi mã mô -đun. Điều này rất quan trọng vì mã mô -đun có thể [trực tiếp hoặc gián tiếp] tự nhập; Thêm nó vàomodule = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 trước đó ngăn chặn đệ quy không giới hạn trong trường hợp xấu nhất và tải nhiều nhất trong tốt nhất.Nếu tải không thành công, mô -đun thất bại - và chỉ mô -đun bị lỗi - sẽ bị xóa khỏi
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7. Bất kỳ mô-đun nào đã có trong bộ đệmmodule = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 và bất kỳ mô-đun nào được tải thành công dưới dạng tác dụng phụ, phải ở trong bộ đệm. Điều này tương phản với việc tải lại trong đó ngay cả mô -đun thất bại còn lại trongmodule = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7.Sau khi mô-đun được tạo nhưng trước khi thực hiện, máy nhập nhập đặt các thuộc tính mô-đun liên quan đến nhập [Hồi _init_module_attrs, trong ví dụ giả mã ở trên], như được tóm tắt trong phần sau.later section.
Thực hiện mô -đun là thời điểm chính của việc tải trong đó không gian tên mô -đun được điền. Thực thi hoàn toàn được ủy quyền cho trình tải, được quyết định những gì được điền và làm thế nào.
Mô -đun được tạo trong quá trình tải và được chuyển cho Exec_Module [] có thể không phải là phần được trả về ở cuối nhập 2.
Đã thay đổi trong phiên bản 3.4: Hệ thống nhập khẩu đã tiếp quản trách nhiệm của các trình tải. Chúng được thực hiện trước đây bằng phương pháp parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
23.The import system has taken over the boilerplate responsibilities of loaders. These were previously performed by the
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py23 method.
5.4.1. Người nạpLoaders¶
Trình tải mô -đun cung cấp chức năng quan trọng của việc tải: Thực hiện mô -đun. Máy nhập nhập gọi phương thức
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py24 chỉ bằng một đối số, đối tượng mô -đun để thực thi. Bất kỳ giá trị nào được trả lại từ
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25 đều bị bỏ qua.
Trình tải phải đáp ứng các yêu cầu sau:
Nếu mô-đun là mô-đun Python [trái ngược với mô-đun tích hợp hoặc tiện ích mở rộng được tải động], trình tải sẽ thực thi mã mô-đun trong không gian tên toàn cầu mô-đun [
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py26].Nếu trình tải không thể thực thi mô -đun, nó sẽ tăng
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27, mặc dù bất kỳ ngoại lệ nào khác được nêu trongparent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25 sẽ được truyền bá.
Trong nhiều trường hợp, trình tìm và bộ tải có thể là cùng một đối tượng; Trong những trường hợp như vậy, phương thức importutil.abc
3 sẽ chỉ trả về một thông số kỹ thuật với trình tải được đặt thành
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py30.
Trình tải mô -đun có thể chọn tham gia để tạo đối tượng mô -đun trong quá trình tải bằng cách thực hiện phương thức
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py31. Nó lấy một đối số, thông số mô -đun và trả về đối tượng mô -đun mới để sử dụng trong quá trình tải.
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py31 không cần đặt bất kỳ thuộc tính nào trên đối tượng mô -đun. Nếu phương thức trả về
importlib
7, bộ máy nhập sẽ tự tạo mô -đun mới.Đã thay đổi trong phiên bản 3.4: Phương pháp parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
34 đã được thay thế bằng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
25 và máy móc nhập khẩu giả định tất cả các trách nhiệm tải của tải.The
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py34 method was replaced by
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25 and the import machinery assumed all the boilerplate responsibilities of loading.
Để tương thích với các trình tải hiện có, máy móc nhập sẽ sử dụng phương thức
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py34 của trình tải nếu nó tồn tại và trình tải cũng không triển khai
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25. Tuy nhiên,
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py34 đã bị phản đối và các trình tải nên thực hiện
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25 thay thế.
Phương pháp
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py34 phải triển khai tất cả các chức năng tải Boilerplate được mô tả ở trên ngoài việc thực thi mô -đun. Tất cả các ràng buộc giống nhau được áp dụng, với một số làm rõ bổ sung:
Nếu có một đối tượng mô -đun hiện có với tên đã cho trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7, trình tải phải sử dụng mô -đun hiện có đó. .Mô -đun phải tồn tại trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7 trước khi trình tải thực thi mã mô -đun, để ngăn chặn đệ quy không giới hạn hoặc tải nhiều.Nếu tải không thành công, bộ tải phải xóa bất kỳ mô -đun nào mà nó đã chèn vào
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7, nhưng nó chỉ phải xóa [các] mô -đun không thành công và chỉ khi chính bộ tải đã tải [các] mô -đun.only the failing module[s], and only if the loader itself has loaded the module[s] explicitly.
Đã thay đổi trong phiên bản 3.5: A parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
47 được tăng lên khi parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
25 được xác định nhưng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
31 thì không.A
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py47 is raised when
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25 is defined but
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py31 is not.
Đã thay đổi trong phiên bản 3.6: parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
27 được tăng lên khi parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
25 được xác định nhưng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
31 thì không.An
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27 is raised when
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py25 is defined but
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py31 is not.
Đã thay đổi trong phiên bản 3.10: Sử dụng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
34 sẽ tăng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
54.Use of
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py34 will raise
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py54.
5.4.2. Mô -đunSubmodules¶
Khi một mô hình con được tải bằng bất kỳ cơ chế nào [ví dụ: API
>>> import spam >>> spam.foo >>> spam.Foo5, các câu lệnh
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 hoặc
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py57 hoặc tích hợp
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9], một liên kết được đặt trong không gian tên mô-đun cha mẹ vào đối tượng mô hình con. Ví dụ: nếu gói
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py59 có mô hình con
import
6, sau khi nhập parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py61,
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py59 sẽ có một thuộc tính
import
6 được liên kết với mô hình con. Hãy nói rằng bạn có cấu trúc thư mục sau:và
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py64 có dòng sau trong đó:
Sau đó thực thi các ràng buộc tên đặt sau đây cho import
6 và
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py66 trong mô -đun
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py59:
>>> import spam >>> spam.foo >>> spam.Foo
Với các quy tắc ràng buộc tên quen thuộc của Python, điều này có vẻ đáng ngạc nhiên, nhưng nó thực sự là một tính năng cơ bản của hệ thống nhập khẩu. Nắm giữ bất biến là nếu bạn có
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py68 và
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py69 [như bạn sẽ nhập vào sau], thì cái sau phải xuất hiện dưới dạng thuộc tính
import
6 của cái trước.5.4.3. Mô -đun spec¶Module spec¶
Bộ máy nhập khẩu sử dụng nhiều thông tin về từng mô -đun trong quá trình nhập, đặc biệt là trước khi tải. Hầu hết các thông tin là phổ biến cho tất cả các mô -đun. Mục đích của một mô-đun thông số kỹ thuật là để gói gọn thông tin liên quan đến nhập khẩu này trên cơ sở mỗi mô-đun.
Sử dụng thông số kỹ thuật trong quá trình nhập cho phép trạng thái được chuyển giữa các thành phần hệ thống nhập khẩu, ví dụ: giữa người tìm tạo thông số kỹ thuật mô -đun và trình tải thực thi nó. Quan trọng nhất, nó cho phép bộ máy nhập khẩu thực hiện các hoạt động tải của tải, trong khi không có thông số mô -đun, trình tải có trách nhiệm đó.
Thông số kỹ thuật mô -đun được hiển thị dưới dạng thuộc tính
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py71 trên một đối tượng mô -đun. Xem
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py72 để biết chi tiết về nội dung của thông số mô -đun.
Mới trong phiên bản 3.4.
5.4.5. Mô -đun .__ Path__¶module.__path__¶
Theo định nghĩa, nếu một mô -đun có thuộc tính
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0, thì đó là một gói.
Một thuộc tính gói
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 được sử dụng trong quá trình nhập khẩu của các thanh phần của nó. Trong bộ máy nhập khẩu, nó hoạt động giống như
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6, tức là cung cấp một danh sách các vị trí để tìm kiếm các mô -đun trong quá trình nhập. Tuy nhiên,
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 thường bị hạn chế hơn nhiều so với
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6.
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 phải là một chuỗi có thể lặp lại, nhưng nó có thể trống rỗng. Các quy tắc tương tự được sử dụng cho
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 cũng áp dụng cho gói
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 và
importutil.abc
0 [được mô tả bên dưới] được tư vấn khi đi qua gói package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0.
Tệp gói
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 của gói có thể đặt hoặc thay đổi thuộc tính gói ____ ____40 và đây thường là cách các gói không gian tên được triển khai trước PEP 420. Với việc áp dụng PEP 420, các gói không gian tên không còn cần cung cấp các tệp
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 chỉ chứa mã thao tác
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0; Bộ máy nhập tự động đặt
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 chính xác cho gói không gian tên.PEP 420. With the adoption of PEP 420, namespace packages no longer need to supply
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py4 files containing only
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 manipulation code; the import machinery automatically sets
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 correctly for the namespace package.
5.4.6. Mô -đun reprs¶Module reprs¶
Theo mặc định, tất cả các mô -đun đều có repr repr, tuy nhiên tùy thuộc vào các thuộc tính được đặt ở trên và trong thông số kỹ thuật của mô -đun, bạn có thể kiểm soát rõ ràng hơn các đối tượng mô -đun.
Nếu mô -đun có thông số kỹ thuật [
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py71], máy móc nhập sẽ cố gắng tạo repr từ nó. Nếu thất bại hoặc không có thông số kỹ thuật, hệ thống nhập sẽ tạo ra một bản repred mặc định bằng bất kỳ thông tin nào có sẵn trên mô -đun. Nó sẽ cố gắng sử dụng
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py89,
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py90 và
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py91 làm đầu vào vào repr, với mặc định cho bất kỳ thông tin nào còn thiếu.
Dưới đây là các quy tắc chính xác được sử dụng:
Nếu mô -đun có thuộc tính
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py71, thông tin trong thông số kỹ thuật được sử dụng để tạo repr. Các tên gọi tên của người khác, người hâm mộ, người hâm mộ, người gốc, và các thuộc tính của Has Has_location được tư vấn.Nếu mô -đun có thuộc tính
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py93, thì đây được sử dụng như một phần của mô -đun repr.Nếu mô -đun không có
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py93 nhưng không cóparent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py95 không phải làimportlib
7, thì bộ tải của bộ tải được sử dụng như một phần của mô -đun repr.Mặt khác, chỉ cần sử dụng mô -đun từ
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py97 trong repr.
Đã thay đổi trong phiên bản 3.4: Sử dụng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
98 đã được không dùng nữa và thông số mô -đun hiện được sử dụng bởi bộ máy nhập khẩu để tạo repred mô -đun.Use of
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py98 has been deprecated and the module spec is now used by the import machinery to generate a module repr.
Để tương thích ngược với Python 3.3, repr mô -đun sẽ được tạo bằng cách gọi phương thức Loader Trình tải ____ ____199, nếu được xác định, trước khi thử một trong hai cách tiếp cận được mô tả ở trên. Tuy nhiên, phương pháp không được chấp nhận.
Đã thay đổi trong phiên bản 3.10: Gọi parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
99 hiện đang xảy ra sau khi cố gắng sử dụng thuộc tính mô -đun ____ ____171 nhưng trước khi rơi trở lại trên parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
93. Việc sử dụng parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
99 dự kiến sẽ dừng trong Python 3.12.Calling
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py99 now occurs after trying to use a module’s
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py71 attribute but before falling back on
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py93. Use of
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py99 is slated to stop in Python 3.12.
5.4.7. Bộ nhớ đệm Bytecode không hợp lệCached bytecode invalidation¶
Trước khi tải python được lưu trong bộ nhớ cache từ tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04, nó sẽ kiểm tra xem bộ đệm có được cập nhật với tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]05 nguồn hay không. Theo mặc định, Python thực hiện điều này bằng cách lưu trữ dấu thời gian và kích thước được sửa đổi cuối cùng trong tệp bộ đệm khi viết nó. Khi chạy, hệ thống nhập sau đó xác thực tệp bộ đệm bằng cách kiểm tra siêu dữ liệu được lưu trữ trong tệp bộ đệm đối với siêu dữ liệu của nguồn.
Python cũng hỗ trợ các tệp bộ nhớ cache dựa trên băm, lưu trữ một hàm băm của nội dung tệp nguồn thay vì siêu dữ liệu của nó. Có hai biến thể của các tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04 dựa trên băm: đã kiểm tra và không được kiểm soát. Đối với các tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04 dựa trên băm, Python xác nhận tệp bộ đệm bằng cách băm tệp nguồn và so sánh băm kết quả với băm trong tệp bộ đệm. Nếu một tệp bộ đệm dựa trên băm được kiểm tra được tìm thấy là không hợp lệ, Python sẽ tái tạo nó và viết một tệp bộ đệm dựa trên băm đã được kiểm tra mới. Đối với các tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04 dựa trên băm không được kiểm tra, Python chỉ cần giả sử tệp bộ đệm là hợp lệ nếu nó tồn tại. Hành vi xác thực tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04 dựa trên băm có thể được ghi đè bằng cờ
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]10.
Đã thay đổi trong phiên bản 3.7: Đã thêm các tệp module = None
if spec.loader is not None and hasattr[spec.loader, 'create_module']:
# It is assumed 'exec_module' will also be defined on the loader.
module = spec.loader.create_module[spec]
if module is None:
module = ModuleType[spec.name]
# The import-related module attributes get set here:
_init_module_attrs[spec, module]
if spec.loader is None:
# unsupported
raise ImportError
if spec.origin is None and spec.submodule_search_locations is not None:
# namespace package
sys.modules[spec.name] = module
elif not hasattr[spec.loader, 'exec_module']:
module = spec.loader.load_module[spec.name]
# Set __loader__ and __package__ if missing.
else:
sys.modules[spec.name] = module
try:
spec.loader.exec_module[module]
except BaseException:
try:
del sys.modules[spec.name]
except KeyError:
pass
raise
return sys.modules[spec.name]
04 dựa trên băm. Trước đây, Python chỉ hỗ trợ sự vô hiệu dựa trên dấu thời gian của bộ đệm mã byte.Added hash-based
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04 files. Previously, Python only supported timestamp-based invalidation of bytecode caches.
5.5. Người tìm dựa trên đường dẫnThe Path Based Finder¶
Như đã đề cập trước đây, Python đi kèm với một số công cụ tìm đường dẫn meta mặc định. Một trong số này, được gọi là Trình tìm dựa trên đường dẫn [
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]12], tìm kiếm một đường dẫn nhập, chứa một danh sách các mục nhập đường dẫn. Mỗi lối vào đường dẫn đặt tên một vị trí để tìm kiếm các mô -đun.path based finder [
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]12], searches an import path, which contains a list of path entries. Each path entry names a location to search for modules.
Bản thân trình tìm dựa trên đường dẫn không biết cách nhập bất cứ thứ gì. Thay vào đó, nó đi qua các mục đường dẫn riêng lẻ, liên kết từng người trong số họ với một công cụ tìm đường dẫn biết cách xử lý loại đường dẫn cụ thể đó.
Tập hợp các công cụ tìm mục nhập mặc định triển khai tất cả các ngữ nghĩa để tìm các mô -đun trên hệ thống tệp, xử lý các loại tệp đặc biệt như mã nguồn Python [tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]05], mã byte Python [tệp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]04] và các thư viện được chia sẻ [ví dụ:
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]15 tệp]. Khi được hỗ trợ bởi mô -đun
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]16 trong thư viện tiêu chuẩn, các công cụ tìm đường dẫn mặc định cũng xử lý việc tải tất cả các loại tệp này [trừ các thư viện được chia sẻ] từ zipfiles.
Các mục nhập không cần phải được giới hạn trong các vị trí hệ thống tệp. Họ có thể tham khảo URL, truy vấn cơ sở dữ liệu hoặc bất kỳ vị trí nào khác có thể được chỉ định dưới dạng chuỗi.
Công cụ tìm dựa trên đường dẫn cung cấp các móc và giao thức bổ sung để bạn có thể mở rộng và tùy chỉnh các loại mục nhập đường dẫn có thể tìm kiếm. Ví dụ: nếu bạn muốn hỗ trợ các mục nhập đường dẫn dưới dạng URL mạng, bạn có thể viết một cái móc thực hiện ngữ nghĩa HTTP để tìm các mô -đun trên web. Móc này [một người có thể gọi] sẽ trả về một công cụ tìm mục nhập đường dẫn hỗ trợ giao thức được mô tả bên dưới, sau đó được sử dụng để lấy trình tải cho mô -đun từ web.path entry finder supporting the protocol described below, which was then used to get a loader for the module from the web.
Một từ cảnh báo: Phần này và cả hai trước đó sử dụng thuật ngữ tìm kiếm, phân biệt giữa chúng bằng cách sử dụng các thuật ngữ tìm thấy công cụ tìm đường dẫn meta và công cụ tìm mục nhập đường dẫn. Hai loại công cụ tìm kiếm rất giống nhau, hỗ trợ các giao thức tương tự và hoạt động theo những cách tương tự trong quá trình nhập, nhưng điều quan trọng là phải nhớ rằng chúng khác nhau một cách tinh tế. Cụ thể, các công cụ tìm đường dẫn meta hoạt động ở đầu quy trình nhập, như đã khóa các đường truyền
>>> import spam >>> spam.foo >>> spam.Foo4.meta path finder and path entry finder. These two types of finders are very similar, support similar protocols, and function in similar ways during the import process, but it’s important to keep in mind that they are subtly different. In particular, meta path finders operate at the beginning of the import process, as keyed off the
>>> import spam >>> spam.foo >>> spam.Foo4 traversal.
Ngược lại, các công cụ tìm đường dẫn có nghĩa là một chi tiết triển khai của công cụ tìm dựa trên đường dẫn và trên thực tế, nếu công cụ tìm dựa trên đường dẫn sẽ bị xóa khỏi
>>> import spam >>> spam.foo >>> spam.Foo4, không có ngữ nghĩa nào trong trình tìm đường dẫn đường dẫn sẽ được gọi.
5.5.1. Người tìm đầu vào đường dẫnPath entry finders¶
Công cụ tìm dựa trên đường dẫn chịu trách nhiệm tìm và tải các mô -đun và gói Python có vị trí được chỉ định với mục nhập đường dẫn chuỗi. Hầu hết các vị trí tên của mục nhập trong hệ thống tệp, nhưng chúng không cần phải giới hạn trong vấn đề này.path based finder is responsible for finding and loading Python modules and packages whose location is specified with a string path entry. Most path entries name locations in the file system, but they need not be limited to this.
Là công cụ tìm đường dẫn meta, công cụ tìm dựa trên đường dẫn thực hiện giao thức importutil.abc
3 được mô tả trước đây, tuy nhiên nó phơi bày các móc bổ sung có thể được sử dụng để tùy chỉnh cách tìm và tải các mô -đun từ đường dẫn nhập.path based finder implements the
importutil.abc
3 protocol previously described, however it exposes additional hooks that can be used to customize how modules are found and loaded from the import path.
Ba biến được sử dụng bởi công cụ tìm dựa trên đường dẫn,
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6,
importutil.abc
0 và module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22. Các thuộc tính
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 trên các đối tượng gói cũng được sử dụng. Chúng cung cấp các cách bổ sung mà máy móc nhập khẩu có thể được tùy chỉnh.path based finder,
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6,
importutil.abc
0 and module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22. The
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 attributes on package objects are also used. These provide additional ways that the import machinery can be customized.
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 chứa một danh sách các chuỗi cung cấp các vị trí tìm kiếm cho các mô -đun và gói. Nó được khởi tạo từ biến môi trường
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]25 và nhiều mặc định khác nhau và thực hiện cụ thể. Các mục trong
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 có thể đặt tên cho các thư mục trên hệ thống tệp, các tệp zip và các vị trí khác có khả năng khác [xem mô -đun
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]27] cần tìm kiếm các mô -đun, chẳng hạn như URL hoặc truy vấn cơ sở dữ liệu. Chỉ các chuỗi nên có mặt trên
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6; Tất cả các loại dữ liệu khác bị bỏ qua.
Công cụ tìm dựa trên đường dẫn là một công cụ tìm đường dẫn meta, do đó, bộ máy nhập khẩu bắt đầu tìm kiếm đường dẫn nhập bằng cách gọi phương thức Finder dựa trên đường dẫn ____ ____993 như được mô tả trước đây. Khi đối số
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]30 cho
importutil.abc
3 được đưa ra, nó sẽ là danh sách các đường dẫn chuỗi để đi qua - thường là thuộc tính gói package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 của gói để nhập trong gói đó. Nếu đối số
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]30 là
importlib
7, điều này cho thấy việc nhập cấp cao nhất và from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 được sử dụng.path based finder is a meta path finder, so the import machinery begins the import path search by calling the path based finder’s
importutil.abc
3 method as described previously. When the module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]30 argument to
importutil.abc
3 is given, it will be a list of string paths to traverse - typically a package’s package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py0 attribute for an import within that package. If the
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]30 argument is
importlib
7, this indicates a top level import and from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 is used.
Công cụ tìm dựa trên đường dẫn lặp lại trên mọi mục nhập trong đường dẫn tìm kiếm và đối với mỗi mục này, tìm kiếm một công cụ tìm đường dẫn đường dẫn thích hợp [
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]36] cho mục nhập đường dẫn. Bởi vì đây có thể là một hoạt động đắt tiền [ví dụ: có thể có chi phí gọi
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]37 cho tìm kiếm này], công cụ tìm dựa trên đường dẫn duy trì các mục nhập đường dẫn ánh xạ bộ đệm đến các công cụ tìm mục nhập đường dẫn. Bộ đệm này được duy trì trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 [mặc dù tên, bộ đệm này thực sự lưu trữ các đối tượng tìm kiếm thay vì bị giới hạn trong các đối tượng nhà nhập khẩu]. Theo cách này, tìm kiếm đắt tiền cho một công cụ tìm mục nhập đường dẫn đường dẫn cụ thể chỉ cần được thực hiện một lần. Mã người dùng có thể tự do xóa các mục nhập bộ đệm khỏi
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 buộc công cụ tìm dựa trên đường dẫn phải thực hiện tìm kiếm mục nhập đường dẫn lại 3.path entry finder [
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]36] for the path entry. Because this can be an expensive operation [e.g. there may be
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]37 call overheads for this search], the path based finder maintains a cache mapping path entries to path entry finders. This cache is maintained in
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 [despite the name, this cache actually stores finder objects rather than being limited to importer objects]. In this way, the expensive search for a particular path entry location’s path entry finder need only be done once. User code is free to remove cache entries from
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 forcing the path based finder to perform the path entry search again 3.
Nếu mục nhập đường dẫn không có trong bộ đệm, công cụ tìm dựa trên đường dẫn sẽ lặp lại trên mỗi lần gọi trong importutil.abc
0. Mỗi móc vào đường dẫn trong danh sách này được gọi với một đối số duy nhất, mục nhập đường dẫn sẽ được tìm kiếm. Điều này có thể gọi có thể trả về một công cụ tìm mục nhập đường dẫn có thể xử lý mục nhập đường dẫn hoặc nó có thể tăng
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27. Một
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27 được sử dụng bởi công cụ tìm dựa trên đường dẫn để báo hiệu rằng móc không thể tìm thấy công cụ tìm đường dẫn đường dẫn cho mục nhập đường dẫn đó. Ngoại lệ bị bỏ qua và nhập đường dẫn đường dẫn tiếp tục. Móc nên mong đợi một đối tượng chuỗi hoặc byte; Việc mã hóa các đối tượng byte tùy thuộc vào móc [ví dụ: nó có thể là mã hóa hệ thống tệp, UTF-8 hoặc một cái gì đó khác] và nếu hook không thể giải mã đối số, nó sẽ tăng
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27.path entry hooks in this list is called with a single argument, the path entry to be searched. This callable may either return a path entry finder that can handle the path entry, or it may raise
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27. An
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27 is used by the path based finder to signal that the hook cannot find a path entry finder for that path entry. The exception is ignored and import path iteration continues. The hook should expect either a string or bytes object; the encoding of bytes objects is up to the hook [e.g. it may be a file system encoding, UTF-8, or something else], and if the hook cannot decode the argument, it should raise
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py27.
Nếu importutil.abc
0 Lặp lại kết thúc mà không có trình tìm đường dẫn đường dẫn được trả về, thì phương thức ____993 dựa trên đường dẫn sẽ lưu trữ importlib
7 trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 [để chỉ ra rằng không có công cụ tìm cho mục nhập đường dẫn này] và trả về các mô -đun.path entry finder being returned, then the path based finder’s
importutil.abc
3 method will store importlib
7 in module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 [to indicate that there is no finder for this path entry] and return
importlib
7, indicating that this
meta path finder could not find the module.Nếu công cụ tìm mục nhập đường dẫn được trả về bởi một trong các ứng dụng hook nhập đường dẫn trên importutil.abc
0, thì giao thức sau được sử dụng để hỏi trình tìm cho một thông số kỹ thuật mô -đun, sau đó được sử dụng khi tải mô -đun.path entry finder is returned by one of the path entry hook callables on
importutil.abc
0, then the following protocol is used to ask the finder for a module spec, which is then used when loading the module.
Thư mục làm việc hiện tại - được biểu thị bằng một chuỗi trống - được xử lý hơi khác với các mục khác trên
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6. Đầu tiên, nếu thư mục làm việc hiện tại được tìm thấy không tồn tại, không có giá trị nào được lưu trữ trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22. Thứ hai, giá trị cho thư mục làm việc hiện tại được tra cứu mới cho mỗi lần tra cứu mô -đun. Thứ ba, đường dẫn được sử dụng cho
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22 và được trả về bởi
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]53 sẽ là thư mục làm việc hiện tại thực tế chứ không phải chuỗi trống.
5.5.2. Giao thức tìm đầu vào đường dẫn giao thứcPath entry finder protocol¶
Để hỗ trợ nhập khẩu các mô -đun và các gói khởi tạo và cũng đóng góp các phần cho các gói không gian tên, trình tìm đường dẫn phải thực hiện phương thức importutil.abc
3.
importutil.abc
3 có hai đối số: Tên đủ điều kiện của mô -đun đang được nhập và mô -đun mục tiêu [tùy chọn]. importutil.abc
3 trả về một thông số kỹ thuật hoàn chỉnh cho mô -đun. Thông số kỹ thuật này sẽ luôn có bộ Loader Trình tải [với một ngoại lệ].
Để chỉ ra cho máy móc nhập khẩu rằng thông số kỹ thuật đại diện cho một phần không gian tên, trình tìm mục nhập đường dẫn đặt Submodule_search_locations thành một danh sách chứa phần.portion, the path entry finder sets “submodule_search_locations” to a list containing the portion.
Đã thay đổi trong phiên bản 3.4: importutil.abc
3 đã thay thế module = None
if spec.loader is not None and hasattr[spec.loader, 'create_module']:
# It is assumed 'exec_module' will also be defined on the loader.
module = spec.loader.create_module[spec]
if module is None:
module = ModuleType[spec.name]
# The import-related module attributes get set here:
_init_module_attrs[spec, module]
if spec.loader is None:
# unsupported
raise ImportError
if spec.origin is None and spec.submodule_search_locations is not None:
# namespace package
sys.modules[spec.name] = module
elif not hasattr[spec.loader, 'exec_module']:
module = spec.loader.load_module[spec.name]
# Set __loader__ and __package__ if missing.
else:
sys.modules[spec.name] = module
try:
spec.loader.exec_module[module]
except BaseException:
try:
del sys.modules[spec.name]
except KeyError:
pass
raise
return sys.modules[spec.name]
58 và parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
15, cả hai đều không được sử dụng, nhưng sẽ được sử dụng nếu importutil.abc
3 không được xác định.importutil.abc
3 replaced
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]58 and
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15, both of which are now deprecated, but will be used if
importutil.abc
3 is not defined.Công cụ tìm đường dẫn cũ hơn có thể thực hiện một trong hai phương pháp không dùng nữa thay vì importutil.abc
3. Các phương pháp vẫn được tôn trọng vì lợi ích của khả năng tương thích ngược. Tuy nhiên, nếu importutil.abc
3 được triển khai trên công cụ tìm mục nhập đường dẫn, các phương thức di sản sẽ bị bỏ qua.
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]58 có một đối số, tên đủ điều kiện của mô -đun đang được nhập.
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]58 Trả về 2-Tuple trong đó mục đầu tiên là trình tải và mục thứ hai là phần không gian tên.portion.
Để tương thích ngược với các triển khai khác của giao thức nhập, nhiều công cụ tìm mục nhập đường dẫn cũng hỗ trợ cho phương thức
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15 truyền thống mà các trình tìm kiếm Meta hỗ trợ. Tuy nhiên, Trình tìm kiếm đường dẫn
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15 Các phương thức không bao giờ được gọi với đối số
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]30 [chúng dự kiến sẽ ghi lại thông tin đường dẫn thích hợp từ cuộc gọi ban đầu đến Hook đường dẫn].
Phương pháp
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15 trên các công cụ tìm mục nhập đường dẫn không được chấp nhận, vì nó không cho phép công cụ tìm nhập đường dẫn đóng góp các phần cho các gói không gian tên. Nếu cả
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]58 và
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15 đều tồn tại trên công cụ tìm mục nhập đường dẫn, hệ thống nhập sẽ luôn gọi
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]58 để ưu tiên cho
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15.
5.6. Thay thế hệ thống nhập tiêu chuẩnReplacing the standard import system¶
Cơ chế đáng tin cậy nhất để thay thế toàn bộ hệ thống nhập là xóa các nội dung mặc định của
>>> import spam >>> spam.foo >>> spam.Foo4, thay thế chúng hoàn toàn bằng móc đường dẫn meta tùy chỉnh.
Nếu chỉ chấp nhận thay đổi hành vi của các báo cáo nhập mà không ảnh hưởng đến các API khác truy cập hệ thống nhập, thì việc thay thế hàm
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 tích hợp có thể là đủ. Kỹ thuật này cũng có thể được sử dụng ở cấp độ mô -đun để chỉ thay đổi hành vi của các báo cáo nhập trong mô -đun đó.
Để ngăn chặn việc nhập một số mô -đun từ một cái móc sớm trên đường dẫn meta [thay vì vô hiệu hóa hoàn toàn hệ thống nhập tiêu chuẩn], nó là đủ để tăng
>>> import spam >>> spam.foo >>> spam.Foo3 trực tiếp từ
importutil.abc
3 thay vì trả lại importlib
7. Cái sau chỉ ra rằng tìm kiếm đường dẫn meta sẽ tiếp tục, trong khi tăng ngoại lệ chấm dứt nó ngay lập tức.5.7. Gói nhập khẩu tương đốiPackage Relative Imports¶
Nhập khẩu tương đối sử dụng các dấu chấm hàng đầu. Một dấu chấm hàng đầu cho biết nhập tương đối, bắt đầu với gói hiện tại. Hai hoặc nhiều dấu chấm hàng đầu cho thấy nhập tương đối vào [các] cha mẹ của gói hiện tại, một cấp trên mỗi dấu chấm sau cấp đầu tiên. Ví dụ: đưa ra bố cục gói sau:
package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py
Trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]78 hoặc
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]79, sau đây là nhập khẩu tương đối hợp lệ:
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo
Nhập khẩu tuyệt đối có thể sử dụng cú pháp
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]80 hoặc
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]81, nhưng nhập khẩu tương đối chỉ có thể sử dụng biểu mẫu thứ hai; Lý do cho điều này là:
Nên phơi bày
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]82 như một biểu thức có thể sử dụng, nhưng .Moduley không phải là một biểu thức hợp lệ.
5,8. Những cân nhắc đặc biệt cho __main__¶Special considerations for __main__¶
Mô -đun
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 là một trường hợp đặc biệt liên quan đến hệ thống nhập khẩu Python. Như đã lưu ý ở nơi khác, mô -đun
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 được khởi tạo trực tiếp khi khởi động phiên dịch viên, giống như
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]85 và
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]86. Tuy nhiên, không giống như hai người đó, nó không đủ điều kiện là một mô-đun tích hợp. Điều này là do cách thức mà
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 được khởi tạo phụ thuộc vào các cờ và các tùy chọn khác mà trình thông dịch được gọi.elsewhere, the
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 module is directly initialized at interpreter startup, much like
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]85 and
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]86. However, unlike those two, it doesn’t strictly qualify as a built-in module. This is because the manner in which
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 is initialized depends on the flags and other options with which the interpreter is invoked.
5.8.1. __Main __.__ spec__¶__main__.__spec__¶
Tùy thuộc vào cách
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 được khởi tạo,
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]89 được đặt một cách thích hợp hoặc
importlib
7.Khi Python được bắt đầu với tùy chọn
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]91,
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py71 sẽ được đặt thành thông số kỹ thuật của mô -đun hoặc gói tương ứng.
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py71 cũng được điền khi mô -đun
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 được tải như một phần của việc thực hiện thư mục, zipfile hoặc mục nhập
from .moduleY import spam from .moduleY import spam as ham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo6 khác.
Trong các trường hợp còn lại
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]89 được đặt thành
importlib
7, vì mã được sử dụng để điền vào module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 không tương ứng trực tiếp với mô -đun có thể nhập:the remaining cases
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]89 is set to
importlib
7, as the code used to populate the module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 does not correspond directly with an importable module:
Lời nhắc tương tác
Tùy chọn
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]
99Chạy từ Stdin
chạy trực tiếp từ tệp nguồn hoặc mã byte
Lưu ý rằng
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]89 luôn là
importlib
7 trong trường hợp cuối cùng, ngay cả khi tệp có thể được nhập trực tiếp về mặt kỹ thuật dưới dạng mô -đun. Sử dụng công tắc module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]91 nếu siêu dữ liệu mô -đun hợp lệ được mong muốn trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83.
Cũng lưu ý rằng ngay cả khi
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 tương ứng với một mô -đun có thể nhập và
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]89 được đặt tương ứng, chúng vẫn được coi là các mô -đun riêng biệt. Điều này là do thực tế là các khối được bảo vệ bởi
>>> import spam >>> spam.foo >>> spam.Foo06 chỉ kiểm tra thực thi khi mô -đun được sử dụng để điền vào không gian tên
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]83 chứ không phải trong quá trình nhập thông thường.
5.9. Người giới thiệu¶References¶
Máy móc nhập khẩu đã phát triển đáng kể kể từ những ngày đầu của Python. Thông số kỹ thuật ban đầu cho các gói vẫn có sẵn để đọc, mặc dù một số chi tiết đã thay đổi kể từ khi viết tài liệu đó.
Thông số kỹ thuật ban đầu cho
>>> import spam >>> spam.foo >>> spam.Foo4 là PEP 302, với phần mở rộng tiếp theo trong PEP 420.PEP 302, with subsequent extension in PEP 420.
PEP 420 đã giới thiệu các gói không gian tên cho Python 3.3. PEP 420 cũng giới thiệu giao thức module = None
if spec.loader is not None and hasattr[spec.loader, 'create_module']:
# It is assumed 'exec_module' will also be defined on the loader.
module = spec.loader.create_module[spec]
if module is None:
module = ModuleType[spec.name]
# The import-related module attributes get set here:
_init_module_attrs[spec, module]
if spec.loader is None:
# unsupported
raise ImportError
if spec.origin is None and spec.submodule_search_locations is not None:
# namespace package
sys.modules[spec.name] = module
elif not hasattr[spec.loader, 'exec_module']:
module = spec.loader.load_module[spec.name]
# Set __loader__ and __package__ if missing.
else:
sys.modules[spec.name] = module
try:
spec.loader.exec_module[module]
except BaseException:
try:
del sys.modules[spec.name]
except KeyError:
pass
raise
return sys.modules[spec.name]
58 như là một giải pháp thay thế cho parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
15. introduced namespace packages for Python 3.3.
PEP 420 also introduced the
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]58 protocol as an alternative to
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py15.
PEP 366 mô tả việc bổ sung thuộc tính >>> import spam
>>> spam.foo
>>> spam.Foo
11 cho nhập khẩu tương đối rõ ràng trong các mô -đun chính. describes the addition of the
>>> import spam >>> spam.foo >>> spam.Foo11 attribute for explicit relative imports in main modules.
PEP 328 đã giới thiệu nhập khẩu tương đối tuyệt đối và rõ ràng và ban đầu đề xuất parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
97 cho ngữ nghĩa PEP 366 cuối cùng sẽ chỉ định cho >>> import spam
>>> spam.foo
>>> spam.Foo
11. introduced absolute and explicit relative imports and initially proposed
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py97 for semantics PEP 366 would eventually specify for
>>> import spam >>> spam.foo >>> spam.Foo11.
PEP 338 định nghĩa các mô -đun thực thi là tập lệnh. defines executing modules as scripts.
PEP 451 thêm đóng gói trạng thái nhập mỗi mô-đun trong các đối tượng Spec. Nó cũng giảm tải hầu hết các trách nhiệm của các bộ tải trở lại máy móc nhập khẩu. Những thay đổi này cho phép sự phản đối của một số API trong hệ thống nhập khẩu và cũng bổ sung các phương thức mới cho công cụ tìm và tải. adds the encapsulation of per-module import state in spec objects. It also off-loads most of the boilerplate responsibilities of loaders back onto the import machinery. These changes allow the deprecation of several APIs in the import system and also addition of new methods to finders and loaders.
Chú thích
1Xem
>>> import spam >>> spam.foo >>> spam.Foo14.2
Việc triển khai nhập khẩu tránh sử dụng giá trị trả về trực tiếp. Thay vào đó, nó có được đối tượng mô -đun bằng cách tìm tên mô -đun trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7. Hiệu ứng gián tiếp của điều này là một mô -đun nhập khẩu có thể thay thế chính nó trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]7. Đây là hành vi cụ thể thực hiện không được đảm bảo để làm việc trong các triển khai Python khác.3
Trong mã kế thừa, có thể tìm thấy các trường hợp
>>> import spam >>> spam.foo >>> spam.Foo17 trong
module = None if spec.loader is not None and hasattr[spec.loader, 'create_module']: # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module[spec] if module is None: module = ModuleType[spec.name] # The import-related module attributes get set here: _init_module_attrs[spec, module] if spec.loader is None: # unsupported raise ImportError if spec.origin is None and spec.submodule_search_locations is not None: # namespace package sys.modules[spec.name] = module elif not hasattr[spec.loader, 'exec_module']: module = spec.loader.load_module[spec.name] # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: spec.loader.exec_module[module] except BaseException: try: del sys.modules[spec.name] except KeyError: pass raise return sys.modules[spec.name]22. Thay vào đó, mã được thay đổi để sử dụng
importlib
7. Xem chuyển mã Python để biết thêm chi tiết.Porting Python code for more details.