Pythonアプリケーションに最適なプロジェクト構造は何ですか? [閉まっている]
-
08-07-2019 - |
質問
Pythonで重要なエンドユーザーデスクトップ(Webではない)アプリケーションを開発するとします。プロジェクトのフォルダー階層を構成する最良の方法は何ですか?
望ましい機能は、メンテナンスの容易さ、IDEの使いやすさ、ソース管理の分岐/マージの適合性、インストールパッケージの生成の容易さです。
特に:
- ソースはどこに置きますか?
- アプリケーションの起動スクリプトはどこに置きますか
- IDEプロジェクトをどこに置くのですか?
- ユニット/受け入れテストはどこに置きますか?
- 設定ファイルなどの非Pythonデータはどこに置きますか?
- pyd / soバイナリ拡張モジュール用のC ++などのPython以外のソースはどこに置きますか
解決
大した問題ではありません。あなたを幸せにするものは何でも動作します。 Pythonプロジェクトは単純なため、馬鹿げたルールはあまりありません。
-
/scripts
または/bin
その種のコマンドラインインターフェースのもの -
/tests
テスト用 -
/lib
C言語ライブラリの場合 -
/doc
ほとんどのドキュメントの場合 -
/apidoc
Epydocで生成されたAPIドキュメントの場合。
また、最上位ディレクトリには、README、Config、その他を含めることができます。
難しい選択は、/src
ツリーを使用するかどうかです。 Pythonには、JavaやCのような/foo
、/bar
、および/baz
の区別はありません。
トップレベルのquux
ディレクトリは意味のないものと見なされるため、トップレベルのディレクトリをアプリケーションのトップレベルのアーキテクチャにすることができます。
-
/quux
-
PYTHONPATH
-
/path/to/quux/foo
これらすべてを<!> quot; name-of-my-product <!> quot;の下に置くことをお勧めします。ディレクトリ。したがって、QUUX.foo
という名前のアプリケーションを作成している場合、これらすべてを含むディレクトリの名前は<=>です。
別のプロジェクトの<=>には、<=>を含めて<=>モジュールを再利用できます。
私の場合、Komodo Editを使用しているため、IDE cuftは単一の.KPFファイルです。実際にトップレベルの<=>ディレクトリに配置し、SVNへの追加を省略しています。
他のヒント
Jean-Paul Calderoneのファイルシステム構造Pythonプロジェクト:
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
この Jean-Paul Calderoneによるブログ投稿は、Freenodeの#pythonで一般的に回答として提供されます。
Pythonプロジェクトのファイルシステム構造
する:
- プロジェクトに関連するディレクトリに名前を付けます。たとえば、プロジェクトの名前が<!> quot; Twisted <!> quot;である場合、ソースファイルの最上位ディレクトリに
Twisted
という名前を付けます。リリースを行うとき、バージョン番号の接尾辞を含める必要があります:Twisted-2.5
。- ディレクトリを作成
Twisted/bin
して、もしあれば実行可能ファイルをそこに置きます。 Pythonのソースファイルであっても、.py
拡張子を付けないでください。プロジェクトのどこかで定義されたメイン関数のインポートと呼び出し以外のコードをそれらに入れないでください。 (わずかなしわ:Windowsでは、インタープリターはファイル拡張子によって選択されるため、Windowsユーザーは実際には.py拡張子を必要とします。したがって、Windows用にパッケージ化する場合、追加することをお勧めします。 POSIXでは.py拡張子のみがいぼであり、Windowsでは不足が実際のバグであり、ユーザーベースにWindowsユーザーが含まれる場合は、.pyのみを選択することをお勧めします。どこでも拡張できます。)- プロジェクトが単一のPythonソースファイルとして表現できる場合は、ディレクトリに配置して、プロジェクトに関連する名前を付けます。たとえば、
Twisted/twisted.py
。複数のソースファイルが必要な場合は、代わりにパッケージを作成し(Twisted/twisted/
、空のTwisted/twisted/__init__.py
を使用)、ソースファイルをその中に配置します。たとえば、Twisted/twisted/internet.py
。- ユニットテストをパッケージのサブパッケージに入れます(注-これは、上記の単一のPythonソースファイルオプションがトリックであったことを意味します-ユニットには少なくとも1つの他のファイルが必要です常にテスト)。たとえば、
気分が良い場合は、それぞれTwisted/twisted/test/
。もちろん、Twisted/twisted/test/__init__.py
でパッケージにします。Twisted/twisted/test/test_internet.py
などのファイルにテストを配置します。Twisted/README
およびTwisted/setup.py
を追加して、ソフトウェアの説明とインストールを行います。しない:
- ソースを
src
またはlib
というディレクトリに置きます。これにより、インストールせずに実行するのが難しくなります。- Pythonパッケージの外部にテストを置きます。これにより、インストールされたバージョンに対してテストを実行することが難しくなります。
- のみに
__init__.py
を持つパッケージを作成し、すべてのコードを<=>に入れます。パッケージの代わりにモジュールを作成するだけで簡単です。- 魔法のハックを考えて、Pythonがモジュールまたはパッケージをインポートできるように、それを含むディレクトリをインポートパスに追加せずにインポートできるようにします(PYTHONPATHまたはその他のメカニズムを使用)。すべてのケースを 正しく処理せず、ソフトウェアが環境で動作しない場合、ユーザーはあなたに腹を立てます。
その優れた記事のプロジェクトレイアウトの一部を抜粋させてください:
プロジェクトを設定するとき、正しくレイアウトするにはレイアウト(またはディレクトリ構造)が重要です。賢明なレイアウトとは、潜在的な貢献者がコードの一部を探すのに永遠に費やす必要がないことを意味します。ファイルの場所は直感的です。私たちは既存のプロジェクトを扱っているので、おそらく何かを動かす必要があることを意味します。
上から始めましょう。ほとんどのプロジェクトには、多くのトップレベルファイル(setup.py、README.md、requirements.txtなど)があります。すべてのプロジェクトに必要な3つのディレクトリがあります。
- プロジェクトドキュメントを含むドキュメントディレクトリ
- 実際のPythonパッケージを格納するプロジェクトの名前が付けられたディレクトリ
- 2つの場所のいずれかのテストディレクトリ
- テストコードとリソースを含むパッケージディレクトリの下
- スタンドアロンの最上位ディレクトリとして ファイルの編成方法をよりよく理解するために、私のプロジェクトの1つであるsandmanのレイアウトの簡単なスナップショットを次に示します。
$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
| |-- conf.py
| |-- generated
| |-- index.rst
| |-- installation.rst
| |-- modules.rst
| |-- quickstart.rst
| |-- sandman.rst
|- requirements.txt
|- sandman
| |-- __init__.py
| |-- exception.py
| |-- model.py
| |-- sandman.py
| |-- test
| |-- models.py
| |-- test_sandman.py
|- setup.py
ご覧のとおり、トップレベルのファイル、docsディレクトリ(sphinxが生成されたドキュメントを置く空のディレクトリ)、sandmanディレクトリ、sandmanの下のテストディレクトリがあります。
<!> quot; Python Packaging Authority <!> quot;サンプルプロジェクトがあります:
https://github.com/pypa/sampleproject
これは、Pythonパッケージングユーザーガイドのプロジェクトのパッケージ化と配布に関するチュートリアルの補助として存在するサンプルプロジェクトです。
python_boilerplate テンプレートを使用してプロジェクトを開始してください。主にベストプラクティスに従います(例: thoseここ)、ただし、ある時点でプロジェクトを複数のエッグに分割したい場合に適しています(そして、最も単純なプロジェクト以外のもので、私は信じます。一般的な状況の1つは他の人のライブラリのローカルに修正されたバージョンを使用する必要があります)。
-
ソースはどこに置きますか
- まともなプロジェクトの場合、ソースをいくつかの卵に分割するのが理にかなっています。各卵は、
PROJECT_ROOT/src/<egg_name>
。 の下で個別のsetuptools-layoutとして使用されます。
- まともなプロジェクトの場合、ソースをいくつかの卵に分割するのが理にかなっています。各卵は、
-
アプリケーションの起動スクリプトはどこに置きますか?
- 理想的なオプションは、アプリケーション起動スクリプトを卵の1つに
entry_point
として登録することです。
- 理想的なオプションは、アプリケーション起動スクリプトを卵の1つに
-
IDEプロジェクトをどこに置くのですか?
- IDEに依存します。彼らの多くは、プロジェクトのルートにある
PROJECT_ROOT/.<something>
に自分のものを保管しています。これは問題ありません。
- IDEに依存します。彼らの多くは、プロジェクトのルートにある
-
ユニット/受け入れテストはどこに置きますか?
- 各eggには個別のテストセットがあり、
PROJECT_ROOT/src/<egg_name>/tests
ディレクトリに保持されます。個人的にはpy.test
を使用して実行することを好みます。
- 各eggには個別のテストセットがあり、
-
設定ファイルなどのPython以外のデータはどこに置きますか?
- それは依存します。 Python以外のデータにはさまざまなタイプがあります。
- <!> quot; Resources <!> quot; 、つまり、卵内にパッケージ化する必要があるデータ。このデータは、パッケージ名前空間内の対応するeggディレクトリに格納されます。
pkg_resources
パッケージ経由で使用できます。 - <!> quot; Config-files <!> quot; 、つまりプロジェクトソースファイルの外部と見なされるが、いくつかの値で初期化する必要がある非Pythonファイルアプリケーションが実行を開始したとき。開発中は、このようなファイルを
PROJECT_ROOT/config
に保存することを好みます。展開にはさまざまなオプションがあります。 Windowsでは%APP_DATA%/<app-name>/config
、Linuxでは/etc/<app-name>
または/opt/<app-name>/config
を使用できます。 - 生成されたファイル、つまり、実行中にアプリケーションによって作成または変更される可能性のあるファイル。開発中は
PROJECT_ROOT/var
に、Linux展開中は/var
の下に置いておきたいと思います。
- <!> quot; Resources <!> quot; 、つまり、卵内にパッケージ化する必要があるデータ。このデータは、パッケージ名前空間内の対応するeggディレクトリに格納されます。
- それは依存します。 Python以外のデータにはさまざまなタイプがあります。
- pyd / soバイナリ拡張モジュール用のC ++などのPython以外のソースはどこに置きますか
- Into
PROJECT_ROOT/src/<egg_name>/native
- Into
ドキュメントは通常PROJECT_ROOT/doc
またはPROJECT_ROOT/src/<egg_name>/doc
に入ります(これは、卵の一部を別の大きなプロジェクトとみなすかどうかによって異なります)。いくつかの追加構成は、PROJECT_ROOT/buildout.cfg
やPROJECT_ROOT/setup.cfg
などのファイルにあります。
私の経験では、繰り返しの問題です。データとコードをどこにでも配置できます。とにかく間違っているでしょう。しかし、物事がどのように形作られるかについてのより良いアイデアを得ると、あなたはこれらの種類の推測をするためにより良い位置にいます。
拡張ソースに関しては、pythonのディレクトリと他のさまざまな言語のディレクトリを含むCodeディレクトリがtrunkの下にあります。個人的には、次回は拡張コードを独自のリポジトリに入れてみる傾向があります。
それで、私は最初のポイントに戻ります:それからあまりにも大きな取引をしないでください。あなたのために働くように見えるどこかにそれを置きます。動作しないものを見つけた場合、変更することができます(変更する必要があります)。
非Pythonデータは、 setuptools package_dataサポートを使用して、Pythonモジュール内に最適にバンドルされます。 >。私が強くお勧めすることの1つは、名前空間パッケージを使用して、複数のプロジェクトが使用できる共有名前空間を作成することです。これは、com.yourcompany.yourproject
にパッケージを置く(および共有com.yourcompany.utils
名前空間を持つことができる)Javaの規則によく似ています。
ブランチとマージを再実行します。十分なソース管理システムを使用している場合は、名前の変更でもマージを処理します。 Bazaar は特にこの点で優れています。
ここでの他のいくつかの答えとは反対に、トップレベルのsrc
ディレクトリ(doc
およびtest
ディレクトリと一緒に)を持っていることに+1です。ドキュメントディレクトリツリーの特定の規則は、使用しているものによって異なります。たとえば、 Sphinx には、クイックスタートツールがサポートする独自の規則があります。
どうか、setuptoolsとpkg_resourcesを活用してください。これにより、他のプロジェクトがコードの特定のバージョンに依存しやすくなります(<=>を使用している場合、複数のバージョンが異なる非コードファイルと同時にインストールされるようになります)。