Яка різниця між модулем Python та пакетом Python?
Дивіться також: Яка різниця між "пакунком" та "модулем" (для інших мов)
__init__.py
файл.
from plumbum.cmd import ls
реалізацію
__init__.py
Яка різниця між модулем Python та пакетом Python?
Дивіться також: Яка різниця між "пакунком" та "модулем" (для інших мов)
__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, які вважають це надзвичайно дивовижним.
Пакет - це також модуль, який може містити інші модулі, «прості модулі на основі файлів та пакети (підпакет)». Код, пов'язаний з типом пакету модуля, надходить у __init__.py
файл.
import pack1
print(type(pack1))
тоді як модулі - це простий файл, який може містити функції, класи, код, який можна виконувати, після імпорту модуля він поводиться як об'єкт, за допомогою якого можна отримати доступ до ідентифікаторів, визначених у модулі.