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

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

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

11 ответов

Решение

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

import my_module

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

from my_package.timing.danger.internets import function_of_love

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

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

Любой файл 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, но я не думаю, что вы хотели бы рассмотреть те, что в вашем вопросе.

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

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

$ 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 не.

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

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

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

Другие ответы здесь могут быть немного расплывчатыми, поэтому я публикую, надеюсь, более четкий ответ. Важно отметить, что заголовок вопроса также немного вводит в заблуждение, и, на мой взгляд, лучшим названием было бы: « Что особенного в пакетных модулях по сравнению с обычными модулями? » .

TL;DR — краткий ответ:

Пакеты тоже являются модулями, однако они являются их особым типом. Специальные в том смысле, что 1. они являются «каталогами» и 2. могут содержать специальные файлы, такие как и .

Чтобы лучше понять - более длинный ответ:

Дело в том, что пакеты — это особый тип модулей , поэтому сначала нам нужно понять модули в целом , а затем станет понятно, что особенного в модулях пакетов. (Примечание: иногда я буду называть «пакетные модули» в этом ответе просто «пакетами» и наоборот)

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

Импорт модуля имеет единственную очевидную цель — получить доступ к тому, что находится внутри этого модуля.

Однако выполнение модуля обычно преследует одну из этих двух целей:

  1. Этот модуль является основным модулем, и его выполнение запустит нашу программу (или одну из ее подпрограмм).
  2. Мы хотим попробовать функциональные возможности этого модуля изолированно, т. е. без необходимости его предварительного импорта.

Давайте лучше разберемся во всем этом на нескольких примерах:

Импорт модулей:

      # bar.py

def talk():
    print("bar")
      # foo.py

import bar # <-- importing module "bar"

bar.talk() # <-- prints "bar"

Выполнение модулей

Цель 1, выполнение модуля как основного модуля:

Предположим, что модуль в приведенном выше примере является основным модулем, который запускает нашу программу. Мы можем запустить его, набрав эту команду в терминале: и тогда он запустит нашу программу.

Цель 2, попробовать функции модуля в отдельности:

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

      # bar.py

def talk():
    print("bar")

if __name__ == '__main__':
    talk()

Теперь запустите эту команду в терминале: а потом напечатает .

Теперь, когда мы знаем, что вообще можно делать с модулями, вернемся к основному вопросу:

Что особенного в пакетных модулях по сравнению с обычными модулями?

1. Обычные модули в Python — это просто «файлы», однако модули пакетов — это «каталоги».

2. Обычные модули можно "импортировать" и можно "выполнить" (как показано в примерах выше), пакетные модули ТАКЖЕ можно "импортировать" и можно "выполнить", ОДНАКО, вы можете справедливо пожаловаться: " но мы можем Не пишите код напрямую в каталоги! Код записывается только в файлы!" , и это действительно очень хорошая жалоба, так как она приводит нас ко второму особенному моменту, касающемуся модулей пакетов. Код модуля пакета записывается в файлы внутри его каталога , и имена этих файлов также зарезервированы Python. Если вы хотите «импортировать» модуль пакета, вам нужно поместить его код в файл в своем каталоге, и если вы хотите «выполнить» модуль пакета, вам придется поместить его код выполнения в файл в своем каталоге.

И вот последний пример объяснения выше:

      # hierarchy of files and folders:
.
├── bar_pack/
│   ├── __init__.py
│   ├── __main__.py
│   foo.py
      # bar_pack/__init__.py

def talk():
    print("bar")
      # bar_pack/__main__.py

import __init__

__init__.talk()
      # foo.py

import bar_pack # <-- importing package module "bar_pack"

bar_pack.talk() # <-- prints "bar"
      # Run this command in the terminal:
python3 bar_pack # <-- executing the package module "bar_pack", prints "bar"

Поздний ответ, еще одно определение:

Пакет представлен импортированной верхней сущностью, которая может быть либо автономным модулем, либо __init__.py специальный модуль как верхний объект из набора модулей в структуре подкаталога.

Таким образом, физически пакет представляет собой распределительный модуль, который предоставляет один или несколько модулей.

Модуль: модуль представляет собой простой файл Python с ( .py), которое содержит наборы функций и глобальных переменных. Это исполняемый файл, и понятие пакета в Python используется для организации всех модулей.

