Шукачі входу в шлях

Оновлено: 28.04.2023

path based finder відповідає за пошук і завантаження модулів і пакетів Python, розташування яких вказано за допомогою рядка path entry. Більшість записів шляхів іменують розташування у файловій системі, але вони не повинні обмежуватися цим.

Як мета-пошук шляху, пошук на основі шляху реалізує find_spec() протокол, описаний раніше, однак він надає додаткові перехоплювачі, які можна використовувати для налаштування способу пошуку модулів і завантажується з шляху імпорту.

Три змінні використовуються path based finder, sys.path, sys.path_hooks і sys.path_importer_cache. Також використовуються атрибути __path__ об’єктів пакета. Це надає додаткові способи налаштування імпортного обладнання.

sys.path contains a list of strings providing search locations for modules and packages. It is initialized from the PYTHONPATH environment variable and various other installation- and implementation-specific defaults. Entries in sys.path can name directories on the file system, zip files, and potentially other «locations» (see the site module) that should be searched for modules, such as URLs, or database queries. Only strings should be present on sys.path; all other data types are ignored.

пошук на основі шляху є метапошуком шляху, тому механізм імпорту починає пошук шляху імпорту, викликаючи Коли вказано аргумент ``path`() для find_spec(), це буде список шляхів до рядків, які потрібно пройти - зазвичай атрибут __path__ пакета для імпорту в цьому пакет. Якщо аргумент path має значення None, це вказує на імпорт верхнього рівня та sys.path використовується.

The path based finder iterates over every entry in the search path, and for each of these, looks for an appropriate path entry finder (PathEntryFinder) for the path entry. Because this can be an expensive operation (e.g. there may be stat() call overheads for this search), the path based finder maintains a cache mapping path entries to path entry finders. This cache is maintained in sys.path_importer_cache (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 sys.path_importer_cache forcing the path based finder to perform the path entry search again 3.

Якщо запису шляху немає в кеші, пошук на основі шляху повторює кожен виклик у sys.path_hooks. Кожен із перехоплювачів запису шляху у цьому списку викликається з одним аргументом, записом шляху, який потрібно шукати. Цей виклик може повертати пошук запису шляху, який може обробити запис шляху, або може викликати ImportError. Помилка ImportError використовується шукачем на основі шляху, щоб сигналізувати про те, що хук не може знайти пошук запису шляху для цього запису шляху. Виняток ігнорується, і повторення шляху імпорту продовжується. Хук повинен очікувати об’єкт string або bytes; кодування об’єктів bytes залежить від хука (наприклад, це може бути кодування файлової системи, UTF-8 або щось інше), і якщо хук не може декодувати аргумент, він має викликати ImportError.

Якщо sys.path_hooks ітерація закінчується без повернення path entry finder, тоді метод пошуку на основі шляху find_spec() зберігатиме None у sys.path_importer_cache (щоб вказати, що немає засобу пошуку для цього запису шляху) і повернути None, вказуючи, що цей meta path finder не зміг знайти модуль.

Якщо path entry finder повертається одним із викликів path entry hook на sys.path_hooks, тоді використовується наступний протокол, щоб запитати модуль на пошуковик spec, який потім використовується під час завантаження модуля.

Поточний робочий каталог, позначений порожнім рядком, обробляється дещо інакше, ніж інші записи в sys.path. По-перше, якщо поточний робочий каталог не існує, жодне значення не зберігається в sys.path_importer_cache. По-друге, значення для поточного робочого каталогу оновлюється для кожного пошуку модуля. По-третє, шлях, який використовується для sys.path_importer_cache і повертається importlib.machinery.PathFinder.find_spec(), буде фактичним поточним робочим каталогом, а не порожнім рядком.