Python学习之路:软件目录开发规范

1、背景

软件开发是一个系统工程,固然编码实现是其中尤为重要的一个环节,关乎到功能需求的实现好坏。这个环节中除了编码这一硬功以外,与之相关的编码风格这一柔道,虽然没有直接决定功能的实现与否,但却在很大程度上决定了的项目代码总体的可读性、健壮性、移植性、可维护性等重要特性。编码风格不只涉及到代码如何编写,也涉及到代码模块的分布组织,即项目代码目录的设计。html

好的代码目录设计能够直观展示开发者的逻辑条理,提升代码的可读性、可维护性、移植性甚至是健壮性,很差的代码目录设计就不细说了,逻辑层次混乱不清,代码拷贝到其余环境不能运行等是最多见的问题了。python

今天就来谈谈软件目录开发设计规范相关的事宜。mysql

2、设计软件目录开发规范的重要性和必要性

在上文中略微提到软件项目代码目录设计规范对项目的一些影响,这里细化展开一下其重要性和必要性,大体为如下几点:linux

  • 可读性高:好的代码目录设计,可让刚接触项目的人员经过目录便可大体了解开发者的逻辑条理,明确程序入口文件、测试样例、说明帮助文档、配置文件等的分布位置,从而能够最快的速度熟悉项目。
  • 可维护性强:当前的目录设计规范能够明确地提示维护者新增的代码文件、配置文件等该设计在哪一个目录下,以便更好的维护项目。这样可确保随着时间的推移和人员的变动,项目自己的可维护性依然很强。
  • 可移植性:当项目上到必定规模或变得复杂时,经过不一样的层级目录来分布不一样用途的文件显得异常重要,这样能够确保代码包拷贝到其余环境后,尽量地避免因模块依赖、配置文件缺乏、目录调用失败等问题致使的运行失败问题。

3、软件开发目录组织方式

仅以Python为例,谈谈建议的软件开发目录组织结构:nginx

Foo/
|-- bin/
|   |-- foo
|
|-- foo/
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py
| |--conf/ |  |-- __init__.py | |-- settings.py | |--logs/ |
|-- docs/
|   |-- conf.py
|   |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README__init__.py | |-- settings.py | |--logs/
 
解释以下:
1. bin/: 存放项目的一些可执行文件,固然起名scripts/之类的也何尝不可
2. foo/: 存放项目的全部源代码。(1) 源代码中的全部模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录存放单元测试代码; (3) 程序的入口最       好命名为。tests/main.py
3. conf/: 存放配置文件
4. logs/: 做为日志目录存放程序运行中生成的各类日志
5. docs/:存放项目的帮助文档
6. setup.py:安装、部署、打包的脚本,通常用于适配环境、解决依赖关系等
7. requirements.txt: 存放软件依赖的外部python包列表
8. README:存放项目说明文档,下文详述
除此以外,有一些方案给出了更加多的内容。好比LICENSE.txt,ChangeLog.txt文件等,其中LICENSE.txt主要是项目开源的时候须要用到。ChangeLog.txt可根据须要肯定是否添加。LICENSE.txtChangeLog.txtChangeLog.txt可根据须要肯定是否添加。

4、README相关

使用过开源软件的朋友们都知道README能够给软件的使用带来很大的帮助,包括软件介绍、功能定位、安装启动使用方法、有建议或bug怎么联系做者等,其必要性和重要性不言而喻。git

所以每个项目都应该有README说明,好的README应该至少包括如下几方面的内容:github

  • 软件的简要介绍、功能定位、适用场景等
  • 软件的安装、环境依赖、启动方法、常见使用命令(使用说明)等
  • 代码的目录结构说明
  • 常见问题说明
  • 遇到建议或bug如何联系做者或项目组

若是再编写的更详细,能够考虑简述软件的基本原理。这方面最好的参考就是开源软件的README,如nginx,redis等。redis

5、requirements.txt和setup.py相关

1. requirements

requirements主要解决如下两个问题:sql

  1. 方便开发者维护软件包依赖 有新的依赖包产生时直接添加进该列表便可,而后经过setup.py自动解决该依赖,避免遗漏
  2. 方便用户明确依赖关系

requirements.txt的格式是每一行包含一个包依赖的说明,一般是flask>=0.10这种格式,要求是这个格式能被pip识别,这样就能够简单的经过 pip install -r requirements.txt来把全部Python包依赖都装好了。具体格式说明: 猛击这里flask

2.setup.py

通常来讲,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。这种方式广泛应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目必定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。

这个问题比如在linux经过yum来安装一个软件同样,咱们不得不认可,在解决环境依赖关系方面,yum安装相对于源码编译安装更方便。

在python项目方面,对于初学者来说,不少都经历过如下问题:

  1. 安装环境时忘了最近又添加了一个新的Python包,结果一到线上运行,程序就出错了。
  2. Python包的版本依赖问题,有时候咱们程序中使用的是一个版本的Python包,可是官方的已是最新的包了,经过手动安装就可能装错了。
  3. 若是依赖的包不少的话,一个一个安装这些依赖是很费时的事情。
  4. 新同窗开始写项目的时候,将程序跑起来很是麻烦,由于可能常常忘了要怎么安装各类依赖。

setup.py的目的是将这些事情自动化起来,统一自动化管理,提升效率并减小出错的几率。"复杂的东西自动化,能自动化的东西必定要自动化。"是一个很是好的习惯。

setuptools的文档比较庞大,刚接触的话,可能不太好找到切入点。先从模仿开始吧,能够参考一下Python的一个Web框架,flask是如何写的: setup.py

若是开发的项目只是在Linux环境上运行,简单点本身写个安装脚本(deploy.sh)替代setup.py也何尝不可。

6、配置文件相关

注意,在上面的目录结构中,没有将conf.py放在源码目录下,而是放在docs/目录下。

不少项目对配置文件的使用作法是:

  1. 配置文件写在一个或多个python文件中,好比此处的conf.py。
  2. 项目中哪一个模块用到这个配置文件就直接经过import conf这种形式来在代码中使用配置。

这种作法我不太赞同:

  1. 这让单元测试变得困难(由于模块内部依赖了外部配置)
  2. 另外一方面配置文件做为用户控制程序的接口,应当能够由用户自由指定该文件的路径。
  3. 程序组件可复用性太差,由于这种贯穿全部模块的代码硬编码方式,使得大部分模块都依赖conf.py这个文件。

因此,我认为配置的使用,更好的方式是,

  1. 模块的配置都是能够灵活配置的,不受外部配置文件的影响。
  2. 程序的配置也是能够灵活控制的。

可以佐证这个思想的是,用过nginx和mysql的同窗都知道,nginx、mysql这些程序均可以自由的指定用户配置。

因此,不该当在代码中直接import conf来使用配置文件。上面目录结构中的conf.py,是给出的一个配置样例,不是在写死在程序中直接引用的配置文件。能够经过给main.py启动参数指定配置路径的方式来让程序读取配置内容。固然,这里的conf.py你能够换个相似的名字,好比settings.py。或者你也可使用其余格式的内容来编写配置文件,好比settings.yaml之类的。

-------------------------atm.py-------------------------------
print(__file__)#返回当前程序的相对路径

import os
import sys
print(os.path.abspath(__file__)) #返回绝对路径
print(os.path.dirname(os.path.abspath(__file__)))#返回上级路径
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append((BASE_DIR))

from conf import settings
from core import main

main.login()



---------------------------main.py------------------------------------

def login():
    print("Welcome to my atm")
相关文章
相关标签/搜索