Qual é a melhor estrutura de projeto para uma aplicação Python? [fechado]

Imagine que deseja desenvolver uma aplicação não trivial do ambiente de trabalho do utilizador final (não web) em Python. Qual é a melhor maneira de estruturar a hierarquia de pastas do projeto?

as características desejáveis são a facilidade de manutenção, a convivialidade, a adequação para a ramificação/fusão do controlo de origem e a fácil geração de pacotes de instalação.

em particular:

    Onde se põe a fonte?
  1. onde é que se colocam os programas de arranque das aplicações?
  2. onde é que se põe o projecto IDE cruft?
  3. onde se colocam os testes de unidade / aceitação?
  4. onde é que se colocam dados não Python, como ficheiros de configuração?
  5. onde é que se colocam fontes não Python como C++ para módulos de extensão binária pyd/so?
Author: suci, 2008-10-11

8 answers

Não importa muito. O que te fizer feliz vai resultar. Não há muitas regras tolas porque os projetos Python podem ser simples.
  • /scripts ou /bin para esse tipo de interface de linha de comando
  • /tests para os seus testes
  • /libpara as suas bibliotecas de C-language
  • /doc para a maior parte da Documentação
  • /apidoc para os documentos de API gerados pela Epydoc.

E o directório de topo pode conter README's, Config's e enfeite.

A escolha difícil é usar ou não uma árvore /src. O Python não tem distinção entre /src, /lib, e /bin como Java ou C tem.

Uma vez que um directório de topo /src é visto por alguns como insignificante, o seu directório de topo pode ser a arquitectura de topo da sua aplicação.

  • /foo
  • /bar
  • /baz

Eu recomendo colocar tudo isso sob o diretório" nome-do-meu-produto". Então, se tu ... escrevendo uma aplicação chamada quux, a pasta que contém todas estas coisas chama-se /quux.

Outro projeto PYTHONPATH, Então, pode incluir /path/to/quux/foo para reutilizar o módulo QUUX.foo.

No meu caso, uma vez que uso o Komodo Edit, o meu IDE cuft é um single .Ficheiro KPF. Eu realmente coloquei isso no diretório de nível superior /quux, e omiti adicioná-lo ao SVN.

 310
Author: S.Lott, 2008-10-11 01:43:11

De acordo com a estrutura do sistema de Ficheiros de Jean-Paul Calderone de um projecto Python:

Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |   
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
|-- README
 204
Author: cmcginty, 2013-06-20 14:56:50

Este post no blog de Jean-Paul Calderone é comumente dado como uma resposta em #python no Freenode.

Estrutura do sistema de Ficheiros de um projecto Python

Faça:

  • diz o nome do directório algo relacionado com o teu projecto. Por exemplo, se o seu projecto for chamado "Twisted", nomeie o directório de topo para os seus ficheiros de código Twisted. Quando você faz lançamentos, você deve incluir um sufixo de número de Versão: Twisted-2.5.
  • crie uma pasta Twisted/bin e põe lá os teus executáveis, se tiveres algum. Não lhes dê uma extensão .py, mesmo que sejam ficheiros de código Python. Não coloque nenhum código neles, exceto uma importação e chamada para uma função principal definida em algum outro lugar em seus projetos. (Pequena ruga: uma vez que no Windows, o interpretador é selecionado pela extensão de Arquivo, seus usuários do Windows realmente querem a extensão .py. Então, quando você empacota para Windows, você pode querer adicioná-lo. Infelizmente não há nenhum truque fácil que eu saiba para automatizar este processo. Considerando que no POSIX a extensão .py é apenas uma verruga, enquanto no Windows a falta é um bug real, se o seu userbase inclui usuários do Windows, você pode querer optar por ter apenas a extensão .py em todos os lugares.)
  • Se o seu projecto for expressável como um único ficheiro de código Python, então coloque-o no directório e dê-lhe o nome de algo relacionado com o seu projecto. Por exemplo, Twisted/twisted.py. Se necessitar de vários ficheiros de código, crie um pacote em alternativa (Twisted/twisted/, com um pacote vazio Twisted/twisted/__init__.py) e coloque seus arquivos fonte nele. Por exemplo, Twisted/twisted/internet.py.
  • coloque os testes da sua unidade num sub-pacote do seu pacote (Nota - Isto significa que a única opção de ficheiro de código Python acima era um truque - você Sempre precisa de pelo menos mais um ficheiro para os seus testes de unidade). Por exemplo, Twisted/twisted/test/. Claro, faça um pacote com Twisted/twisted/test/__init__.py. Coloque os testes em arquivos como Twisted/twisted/test/test_internet.py.
  • adicione Twisted/README e Twisted/setup.py para explicar e instalar o seu software, respectivamente, se se sentir bem.

