Question

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 des dossiers du projet?

Les fonctionnalités souhaitables sont la facilité de maintenance, la compatibilité IDE, l’adéquation de la fusion / contrôle du contrôle de source et la génération aisée de packages d’installation.

En particulier:

  1. Où mettez-vous la source?
  2. Où mettez-vous les scripts de démarrage d'application?
  3. Où placez-vous le projet IDE à l'état brut?
  4. Où placez-vous les tests unitaires / d'acceptation?
  5. Où mettez-vous des données non Python telles que des fichiers de configuration?
  6. Où placez-vous les sources non Python telles que C ++ pour les modules d'extension pyd / so binary?
Était-ce utile?

La solution

Peu importe. Tout ce qui vous rend heureux fonctionnera. Il n’ya pas beaucoup de règles stupides car les projets Python 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 les documents d'API générés par Epydoc.

Et le répertoire de niveau supérieur peut contenir des fichiers README, Config et autres.

Le choix difficile consiste à utiliser ou non un arbre /src. Python ne fait pas la distinction entre /foo, /bar et /baz comme Java ou C.

Etant donné qu'un répertoire quux 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.

  • /quux
  • PYTHONPATH
  • /path/to/quux/foo

Je recommande de placer tout cela sous le " nom-de-mon-produit " annuaire. Donc, si vous écrivez une application nommée QUUX.foo, le répertoire qui contient tout cela est nommé <=>.

Un autre projet <=> peut alors inclure <=> pour réutiliser le module <=>.

Dans mon cas, puisque j'utilise Komodo Edit, mon fichier IDE est un fichier .KPF unique. En fait, je mets cela dans le répertoire de niveau supérieur <=> et omis de l'ajouter à SVN.

Autres conseils

Selon la structure de système de fichiers d'un Jean-Paul Calderone Projet Python :

Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |   
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
|-- README

Ce billet de blog de Jean-Paul Calderone est généralement donné comme réponse dans #python sur Freenode.

  

Structure de système de fichiers d'un projet Python

     

Faites:

     
      
  • 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 une extension .py, même s’ils sont des 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: puisque sous 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 pouvez vouloir 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 d’utilisateur inclut des utilisateurs Windows, vous voudrez peut-être opter simplement pour le .py extension partout.)
  •   
  • Si votre projet peut être exprimé en tant que fichier source Python unique, placez-le dans le répertoire et nommez-le de la même manière que votre projet. Par exemple, Twisted/twisted.py. Si vous avez besoin de plusieurs fichiers source, créez un package à la place (Twisted/twisted/ avec un Twisted/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 l'option de fichier source Python unique ci-dessus était une astuce - vous toujours devez disposer d'au moins un autre fichier pour votre unité. tests). Par exemple, Twisted/twisted/test/. Bien sûr, faites-en un paquet avec Twisted/twisted/test/__init__.py. Placez les tests dans des fichiers tels que Twisted/twisted/test/test_internet.py.
  •   
  • ajoutez Twisted/README et Twisted/setup.py pour expliquer et installer votre logiciel, si vous vous sentez bien.
  •   
     

Ne pas:

     
      
  • placez votre source dans un répertoire appelé src ou lib. Cela rend difficile l'exécution sans installation.
  •   
  • placez vos tests en dehors de votre paquet Python. Cela rend difficile l’exécution des tests sur une version installée.
  •   
  • créez un package qui uniquement possède un __init__.py, puis placez tout votre code dans <=>. Créez simplement un module au lieu d’un package, c’est plus simple.
  •   
  • essayez de créer des hack magiques pour permettre à Python d'importer votre module ou package sans que l'utilisateur ajoute le répertoire qui le contient à son chemin d'importation (via PYTHONPATH ou un autre mécanisme). Ne pas gérez correctement tous les cas et les utilisateurs se fâcheront contre vous lorsque votre logiciel ne fonctionnera pas dans leur environnement.
  •   

