Apa perbedaan antara modul Python dan paket Python?

577

Apa perbedaan antara modul Python dan paket Python?

Lihat juga: Apa perbedaan antara "paket" dan "modul" (untuk bahasa lain)

Dave
sumber
9
Saya mungkin salah tetapi bagi saya: modul pada dasarnya adalah satu file python. Paket adalah folder dengan banyak modul (file python).
lc2817
36
Untuk dianggap sebagai paket, folder itu harus berisi __init__.pyfile.
Giulio Piancastelli
@ lc2817: ini adalah kasus yang paling umum tetapi modul tidak perlu dimuat dari sistem file misalnya, lihat from plumbum.cmd import lsimplementasi
jfs
4
@GiulioPiancastelli: Dalam Python 3.3+, paket namespace tidak digunakan__init__.py
jfs
Bagaimana komunitas membedakan antara paket Python, dan paket yang digunakan untuk mendistribusikan komponen Python seperti PyPI / wheels / etc? Keduanya tampak seperti aplikasi yang berbeda dari kata "paket" bagi saya.
davidA

Jawaban:

372

Modul adalah file tunggal (atau file) yang diimpor dengan satu impor dan digunakan. misalnya

import my_module

Paket adalah kumpulan modul dalam direktori yang memberikan hierarki paket.

from my_package.timing.danger.internets import function_of_love

Dokumentasi untuk modul

Pengantar paket

Jakob Bowyer
sumber
54
Ketika Anda mengatakan: "Modul adalah file tunggal (atau file) yang diimpor dengan satu impor" dapatkah Anda menjelaskan situasi di mana modul lebih dari satu file? Atau apakah saya salah membaca maksud Anda?
Pengguna
6
Anda tidak perlu file untuk membuat modul misalnya, Anda bisa mengimpor modul dari file zip. Sama untuk paket. Hanya ada satu kelas untuk modul / paket dengan Python. Paket hanyalah modul dengan __path__atribut.
jfs
33
Paket juga merupakan modul . Mereka hanya dikemas secara berbeda; mereka dibentuk oleh kombinasi dari direktori plus __init__.pyfile. Mereka adalah modul yang dapat berisi modul lain.
Martijn Pieters
15
@ Jacquot yakin, lihat Sistem impor dalam dokumentasi referensi: Penting untuk diingat bahwa semua paket adalah modul .
Martijn Pieters
6
@ Jacquot: dan glosarium pada "paket" : Modul Python yang dapat berisi submodula atau secara rekursif, subpackage. Secara teknis, sebuah paket adalah modul Python dengan __path__atribut.
Martijn Pieters
556

File Python adalah modul , namanya menjadi nama dasar file tanpa .pyekstensi. Sebuah paket adalah kumpulan dari modul Python: sementara modul adalah file Python tunggal, sebuah paket adalah direktori modul Python yang berisi tambahan __init__.pyfile, untuk membedakan sebuah paket dari sebuah direktori yang kebetulan mengandung banyak skrip Python. Paket dapat disarangkan ke kedalaman apa saja, asalkan direktori terkait berisi __init__.pyfile mereka sendiri .

Perbedaan antara modul dan paket tampaknya hanya pada tingkat sistem file. Saat Anda mengimpor modul atau paket, objek terkait yang dibuat oleh Python selalu bertipe module. Catatan, bagaimanapun, ketika Anda mengimpor paket, hanya variabel / fungsi / kelas dalam __init__.pyfile paket yang langsung terlihat, bukan sub-paket atau modul. Sebagai contoh, pertimbangkan xmlpaket di pustaka standar Python: xmldirektori -nya berisi __init__.pyfile dan empat sub-direktori; sub-direktori etreeberisi __init__.pyfile dan, antara lain, ElementTree.pyfile. Lihat apa yang terjadi ketika Anda mencoba mengimpor paket / modul secara interaktif:

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

Dalam Python ada juga modul built-in, seperti sys, yang ditulis dalam C, tapi saya tidak berpikir Anda bermaksud mempertimbangkan mereka dalam pertanyaan Anda.

Giulio Piancastelli
sumber
9
Terima kasih karena secara eksplisit menyebutkan bahwa objek terkait yang dibuat oleh Python selalu bertipe module. Saya sedang dalam proses menulis debugger dan khawatir bahwa debugger saya salah dalam mengatakan bahwa paket saya adalah modules.
ArtOfWarfare
8
@jolvi file Python dengan nama file yang mengandung tanda hubung masih dapat diimpor sebagai modul, hanya saja tidak dengan importpernyataan biasa , karena tanda hubung tidak diperbolehkan dalam pengidentifikasi Python. Gunakan importlib.import_module()sebagai gantinya.
Giulio Piancastelli
2
@ jolvi saya tidak. Di mana dalam komentar saya, Anda membacanya? Saya hanya mengatakan bahwa, jika Anda memiliki atau menemukan file Python dengan tanda hubung dalam namanya, Anda masih dapat mengimpornya sebagai modul. Saya tidak membuat pernyataan tentang cara yang disukai untuk penamaan file Python. Saya yakin Anda dapat menemukannya di tempat lain: biasanya sangat disarankan untuk menghindari tanda hubung yang mendukung garis bawah.
Giulio Piancastelli
3
Menjadi baru untuk Python, sub-paket atau modul tidak tersedia secara default ketika mengimpor paket induk adalah apa yang membuat saya tersandung. Apakah ada alasan khusus untuk itu? Dan apakah ada pola umum bagaimana membuat sub-paket atau modul (melalui nama yang sepenuhnya memenuhi syarat) saat mengimpor paket induk?
sschuberth
2
@sschuberth Cukup impor sub-paket di init .py dari paket induk.
Anna
33

