Estou usando o Python 3.5.1. Li o documento e a seção do pacote aqui: https://docs.python.org/3/tutorial/modules.html#packages
Agora, tenho a seguinte estrutura:
/home/wujek/Playground/a/b/module.py
module.py
:
class Foo:
def __init__(self):
print('initializing Foo')
Agora, enquanto estiver em /home/wujek/Playground
:
~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>
Da mesma forma, agora em casa, superdobrador de Playground
:
~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>
Na verdade, eu posso fazer todo tipo de coisa:
~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b
Por que isso funciona? Eu pensei que precisava haver __init__.py
arquivos (os vazios funcionariam) em ambos a
e b
para module.py
serem importáveis quando o caminho do Python apontar para a Playground
pasta?
Isso parece ter mudado do Python 2.7:
~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module
Com __init__.py
em ambos ~/Playground/a
e ~/Playground/a/b
funciona bem.
fonte
Zen Of Python
linha 2:Explicit is better than implicit.
....__init__.py
vezes não. No Python 3, quando preciso dessas coisas, crio um novo__init__.py
com código específico, caso contrário, não preciso . Isso é útil para saber, visualmente, quais pacotes possuem init personalizado. Em vez disso, no python 2, sempre tenho que colocar um__init__.py
(geralmente vazio), tornando um grande número deles e, finalmente, mais difícil de lembrar onde você colocou seu código de inicialização. Isso também deve se encaixar "Deve haver uma - e preferencialmente apenas uma - maneira óbvia de fazer isso".IMPORTANTE
A resposta de Mike está correta, mas é imprecisa. É verdade que o Python 3.3+ suporta pacotes de espaço para nome implícito, o que permite criar um pacote sem um
__init__.py
arquivo.Isso, no entanto, APENAS se aplica a arquivos VAZIOS
__init__.py
. Portanto, os arquivos VAZIOS__init__.py
não são mais necessários e podem ser omitidos. Se você deseja executar um script de inicialização específico quando o pacote ou qualquer um de seus módulos ou subpacotes forem importados, você ainda precisará de um__init__.py
arquivo. Esta é uma ótima resposta do Stack Overflow para o motivo de você querer usar um__init__.py
arquivo para fazer alguma inicialização adicional, caso esteja se perguntando por que isso é útil.Exemplo de estrutura de diretório:
parent_package/child_package/__init__.py
:EXEMPLOS
Os exemplos abaixo demonstram como o script de inicialização é executado quando o
child_package
ou um de seus módulos é importado.Exemplo 1 :
Exemplo 2 :
fonte
run_script.py
mesmo diretório, comoparent_package
posso apenas importar comofrom parent_package.child_package import child1
sem__init__.py
?child1.py
, emchild2.py
vez de apenas colocar o código deles em__init__
.py diretamente.__init__
ser importações relativas, ou sejafrom . import child1
? A importação absoluto me dáModuleNotFoundError
(em Python 3.6)__init__.py
às vezes ainda é necessário um vazio , como quando você deseja referenciar uma subpasta como um pacote. Por exemplo, se eu executá-python -m test.foo
lo, não funcionaria até criar um vazio__init__.py
na pasta de teste. E eu estou falando sobre a versão 3.6.6 aqui!Se você possui
setup.py
um projeto e o utilizafind_packages()
, é necessário ter um__init__.py
arquivo em cada diretório para que os pacotes sejam encontrados automaticamente.UPD : Se você quiser usar pacotes de namespace implícitas sem
__init__.py
você apenas tem que usarfind_namespace_packages()
em vezDocumentos
fonte
Eu diria que um deve omitir o
__init__.py
único se quiser ter o pacote implícito de namespace . Se você não sabe o que significa, provavelmente não o deseja e, portanto, deve continuar usando o__init__.py
even no Python 3.fonte