Prenez l'habitude d'écrire ensemble ! C'est le 12ème jour de ma participation au "Nuggets Daily New Plan · April Update Challenge", cliquez pour voir les détails de l'événement .
Si un langage veut devenir plus gros et plus fort, il a besoin d'un système de gestion de modules. Par exemple, le collecteur de js est indispensable pour l'outil de gestion de paquets npm. Rust a du fret et le langage golang a déjà été dénoncé, mais il n'y a pas de paquet officiel Outil de gestion.
Les programmes Python doivent généralement introduire des bibliothèques standard ou des bibliothèques tierces, et les projets doivent également être organisés et gérés en modules. Par conséquent, comprendre le mécanisme d'importation de python et comment gérer les modules est un problème auquel sont confrontés les développeurs.Le paquet sys fournit un mécanisme d'importation pour aider à importer des modules.
Prenez l'habitude d'écrire ensemble ! C'est le 12ème jour de ma participation au "Nuggets Daily New Plan · April Update Challenge", cliquez pour voir les détails de l'événement .
J'ai partagé quelques articles sur ce qui s'est passé derrière l'importation de modules en python auparavant. Le contenu des articles est un peu dispersé. Aujourd'hui, je vais essayer de trier les idées.
import socket
import numpy as np
from tqdm import tqdm
复制代码
Le processus de chargement des modules __import__()
est ,
- Tout d'abord, il recherchera le module
sys.modules
à charger. Si le module a déjà été chargé, alors vous pouvezsys.modules
obtenir le module directement depuis le cache - Habituellement, le chemin que nous voulons importer le module est un chemin de fichier hiérarchique et similaire, c'est-à-dire qu'il doit commencer à partir du répertoire de niveau supérieur en fonction du chemin du module, puis pendant le processus de chargement, il traversera d'abord
sys.meta_path
le MetaPathFinder pour sélectionner un Finder approprié . Considérez-le comme un chercheur. Après avoir sélectionné le chercheur, vous pouvez appeler lafind_module
méthode et transmettre le chemin à cette fonction. Cette fonction renverra un objet chargeur. Cet objet chargeur a uneload_module
méthode pour charger le module que vous voulez charge. - Le chargement d'un module stockera également le module dans
sys.modules
ce cache. La prochaine fois que le module sera rechargé, le module serasys.modules
obtenu directement à partir de , pour éviter de charger à plusieurs reprises le même module.
>>> print(sys.meta_path)
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
复制代码
- BuiltinImporter est utilisé pour charger des modules au niveau du noyau tels que sys, os tels modules
- FrozenImporter est utilisé pour importer des modules de bytecode gelés. En fait, ces modules ont été compilés dans l'interpréteur de python. Ce finder n'est généralement utilisé que pour initialiser le mécanisme d'importation de Python. Charger directement des modules qui peuvent être exécutés sans interpréteur python
- PathFinder Nous savons par son nom qu'il s'agit d'une recherche de chemin de support. Il s'agit d'une implémentation de chargement de ressources basée sur le système de fichiers pour l'importation, qui peut être utilisée pour importer des fichiers .py, .pyc et .zip. Il s'agit d'un chercheur de méta-chemins, la plupart des modules sont importés de cette façon
class CustomFinder(object):
def find_module(self, fullname,path=None):
print(f"Looking for {fullname},{path}")
return None
import sys
sys.meta_path.insert(0,CustomFinder())
import math
import xml.etree.ElementTree
复制代码
Vous pouvez en définir un vous-même. Vous CustomFinder
devez implémenter une méthode find_module à l'intérieur de la classe. Cette méthode doit être appelée par l'interpréteur, et deux paramètres seront injectés lors de l'appel de la fonction. Ensuite, il suffit de sortir ces deux paramètres à l'intérieur de la fonction, sys.meta_path
puis de l'enregistrer, puis d'importer l'instruction pour essayer d'importer les deux modules math et xml.etree.ElementTree.
print(sys.meta_path)
复制代码
Vous pouvez rechercher via la commande sys.meta_path pour trouver que CustomFinder existe déjà dans la liste meta_path.
[<__main__.CustomFinder object at 0x10c0d8430>, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
复制代码
Nous avons découvert que nous pouvions rechercher le chemin xml et renvoyer Aucun. Pourquoi continuer à rechercher vers le bas ? C'est parce que CustomFinder continue à rechercher vers le bas via un autre finder.
Looking for xml,None
Looking for xml.etree,['/anaconda3/envs/py38/lib/python3.8/xml']
Looking for xml.etree.ElementTree,['/anaconda3/envs/py38/lib/python3.8/xml/etree']
复制代码