Para que serve __init__.py
em um diretório de origem Python?
python
module
package
python-packaging
Esteira
fonte
fonte
Respostas:
Costumava ser uma parte necessária de um pacote ( antigo "pacote regular" anterior à 3.3 , e não mais recente "pacote de namespace" 3.3+ mais recente ).
Aqui está a documentação.
Mas basta clicar no link, ele contém um exemplo, mais informações e uma explicação dos pacotes de namespace, o tipo de pacote sem
__init__.py
.fonte
sys.path.insert(0, '/path/to/datetime')
, substituindo esse caminho pelo caminho para o diretório que você acabou de criar. Agora tente algo parecidofrom datetime import datetime;datetime.now()
. Você deve obter um AttributeError (porque está importando seu arquivo em branco agora). Se você repetisse essas etapas sem criar o arquivo init em branco, isso não aconteceria. Isso é o que se pretende impedir.from datetime import datetime
sem erros. Isso é bom desde a versão 2.3!builtins
lista funções e classes internas , não módulos internos (cf. docs.python.org/3/tutorial/modules.html#the-dir-function ). Se você deseja listar os módulos internos , façaimport sys; print(sys.builtin_module_names)
(cf. docs.python.org/3/library/sys.html#sys.builtin_module_names ).Os arquivos nomeados
__init__.py
são usados para marcar diretórios no disco como diretórios de pacotes Python. Se você tiver os arquivose
mydir
está no seu caminho, você pode importar o códigomodule.py
comoou
Se você remover o
__init__.py
arquivo, o Python não procurará mais submódulos dentro desse diretório; portanto, as tentativas de importar o módulo falharão.O
__init__.py
arquivo geralmente está vazio, mas pode ser usado para exportar partes selecionadas do pacote com um nome mais conveniente, manter funções de conveniência etc. etc. Dado o exemplo acima, o conteúdo do módulo init pode ser acessado comocom base nisso
fonte
__init__.py
foi necessário no Python 2.X e ainda é necessário no Python 2.7.12 (eu testei), mas não é mais necessário (supostamente) do Python 3.3 em diante e não é necessário no Python 3.4.3 (I testado). Consulte stackoverflow.com/questions/37139786 para obter mais detalhes.__init__.py
.setup.py
e usarfind_packages()
, é necessário ter__init__.py
em todos os diretórios. Veja stackoverflow.com/a/56277323/7127824Além de rotular um diretório como um pacote Python e definir
__all__
,__init__.py
permite definir qualquer variável no nível do pacote. Isso geralmente é conveniente se um pacote definir algo que será importado com frequência, de maneira semelhante à API. Esse padrão promove a aderência à filosofia "plana é melhor do que aninhada".Um exemplo
Aqui está um exemplo de um dos meus projetos, no qual eu frequentemente importo uma
sessionmaker
chamadaSession
para interagir com meu banco de dados. Eu escrevi um pacote "database" com alguns módulos:My
__init__.py
contém o seguinte código:Como defino
Session
aqui, posso iniciar uma nova sessão usando a sintaxe abaixo. Esse código seria o mesmo executado dentro ou fora do diretório do pacote "database".Obviamente, essa é uma pequena conveniência - a alternativa seria definir
Session
em um novo arquivo como "create_session.py" no meu pacote de banco de dados e iniciar novas sessões usando:Leitura adicional
Existe um tópico reddit bastante interessante que cobre os usos apropriados
__init__.py
aqui:http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
A opinião da maioria parece ser que os
__init__.py
arquivos devem ser muito finos para evitar violar a filosofia "explícito é melhor que implícito".fonte
engine
,sessionmaker
,create_engine
, Eos
podem também ser importados dedatabase
agora ... parece que você fez uma confusão de que namespace.__all__ = [...]
para limitar o que é importadoimport *
. Além disso, sim, você fica com um namespace de nível superior confuso.Existem 2 razões principais para
__init__.py
Por conveniência: os outros usuários não precisarão conhecer a localização exata de suas funções na hierarquia de pacotes.
outras pessoas podem chamar add () por
sem saber file1, como
Se você deseja que algo seja inicializado; por exemplo, log (que deve ser colocado no nível superior):
fonte
__init__.py
pode ser útil algumas vezes, mas nem sempre.O
__init__.py
arquivo faz o Python tratar os diretórios que o contêm como módulos.Além disso, este é o primeiro arquivo a ser carregado em um módulo, portanto, você pode usá-lo para executar o código que deseja executar cada vez que um módulo é carregado ou especificar os submódulos a serem exportados.
fonte
Desde o Python 3.3,
__init__.py
não é mais necessário definir diretórios como pacotes Python importáveis.Verifique PEP 420: Pacotes implícitos de espaço para nome :
Aqui está o teste:
referências:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Is __init__. py não é necessário para pacotes em Python 3?
fonte
No Python, a definição de pacote é muito simples. Como Java, a estrutura hierárquica e a estrutura de diretórios são as mesmas. Mas você tem que ter
__init__.py
em um pacote. Vou explicar o__init__.py
arquivo com o exemplo abaixo:__init__.py
pode estar vazio, enquanto existir. Indica que o diretório deve ser considerado como um pacote. Claro,__init__.py
também pode definir o conteúdo apropriado.Se adicionarmos uma função no module_n1:
Depois de correr:
Em seguida, seguimos o pacote de hierarquia e chamamos module_n1 a função. Podemos usar
__init__.py
no subPackage_b assim:Depois de correr:
Portanto, usando a importação *, o pacote do módulo está sujeito ao
__init__.py
conteúdo.fonte
from package_x.subPackage_b.module_n1 import function_X
Embora o Python funcione sem um
__init__.py
arquivo, você ainda deve incluir um.Ele especifica que um pacote deve ser tratado como um módulo; portanto, inclua-o (mesmo que esteja vazio).
Também existe um caso em que você pode realmente usar um
__init__.py
arquivo:Imagine que você tivesse a seguinte estrutura de arquivos:
E
methods.py
continha isso:Para usar,
foo()
você precisaria de um dos seguintes:Talvez você precise (ou queira) manter
methods.py
dentromain_methods
(tempos de execução / dependências, por exemplo), mas você só deseja importarmain_methods
.Se você mudou o nome de
methods.py
para,__init__.py
então você pode usarfoo()
apenas importandomain_methods
:Isso funciona porque
__init__.py
é tratado como parte do pacote.Alguns pacotes Python realmente fazem isso. Um exemplo é com JSON , em que a execução
import json
é realmente importada__init__.py
dojson
pacote ( consulte a estrutura do arquivo do pacote aqui ):fonte
__init__.py
tratará o diretório em que está como um módulo carregável.Para quem prefere ler código, coloquei o comentário do Alquimista de dois bits aqui.
fonte
Facilita a importação de outros arquivos python. Quando você colocou esse arquivo em um diretório (digamos, stuff) contendo outros arquivos py, você pode fazer algo como importar coisas.outros.
Sem isso
__init__.py
dentro do diretório, você não poderia importar other.py, porque o Python não sabe onde está o código-fonte e não consegue reconhecê-lo como um pacote.fonte
Um
__init__.py
arquivo facilita as importações. Quando um__init__.py
está presente em um pacote, a funçãoa()
pode ser importada do arquivo da seguinteb.py
maneira:Sem ele, no entanto, você não pode importar diretamente. Você precisa alterar o caminho do sistema:
fonte