Alguém poderia me fornecer uma boa maneira de importar um diretório inteiro de módulos?
Eu tenho uma estrutura como esta:
/Foo
bar.py
spam.py
eggs.py
Tentei convertê-lo em um pacote adicionando __init__.py
e executando, from Foo import *
mas não funcionou da maneira que eu esperava.
python
python-import
Evan Fosmark
fonte
fonte
Respostas:
Liste todos os
.py
arquivos python ( ) na pasta atual e coloque-os como__all__
variáveis em__init__.py
fonte
if not os.path.basename(f).startswith('_')
ou pelo menosif not f.endswith('__init__.py')
até o fim da lista de compreensãoos.path.isfile(f)
éTrue
. Isso filtrar links simbólicos quebrados e diretórios comosomedir.py/
(canto caso, eu admito, mas ainda assim ...)from . import *
após a configuração__all__
se desejar que os submódulos estejam disponíveis usando.
(por exemplomodule.submodule1
, comomodule.submodule2
, etc.).Adicione a
__all__
variável a__init__.py
conter:Veja também http://docs.python.org/tutorial/modules.html
fonte
os.listdir()
, alguma filtragem, remoção de.py
extensão e__all__
.moduleName.varName
ref. stackoverflow.com/a/710603/248616Atualização em 2017: você provavelmente deseja usar
importlib
.Torne o diretório Foo um pacote adicionando um
__init__.py
. Nesse__init__.py
aditamento:Como você deseja que seja dinâmico (o que pode ou não ser uma boa idéia), liste todos os arquivos py com o diretório dir e importe-os com algo como isto:
Em seguida, no seu código, faça o seguinte:
Agora você pode acessar os módulos com
etc.
from Foo import *
não é uma boa ideia por vários motivos, incluindo conflitos de nome e dificultando a análise do código.fonte
__import__
hackish, eu acho que seria melhor para adicionar os nomes para__all__
e em seguida, colocarfrom . import *
na parte inferior do script__import__
não é para usos gerais, é usado porinterpreter
, use emimportlib.import_module()
vez disso.from . import eggs
etc.__init__.py
antes que o Python pudesse importar. Com apenasimport eggs
receboModuleNotFoundError: No module named 'eggs'
ao tentarimport Foo
nomain.py
no diretório acima.Expandindo a resposta de Mihail, acredito que a maneira não hackeada (como em não manipular os caminhos do arquivo diretamente) é a seguinte:
__init__.py
arquivo vazio emFoo/
Você terá:
fonte
RuntimeWarning
mensagens também podem ser evitados por não usar full_package_name em tudo:importer.find_module(package_name).load_module(package_name)
.RuntimeWarning
erros também podem ser evitados (de uma maneira indiscutivelmente feia) importando o pai (nome do diretório AKA). Uma maneira de fazer isso é -if dirname not in sys.modules: pkgutil.find_loader(dirname).load_module(dirname)
. Obviamente, isso só funciona sedirname
for um caminho relativo de componente único; sem barras. Pessoalmente, prefiro a abordagem do @ Artfunkel de usar a base package_name.Python, inclua todos os arquivos em um diretório:
Para iniciantes que simplesmente não conseguem fazê-lo funcionar e que precisam de suas mãos.
Crie uma pasta / home / el / foo e crie um arquivo
main.py
em / home / el / foo Coloque este código lá:Crie um diretório
/home/el/foo/hellokitty
Crie um arquivo
__init__.py
abaixo/home/el/foo/hellokitty
e coloque este código lá:Crie dois arquivos python:
spam.py
eham.py
sob/home/el/foo/hellokitty
Defina uma função dentro do spam.py:
Defina uma função no ham.py:
Executá-lo:
fonte
import *
é considerado uma prática ruim de codificação Python. Como você faz isso sem isso?Eu mesmo me cansei desse problema, então escrevi um pacote chamado automodinit para corrigi-lo. Você pode obtê-lo em http://pypi.python.org/pypi/automodinit/ .
O uso é assim:
automodinit
pacote em suassetup.py
dependências.É isso aí! A partir de agora, a importação de um módulo definirá __all__ como uma lista de arquivos .py [co] no módulo e também importará cada um desses arquivos como se você tivesse digitado:
Portanto, o efeito de "from M import *" corresponde exatamente a "import M".
automodinit
é feliz executando dentro de arquivos ZIP e, portanto, é seguro para ZIP.Niall
fonte
Sei que estou atualizando um post bastante antigo e tentei usá-lo
automodinit
, mas descobri que o processo de instalação está quebrado para o python3. Portanto, com base na resposta de Luca, criei uma resposta mais simples - que pode não funcionar com .zip - para esta questão, então achei que deveria compartilhá-la aqui:dentro do
__init__.py
módulo deyourpackage
:e dentro de outro pacote abaixo
yourpackage
:Então você terá todos os módulos que estão dentro do pacote carregados e, se você escrever um novo módulo, ele também será importado automaticamente. Obviamente, use esse tipo de coisa com cuidado, com grandes poderes e grandes responsabilidades.
fonte
fonte
Eu também encontrei esse problema e esta foi a minha solução:
Essa função cria um arquivo (na pasta fornecida) nomeado
__init__.py
, que contém uma__all__
variável que contém todos os módulos da pasta.Por exemplo, eu tenho uma pasta chamada
Test
que contém:Portanto, no script, quero que os módulos sejam importados para o arquivo:
Isso importará tudo
Test
e o__init__.py
arquivoTest
agora conterá:fonte
O exemplo de Anurag com algumas correções:
fonte
Resposta Anurag Uniyal com melhorias sugeridas!
fonte
Veja que o seu
__init__.py
define__all__
. Os módulos - pacotes doc dizfonte
Esta é a melhor maneira que encontrei até agora:
fonte
Usando
importlib
a única coisa que você precisa adicionar éfonte
error: Type of __all__ must be "Sequence[str]", not "List[Module]"
. A definição__all__
não é necessária se essaimport_module
abordagem baseada for usada.Veja o módulo pkgutil da biblioteca padrão. Isso permitirá que você faça exatamente o que deseja, desde que tenha um
__init__.py
arquivo no diretório O__init__.py
arquivo pode estar vazio.fonte
Eu criei um módulo para isso, que não depende
__init__.py
(ou qualquer outro arquivo auxiliar) e me faz digitar apenas as duas linhas a seguir:Sinta-se à vontade para reutilizar ou contribuir: http://gitlab.com/aurelien-lourot/importdir
fonte
Apenas importe-os por importlib e adicione-os a
__all__
(aadd
ação é opcional) em recursão no__init__.py
pacote.fonte
py
Quando
from . import *
não é bom o suficiente, é uma melhoria em relação à resposta de ted . Especificamente, o uso de__all__
não é necessário com essa abordagem.Observe que
module_name not in globals()
se destina a evitar a reimportação do módulo se ele já estiver importado, pois isso pode arriscar importações cíclicas.fonte