Dari daftar istilah Python :

Penting untuk diingat bahwa semua paket adalah modul, tetapi tidak semua modul adalah paket. Atau dengan kata lain, paket hanyalah jenis modul khusus. Khususnya, modul apa pun yang berisi __path__atribut dianggap sebagai paket.

File Python dengan tanda hubung dalam nama, seperti my-file.py, tidak dapat diimpor dengan importpernyataan sederhana . Dari sisi kode, import my-filesama dengan import my - fileyang akan memunculkan eksepsi. File-file seperti itu lebih baik ditandai sebagai skrip sedangkan file yang dapat diimpor adalah modul .

Jolvi
sumber
23

Pertama, perlu diingat bahwa, dalam definisi yang tepat, modul adalah objek dalam memori juru bahasa Python, sering dibuat dengan membaca satu atau lebih file dari disk. Meskipun kami secara informal dapat memanggil file disk seperti a/b/c.py"modul," itu tidak benar-benar menjadi satu sampai dikombinasikan dengan informasi dari beberapa sumber lain (seperti sys.path) untuk membuat objek modul.

(Perhatikan, misalnya, bahwa dua modul dengan nama berbeda dapat diambil dari file yang sama, tergantung pada sys.pathdan pengaturan lainnya. Inilah yang terjadi dengan python -m my.modulediikuti oleh import my.modulepenerjemah; akan ada dua objek modul, __main__dan my.module, keduanya dibuat dari file yang sama pada disk my/module.py,.)

Sebuah paket adalah modul yang mungkin memiliki submodul (termasuk subpackages). Tidak semua modul dapat melakukan ini. Sebagai contoh, buat hierarki modul kecil:

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

Pastikan tidak ada file lain di bawah a. Mulai juru bahasa Python 3.4 atau yang lebih baru (mis. Dengan python3 -i) dan periksa hasil dari pernyataan berikut:

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

Modul adan a.bpaket (pada kenyataannya, jenis paket tertentu disebut "paket namespace," meskipun kami tidak khawatir tentang itu di sini). Namun, modul a.b.cbukan paket. Kami dapat menunjukkan ini dengan menambahkan file lain, a/b.pyke struktur direktori di atas dan memulai juru bahasa baru:

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 memastikan bahwa semua modul induk dimuat sebelum modul anak dimuat. Di atasnya ditemukan bahwa itu a/adalah direktori, dan menciptakan paket namespace a, dan itu a/b.pyadalah file sumber Python yang dimuat dan digunakan untuk membuat modul (non-paket) a.b. Pada titik ini Anda tidak dapat memiliki modul a.b.ckarena a.bbukan paket, dan dengan demikian tidak dapat memiliki submodula.

Anda juga dapat melihat di sini bahwa modul paket amemiliki __path__atribut (paket harus memiliki ini) tetapi modul non-paket a.btidak.

cjs
sumber
1
Jika Anda belum melakukannya, kembalilah dan telusuri contoh-contoh dalam jawaban ini.
Donal Lafferty
2

Jawaban yang terlambat, definisi lain:

Paket diwakili oleh entitas teratas yang diimpor yang bisa berupa modul mandiri, atau __init__.pymodul khusus sebagai entitas teratas dari satu set modul dalam struktur sub direktori.

Jadi secara fisik paket adalah unit distribusi, yang menyediakan satu atau lebih modul.

acue
sumber
1
Saya merasa bahwa ada dua definisi untuk paket dalam Python dan mereka berbeda. Jawaban Anda sepertinya menggabungkan keduanya. Sebenarnya, paket python adalah direktori dengan __init__.pymodul di dalamnya, namun jika Anda berbicara tentang unit distribusi (umumnya melalui PyPI) maka ini adalah jenis paket lain seluruhnya (biasanya ditentukan oleh keberadaan setup.py). Saya menemukan dua penggunaan istilah ini packagemembingungkan, dan saya telah berbicara dengan beberapa pemula Python yang merasa sangat membingungkan.
davidA
@davidA, Ini bukan hanya bagaimana perasaan Anda. Sudah dikodifikasikan: packaging.python.org/glossary/#term-distribution-package (Terima kasih telah menjelaskan juga!)
Lorem Ipsum