Вопрос-Ответ

What's the difference between a module and package in Python?

В чем разница между модулем и пакетом в Python?

В чем разница между модулем и пакетом в Python?

Смотрите также: В чем разница между "пакетом" и "модулем"? (для других языков)

Переведено автоматически
Ответ 1

  • Любой файл Python является модулем, его имя является базовым именем файла без .py расширения.

  • Пакет - это коллекция модулей Python: в то время как модуль представляет собой отдельный файл Python, пакет представляет собой каталог модулей Python, содержащий дополнительный __init__.py файл, чтобы отличать пакет от каталога, который просто случайно содержит кучу скриптов Python. Пакеты могут быть вложены на любую глубину при условии, что соответствующие каталоги содержат их собственный __init__.py файл.

Различие между модулем и пакетом, похоже, сохраняется только на уровне файловой системы. Когда вы импортируете модуль или пакет, соответствующий объект, созданный Python, всегда имеет тип module. Однако обратите внимание, что при импорте пакета непосредственно видны только переменные / функции / классы в __init__.py файле этого пакета, не подпакеты или модули.


Пример

В качестве примера рассмотрим xml пакет в стандартной библиотеке Python: его xml каталог содержит __init__.py файл и четыре подкаталога; подкаталог etree содержит __init__.py файл и, среди прочих, ElementTree.py файл.

Посмотрите, что происходит при попытке интерактивного импорта пакета / модулей:

>>> 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>

ПРИМЕЧАНИЕ

В Python также есть встроенные модули, такие как sys, которые написаны на C, но я не думаю, что вы имели в виду учитывать их в своем вопросе.

Ответ 2

Модуль - это отдельный файл (или файлы), которые импортируются в рамках одного импорта и используются. например

import my_module

Пакет - это набор модулей в каталогах, которые задают иерархию пакетов.

from my_package.timing.danger.internets import function_of_love

Документация по модулям

Введение в пакеты

Ответ 3

Во-первых, имейте в виду, что по своему точному определению модуль - это объект в памяти интерпретатора Python, часто создаваемый путем чтения одного или нескольких файлов с диска. Хотя мы можем неофициально называть дисковый файл, такой как a/b/c.py "модуль", фактически он таковым не становится, пока не будет объединен с информацией из нескольких других источников (например, sys.path) для создания объекта module.

(Обратите внимание, например, что два модуля с разными именами могут быть загружены из одного файла, в зависимости от sys.path и других настроек. Это именно то, что происходит с python -m my.module за которым следует import my.module в интерпретаторе; будет два объекта модуля, __main__ и my.module, оба созданы из одного файла на диске, my/module.py.)

Пакет - это модуль, который может иметь подмодули (включая подпакеты). Не все модули могут это делать. В качестве примера создайте небольшую иерархию модулей:

$ mkdir -p a/b
$ touch a/b/c.py

Убедитесь, что в a нет других файлов. Запустите интерпретатор Python 3.4 или более поздней версии (например, с python3 -i) и проверьте результаты выполнения следующих инструкций:

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'>

Модули a и a.b являются пакетами (на самом деле, определенный вид пакета называется "пакетом пространства имен", хотя мы не будем беспокоиться об этом здесь). Однако модуль a.b.c не является пакетом. Мы можем продемонстрировать это, добавив еще один файл, a/b.py к приведенной выше структуре каталогов и запустив новый интерпретатор:

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__'

Python гарантирует, что все родительские модули загружаются до загрузки дочернего модуля. Выше он обнаруживает, что a/ это каталог, и таким образом создает пространство имен package a, а это a/b.py исходный файл Python, который он загружает и использует для создания (непакетного) модуля a.b. На данном этапе у вас не может быть модуля, a.b.c потому что a.b это не пакет, и, следовательно, не может быть подмодулей.

Здесь также можно увидеть, что у модуля package a есть __path__ атрибут (пакеты должны иметь это), а у модуля, не связанного с пакетом, a.b его нет.

Ответ 4

Из глоссария Python:


Важно иметь в виду, что все пакеты являются модулями, но не все модули являются пакетами. Или, другими словами, пакеты - это просто особый вид модуля. В частности, любой модуль, содержащий __path__ атрибут, считается пакетом.


Файлы Python с тире в названии, например, my-file.py, не могут быть импортированы с помощью простого import оператора. С точки зрения кода, import my-file это то же самое, что import my - file который вызовет исключение. Такие файлы лучше характеризовать как скрипты, тогда как импортируемые файлы - это модули.

python