python O que é __init__.py para?



5 Answers

Arquivos chamados __init__.py são usados ​​para marcar diretórios no disco como diretórios de pacotes do Python. Se você tiver os arquivos

mydir/spam/__init__.py
mydir/spam/module.py

e mydir está no seu caminho, você pode importar o código em module.py como

import spam.module

ou

from spam import module

Se você remover o arquivo __init__.py , o Python não procurará mais submódulos dentro desse diretório, portanto, as tentativas de importar o módulo falharão.

O arquivo __init__.py é geralmente vazio, mas pode ser usado para exportar partes selecionadas do pacote sob um nome mais conveniente, manter funções de conveniência, etc. Dado o exemplo acima, o conteúdo do módulo init pode ser acessado como

import spam

com base this

python module

O que é o __init__.py em um diretório de origem do Python?




Existem 2 motivos principais para __init__.py

  1. Por conveniência: os outros usuários não precisarão saber a localização exata de suas funções na hierarquia de pacotes.

    your_package/
      __init__.py
      file1.py/
      file2.py/
        ...
      fileN.py
    
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    
    # in file1.py
    def add():
        pass

    então outros podem chamar add () por

    from your_package import add

    sem saber file1, como

    from your_package.file1 import add
  2. Se você quer algo para ser inicializado; por exemplo, logging (que deve ser colocado no nível superior):

    import logging.config
    logging.config.dictConfig(Your_logging_config)



Desde o Python 3.3, __init__.py não é mais necessário para definir diretórios como pacotes Python importáveis.

Verifique o PEP 420: Pacotes de Namespace Implícitos :

Suporte nativo para diretórios de pacotes que não exigem arquivos de marcadores __init__.py e podem abranger automaticamente vários segmentos de caminho (inspirados por várias abordagens de terceiros para pacotes de namespace, conforme descrito em PEP 420 )

Aqui está o teste:

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

referências:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
O __init__.py não é necessário para pacotes no Python 3?




__init__.py tratará o diretório no qual ele está como um módulo carregável.

Para as pessoas que preferem ler códigos, eu coloco o comentário do Alquimista de Dois Bits aqui.

$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$ 
$ rm /tmp/mydir/spam/__init__.py*
$ 
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>> 



Embora o Python funcione sem um arquivo __init__.py você ainda deve incluir um.

Ele especifica que um pacote deve ser tratado como um módulo, portanto, inclua-o (mesmo se estiver vazio).

Há também um caso em que você pode realmente usar um arquivo __init__.py :

Imagine que você tivesse a seguinte estrutura de arquivos:

main_methods 
    |- methods.py

E o methods.py continha isto:

def foo():
    return 'foo'

Para usar o foo() você precisaria de um dos seguintes:

from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()

Talvez você precise (ou queira) manter o main_methods methods.py dentro de main_methods (tempos de execução / dependências, por exemplo), mas só quer importar main_methods .

Se você mudou o nome de methods.py para __init__.py então você poderia usar foo() importando apenas main_methods :

import main_methods
print(main_methods.foo()) # Prints 'foo'

Isso funciona porque __init__.py é tratado como parte do pacote.

Alguns pacotes Python realmente fazem isso. Um exemplo é com o JSON , onde a execução do import json está realmente importando o __init__.py do pacote json ( veja a estrutura do arquivo do pacote aqui ):

Código fonte: Lib/json/__init__.py




Related