Hướng dẫn python import pyc from path - pyc nhập python từ đường dẫn
0 cũng liên kết mô -đun với tên Show
Sau đó, bạn có thể làm một cái gì đó như:
Hoàn thành phiên ví dụ:
Chỉnh sửa về bình luận ( 1), tôi cho rằng lỗi là do mã trong 2 và 3 sống trong cùng một thư mụcTrong trường hợp đó, như những người khác đã đề xuất, việc thêm thư mục có chứa 4 vào 5 đơn giản hơn và sử dụng cơ chế nhập thông thường, cụ thể là 6Đây là một chức năng nên làm những gì bạn muốn: 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ố 7 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ư 8 và 9 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 7 statement
is the most common way of invoking the import machinery, but it is not the only way. Functions such as 8 and built-in 9 can also be used to invoke the import machinery.Tuyên bố 7 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 7 được định nghĩa là một cuộc gọi đến hàm 9, với các đối số thích hợp. Giá trị trả về của 9 được sử dụng để thực hiện hoạt động liên kết tên của câu lệnh 7. Xem câu lệnh 7 để 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 9 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 7), nhưng chỉ câu lệnh 7 thực hiện hoạt động ràng buộc tên.Khi một câu lệnh 7 được thực thi, hàm 9 đượ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ư 8) có thể chọn bỏ qua 9 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, 3 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 4. In addition, native namespace package support has been implemented (see PEP
420).5.1. ________ 35¶import os def load_path(filepath): """Given a path like /path/to/my_module.pyc (or .py) imports the module and returns it """ path, fname = os.path.split(filepath) modulename, _ = os.path.splitext(fname) if path not in sys.path: sys.path.insert(0, path) return __import__(modulename) if __name__ == '__main__': # Example usage my_module = load_path('/tmp/my_module.py') my_module.yayfunctions('test') 5¶Mô -đun 5 cung cấp API phong phú để tương tác với hệ thống nhập. Ví dụ: 8 cung cấp API đơn giản, được đề xuất hơn so với 9 tích hợp để gọi máy móc nhập khẩu. Tham khảo tài liệu thư viện 5 để 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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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à parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py1, đến lượt nó có một gói con được gọi là parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py2 và một mô -đun trong gói con đó được gọi là parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py4. Khi một gói thông thường được nhập, tệp parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py4 file. When a regular package is imported, this parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py4 file is implicitly executed, and the objects it defines are bound to names in the package’s namespace. The parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py7 với ba thanh toán con: parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py Nhập parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py8 sẽ ngầm thực hiện parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9 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]0. Nhập khẩu sau đó 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]1 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]2 sẽ thực hiện tương ứ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]3 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]4. 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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 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]6 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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py9. Trên thực tế, có thể có nhiều thư mục parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 đó, 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]9 có thể không được định vị vật lý bên cạnh >>> import spam >>> spam.foo0. Trong trường hợp này, Python sẽ tạo gói không gian tên cho gói parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 7 hoặc từ các tham số đến các hàm 8 hoặc 9.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
7 statement, or from the parameters to the 8 or 9 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 spam >>> spam.foo5. Trong trường hợp này, Python trước tiên cố gắng nhập >>> import spam >>> spam.foo6, sau đó >>> import spam >>> spam.foo7, và cuối cùng là >>> import spam >>> spam.foo5. Nếu bất kỳ nhập khẩu trung gian nào thất bại, 3 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à 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 spam >>> spam.foo5 trước đây được nhập, 7 sẽ chứa các mục nhập cho >>> import spam >>> spam.foo6, >>> import spam >>> spam.foo7 và >>> import spam >>> spam.foo5. 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 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à package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, thì 3 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. 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 package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, buộc việc nhập tiếp theo của mô -đun phải dẫn đến 3.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 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, 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 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 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 7 tra cứu. Điều này cho phép các móc meta ghi đè lên xử 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]6, 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 4, 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ý 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]6 (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 foo9), 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 imp.load_compiled 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 7, Python tiếp theo tìm kiếm 4, 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à imp.load_compiled 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ề package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7. Nếu 4 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 3 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 >>> import spam >>> spam.foo5. Đố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à package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, 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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 thích hợp không thể được truy cập, thì 3 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 spam >>> spam.foo5 trước tiên sẽ thực hiện nhập cấp cao nhất, gọi 04 trên mỗi công cụ tìm đường dẫn meta ( 05). Sau khi >>> import spam >>> spam.foo6 đã được nhập khẩu, >>> import spam >>> spam.foo7 sẽ được nhập khẩu bằng cách đi qua đường dẫn Meta lần thứ hai, gọi 08. Khi >>> import spam >>> spam.foo7 đã được nhập khẩu, lần cuối cùng sẽ gọi 10.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 package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 khi bất cứ điều gì khác ngoài package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 được thông qua như là đối số thứ hai. Python sườn mặc định 4 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 15, 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 imp.load_compiled 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:
Đã 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 23 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 24 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ừ 25 đều bị bỏ qua.Trình tải phải đáp ứng các yêu cầu sau:
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 30.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 31. 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. 31 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ề package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, 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 34 method was replaced by 25 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 34 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 25. Tuy nhiên, 34 đã bị phản đối và các trình tải nên thực hiện 25 thay thế.Phương pháp 34 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:
Đã thay đổi trong phiên bản 3.5: A 47 is raised when 25 is defined but 31 is not.Đã thay đổi trong phiên bản 3.6: 27 is raised when 25 is defined but 31 is not.Đã thay đổi trong phiên bản 3.10: Sử dụng 34 will raise
54.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 5, các câu lệnh 7 hoặc 57 hoặc tích hợp 9), 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 59 có mô hình con >>> import spam >>> spam.foo6, sau khi nhập 61, 59 sẽ có một thuộc tính >>> import spam >>> spam.foo6 đượ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à 64 có dòng sau trong đó:Sau đó thực thi các ràng buộc tên đặt sau đây cho >>> import spam >>> spam.foo6 và 66 trong mô -đun 59:>>> import spam >>> 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ó 68 và 69 (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 spam >>> spam.foo6 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 71 trên một đối tượng mô -đun. Xem 72 để 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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0, thì đó là một gói. Một thuộc tính gói parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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ư 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]6, 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, parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 thường bị hạn chế hơn nhiều so vớ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]6. parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 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]6 cũng áp dụng cho gói parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 và imp.load_compiled 0 (được mô tả bên dưới) được tư vấn khi đi qua gói parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0. Tệp gói parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py4 chỉ chứa mã thao tác parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0; Bộ máy nhập tự động đặt parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py4 files containing only parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 manipulation code; the import machinery automatically sets parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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 ( 71), 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 89, 90 và 91 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:
Đã thay đổi trong phiên bản 3.4: Sử dụng 98 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 99 now occurs after trying to use a module’s 71 attribute but before falling back on 93. Use of 99 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 04, nó sẽ kiểm tra xem bộ đệm có được cập nhật với tệp 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 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 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 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 04 dựa trên băm có thể được ghi đè bằng cờ 10.Đã thay đổi trong phiên bản 3.7: Đã thêm các tệp 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 ( 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 ( 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 05), mã byte Python (tệp 04) và các thư viện được chia sẻ (ví dụ: 15 tệp). Khi được hỗ trợ bởi mô -đun 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 4.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
4 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 4, 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 Ba biến được sử dụng bởi công cụ 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]6, imp.load_compiled 0 và 22. Các thuộc tính parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.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, 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]6, imp.load_compiled 0 and 22. The
parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 attributes on package objects are also used. These provide additional ways that the import machinery can be customized. 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]6 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 25 và nhiều mặc định khác nhau và thực hiện cụ thể. Các mục 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]6 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 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 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]6; 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ố 30 cho imp.load_compiled 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 parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 của gói để nhập trong gói đó. Nếu đối số 30 là package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, điều này cho thấy việc nhập cấp cao nhất 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]6 đượ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 imp.load_compiled 3 method as described previously. When the 30 argument to
imp.load_compiled 3 is given, it will be a list of string paths to traverse - typically a package’s parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py0 attribute for an import within that package. If the 30 argument is package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, this indicates a top level import 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]6 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 ( 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 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 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 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 ( 36) for the path entry. Because this can be an expensive operation (e.g. there may be 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 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 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 27. Một 27 đượ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 27.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
27. An 27 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 27.Nếu package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 trong 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
imp.load_compiled 3 method will store package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 in 22 (to indicate that there is no finder for this path entry) and return package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, 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 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 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]6. Đầ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 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 22 và được trả về bởi 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
Để 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: 58 and 15, both of which are now deprecated, but will be used if imp.load_compiled 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ì 58 có một đối số, tên đủ điều kiện của mô -đun đang được nhập. 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 15 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 15 Các phương thức không bao giờ được gọi với đối số 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 15 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ả 58 và 15 đề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 58 để ưu tiên cho 15.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 4, 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 9 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 3 trực tiếp từ imp.load_compiled 3 thay vì trả lại package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7. 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 78 hoặc 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 80 hoặc 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 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 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 83 được khởi tạo trực tiếp khi khởi động phiên dịch viên, giống như 85 và 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à 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 83 module is directly initialized at interpreter startup, much like 85 and
86. However, unlike those two, it doesn’t strictly qualify as a built-in module. This is because the manner in which 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 83 được khởi tạo, 89 được đặt một cách thích hợp hoặc package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7. Khi Python được bắt đầu với tùy chọn 91, 71 sẽ được đặt thành thông số kỹ thuật của mô -đun hoặc gói tương ứng. 71 cũng được điền khi mô -đun 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 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]6 khác. Trong các trường hợp còn lại 89 được đặt thành package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, vì mã được sử dụng để điền vào 83 không tương ứng trực tiếp với mô -đun có thể nhập:the remaining cases 89 is set to package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7, as the code used to populate the 83 does not correspond directly with an importable
module:
Lưu ý rằng 89 luôn là package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7 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 91 nếu siêu dữ liệu mô -đun hợp lệ được mong muốn trong 83.Cũng lưu ý rằng ngay cả khi 83 tương ứng với một mô -đun có thể nhập và 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 06 chỉ kiểm tra thực thi khi mô -đun được sử dụng để điền vào không gian tên 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 4 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 58 protocol as an alternative to 15.PEP 366 mô tả việc bổ sung thuộc tính 11 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 97 for semantics PEP 366 would eventually specify for 11.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 14.2Việ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 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 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.3Trong mã kế thừa, có thể tìm thấy các trường hợp 17 trong 22. Thay vào đó, mã được thay đổi để sử dụng package/ __init__.py subpackage1/ __init__.py moduleX.py moduleY.py subpackage2/ __init__.py moduleZ.py moduleA.py7. Xem chuyển mã Python để biết thêm chi tiết.Porting Python code for more details. Làm cách nào để nhập tệp .pyc?Tóm lại, để nhập tệp được biên dịch Python (ví dụ: mô -đun. PYC), chỉ cần đặt nó vào cùng một thư mục trong đó nguồn (ví dụ: mô -đun.py) và đảm bảo rằng không có tệp nguồn tương ứng (mô -đun.py.py trong ví dụ của chúng tôi) ở đó. Sau đó, mô -đun nhập thông thường sẽ hoạt động liền mạch.place it in the same directory where the source (e.g module.py) would be, and ensure that there is no corresponding source file (module.py in our example) there. Then the usual import module will work seamlessly.
Làm cách nào để nhập một đường dẫn Python?Chức năng nối ().Đây là cách dễ nhất để nhập mô -đun Python bằng cách thêm đường dẫn mô -đun vào biến đường dẫn.Biến đường dẫn chứa các thư mục thông dịch viên Python tìm kiếm để tìm các mô -đun được nhập trong các tệp nguồn.. This is the easiest way to import a Python module by adding the module path to the path variable. The path variable contains the directories Python interpreter looks in for finding modules that were imported in the source files.
Làm cách nào để nhập một mô -đun cụ thể trong Python?Nhập các mô -đun để sử dụng các chức năng trong một mô -đun, bạn sẽ cần nhập mô -đun với một câu lệnh nhập.Một câu lệnh nhập được tạo thành từ từ khóa nhập cùng với tên của mô -đun.Trong một tệp Python, điều này sẽ được khai báo ở đầu mã, dưới bất kỳ dòng shebang hoặc bình luận chung nào.import the module with an import statement. An import statement is made up of the import keyword along with the name of the module. In a Python file, this will be declared at the top of the code, under any shebang lines or general comments.
PYC có nhanh hơn PY không?Các tệp PYC nhanh hơn so với phân tích tệp .py bằng ANTLR.Tạo cây cú pháp trừu tượng (AST) cho nguồn Python có hai giai đoạn. py file using ANTLR. Creating the abstract syntax tree (AST) for a Python source has two phases. |