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.modules
a ser carregado. Se o módulo já foi carregado, você poderásys.modules
obtê-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_path
o MetaPathFinder para selecionar um Finder adequado . Pense nisso como um buscador. Após selecionar o localizador, você pode chamar ofind_module
método e passar o caminho para esta função. Esta função retornará um objeto carregador. Este objeto carregador possui umload_module
método para carregar o módulo que você deseja carregar. - Carregar um módulo também armazenará o módulo
sys.modules
neste cache.Na próxima vez que o módulo for carregado novamente, o módulo serásys.modules
obtido 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ê CustomFinder
precisa 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_path
depois 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']
复制代码