软件开发目录规范的作用
为了提高程序的可读性与可维护性,我们应该为软件设计良好的目录结构,这与规范的编码风格同等重要。软件的目录规范并无硬性标准,只要清晰可读即可,
项目示例
===== 项目示例 ===== PerfectProject/ |-- start.py | |-- api/ | |-- api.py | |-- core/ | |-- src.py | |-- db/ | |-- db_handle.py | |-- lib/ | |-- common.py | |-- conf/ | |-- settings.py | |-- log/ | |-- user.log | |-- requirements.txt |-- README.me |-- setup.py
===== 目录功能说明 ====
•
bin
- 存放启动文件的目录(可以没有该目录)•
api
- 存放接口文件,接口主要用于为业务逻辑提供数据操作。•
core
- 存放业务逻辑相关代码•
db
- 存放操作数据库相关文件,主要用于与数据库交互•
lib
- 存放程序中常用的自定义模块•
conf
- 存放配置文件•
log
- 存放日志相关的文件
===== 重要文件功能说明 ====
•
run.py
/start.py
- 程序的启动文件,一般放在项目的根目录下,因为在运行时会默认将运行文件所在的文件夹作为sys.path
的第一个路径,这样就省去了处理环境变量的步骤•
setup.py
- 安装、部署、打包的脚本。•
requirements.txt
- 存放软件依赖的外部Python包列表。•
README.me
- 项目说明文件。
===== 其他功能补充说明 ====
除此之外,有一些方案给出了更加多的内容,比如
LICENSE.txt
,ChangeLog.txt
文件等,主要是在项目需要开源时才会用到,请读者自行查阅。关于
README.me
的内容,这个应该是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。它需要说明以下几个事项:1、软件定位,软件的基本功能;
2、运行代码的方法: 安装环境、启动命令等;
3、简要的使用说明;
4、代码目录结构说明,更详细点可以说明软件的基本原理;
5、常见问题说明。
关于
setup.py
和requirements.txt
一般来说,用
setup.py
来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools
来管理这些事情,这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。
requirements.txt
文件的存在是为了方便开发者维护软件的依赖库。我们需要将开发过程中依赖库的信息添加进该文件中,避免在setup.py
安装依赖时漏掉软件包,同时也方便了使用者明确项目引用了哪些Python包。这个文件的格式是每一行包含一个包依赖的说明,通常是
flask>=0.10
这种格式,要求是这个格式能被pip
识别,这样就可以简单的通过pip install -r requirements.txt
来把所有Python依赖库都装好了,具体格式参照https://pip.readthedocs.io/en/1
各部件详细代码
# run.py #!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # __file__ 是当前文件的绝对路径,os.path.dirname是上级目录 sys.path.append(BASE_DIR) # 将执行文件的上两级目录,也就是PerfectProject目录添加至环境变量中。 from core import src if __name__ == '__main__': src.run() """ 当run.py程序执行时,添加的路径就存在于整个PerfectProject项目中。 由于我们添加的路径是以PerfectProject文件夹为根目录,故今后使用该项目下 的任何文件夹直接导入即可... """
# settings.py import os import sys BASE_DIR = os.path.dirname(os.path.dirname(__file__)) sys.path.append(BASE_DIR) # 即使run.py存在BASE_DIR,其他位置的文件也不应该对其进行导入。 # LOG_PATH : 日志记录的路径 LOG_PATH = os.path.join(BASE_DIR,r"log/user.log")
# src.py from lib.common import logger from db.db_handle import * def login(): print("登录功能...") logger("用户Yunya登录了") def reqister(): print("注册功能...") logger("用户Yunya注册了") def witdraw(): print("提现功能...") logger("用户Yunya正在提现") def transfer(): print("转账功能...") logger("用户Yunya正在向XXX转账") func_dic = { "0":["退出",exit], "1":["登录",login], "2":["注册",reqister], "3":["提现",witdraw], "4":["转账",transfer], } def run(): while 1: for k in func_dic: print(k,func_dic[k][0]) choice = input("请输入指令编号:").strip() if choice in func_dic: func_dic[choice][1]() else: print("请重新输入")
# common.py import time from conf import settings # 导入配置文件 def logger(msg): # 由于logger功能会十分常用。故我们将它列到常用库中。 with open(file=settings.LOG_PATH, mode='at', encoding='utf-8') as f: f.write("%s : %s " % (time.strftime("%Y-%m-%d %H:%M:%S"), msg))