Pergunta

Imagine que você quer desenvolver uma área de trabalho do usuário final não-trivial (não web) aplicação em Python. Qual é a melhor forma de estruturar a hierarquia de pastas do projeto?

As características desejáveis ??são a facilidade de manutenção, IDE de uso, adequação para controle de origem ramificação / fusão e geração fácil de instalar pacotes.

Em particular:

  1. Onde você coloca a fonte?
  2. Onde você colocar scripts de inicialização de aplicativos?
  3. Onde você colocar o cruft projeto IDE?
  4. Onde você colocar a unidade / testes de aceitação?
  5. Onde você colocar os dados não-Python, tais como arquivos de configuração?
  6. Onde você colocar fontes não-Python, como C ++ para PYD / so binário módulos de extensão?
Foi útil?

Solução

não importa muito. O que faz você feliz trabalho vontade. Não há um monte de regras tolas porque os projetos Python pode ser simples.

  • /scripts ou /bin para esse tipo de coisa interface de linha de comando
  • /tests para os testes
  • /lib para as suas bibliotecas de linguagem C
  • /doc para a maioria documentação
  • /apidoc para a documentação da API gerada pelo epydoc.

E o diretório de nível superior pode conter README de, configuração de e outros enfeites.

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

Uma vez que um diretório de nível superior /src é visto por alguns como sem sentido, seu diretório de nível superior pode ser a arquitetura de nível superior da sua aplicação.

  • /foo
  • /bar
  • /baz

Eu recomendo colocar tudo isso sob o diretório "nome-do-meu-produto". Então, se você estiver escrevendo um aplicativo chamado quux, o diretório que contém todo este material é nomeado /quux.

PYTHONPATH Outro projeto, em seguida, pode incluir /path/to/quux/foo reutilizar o módulo QUUX.foo.

No meu caso, desde que eu uso Komodo Edit, meu IDE CUFT é um único arquivo .KPF. Na verdade, eu colocar isso no diretório /quux de nível superior, e omitir adicioná-lo ao SVN.

Outras dicas

De acordo com a estrutura do Sistema de Arquivos de Jean-Paul Calderone de um Python projeto :

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

Este blog por Jean-Paul Calderone é comumente dado como uma resposta em #python na Freenode.

estrutura de sistema de arquivos de um projeto Python

Do:

  • nomear o diretório algo relacionado ao seu projeto. Por exemplo, se seu projeto é chamado de "Twisted", o nome do diretório de nível superior para a sua arquivos de origem Twisted. Ao fazer lançamentos, você deve incluir um sufixo número de versão:. Twisted-2.5
  • criar um Twisted/bin diretório e colocar os executáveis ??lá, se tiver algum. Não dê a eles uma extensão .py, mesmo se eles são arquivos de origem Python. Não coloque qualquer código em si, exceto uma importação de e chamada para uma função principal definido em outro lugar em seus projetos. (Rugas Ligeira:. Uma vez no Windows, o intérprete é selecionado pela extensão de arquivo, os usuários do Windows, na verdade, quer a extensão .py Assim, quando você pacote para Windows, você pode querer adicioná-lo Infelizmente não há nenhuma fáceis distutils truque que. Eu conheço para automatizar esse processo. Considerando-se que em POSIX a extensão .py é uma apenas uma verruga, enquanto que no Windows a falta é um bug real, se a sua base de usuários inclui usuários do Windows, você pode querer opt para apenas ter o .py extensão em todos os lugares.)
  • Se o seu projeto é expressável como um único arquivo fonte Python, em seguida, colocá-lo para o diretório e nomeá-la algo relacionado ao seu projeto. Por exemplo, Twisted/twisted.py. Se você precisar de vários arquivos de origem, criar um pacote em vez (Twisted/twisted/, com um Twisted/twisted/__init__.py vazio) e colocar seus arquivos de origem na mesma. Por exemplo, Twisted/twisted/internet.py.
  • colocar os testes de unidade em um sub-pacote do seu pacote (nota - isto significa que a opção de arquivo única fonte Python em cima, era um truque - você sempre necessidade de pelo menos um outro arquivo para a sua unidade testes). Por exemplo, Twisted/twisted/test/. Claro, torná-lo um pacote com Twisted/twisted/test/__init__.py. Testes lugar em arquivos como Twisted/twisted/test/test_internet.py.
  • Twisted/README add e Twisted/setup.py para explicar e instalar o seu software, respectivamente, se você está se sentindo agradável.

Do not:

  • colocar a sua fonte em um diretório chamado src ou lib. Isso torna difícil para executar sem instalar.
  • colocar seus testes fora de seu pacote Python. Isso torna difícil para executar os testes contra uma versão instalada.
  • criar um pacote que única tem um __init__.py e, em seguida, colocar todo seu código em __init__.py. Basta fazer um módulo em vez de um pacote, é mais simples.
  • tentar chegar com hacks mágicas para fazer Python capaz de importar o módulo ou pacote sem ter o usuário adicionar o diretório que contém-lo ao seu caminho de importação (via PYTHONPATH ou algum outro mecanismo). Você vai não lidar corretamente todos os casos e os usuários vão ficar com raiva de você quando o seu software não funciona em seu ambiente.

Confira abrir o código de um Python projetar a caminho certo.

Deixe-me excerpt o projeto de layout parte desse excelente artigo:

