PythonモジュールとPythonパッケージの違いは何ですか?


576

PythonモジュールとPythonパッケージの違いは何ですか?

参照:「パッケージ」と「モジュール」の違いは何ですか(他の言語の場合)


9
私は間違っているかもしれませんが、私にとっては:モジュールは基本的に1つのpythonファイルです。パッケージは、一連のモジュール(Pythonファイル)を含むフォルダーです。
lc2817 2011年

36
パッケージと見なされるには、そのフォルダーに__init__.pyファイルが含まれている必要があります。
Giulio Piancastelli、2011年

@ lc2817:最も一般的なケースですが、ファイルシステムからモジュールをロードする必要はありません。たとえば、実装を参照してくださいfrom plumbum.cmd import ls
jfs

4
@GiulioPiancastelli:でのPython 3.3+、名前空間のパッケージが使用していない__init__.py
JFS

コミュニティは、Pythonパッケージと、PyPI / wheelsなどのPythonコンポーネントの配布に使用されるパッケージをどのように区別していますか?この2つは、「パッケージ」という言葉の私への異なる適用のように見えます。
davidA

回答:


372

モジュールは、1回のインポートでインポートされて使用される単一のファイルです。例えば

import my_module

パッケージは、パッケージ階層を提供するディレクトリ内のモジュールのコレクションです。

from my_package.timing.danger.internets import function_of_love

モジュールのドキュメント

パッケージの紹介


54
「モジュールは単一のインポートでインポートされる単一のファイル(または複数のファイル)です」と言うとき、モジュールが複数のファイルである状況を説明できますか?または私はあなたが何を意味するのかを誤解していますか?
ユーザー

6
モジュールを作成するためにファイルは必要ありません。たとえば、zipファイルからモジュールをインポートできます。パッケージについても同じです。Pythonのモジュール/パッケージのクラスは1つだけです。パッケージは、__path__属性を持つモジュールにすぎません。
jfs

33
パッケージもモジュールです。それらは異なる方法でパッケージ化されています。それらは、ディレクトリと__init__.pyファイルの組み合わせによって形成されます。それらは他のモジュールを含むことができるモジュールです。
Martijn Pieters

15
@Jacquot確かに、リファレンスドキュメントのインポートシステムを参照してください。すべてのパッケージはモジュールであることを覚えておくことが重要です。
Martijn Pieters

6
@Jacquot:および「パッケージ」の用語集サブモジュールまたは再帰的にサブパッケージを含めることができるPythonモジュール。技術的には、パッケージは__path__属性を持つPythonモジュールです。
Martijn Pieters

556

Pythonファイルはすべてモジュールであり、その名前は.py拡張子なしのファイルのベース名です。パッケージには、 Pythonモジュールのコレクションです:モジュールは、単一のPythonのファイルがある一方で、パッケージが追加含むPythonモジュールのディレクトリである__init__.pyだけでPythonスクリプトの束を含むように起こるのディレクトリからパッケージを区別するために、ファイルを。対応するディレクトリに独自のパッケージが含まれている場合、パッケージは任意の深さにネストできます__init__.pyファイルます。

モジュールとパッケージの違いは、ファイルシステムレベルでのみ保持されているようです。モジュールまたはパッケージをインポートする場合、Pythonによって作成された対応するオブジェクトは常にタイプmoduleです。ただし、パッケージをインポートすると__init__.py、そのパッケージのファイル内の変数/関数/クラスのみが直接表示され、サブパッケージやモジュール表示されないことに注意してください。例として、xmlPython標準ライブラリのパッケージを考えます。そのxmlディレクトリには__init__.pyファイルと4つのサブディレクトリが含まれています。サブディレクトリ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などで作成されたなどの組み込みモジュールもありますが、質問でそれらを考慮するつもりはないと思います。


9
Pythonによって作成された対応するオブジェクトは常にタイプであると明示的に言及していただきありがとうございますmodule。私はデバッガを書いている最中ですが、自分のパッケージがmodules であると私のデバッガが間違っていると心配していました。
ArtOfWarfare 2015

