Primeiro, lembre-se de que, em sua definição precisa, um módulo é um objeto na memória de um intérprete Python, geralmente criado pela leitura de um ou mais arquivos do disco. Embora possamos informalmente chamar um arquivo de disco como a/b/c.py
um "módulo", ele na verdade não se torna um até ser combinado com informações de várias outras fontes (comosys.path
) para criar o objeto do módulo.
(Observe, por exemplo, que dois módulos com nomes diferentes podem ser carregados do mesmo arquivo, dependendo de sys.path
e outras configurações. É exatamente o que acontece com python -m my.module
seguido por um import my.module
no intérprete; haverá dois objetos de módulo __main__
e my.module
, ambos criados do mesmo arquivo no disco,my/module.py
,.)
Um pacote é um módulo que pode ter submódulos (incluindo subpacotes). Nem todos os módulos podem fazer isso. Como exemplo, crie uma pequena hierarquia de módulos:
$ mkdir -p a/b
$ touch a/b/c.py
Verifique se não há outros arquivos abaixo a
. Inicie um intérprete Python 3.4 ou posterior (por exemplo, com python3 -i
) e examine os resultados das seguintes instruções:
import a
a ⇒ <module 'a' (namespace)>
a.b ⇒ AttributeError: module 'a' has no attribute 'b'
import a.b.c
a.b ⇒ <module 'a.b' (namespace)>
a.b.c ⇒ <module 'a.b.c' from '/home/cjs/a/b/c.py'>
Módulos a
e a.b
pacotes (na verdade, um certo tipo de pacote chamado "pacote de espaço para nome", embora não nos preocupemos com isso aqui). No entanto, o módulo a.b.c
não é um pacote. Podemos demonstrar isso adicionando outro arquivo a/b.py
à estrutura de diretórios acima e iniciando um novo intérprete:
import a.b.c
⇒ ImportError: No module named 'a.b.c'; 'a.b' is not a package
import a.b
a ⇒ <module 'a' (namespace)>
a.__path__ ⇒ _NamespacePath(['/.../a'])
a.b ⇒ <module 'a.b' from '/home/cjs/tmp/a/b.py'>
a.b.__path__ ⇒ AttributeError: 'module' object has no attribute '__path__'
O Python garante que todos os módulos pai sejam carregados antes que um módulo filho seja carregado. Acima, ele descobre que a/
é um diretório e, portanto, cria um pacote de namespace a
, e a/b.py
é um arquivo de origem Python que ele carrega e usa para criar um módulo (sem pacote) a.b
. Neste ponto, você não pode ter um módulo a.b.c
porque a.b
não é um pacote e, portanto, não pode ter submódulos.
Você também pode ver aqui que o módulo do pacote a
tem um __path__
atributo (os pacotes devem ter isso), mas o módulo não-pacote a.b
não.