Qual é a diferença entre um módulo Python e um pacote Python?

577

Qual é a diferença entre um módulo Python e um pacote Python?

Veja também: Qual é a diferença entre "pacote" e "módulo" (para outros idiomas)

Dave
fonte
9
Posso estar errado, mas para mim: um módulo é basicamente um arquivo python. Um pacote é uma pasta com vários módulos (arquivos python).
lc2817
36
Para ser considerada um pacote, essa pasta deve conter um __init__.pyarquivo.
Giulio Piancastelli 30/10
@ lc2817: é o caso mais comum, mas não é necessário que um módulo seja carregado a partir de um sistema de arquivos, por exemplo, consulte from plumbum.cmd import lsimplementação
jfs
4
@GiulioPiancastelli: Em Python 3.3+, pacotes de namespace não use__init__.py
jfs
Como a comunidade diferencia entre pacotes Python e pacotes usados ​​para distribuir componentes Python como PyPI / wheels / etc? Os dois parecem diferentes aplicações da palavra "pacote" para mim.
precisa saber é

Respostas:

372

Um módulo é um único arquivo (ou arquivos) que são importados sob uma importação e usados. por exemplo

import my_module

Um pacote é uma coleção de módulos em diretórios que fornecem uma hierarquia de pacotes.

from my_package.timing.danger.internets import function_of_love

Documentação para módulos

Introdução aos pacotes

Jakob Bowyer
fonte
54
Quando você diz: "Um módulo é um único arquivo (ou arquivos) importados sob uma importação", você pode explicar a situação em que um módulo possui mais de um arquivo? Ou estou interpretando mal o que você quer dizer?
Utilizador
6
Você não precisa de um arquivo para criar um módulo, por exemplo, você pode importar um módulo de um arquivo zip. Mesmo para pacotes. Existe apenas uma classe para módulos / pacotes no Python. O pacote é apenas um módulo com um __path__atributo.
usar o seguinte
33
Pacotes também são módulos . Eles são empacotados de maneira diferente; eles são formados pela combinação de um diretório mais um __init__.pyarquivo. Eles são módulos que podem conter outros módulos.
Martijn Pieters
15
@ Jacquot, consulte O sistema de importação na documentação de referência: É importante ter em mente que todos os pacotes são módulos .
Martijn Pieters
6
@ Jacquot: e o glossário em “pacote” : Um módulo Python que pode conter sub-módulos ou recursivamente sub- __path__
Martijn Pieters
556

Qualquer arquivo Python é um módulo , cujo nome é o nome base do arquivo sem a .pyextensão. Um pacote é uma coleção de módulos Python: enquanto um módulo é um único arquivo Python, um pacote é um diretório de módulos Python contendo um __init__.pyarquivo adicional , para distinguir um pacote de um diretório que por acaso contém vários scripts Python. Os pacotes podem ser aninhados em qualquer profundidade, desde que os diretórios correspondentes contenham seu próprio __init__.pyarquivo.

A distinção entre módulo e pacote parece manter-se apenas no nível do sistema de arquivos. Quando você importa um módulo ou pacote, o objeto correspondente criado pelo Python é sempre do tipo module. Observe, no entanto, quando você importa um pacote, apenas variáveis ​​/ funções / classes no __init__.pyarquivo desse pacote são diretamente visíveis, não subpacotes ou módulos. Como exemplo, considere o xmlpacote na biblioteca padrão do Python: seu xmldiretório contém um __init__.pyarquivo e quatro subdiretórios; o subdiretório etreecontém um __init__.pyarquivo e, entre outros, um ElementTree.pyarquivo. Veja o que acontece quando você tenta importar interativamente pacotes / módulos:

>>> import xml
>>> type(xml)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'etree'
>>> import xml.etree
>>> type(xml.etree)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ElementTree'
>>> import xml.etree.ElementTree
>>> type(xml.etree.ElementTree)
<type 'module'>
>>> xml.etree.ElementTree.parse
<function parse at 0x00B135B0>

No Python, também existem módulos internos, como os sysescritos em C, mas acho que você não considerou os que estão em sua pergunta.

Giulio Piancastelli
fonte
9
Obrigado por mencionar explicitamente que o objeto correspondente criado pelo Python é sempre do tipo module. Estou escrevendo um depurador e estava preocupado que meu depurador estivesse incorreto ao dizer que meus pacotes eram modules.
ArtOfWarfare
8
@jolvi Arquivos Python com um nome de arquivo contendo traços ainda podem ser importados como módulos, mas não com a importinstrução usual , porque traços não são permitidos nos identificadores Python. Use em importlib.import_module()vez disso.
Giulio Piancastelli
2
@jolvi Eu não sou. Onde no meu comentário você está lendo isso? Só estou dizendo que, se você tiver ou encontrar um arquivo Python com traços em seu nome, ainda poderá importá-lo como um módulo. Eu não estou fazendo uma declaração sobre a maneira preferida de nomear um arquivo Python. Tenho certeza que você pode encontrar isso em outro lugar: geralmente é altamente recomendável evitar traços em favor de sublinhados.
Giulio Piancastelli
3
Ser novo no Python, subpacotes ou módulos que não estão disponíveis por padrão ao importar o pacote pai é o que me fez tropeçar. Existe uma razão específica para isso? E existe um padrão comum de como disponibilizar subpacotes ou módulos (através do nome completo) ao importar o pacote pai?
precisa saber é o seguinte
2
@sschuberth Apenas importe subpacotes no init .py de um pacote pai.
Anna
33

No glossário Python :

É importante ter em mente que todos os pacotes são módulos, mas nem todos os módulos são pacotes. Ou, dito de outra forma, os pacotes são apenas um tipo especial de módulo. Especificamente, qualquer módulo que contenha um __path__atributo é considerado um pacote.

Arquivos Python com um traço no nome, como my-file.py, não podem ser importados com uma importdeclaração simples . Em termos de código, import my-fileé o mesmo import my - fileque gerará uma exceção. Esses arquivos são mais bem caracterizados como scripts, enquanto os arquivos importáveis ​​são módulos .

jolvi
fonte
23

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.pyum "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.pathe outras configurações. É exatamente o que acontece com python -m my.moduleseguido por um import my.moduleno 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 ae a.bpacotes (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.cnã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.cporque a.bnão é um pacote e, portanto, não pode ter submódulos.

Você também pode ver aqui que o módulo do pacote atem um __path__atributo (os pacotes devem ter isso), mas o módulo não-pacote a.bnão.

cjs
fonte
1
Se você ainda não o fez, volte e trabalhe com os exemplos nesta resposta.
Donal Lafferty
2

Uma resposta tardia, mais uma definição:

Um pacote é representado por uma entidade superior importada que pode ser um módulo independente ou o __init__.pymódulo especial como entidade superior de um conjunto de módulos dentro de uma estrutura de subdiretório.

Então, fisicamente, um pacote é uma unidade de distribuição, que fornece um ou mais módulos.

um palpite
fonte
1
Eu sinto que existem duas definições para pacote no Python e elas são distintas. Sua resposta parece combiná-los. Estritamente falando, um pacote python é um diretório com um __init__.pymódulo, mas se você falar sobre unidades de distribuição (geralmente via PyPI), esse é outro tipo de pacote inteiramente (geralmente definido pela existência de setup.py). Acho esses dois usos do termopackage confusos e falei com alguns iniciantes em Python que o consideram totalmente desconcertante.
precisa saber é
@ DavidA, não é apenas como você se sente. Tem sido codificado: packaging.python.org/glossary/#term-distribution-package (Obrigado por esclarecer, também!)
Lorem Ipsum