Não ...

  • coloque a sua fonte numa pasta chamada src ou lib. Isso torna difícil de executar sem instalar.
  • Ponha os testes fora do pacote Python. Isso torna difícil executar os testes com uma versão instalada.
  • crie um pacote que apenas tenha um __init__.py e depois coloque todo o seu código em __init__.py. Basta fazer um módulo em vez de um pacote, é mais simples.
  • Tenta inventar hacks mágicos para fazer Python. capaz de importar o seu módulo ou pacote sem que o utilizador adicione a pasta que a Contém ao seu caminho de importação (seja através do PYTHONPATH ou de outro mecanismo). Você vai não corretamente lidar com todos os casos e os usuários vão ficar com raiva de você quando o seu software não funciona em seu ambiente.
 182
Author: Adrian, 2015-03-06 20:42:24

Confira abrir um projecto Python da forma correcta .

Deixe-me citar a disposição do projecto parte desse excelente artigo:

Ao configurar um projecto, a disposição (ou estrutura de directórios) é importante para acertar. Um layout sensato significa que os contribuintes potenciais não têm que passar para sempre à procura de um pedaço de código; localizações de arquivos são intuitivos. Uma vez que estamos a lidar com um projecto existente, significa que provavelmente vais precisar de mudar-te. algumas coisas por aí.

Vamos começar pelo topo. A maioria dos projetos tem uma série de arquivos de alto nível (como setup.py, README.md, requisitos.txt, etc). Existem então três diretórios que cada projeto deve ter:
  • um directório de documentos contendo a documentação do projecto
  • uma pasta com o nome do projecto que armazena o pacote Python actual
  • uma lista de testes num dos dois locais
    • sob a pasta de pacotes contendo código de ensaio e recursos
    • como uma pasta de topo Autónoma Para ter uma melhor noção de como seus arquivos devem ser organizados, aqui está um instantâneo simplificado do layout para um dos meus projetos, 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

Como pode ver, existem alguns ficheiros de topo, um directório docs (gerado é um directório vazio onde a sphinx irá colocar a documentação gerada), um directório sandman e um directório de testes sob a sandman.

 96
Author: David C. Bishop, 2014-08-08 09:44:30

A "Python Packaging Authority" tem um sampleproject:

Https://github.com/pypa/sampleproject

É um projecto de amostra que existe como uma ajuda ao Tutorial do utilizador de embalagens Python sobre Embalagens e distribuição de projectos.

 18
Author: guettli, 2017-03-07 05:37:41

