Imaginez que vous souhaitiez développer une application de bureau (non Web) non-triviale pour l'utilisateur final en Python. Quel est le meilleur moyen de structurer la hiérarchie de dossiers du projet?
Les fonctionnalités souhaitables sont la facilité de maintenance, la convivialité IDE, l’adéquation de la fusion/contrôle de contrôle de source et la génération facile de packages d’installation.
En particulier:
Peu importe trop. Tout ce qui vous rend heureux fonctionnera. Il n'y a pas beaucoup de règles stupides parce que Python projets peuvent être simples.
/scripts
ou /bin
pour ce type d'interface de ligne de commande/tests
pour vos tests/lib
pour vos bibliothèques en langage C/doc
pour la plupart de la documentation/apidoc
pour la documentation de l'API générée par Epydoc.Et le répertoire de niveau supérieur peut contenir les fichiers README, Config et autres.
Le choix difficile consiste à utiliser ou non un arbre /src
. Python n'a pas de distinction entre /src
, /lib
et /bin
comme Java ou C.
Etant donné qu'un répertoire /src
de niveau supérieur est considéré comme dépourvu de sens, votre répertoire de niveau supérieur peut être l'architecture de niveau supérieur de votre application.
/foo
/bar
/baz
Je recommande de mettre tout cela dans le répertoire "nom-de-mon-produit". Donc, si vous écrivez une application nommée quux
, le répertoire qui contient tout ce contenu est nommé /quux
.
Un autre projet PYTHONPATH
peut alors inclure /path/to/quux/foo
pour réutiliser le module QUUX.foo
.
Dans mon cas, depuis que j'utilise Komodo Edit, mon IDE cuft est un fichier .KPF unique. En fait, je mets cela dans le répertoire /quux
de niveau supérieur et omet de l'ajouter à SVN.
Selon Jean-Paul Calderone Structure de système de fichiers d'un projet Python :
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
This article de blog de Jean-Paul Calderone est généralement donné comme réponse en #python sur Freenode.
Structure de système de fichiers d'un projet Python
Faire:
- nommez le répertoire quelque chose en rapport avec votre projet. Par exemple, si votre projet s'appelle "Twisted", nommez le répertoire de niveau supérieur pour ses fichiers source
Twisted
. Lorsque vous publiez des versions, vous devez inclure un suffixe de numéro de version:Twisted-2.5
.- créez un répertoire
Twisted/bin
et placez-y vos fichiers exécutables, le cas échéant. Ne leur donnez pas l'extension.py
, même s'il s'agit de fichiers source Python. Ne mettez aucun code dedans sauf une importation et un appel à une fonction principale définie quelque part ailleurs dans vos projets. (Légère erreur: étant donné que, dans Windows, l'interpréteur est sélectionné par l'extension de fichier, vos utilisateurs Windows veulent en fait l'extension .py. Ainsi, lorsque vous compilez pour Windows, vous souhaiterez peut-être l'ajouter. Malheureusement, il n'y a pas de solution facile pour distutils qui Je sais que pour automatiser ce processus. Considérant que sur POSIX, l’extension .py n’est qu’une verrue, alors que sous Windows le manque est un bogue réel, si votre base utilisateur inclut des utilisateurs Windows, vous voudrez peut-être opter pour le .py extension partout.)- Si votre projet peut être exprimé en tant que fichier source unique Python, placez-le dans le répertoire et nommez-le en relation avec votre projet. Par exemple,
Twisted/twisted.py
. Si vous avez besoin de plusieurs fichiers source, créez un package à la place (Twisted/twisted/
, avec unTwisted/twisted/__init__.py
vide) et placez-y vos fichiers source. Par exemple,Twisted/twisted/internet.py
.- placez vos tests unitaires dans un sous-package de votre package (remarque - cela signifie que la seule option de fichier source Python ci-dessus était une astuce - vous toujours nécessite au moins un autre fichier pour vos tests unitaires). Par exemple,
Twisted/twisted/test/
. Bien sûr, faites-en un paquet avecTwisted/twisted/test/__init__.py
. Placez les tests dans des fichiers tels queTwisted/twisted/test/test_internet.py
.- ajoutez
Twisted/README
etTwisted/setup.py
pour expliquer et installer votre logiciel, respectivement, si vous vous sentez bien.Ne pas:
- placez votre source dans un répertoire appelé
src
oulib
. Cela rend difficile l'exécution sans installation.- placez vos tests en dehors de votre package Python. Cela rend difficile l'exécution des tests sur une version installée.
- créez un package qui uniquement a un
__init__.py
, puis placez tout votre code dans__init__.py
. Créez simplement un module au lieu d’un package, c’est plus simple.- essayez de créer des hacks magiques pour permettre à Python d'importer votre module ou package sans que l'utilisateur ajoute le répertoire le contenant à son chemin d'importation (via PYTHONPATH ou un autre mécanisme). vous ne gérerez pas correctement tous les cas et les utilisateurs se mettront en colère contre vous lorsque votre logiciel ne fonctionnera pas dans leur environnement.
Départ Ouvrir la recherche d'un Python Project the Right Way .
Permettez-moi d'extraire la partie de la mise en page du projet de cet excellent article:
Lors de la configuration d'un projet, il est important que la disposition (ou la structure de répertoires) soit correcte. Une disposition judicieuse signifie que les contributeurs potentiels n'ont pas à dépenser pour toujours pour un morceau de code; les emplacements de fichiers sont intuitifs. Comme nous traitons d'un projet existant, cela signifie que vous devrez probablement déplacer certaines choses.
Commençons par le haut. La plupart des projets contiennent un certain nombre de fichiers de niveau supérieur (tels que setup.py, README.md, Requirements.txt, etc.). Il y a ensuite trois répertoires que chaque projet devrait avoir:
- Un répertoire de documentation contenant la documentation du projet
- Un répertoire nommé avec le nom du projet qui stocke le package Python actuel
- Un répertoire de test à l’un des deux endroits
- Sous le répertoire du paquet contenant le code de test et les ressources
- En tant que répertoire de niveau supérieur autonome Pour avoir une meilleure idée de la manière dont vos fichiers doivent être organisés, voici un instantané simplifié de la mise en page de l'un de mes projets, 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
Comme vous pouvez le constater, il existe des fichiers de niveau supérieur, un répertoire docs (généré est un répertoire vide dans lequel sphinx mettra la documentation générée), un répertoire sandman et un répertoire de test sous sandman.
"Python Packaging Authority" a un exemple de projet:
https://github.com/pypa/sampleproject
Il s'agit d'un exemple de projet destiné à faciliter le didacticiel sur le packaging et la distribution de projets du Python Packaging Guide de l'utilisateur.
Essayez de démarrer le projet en utilisant le modèle python_boilerplate . Il suit en grande partie les meilleures pratiques (par exemple celles-ci ), mais convient mieux si vous êtes prêt à scinder votre projet en plusieurs œufs à un moment donné (et croyez-moi, avec autre chose que la Les projets les plus simples, vous le ferez. Une situation courante est celle où vous devez utiliser une version modifiée localement de la bibliothèque de quelqu'un d'autre).
Où mettez-vous la source?
PROJECT_ROOT/src/<Egg_name>
.Où mettez-vous les scripts de démarrage d'application?
entry_point
dans l'un des oeufs.Où placez-vous le IDE projet cruft?
PROJECT_ROOT/.<something>
à la racine du projet, et c’est très bien.Où placez-vous les tests unitaires/d'acceptation?
PROJECT_ROOT/src/<Egg_name>/tests
. Personnellement, je préfère utiliser py.test
pour les exécuter.Où mettez-vous des données non Python telles que des fichiers de configuration?
pkg_resources
.PROJECT_ROOT/config
. Pour le déploiement, il peut y avoir différentes options. Sous Windows, vous pouvez utiliser %APP_DATA%/<app-name>/config
, sous Linux, /etc/<app-name>
ou /opt/<app-name>/config
.PROJECT_ROOT/var
pendant le développement et sous /var
pendant le déploiement de Linux.PROJECT_ROOT/src/<Egg_name>/native
La documentation doit généralement aller dans PROJECT_ROOT/doc
ou PROJECT_ROOT/src/<Egg_name>/doc
(cela dépend si vous considérez certains des œufs comme un grand projet séparé). Certaines configurations supplémentaires seront dans des fichiers tels que PROJECT_ROOT/buildout.cfg
et PROJECT_ROOT/setup.cfg
.
D'après mon expérience, ce n'est qu'une question d'itération. Mettez vos données et votre code où que vous pensiez. Les chances sont, vous aurez tort quand même. Mais une fois que vous avez une meilleure idée de la façon dont les choses vont évoluer, vous êtes beaucoup mieux placé pour faire ce type de conjectures.
En ce qui concerne les sources d'extension, nous avons un répertoire Code sous le tronc qui contient un répertoire pour python et un répertoire pour diverses autres langues. Personnellement, je suis plus enclin à essayer de placer n'importe quel code d'extension dans son propre référentiel la prochaine fois.
Cela dit, je reviens à mon point de départ: ne faites pas une grosse affaire. Placez-le quelque part qui semble fonctionner pour vous. Si vous trouvez quelque chose qui ne fonctionne pas, il peut (et devrait) être changé.
Les données non-Python sont mieux intégrées dans vos modules Python à l'aide du support package_data
de setuptools . Une chose que je recommande fortement est d’utiliser des packages d’espaces de noms pour créer des espaces de noms partagés pouvant être utilisés par plusieurs projets - un peu comme la convention Java consistant à placer des packages dans com.yourcompany.yourproject
(et de pouvoir disposer d’un partage com.yourcompany.utils
espace de noms).
Pour ce qui est de la création de branches et de fusions, si vous utilisez un système de contrôle de code source assez bon, il gérera les fusions même après les renommer; Bazar est particulièrement doué pour ça.
Contrairement à d'autres réponses ici, je suis sur +1 d'avoir un répertoire de niveau src
(avec les répertoires doc
et test
à côté). Les conventions spécifiques pour les arborescences de répertoires de documentation varient en fonction de ce que vous utilisez. Sphinx , par exemple, a ses propres conventions prises en charge par son outil de démarrage rapide.
S'il vous plaît, veuillez utiliser setuptools et pkg_resources; cela facilite beaucoup la tâche à d'autres projets de s'appuyer sur des versions spécifiques de votre code (et l'installation simultanée de plusieurs versions avec différents fichiers autres que du code, si vous utilisez package_data
).