web-dev-qa-db-ja.com

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

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

"package"と "module"の違いは何ですか (他の言語の場合)

470
Dave

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

import my_module

パッケージは、パッケージ階層を与えるディレクトリ内のモジュールの集まりです。

from my_package.timing.danger.internets import function_of_love

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

パッケージの紹介

312
Jakob Bowyer

どのPythonファイルも モジュール であり、その名前はファイルの.py拡張子を除いた基本名です。 パッケージ はPythonモジュールの集まりです。モジュールは単一のPythonファイルですが、パッケージは追加の__init__.pyファイルを含むPythonモジュールのディレクトリです。たまたまたくさんのPythonスクリプトが入っているディレクトリとパッケージを区別するため。対応するディレクトリに独自の__init__.pyファイルが含まれている場合、パッケージは任意の深さにネストできます。

モジュールとパッケージの違いは、ファイルシステムレベルでのみ成り立つようです。モジュールまたはパッケージをインポートすると、Pythonによって作成された対応するオブジェクトは常にmodule型になります。ただし、パッケージをインポートすると、そのパッケージの__init__.pyファイル内の変数/関数/クラスのみが直接表示されます。notサブパッケージまたはモジュールは表示されません。例として、Python標準ライブラリのxmlパッケージを考えてみましょう。その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にはCで書かれたsysのような組み込みモジュールもありますが、あなたが質問の中でそれらを考慮するつもりはないと思います。

463

Pythonの用語集から

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

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

28
jolvi

まず、その正確な定義では、モジュールは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'>

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

14
Curt J. Sampson

もう一つの定義、遅い答えです。

パッケージは、自己完結型モジュール、またはサブディレクトリ構造内の一連のモジュールの最上位エンティティとしての__init__.py特殊モジュールのいずれかである可能性があるインポートされた最上位エンティティによって表されます。

したがって、物理的にはパッケージは1つ以上のモジュールを提供する配布単位です。

1
acue