Python项目脚手架

为什么需要弄脚手架?

平时,主要是开发一些工具给自己或部门使用,因此对代码管理比较随意,也不需要其他人查看或修改代码。近期,有个工具要推广给其他人使用,为了方便他们修改代码,要增加注释之类的工作。在这个过程中,发现了一大段问题,比如地址的引用,存在较多相对地址,容易发生错误,代码命名不规范等一大堆规范性问题。

为了改善自己的编码习惯、减少规范性问题,花了一些时间查找、研究Python项目管理的方式,经过几次折腾后,总算确定了自己的项目管理方式(短期内应该不会再调整了)。

环境管理

我原先使用的是Anaconda,但是后面觉得有点臃肿,适合做数据分析或机器学习,但不太适合做开发,因此改用 pipenv 进行环境管理(机器学习开发环境也是用pipenv)。

创建虚拟环境

pipenv install --python version

上述命令会生成Pipfile和Pipfile.lock,且会使用pipenv创建虚拟环境,自动生成一个随机的虚拟环境目录名。般虚拟环境目录名的前缀是你创建环境时所在的项目目录名,如在myblog目录下执行命令,虚拟环境的目录名称就是myblog-Gtn4e1q9,后半部分为随机字符串。

在windows系统下执行命令,虚拟环境的文件 C:\Users\用户名.virtualenvs 文件夹下。若要修改存储地址,则要在系统新建【WORKON_HOME】的环境变量。

pipenv --venv  # 获取当前虚拟环境的位置
pipenv --where # 寻找当前项目的根目录

激活虚拟环境

创建环境后会自动进入到虚拟环境中,当退出虚拟环境重新进入到虚拟环境则需要激活虚拟环境。

在项目目录下,执行如下命令,即可激活虚拟环境.

pipenv shell

激活虚拟环境后,所有的操作仅影响当前的虚拟环境。

包管理

安装依赖包到虚拟环境

建议使用pipenv来安装/卸载相关包,便于开发依赖包的管理。安装与卸载同理,不额外说明。

pipenv install module_name # 安装生产环境的依赖包 
pipenv install module_name --dev # 安装开发环境的依赖包

不管是否激活虚拟环境,都可以执行pipenv install module_name来安装。

若要使用pip进行安装,则按如下命令执行:

pipenv run pip install module_name

使用pipenv安装时,可能会出现lock fail。这个让我苦恼了很久,解决方案如下:

  1. 跳过lock环节,先把包安装上。
pipenv install requests --skip-lock
  1. 查看安装包的版本号,并添加到pipfile中。
pipenv graph

3.更新pipfile.lock,重新安装虚拟环节时,依赖这个文件,不能漏了。

pipenv lock --dev

导出/安装包文件

导出依赖包

pipenv lock -r > requirements_dev.txt # 不包含开发环境的依赖包
pipenv lock -r --dev > requirements_dev.txt # 包含开发环境的依赖包

也可以使用pip进行导出,不过无法区分开发环境的依赖包。

pipenv run pip freeze > requirements.txt

根据pipfile安装依赖包

pipenv install  # 不包含开发环境的依赖包
pipenv install --dev # 包含开发环境的依赖包

根据requirements安装。

pipenv install -r > requirements.txt

开发环境配置

开发环境配置,主要关注几点:代码风格统一、静态类型检查、单元测试。

使用black进行格式化我们的代码。--dev用来区分开发环境,不要忘了。

pipenv install black --dev # 安装
pipenv run black file_name/dir_name # 运行

使用isort对import进行管理。

pipenv install isort --dev # 安装
pipenv run isort file_name/dir_name # 运行

使用 flake8 保证代码风格,可以参考谷歌Python风格指南。

pipenv install flake8 --dev # 安装
pipenv run flake8 file_name/dir_name # 运行

使用 mypy 进行静态类型检查。不过,Python的类型注释还是不好用。

pipenv install mypy --dev # 安装
pipenv run mypy file_name/dir_name # 运行

用 pytest 进行测试,我用的比较少,实在是懒得写测试代码。

pipenv install pytest --dev # 安装
pipenv run pytest # 运行

以上就是主要的开发环境内容,但是每次手动执行还是比较麻烦的。因此,需要用到 Git 的 pre-commit,在提交代码前自动执行相关命令。这里需要用到 pre-commit 库。

pipenv install pre-commit --dev

然后新建.pre-commit-config.yaml,并添加下述配置。

repos:

 - repo: local
 hooks:

 - id: isort
 name: isort
 stages: [commit]
 language: system
 entry: pipenv run isort {{cookiecutter.project_slug}}
 types: [python]

 - id: black
 name: black
 stages: [commit]
 language: system
 entry: pipenv run black {{cookiecutter.project_slug}}
 types: [python]

 - id: flake8
 name: flake8
 stages: [commit]
 language: system
 entry: pipenv run flake8 {{cookiecutter.project_slug}}
 types: [python]
 exclude: setup.py

 - id: mypy
 name: mypy
 stages: [commit]
 language: system
 entry: pipenv run mypy
 types: [python]
 pass_filenames: false

 - id: pytest
 name: pytest
 stages: [commit]
 language: system
 entry: pipenv run pytest
 types: [python]

最后,执行下述命令生成git hooks。

pipenv run pre-commit install

快速创建项目

开发环境的配置还是有较多内容,为了减少重复工作,需要用到 cookiecutter 进行项目创建。我已经将上述内容整合到项目模板中,执行如下命令可直接创建项目。

pip install cookiecutter # 不用安装到虚拟环境。
cookiecutter https://e.coding.net/jinuobushibili/zzz_tools/ProjectTemplate.git

除上述内容外,项目模板中还包含项目目录、项目配置等多项内容。

项目代码结构

  • docs(dir):项目文档库
  • template(dir):模板文件库
  • bin(dir):入口文件,可无
  • db(dir):数据文件地址
  • log(dir):项目日志文件
  • conf(dir):项目配置文件
  • tests(dir):测试代码
  • lib(dir):自定义的模块或包
  • sample(dir):关键代码文件,每个包单独目录
    • _ init _.py
    • main.py
    • setting.py:添加了部分目录的路径变量,如db。
  • README.md:项目说明文档
  • requirements.txt:项目依赖的三方库
  • setup.py:安装、部署、打包代码

修改项目模板

若要基于自己的需求,对项目模板进行修改的话,也是比较简单的。

变量修改

cookiecutter变量,通过 cookiecutter.json 进行修改。其中的值为默认值,在创建项目时,会要求再次确认。而变量的使用,只需在对应的文件中,使用 {{ 变量名 }}即可。但需保证文件的编码为utf-8。

目录/文件调整

cookiecutter生成的文件目录是{{cookiecutter.project_slug}},需要项目自动生成的文件要放到这个目录下。

在{{cookiecutter.project_slug}}目录下操作即可,对根目录下其他目录的修改是不会影响创建项目的。

开发环境调整

调整完以后,记得更新requirem或pipfile即可。相关操作,请查看上方对应内容。

Hooks

cookiecutter的hooks全部在hooks目录下。

  • pre_gen_project.py:项目创建前
  • post_gen_project.py:项目创建后

结合cookiecutter变量与hooks,可以进行许多复杂的操作。我还没怎么用。

你可能感兴趣的:(Python项目脚手架)