Não é possível importar * de um subdiretório em Python [duplicado]
Estou procurando importar um conjunto de módulos de um subdiretório para um único módulo principal no diretório pai:
Projeto/
main.py
subdirectory/
__init__.py
timer.py
example.py
Posso solicitar qualquer um dos arquivos .py individuais, como:
from subdirectory import timer.py
Mas, se eu executar o seguinte comando,
from subdirectory import *
e tento usar um módulo dentro desse subdiretório, recebo o seguinte erro:
File "My:\Path\Here\...", line 33, in main
t = timer.timer()
NameError: name 'timer' is not defined
Quero poder importar todos os arquivos em um lote, pois estou importando alguns módulos. Já adicionei um arquivo init .py em branco ao subdiretório. Há algo que estou perdendo?
Respostas
Você deve declarar seus nomes de módulos usando __all__em sua __init__.py:
__init__.py:
__all__ = ["timer", "example"]
Este comportamento está documentado :
A única solução é o autor do pacote fornecer um índice explícito do pacote. A
importinstrução usa a seguinte convenção: se o__init__.pycódigo de um pacote define uma lista nomeada__all__, ela é considerada a lista de nomes de módulos que devem ser importados quandofrom package import *são encontrados.
Se você quiser apenas fazer as importações funcionarem, adicione subdirectory/__init__.pyo seguinte conteúdo:
from * import example
from * import timer
No entanto, se você quiser fazer isso com um número arbitrário de módulos (antigos e novos), acho que esta resposta pode ser o que você está procurando:
Você começa com a seguinte estrutura:
main.py
subdirectory/
subdirectory/__init__.py
subdirectory/example.py
subdirectory/timer.py
Em seguida, importe tudo subdirectoryde main.py:
from subdirectory import *
t = timer.timer()
Em seguida, adicione o seguinte ao subdirectory/__init__.pymódulo:
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not
f.endswith('__init__.py')]
E para completar o subdirectory/timer.pymódulo:
def timer():
return 42
As importações vão assim.
# if you have timer.py, import it as
import timer
Tente adicionar __init__.pyao subdiretório. Agora será semelhante a:
Projeto/
main.py
subdirectory/
__init__.py
timer.py
example.py
Se isso não funcionar: no main.pyadd
import sys
sys.path.append("path/to/subdirectory") # replace with the path
import timer