博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为 Python 项目编写 Makefile
阅读量:2160 次
发布时间:2019-05-01

本文共 2995 字,大约阅读时间需要 9 分钟。

来自:未闻Code

本文翻译自Writing Makefiles for Python Projects[1]。原作者:Bastian Venthur.

作为 Makefiles的粉丝,我几乎在每一个业余项目里面都使用它们。并且我也主张在工作项目中使用。

对开源项目来说,Makefiles 让代码贡献者知道怎么构建、测试、部署项目。并且,如果你正确使用了 Makefiles,他们可以大大简化你的CI/CD 流程脚本。因为你只需要简单地调用对应的 make 命令就可以了。最重要的是,Makefiles 可以简化你的开发工作。

对 Python 项目来说,我总是使用虚拟环境,因此我使用了两个不同的 Makefiles 策略:

  1. 假设 make 命令是在虚拟环境里面执行的

  2. 通过 make 命令来封装虚拟环境的命令

假设 make 命令是在虚拟环境中执行的

我们来看一个非常简单的 Makefile 文件,这个文件可以让你实现构建、测试和发布 Python 项目:

all: lint test.PHONY: testtest:    pytest.PHONY: lintlint:    flake8.PHONY: releaserelease:    python3 setup.py sdist bdist_wheel uploadclean:    find . -type f -name *.pyc -delete    find . -type d -name __pycache__ -delete

这几段代码写的非常直接,所有潜在贡献者立刻就知道你项目的入口在哪里了。

假设已经有一个虚拟环境了,那么你需要首先激活它,然后再运行 make 命令:

$ . venv/bin/activate$ make test

当然,不方便的地方在于,你的每一个 shell 窗口都必须手动激活虚拟环境。所以当你使用 tmux  激活一个新的终端窗口或者把 vim 放到后台上去运行的时候,就很麻烦。

在 make 命令里面激活虚拟环境看起来是很难做到的,因为每一段代码甚至每一个命令都会在它自己的 shell 里面运行。但是我们稍后看一个办法绕过这个限制,比如说使用.ONESHELL标志,但这无法解决新开新的代码片段运行在新 shell 的问题。

在 make 命令里面封装虚拟环境的调用命令

第二个方法基本上解决了在 make 命令里面激活虚拟环境的问题。这个办法是从makefile.venv[2]里面学到的,我简化了一下:

# system python interpreter. used only to create virtual environmentPY = python3VENV = venvBIN=$(VENV)/bin# make it work on windows tooifeq ($(OS), Windows_NT)    BIN=$(VENV)/Scripts    PY=pythonendifall: lint test$(VENV): requirements.txt requirements-dev.txt setup.py    $(PY) -m venv $(VENV)    $(BIN)/pip install --upgrade -r requirements.txt    $(BIN)/pip install --upgrade -r requirements-dev.txt    $(BIN)/pip install -e .    touch $(VENV).PHONY: testtest: $(VENV)    $(BIN)/pytest.PHONY: lintlint: $(VENV)    $(BIN)/flake8.PHONY: releaserelease: $(VENV)    $(BIN)/python setup.py sdist bdist_wheel uploadclean:    rm -rf $(VENV)    find . -type f -name *.pyc -delete    find . -type d -name __pycache__ -delete

仅从功能上看,这个 Makefile 跟刚才的差不多,但是代码看起来更复杂了。所以我们现在一行一行来看看它是怎么实现的。

如果虚拟环境已经激活,或者pytest, flake8这些包已经安装到了系统 Python 环境里面,那么我们直接调用他们就可以了。但是现在,在新的 Makefile 文件中,我们显式地使用虚拟环境中的绝对路径来调用他们。为了确保虚拟环境存在,每一段代码都依赖于$(VENV)这一项。这一项确保了当前有一个最新的虚拟环境可用。

这种方案有效,是因为当我们执行. venv/bin/activate的时候,本来虚拟环境就是把它自己的绝对路径放到了环境变量里面。因此每一次调用 Python 或者其他包的时候,都是使用虚拟环境中安装的。

虽然 Makefile 文件变得有点复杂了,但是我们要测试代码的时候,还是仅仅需要简单地执行一下命令:

$ make test

就可以了,我们不需要再去关心虚拟环境是不是已经安装了之类的问题。如果你不需要支持 Windows,甚至可以从 Makefile 里面移除Windows 相关的部分。这样一来,这个 Makefile 文件即使对于不怎么用的人来说也不难理解。

哪一种更好?

我觉得第二种方案更方便。虽然第一种方法我已经快乐地用了几年了,而第二种方法是最近才学到的。之前我确实没有注意到这种方法。但我注意到几乎所有使用 Makefile的 Python 项目都用的第一种方法,我也想知道为什么。

Kingname 点评

我在Python 项目和Golang 项目里面经常使用Makefile,其中,Python 项目我主要用来删除__pycache__,而 Golang 项目中,由于我使用的是 VSCode 来开发,它的 lint 有点问题,所以代码写完以后,我会使用 Makefile 来执行一段gofmt命令,把所有.go文件都格式化。

但 Makefile 有一个非常智障的地方——它里面的缩进必须使用制表符,不能使用空格。所以要写Makefile 的时候,我还必须用 vim 来写。因为我的 PyCharm 已经调成把所有制表符换成空格的设置了。而如果在 Makefile 的缩进里面混入了空格,它就会报错。

如果大家对 Makefile 有兴趣的话,我给大家写一篇从入门到精通的文章。有兴趣的同学请留言~

参考资料

[1]

Writing Makefiles for Python Projects: https://venthur.de/2021-03-31-python-makefiles.html

[2]

makefile.venv: https://github.com/sio/Makefile.venv

---------End---------

关注后回复“w”,加我私人微信

????分享、点赞、在看,给个三连击呗!???? 

转载地址:http://djzzb.baihongyu.com/

你可能感兴趣的文章
Windows程序设计:直线绘制
查看>>
linux之CentOS下文件解压方式
查看>>
Django字段的创建并连接MYSQL
查看>>
div标签布局的使用
查看>>
HTML中表格的使用
查看>>
(模板 重要)Tarjan算法解决LCA问题(PAT 1151 LCA in a Binary Tree)
查看>>
(PAT 1154) Vertex Coloring (图的广度优先遍历)
查看>>
(PAT 1115) Counting Nodes in a BST (二叉查找树-统计指定层元素个数)
查看>>
(PAT 1143) Lowest Common Ancestor (二叉查找树的LCA)
查看>>
(PAT 1061) Dating (字符串处理)
查看>>
(PAT 1118) Birds in Forest (并查集)
查看>>
数据结构 拓扑排序
查看>>
(PAT 1040) Longest Symmetric String (DP-最长回文子串)
查看>>
(PAT 1145) Hashing - Average Search Time (哈希表冲突处理)
查看>>
(1129) Recommendation System 排序
查看>>
PAT1090 Highest Price in Supply Chain 树DFS
查看>>
(PAT 1096) Consecutive Factors (质因子分解)
查看>>
(PAT 1019) General Palindromic Number (进制转换)
查看>>
(PAT 1073) Scientific Notation (字符串模拟题)
查看>>
(PAT 1080) Graduate Admission (排序)
查看>>