Tente iniciar o projecto usando o modelo python_ boilerplate. Segue em grande parte as melhores práticas (por exemplo aqueles aqui), mas é mais adequado no caso de você se encontrar disposto a dividir o seu projeto em mais de um ovo em algum momento (e acredite em mim, com qualquer coisa menos os projetos mais simples, você vai. Uma situação comum é onde você tem que usar uma versão localmente modificada da biblioteca de outra pessoa).

  • Onde você coloca o fonte?

      Para projectos decentemente grandes, faz sentido dividir a fonte em vários ovos. Cada ovo iria como um setuptools separado-layout sob PROJECT_ROOT/src/<egg_name>.
  • Onde é que coloca os programas de inicialização da aplicação?

    • a opção ideal é ter o script de inicialização da aplicação registado como um entry_point num dos ovos.
  • Onde você coloca o projeto IDE cruft?

      Depende da IDE. Muitos deles guardam as suas coisas na raiz do projecto, e isto é bom.
  • Onde você coloca os testes de unidade / aceitação?

    • cada ovo tem um conjunto separado de testes, mantidos no seu directório PROJECT_ROOT/src/<egg_name>/tests. Eu pessoalmente prefiro usar py.test para executá-los.
  • Onde você coloca dados não-Python, como arquivos de configuração?

      Depende. La podem ser diferentes tipos de dados não Python.
      • "recursos" , ou seja, dados que devem ser embalados dentro de um ovo. Estes dados vão para o diretório de ovos correspondente, em algum lugar dentro do espaço de nomes de pacotes. Pode ser utilizado através da embalagem pkg_resources.
      • "ficheiros de configuração" , ou seja, ficheiros não Python que devem ser considerados como exteriores aos ficheiros de código do projecto, mas que têm de ser inicializados com alguns valores quando a aplicação começar a correr. Durante o desenvolvimento eu prefiro manter files in PROJECT_ROOT/config. Para a implantação pode haver várias opções. No Windows pode-se usar %APP_DATA%/<app-name>/config, no Linux, /etc/<app-name> ou /opt/<app-name>/config.
      • arquivos gerados , ou seja, arquivos que podem ser criados ou modificados pela aplicação durante a execução. Eu preferiria mantê-los em PROJECT_ROOT/var durante o desenvolvimento, e em /var durante a implementação do Linux.
  • onde é que se colocam fontes não Python como C++ para módulos de extensão binária pyd/so?
    • em PROJECT_ROOT/src/<egg_name>/native
  • [[18]} A documentação normalmente iria para PROJECT_ROOT/doc ou PROJECT_ROOT/src/<egg_name>/doc (isto depende se você considera alguns dos ovos como um grande projeto separado). Alguma configuração adicional estará em arquivos como PROJECT_ROOT/buildout.cfg e PROJECT_ROOT/setup.cfg.
     16
    Author: KT., 2014-03-21 09:49:41
    Pela minha experiência, É só uma questão de iteração. Coloque os seus dados e Código onde quer que pense que eles vão. É provável que estejas enganado. Mas uma vez que você tem uma idéia melhor de exatamente como as coisas vão se formar, você está em uma posição muito melhor para fazer esse tipo de suposições.

    Quanto às fontes de extensão, temos um directório de código em trunk que contém um directório para python e um directório para várias outras línguas. Pessoalmente, estou mais inclinado a tentar colocando qualquer código de extensão em seu próprio repositório da próxima vez.

    Dito isto, volto ao meu ponto inicial: não exagere. Põe-no num sítio que pareça funcionar para ti. Se você encontrar algo que não funciona, ele pode (e deve) ser mudado.
     14
    Author: Jason Baker, 2008-10-10 22:57:39

    Os dados não-python são melhor agrupados dentro dos seus módulos Python usando o Suporte package_data em setuptools . Uma coisa que recomendo fortemente é usar pacotes de espaços de nomes para criar espaços de nomes compartilhados que vários projetos podem usar -- muito parecido com a Convenção Java de colocar pacotes em com.yourcompany.yourproject (e ser capaz de ter um espaço de nomes compartilhado com.yourcompany.utils).

    Re ramificar e fundir, se usar um sistema de controlo de origem suficientemente bom para lidar com a fusão, mesmo através de renomeações; O Bazar é particularmente bom nisto.

    Ao contrário de algumas outras respostas aqui, eu sou +1 em ter um src diretório de topo (com doc e test diretórios ao lado). As convenções específicas para as árvores de pastas de documentação irão variar dependendo do que estiver a usar; a Sphinx , por exemplo, tem as suas próprias convenções que a sua ferramenta de arranque rápido suporta.

    Por favor, por favor, utilize as setuptools e os recursos pkg_; isto torna muito mais fácil para outros projectos confiar em versões específicas do seu código (e para várias versões serem instaladas simultaneamente com diferentes ficheiros Não-código, se estiver a utilizar package_data).

     7
    Author: Charles Duffy, 2008-10-10 22:39:22