Em python, explique o mecanismo de importação em detalhes (1)

Adquira o hábito de escrever juntos! Este é o 12º dia da minha participação no "Nuggets Daily New Plan · April Update Challenge", clique para ver os detalhes do evento .

Se uma linguagem quer se tornar maior e mais forte, ela precisa de um sistema de gerenciamento de módulos. Por exemplo, o manifold de js é indispensável para a ferramenta de gerenciamento de pacotes npm. Rust tem carga e a linguagem golang já foi reclamada antes, mas não há pacote oficial Ferramenta de gestão.

Os programas Python geralmente precisam introduzir algumas bibliotecas padrão ou bibliotecas de terceiros, e os projetos também precisam ser organizados e gerenciados em módulos. Portanto, entender o mecanismo de importação do python e como gerenciar módulos é um problema enfrentado pelos desenvolvedores.O pacote sys fornece um mecanismo de importação para ajudar na importação de módulos.

Adquira o hábito de escrever juntos! Este é o 12º dia da minha participação no "Nuggets Daily New Plan · April Update Challenge", clique para ver os detalhes do evento .

Eu compartilhei alguns artigos sobre o que aconteceu por trás da importação de módulos em python antes. O conteúdo dos artigos é um pouco disperso. Hoje, vou tentar resolver as idéias.

import socket
import numpy as np
from tqdm import tqdm
复制代码

O processo de carregamento de módulos __import__()é ,

  • Primeiro, ele procurará o módulo sys.modulesa ser carregado. Se o módulo já foi carregado, você poderá sys.modulesobtê-lo diretamente do cache
  • Normalmente, o caminho que queremos importar o módulo é um caminho de arquivo hierárquico e semelhante, de modo que comece no diretório de nível superior de acordo com o caminho do módulo; durante o processo de carregamento, ele primeiro percorrerá sys.meta_patho MetaPathFinder para selecionar um Finder adequado . Pense nisso como um buscador. Após selecionar o localizador, você pode chamar o find_modulemétodo e passar o caminho para esta função. Esta função retornará um objeto carregador. Este objeto carregador possui um load_modulemétodo para carregar o módulo que você deseja carregar.
  • Carregar um módulo também armazenará o módulo sys.modulesneste cache.Na próxima vez que o módulo for carregado novamente, o módulo será sys.modulesobtido diretamente de , para evitar carregar repetidamente o mesmo módulo.
>>> print(sys.meta_path)
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
复制代码
  • BuiltinImporter é usado para carregar módulos no nível do kernel, como sys, os tais módulos
  • FrozenImporter é usado para importar módulos de bytecode congelados. Na verdade, esses módulos foram compilados no interpretador do python. Este localizador geralmente é usado apenas para inicializar o mecanismo de importação do Python. Carregar diretamente módulos que podem ser executados sem um interpretador python
  • PathFinder Sabemos pelo nome que esta é uma pesquisa de caminho de suporte. Esta é uma implementação de carregamento de recursos baseada em sistema de arquivos para importação, que pode ser usada para importar arquivos .py, .pyc e .zip. Este é um localizador de meta caminho, a maioria dos módulos são importados dessa maneira
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
复制代码

Você mesmo pode definir um. Você CustomFinderprecisa implementar um método find_module dentro da classe. Este método deve ser chamado pelo interpretador, e dois parâmetros serão injetados ao chamar a função. Em seguida, basta imprimir esses dois parâmetros dentro da função, sys.meta_pathdepois registrá-lo, e então importamos a instrução para tentar importar os dois módulos são math e xml.etree.ElementTree.

print(sys.meta_path)
复制代码

Você pode pesquisar por meio do comando sys.meta_path para descobrir que o CustomFinder já existe na lista meta_path.

[<__main__.CustomFinder object at 0x10c0d8430>, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
复制代码

Descobrimos que podemos pesquisar o caminho xml e retornar Nenhum. Por que continuar pesquisando? Isso ocorre porque se o CustomFinder continuar pesquisando por meio de outro localizador.

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']
复制代码

Acho que você gosta

Origin juejin.im/post/7085586140769550349
Recomendado
Clasificación