Situação: - Há um módulo na pasta project_ chamado calendar - Gostaria de usar a classe Calendar incorporada das bibliotecas Python - Quando uso a importação de calendário, o Calendar reclama porque está tentando carregar do meu módulo.
Fiz algumas pesquisas e não consigo encontrar uma solução para o meu problema.
- Como acessar um módulo de biblioteca padrão no Python quando existe um módulo local com o mesmo nome?
- http://docs.python.org/whatsnew/2.5.html
- Como evitar escrever o nome do módulo o tempo todo ao importar um módulo em python?
Alguma idéia sem ter que renomear meu módulo?
Respostas:
A solução aceita contém uma abordagem agora obsoleta.
A documentação importlib aqui fornece um bom exemplo da maneira mais apropriada de carregar um módulo diretamente de um caminho de arquivo para python> = 3.5:
Portanto, você pode carregar qualquer arquivo .py a partir de um caminho e definir o nome do módulo para o que quiser. Portanto, apenas ajuste-o
module_name
como qualquer nome personalizado que você gostaria que o módulo tivesse ao importar.Para carregar um pacote em vez de um único arquivo,
file_path
deve ser o caminho para a raiz do pacote__init__.py
fonte
file_path=r"C:\Users\My User\My Path\Module File.py"
. Então chameimodule_name
exatamente como o módulo lançado, para ter um script de trabalho completo que, retirado esse trecho, poderia ser usado em outros computadoresNão é necessário alterar o nome do seu módulo. Em vez disso, você pode usar absolute_import para alterar o comportamento de importação. Por exemplo, com stem / socket.py , importo o módulo de soquete da seguinte maneira:
Isso funciona apenas com o Python 2.5 e superior; está permitindo um comportamento padrão no Python 3.0 e superior. O Pylint irá reclamar do código, mas é perfeitamente válido.
fonte
PYTHONPATH
. Outra pergunta mostra como resolver isso.Na verdade, resolver isso é bastante fácil, mas a implementação sempre será um pouco frágil, porque depende do interior do mecanismo de importação python e eles estão sujeitos a alterações em versões futuras.
(o código a seguir mostra como carregar módulos locais e não locais e como eles podem coexistir)
A melhor solução, se possível, é evitar nomear seus módulos com o mesmo nome da biblioteca padrão ou dos nomes dos módulos internos.
fonte
sys.modules
e as tentativas subseqüentes de carregar o módulo local?A única maneira de resolver esse problema é seqüestrar o maquinário interno de importação. Isso não é fácil e cheio de perigos. Você deve evitar o farol em forma de graal a todo custo, porque o perigo é muito perigoso.
Renomeie seu módulo.
Se você quiser aprender a seqüestrar o mecanismo interno de importação, é aqui que você descobrirá como fazer isso:
Às vezes, existem boas razões para entrar nesse perigo. A razão que você dá não está entre eles. Renomeie seu módulo.
Se você seguir o caminho perigoso, um problema que você encontrará é que, quando você carrega um módulo, ele acaba com um 'nome oficial', para que o Python evite ter que analisar o conteúdo desse módulo novamente. Um mapeamento do 'nome oficial' de um módulo para o próprio objeto do módulo pode ser encontrado em
sys.modules
.Isso significa que, se você estiver
import calendar
em um lugar, qualquer módulo importado será considerado o módulo com o nome oficialcalendar
e todas as outras tentativas paraimport calendar
qualquer outro lugar, incluindo outro código que faça parte da biblioteca principal do Python, receberá esse calendário.Pode ser possível projetar um importador de clientes usando o módulo imputil no Python 2.x que fez com que os módulos carregados de determinados caminhos procurassem os módulos que estavam importando em algo diferente do
sys.modules
primeiro ou algo parecido. Mas isso é algo extremamente complicado de se fazer, e de qualquer maneira não funcionará no Python 3.x.Há uma coisa extremamente feia e horrível que você pode fazer que não envolve enganchar o mecanismo de importação. Isso é algo que você provavelmente não deve fazer, mas provavelmente funcionará. Transforma seu
calendar
módulo em um híbrido do módulo de calendário do sistema e seu módulo de calendário. Agradeço a Boaz Yaniv pelo esqueleto da função que uso . Coloque isso no início do seucalendar.py
arquivo:fonte
code
módulo std do Python ), o que significa que apenas uma fração dos desenvolvedores pode ter problemas com esse "hack de mesclagem". Os usuários não seriam afetados.Eu gostaria de oferecer minha versão, que é uma combinação da solução de Boaz Yaniv e Omnifarious. Importará a versão do sistema de um módulo, com duas principais diferenças em relação às respostas anteriores:
Coloque isso em algum lugar acessível para que você possa chamá-lo (eu tenho o meu no meu arquivo __init__.py):
Exemplo
Eu queria importar o mysql.connection, mas já tinha um pacote local chamado mysql (os utilitários oficiais do mysql). Então, para obter o conector do pacote mysql do sistema, substituí este:
Com isso:
Resultado
fonte
Mude o caminho de importação:
fonte
sys.modules
e não importará um módulo com o mesmo nome novamente.