8
ダッシュを含むファイル名を含む@jolvi Pythonファイルは、importPython識別子ではダッシュを使用できないため、通常のステートメントではなく、モジュールとしてインポートできます。importlib.import_module()代わりに使用してください。
ジュリオピアンカステッリ

2
@jolvi私は違います。私のコメントのどこを読んでいますか?名前にダッシュが含まれているPythonファイルを見つけた、または偶然見つけた場合でも、モジュールとしてインポートできます。私は、Pythonファイルに名前を付ける好ましい方法については述べていません。私はあなたがそれをどこか他の場所で見つけることができると確信しています:アンダースコアのためにダッシュを避けることは通常強く推奨されます。
Giulio Piancastelli、2016年

3
Pythonの初心者であるため、親パッケージをインポートするときにサブパッケージまたはモジュールがデフォルトで使用できないため、困惑しました。特別な理由はありますか?親パッケージをインポートするときにサブパッケージまたはモジュールを(完全修飾名を介して)利用できるようにする一般的なパターンはありますか?
sschuberth 2017年

2
@sschuberth 親パッケージのinit .pyにサブパッケージをインポートするだけです。
アンナ

33

Python用語集から:

すべてのパッケージがモジュールであることを覚えておくことが重要ですが、すべてのモジュールがパッケージであるとは限りません。言い換えれば、パッケージは特別な種類のモジュールにすぎません。具体的には、__path__属性を含むモジュールはパッケージと見なされます。

のようmy-file.pyに名前にダッシュが含まれるPythonファイルは、単純なimportステートメントではインポートできません。コード的にimport my-fileimport my - file、例外が発生するのと同じです。そのようなファイルはスクリプトとしてよりよく特徴付けられますが、インポート可能なファイルはモジュールです。


23

まず、正確な定義では、モジュールはPythonインタープリターのメモリー内のオブジェクトであり、ディスクから1つ以上のファイルを読み取ることによって作成されることが多いことに注意してください。非公式にa/b/c.py「モジュール」などのディスクファイルを呼び出すこともありsys.pathますが、モジュールオブジェクトを作成するために他のいくつかのソース(など)からの情報と組み合わせるまで、実際には1つにはなりません。

(たとえば、sys.path他の設定に応じて、異なる名前の2つのモジュールを同じファイルからロードできることに注意してください。これは、インタープリター内のがpython -m my.module後に続くものとまったく同じimport my.moduleです。2つのモジュールオブジェクト__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'>

モジュールaa.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はないこともわかります。


1
まだ行っていない場合は、戻ってこの回答の例を確認してください。
Donal Lafferty、

2

遅い答え、さらに別の定義:

パッケージは、インポートされたトップエンティティによって表されます。これは、自己完結型モジュールか、__init__.pyサブディレクトリ構造内のモジュールセットからのトップエンティティとしての特別なモジュールのいずれかです。

したがって、物理的にはパッケージは配布ユニットであり、1つ以上のモジュールを提供します。


1
Pythonのパッケージには2つの定義があり、それらは異なると感じます。あなたの答えはそれらを一緒に組み合わせるようです。厳密に言うと、pythonパッケージは__init__.py内部にモジュールがあるディレクトリですが、(通常PyPIを介して)ディストリビューションユニットについて話す場合、これは完全に別のタイプのパッケージです(通常はの存在によって定義されsetup.pyます)。私はこの2つの用語の使い方がわかりpackageにくいので、Pythonの初心者がまったく困惑していると話しました。
davidA

@davidA、それはあなたの気持ちだけではありません。それは成文化されました:packages.python.org/glossary/#term-distribution-package(明確にしてくれてありがとう!)
Lorem Ipsum

-1

パッケージは、他のモジュール、「単純なファイルベースのモジュール、およびパッケージ(サブパッケージ)」を含むことができるモジュールでもあります。モジュールのパッケージタイプに関連するコードは、__init__.pyファイルます。

import pack1
print(type(pack1))

モジュールは、関数、クラス、実行可能コードなどを含むことができる単純なファイルですが、モジュールをインポートした後は、モジュールで定義された識別子にアクセスできるオブジェクトのように動作します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.