В чем разница между модулем Python и пакетом Python?
Смотрите также: В чем разница между "package" и "module" (для других языков)
__init__.py
файл.
from plumbum.cmd import ls
реализацию
__init__.py
В чем разница между модулем Python и пакетом Python?
Смотрите также: В чем разница между "package" и "module" (для других языков)
__init__.py
файл.
from plumbum.cmd import ls
реализацию
__init__.py
Ответы:
Модуль - это отдельный файл (или файлы), которые импортируются и используются при одном импорте. например
import my_module
Пакет - это набор модулей в каталогах, которые предоставляют иерархию пакетов.
from my_package.timing.danger.internets import function_of_love
__path__
атрибутом.
__init__.py
файл. Это модули, которые могут содержать другие модули.
__path__
атрибутом.
Любой файл 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, но я не думаю, что вы хотели рассмотреть те из них, которые у вас возникли.
module
. Я нахожусь в процессе написания отладчика и беспокоился, что мой отладчик неверно сказал, что мои пакеты были module
s.
import
оператора, поскольку дефисы не допускаются в идентификаторах Python. Используйте importlib.import_module()
вместо этого.
Из глоссария Python :
Важно помнить, что все пакеты являются модулями, но не все модули являются пакетами. Или, другими словами, пакеты - это просто особый вид модуля. В частности, любой модуль, содержащий
__path__
атрибут, считается пакетом.
Файлы Python с тире в имени, например my-file.py
, не могут быть импортированы с помощью простого import
оператора. С точки зрения кода, import my-file
это то же самое, import my - file
что вызовет исключение. Такие файлы лучше охарактеризовать как скрипты, тогда как импортируемые файлы - это модули .
Во-первых, имейте в виду, что в своем точном определении модуль - это объект в памяти интерпретатора Python, который часто создается путем чтения одного или нескольких файлов с диска. Хотя мы можем неофициально называть дисковый файл, такой как a/b/c.py
«модуль», он фактически не становится единым, пока не будет объединен с информацией из нескольких других источников (например, sys.path
) для создания объекта модуля.
(Обратите внимание, например, что два модуля с разными именами могут быть загружены из одного и того же файла, в зависимости от 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/
это каталог, и, таким образом, создает пакет пространства имен a
, и a/b.py
это исходный файл Python, который он загружает и использует для создания (не пакетного) модуля a.b
. На данный момент вы не можете иметь модуль, a.b.c
потому чтоa.b
он не является пакетом и, следовательно, не может иметь подмодулей.
Здесь вы также можете видеть, что у модуля пакета a
есть __path__
атрибут (у пакетов должен быть такой), а у модуля без пакета a.b
его нет.
Поздний ответ, еще одно определение:
Пакет представлен импортированной верхней сущностью, которая может быть либо автономным модулем, либо
__init__.py
специальным модулем в качестве верхней сущности из набора модулей в структуре подкаталога.
Таким образом, физически пакет представляет собой распределительный модуль, который предоставляет один или несколько модулей.
__init__.py
модулем внутри, но если вы говорите о единицах распределения (обычно через PyPI), то это совершенно другой тип пакета (обычно определяемый существованием setup.py
). Я нахожу эти два использования термина package
запутывающими, и я говорил с некоторыми новичками Python, которые находят это совершенно изумительным.