Например: Сохраните код в файле с именем demo ( module.py).

      def myModule1(name):
    print("My Module name is: "+ name)

Импортируйте модуль демонстрационного модуля и используйте в нем функцию myModule1.

      import demo_module
  
demo_module.myModule1("Math")

Решение:

Имя моего модуля: Математика

Пакет: Пакет — это базовый каталог, содержащий набор модулей. Этот каталог содержит модули Python, а также ( __init .py__), который интерпретатор использует для распознавания его как пакета. Пакет — это не что иное, как пространство имен. Внутри пакета есть подпакеты.

Для примера:

Студент (Пакет)

| __init__.py(Конструктор)

| details.py(Модуль)

| marks.py(Модуль)

| collegeDetails.py(Модуль)

| demo_module.py(Модуль)

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

      from Student import details, collegeDetails, demo_module

Я читал разные ответы на этот вопрос. Вопрос раскрыт полностью. Но мне кажется, что поставить лишнюю точку может быть и не плохой идеей. Если мы рассмотрим значение __package__ для разных модулей, то получим следующий результат. Все они являются типами модулей, но для некоторых из них пакет не определен. Проверьте __package__ на " random " и " math ".

      import cv2
import math
import random
import tkinter as tk

print('cv2:',type(cv2))             # <class 'module'>
print('cv2:',cv2)                   # <module 'cv2.cv2' from 'PATH'>
print('cv2:',cv2.__package__)       # cv2

print('random:',type(random))       # <class 'module'>
print('random:',random)             # <module 'random' from 'PATH'>
print('random:',random.__package__) # [EMPTY]

print('tk:',type(tk))               # <class 'module'>
print('tk:',tk)                     # <module 'tkinter' from 'PATH'>
print('tk:',tk.__package__)         # tkinter

print('math:',type(math))           # <class 'module'>
print('math:',math)                 # <module 'math' (built-in)>
print('math:',math.__package__)     # [EMPTY]

Итак, если мы определим папку следующим образом:

Вот как мы можем увидеть вывод __package__ :

      import myfolder
import myfolder.script1 as s1
import myfolder.script2 as s2
import myfolder.mySubfolder.script3 as s3

print(type(s1)) # <class 'module'>
print(type(s2)) # <class 'module'>
print(type(s3)) # <class 'module'>

print(s1.__package__) # myfolder
print(s2.__package__) # myfolder
print(s3.__package__) # myfolder.mySubfolder

print(myfolder)                     # <module 'myfolder' (namespace)>
print(myfolder.mySubfolder)         # <module 'myfolder.mySubfolder' (namespace)>
print(myfolder.mySubfolder.script3) # <module 'myfolder.mySubfolder.script3' from 'PATH'>

print(myfolder.__package__)                     # myfolder        
print(myfolder.mySubfolder.__package__)         # myfolder.mySubfolder
print(myfolder.mySubfolder.script3.__package__) # myfolder.mySubfolder

Просто скажем ниже о том, что говорится в документе в и :

  • Модуль — это файл или пакет (папка).

  • Пакет — это модуль, который может иметь несколько модулей (файлов и пакетов (папок)).

И вот что на самом деле говорит документ ниже в модулемодуле :

  • Объект, служащий организационной единицей кода Python. Модули имеют пространство имен, содержащее произвольные объекты Python. Модули загружаются в Python в процессе импорта.

И вот что на самом деле говорит документ ниже в пакетепакете :

  • Модуль Python, который может содержать подмодули или рекурсивно подпакеты. Технически пакет представляет собой модуль Python с атрибутом пути .

Наконец, вы можете увидеть мой ответ , объясняющий, как создавать модули (файлы и пакеты), и вы можете увидеть мой ответ , объясняющий, как создать, загрузить и установить пакет для TestPyPI и PyPI .

Я знаю, уже слишком поздно, но простой ответ, которого для некоторых будет достаточно:

модуль - это файл,

пакет - это папка.

Итак, вы вспоминаете свои учебники, где на странице контента главы были разделены на модули. Таким образом, в основе концепции лежат разные главы, которые имеют одну и ту же цель или часть одной и той же теории, тогда как эти части объединены в группы и известны как модуль. Точно так же в программировании, когда различные функции сгруппированы вместе, они разделяются и называются модулем.

Другие вопросы по тегам