Découvrez Open Sourcing d'un python Projetez dans le bon sens .

Permettez-moi d'extraire la partie du projet de cet excellent article:

  

Lors de la configuration d'un projet, la mise en page (ou la structure de répertoires) est importante. 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 avons affaire à 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 à deux endroits   
        
    • Sous le répertoire du package 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 aperçu 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 placera la documentation générée), un répertoire sandman et un répertoire de test sous sandman.

L'autorité de conditionnement Python & ";" a un exemple de projet:

https://github.com/pypa/sampleproject

Il s’agit d’un exemple de projet destiné à aider le didacticiel sur l’emballage et la distribution de projets du Guide de l’emballage de Python.

Essayez de démarrer le projet en utilisant le modèle python_boilerplate . Il suit en grande partie les meilleures pratiques (par exemple, ces ici ), mais convient mieux au cas où vous seriez prêt à scinder votre projet en plusieurs œufs à un moment donné (et croyez-moi, avec tout, sauf les projets les plus simples, vous le ferez. Une des situations courantes utiliser une version modifiée localement de la bibliothèque de quelqu'un d'autre).

  • Où placez-vous la source?

    • Pour les projets de taille décente, il est judicieux de scinder la source en plusieurs oeufs. Chaque oeuf irait comme un setuptools-layout séparé sous PROJECT_ROOT/src/<egg_name>.
  • Où placez-vous les scripts de démarrage d'application?

    • L'option idéale consiste à enregistrer le script de démarrage de l'application en tant que entry_point dans l'un des oeufs.
  • Où placez-vous le projet IDE?

    • Dépend de l'IDE. Beaucoup d’entre eux conservent leurs données PROJECT_ROOT/.<something> à la racine du projet, ce qui est bien.
  • Où placez-vous les tests unitaires / d'acceptation?

    • Chaque oeuf a un ensemble de tests séparé, conservé dans son répertoire 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?

    • Cela dépend. Il peut exister différents types de données non Python.
      • & "Ressources &"; , c’est-à-dire les données qui doivent être conditionnées dans un oeuf. Ces données sont placées dans le répertoire egg correspondant, quelque part dans l'espace de noms du paquet. Il peut être utilisé via pkg_resources le package.
      • " fichiers de configuration " , c’est-à-dire des fichiers non Python qui doivent être considérés comme externes aux fichiers source du projet, mais doivent être initialisés avec certaines valeurs quand l'application commence à courir. Pendant le développement, je préfère conserver ces fichiers dans PROJECT_ROOT/config. Pour le déploiement, il peut y avoir différentes options. Sous Windows, on peut utiliser %APP_DATA%/<app-name>/config, sous Linux, /etc/<app-name> ou /opt/<app-name>/config.
      • Fichiers générés , c’est-à-dire des fichiers pouvant être créés ou modifiés par l’application lors de son exécution. Je préférerais les conserver dans PROJECT_ROOT/var pendant le développement et sous /var lors du déploiement de Linux.
  • Où placez-vous les sources non Python telles que C ++ pour les modules d'extension pyd / so binary?
    • dans PROJECT_ROOT/src/<egg_name>/native

La documentation est généralement classée dans PROJECT_ROOT/doc ou PROJECT_ROOT/src/<egg_name>/doc (cela dépend si vous considérez certains des œufs comme des projets volumineux distincts). 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 trunk 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é.

Il est préférable de regrouper vos données Python dans vos modules Python en utilisant le package_data support de setuptools Une chose que je recommande fortement consiste à 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 qui consiste à placer les packages dans com.yourcompany.yourproject (et pouvant disposer d'un com.yourcompany.utils espace de noms partagé).

En ce qui concerne 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 avoir renommés; Le Bazaar est particulièrement efficace à cet égard.

Contrairement à d'autres réponses ici, je suis +1 sur le fait d'avoir un répertoire de niveau supérieur 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 prise en main 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 des codes, si vous utilisez <=>).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top