Quando da criação de um projeto, o layout (ou estrutura de diretórios) é importante para obter direito. Um meio de layout sensatas que potenciais contribuintes não têm de passar sempre à procura de um pedaço de código; localizações de arquivos são intuitivos. Como estamos lidando com um projeto existente, isso significa que você provavelmente precisará mover algumas coisas ao redor.

Vamos começar no topo. A maioria dos projetos têm um número de arquivos de nível superior (como setup.py, README.md, requirements.txt, etc). Há, então, três diretórios que cada projeto deve ter:

  • A docs documentação diretório contendo projeto
  • Um diretório nomeado com o nome do projeto que armazena o pacote real Python
  • Um diretório de teste em um dos dois lugares
    • Sob o diretório do pacote que contém o código de teste e recursos
    • Como um diretório de nível superior stand-alone Para obter 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 você pode ver, existem alguns arquivos nível superior, um diretório docs (gerado é um diretório vazio onde esfinge vai colocar a documentação gerada), um diretório sandman, e um diretório de teste sob sandman.

A "Autoridade Python Embalagem" tem um SampleProject:

https://github.com/pypa/sampleproject

É um projeto de exemplo que existe como uma ajuda para o Python Packaging usuário Tutorial do Guia sobre Projetos Distribuindo embalagem e.

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

  • Onde você coloca a fonte?

    • Para decentemente grandes projetos, faz sentido dividir a fonte em vários ovos. Cada ovo iria como um setuptools-disposição separada sob PROJECT_ROOT/src/<egg_name>.
  • Onde você colocar scripts de inicialização de aplicativos?

    • A opção ideal é ter script de inicialização do aplicativo registrado como um entry_point em um dos ovos.
  • Onde você colocar o cruft projeto IDE?

    • Depende do IDE. Muitos deles manter suas coisas em PROJECT_ROOT/.<something> na raiz do projeto, e isso é bom.
  • Onde você colocar os testes de unidade / aceitação?

    • Cada ovo tem um conjunto separado de testes, mantido em seu diretório PROJECT_ROOT/src/<egg_name>/tests. Eu, pessoalmente, prefiro usar py.test para executá-los.
  • Onde você colocar os dados não Python, tais como arquivos de configuração?

    • Depende. Não pode haver diferentes tipos de dados não-Python.
      • "Recursos" , ou seja, dados que devem ser embalados dentro de um ovo. Esta informação vai para o diretório ovo correspondente, em algum lugar dentro namespace pacote. Ele pode ser usado através de pacote pkg_resources.
      • "config-files" , arquivos ou seja, não-Python que estão a ser considerada como externa para os arquivos de origem do projeto, mas têm de ser inicializado com alguns valores quando o aplicativo começa a funcionar. Durante o desenvolvimento prefiro manter esses arquivos em PROJECT_ROOT/config. Para 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.
      • Os arquivos gerados , ou seja, arquivos que podem ser criados ou modificados pelo aplicativo durante a execução. Eu preferiria mantê-los em PROJECT_ROOT/var durante o desenvolvimento, e sob /var durante a implantação Linux.
  • Onde você colocar fontes não-Python, como C ++ para PYD / módulos de extensão de modo binário?
    • Em PROJECT_ROOT/src/<egg_name>/native

Documentação normalmente entrar em PROJECT_ROOT/doc ou PROJECT_ROOT/src/<egg_name>/doc (isso depende se você considerar alguns dos ovos para ser um grandes projetos separados). Alguma configuração adicional será em arquivos como PROJECT_ROOT/buildout.cfg e PROJECT_ROOT/setup.cfg.

Na minha experiência, é apenas uma questão de iteração. Coloque seus dados e código onde você acha que eles vão. As possibilidades são, você estará de qualquer maneira errada. Mas uma vez que você ter uma idéia melhor de como exatamente as coisas vão moldar-se, você está em uma posição muito melhor para fazer esses tipos de suposições.

Quanto fontes de extensão, temos um diretório de código, sob tronco que contém um diretório para python e um diretório para vários outros idiomas. Pessoalmente, estou mais inclinado para tentar colocar qualquer código de extensão em seu próprio próxima vez repositório de volta.

Com o que disse, eu volto ao meu ponto inicial: não faça muito grande um negócio fora dele. Colocá-lo em algum lugar que parece funcionar para você. Se você encontrar algo que não funciona, ele pode (e deve) ser alterado.

Os dados não-Python é melhor empacotada dentro de seus módulos Python usando o suporte package_data em setuptools . Uma coisa que eu recomendo fortemente é o uso de pacotes de namespace para criar namespaces 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 com.yourcompany.utils compartilhada)

Re ramificação e mesclagem, se você usar um bom sistema de controle de origem o suficiente ele vai lidar com fusões mesmo através renomeações; Bazaar é particularmente bom nisso.

Ao contrário de algumas outras respostas aqui, eu sou +1 em ter um alto nível de diretório src (com doc e test diretórios ao lado). convenções específicas para árvores de diretório documentação vai variar dependendo do que você está usando; Esfinge , por exemplo, tem suas próprias convenções que seus suportes de ferramentas quickstart.

Por favor, por favor, setuptools alavancagem e pkg_resources; isso torna muito mais fácil para os outros projectos a contar com versões específicas do seu código (e para várias versões para ser instalado em simultâneo com diferentes arquivos não-código, se você estiver usando package_data).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top