Qual é a melhor estrutura do projeto para uma aplicação Python? [fechadas]
-
08-07-2019 - |
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:
- Onde você coloca a fonte?
- Onde você colocar scripts de inicialização de aplicativos?
- Onde você colocar o cruft projeto IDE?
- Onde você colocar a unidade / testes de aceitação?
- Onde você colocar os dados não-Python, tais como arquivos de configuração?
- Onde você colocar fontes não-Python, como C ++ para PYD / so binário módulos de extensão?
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 umTwisted/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 comTwisted/twisted/test/__init__.py
. Testes lugar em arquivos comoTwisted/twisted/test/test_internet.py
.Twisted/README
add eTwisted/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
oulib
. 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>
.
- Para decentemente grandes projetos, faz sentido dividir a fonte em vários ovos. Cada ovo iria como um setuptools-disposição separada sob
-
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.
- A opção ideal é ter script de inicialização do aplicativo registrado como um
-
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.
- Depende do IDE. Muitos deles manter suas coisas em
-
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 usarpy.test
para executá-los.
- Cada ovo tem um conjunto separado de testes, mantido em seu diretório
-
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.
- "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
- Depende. Não pode haver diferentes tipos de dados não-Python.
- 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
- Em
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
).