En python, expliquer en détail le mécanisme d'import (1)

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 pouvez sys.modulesobtenir 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_pathle MetaPathFinder pour sélectionner un Finder approprié . Considérez-le comme un chercheur. Après avoir sélectionné le chercheur, vous pouvez appeler la find_moduleméthode et transmettre le chemin à cette fonction. Cette fonction renverra un objet chargeur. Cet objet chargeur a une load_moduleméthode pour charger le module que vous voulez charge.
  • Le chargement d'un module stockera également le module dans sys.modulesce cache. La prochaine fois que le module sera rechargé, le module sera sys.modulesobtenu 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 CustomFinderdevez 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_pathpuis 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']
复制代码

Je suppose que tu aimes

Origine juejin.im/post/7085586140769550349
conseillé
Classement