作为很长一段时间的Python程序员,我想知道,如果Python文化的一个核心方面很长一段时间让我感到困惑:我们做什么而不是Makefile?
我见过的大多数ruby项目(不仅仅是rails)使用 Rake ,在 node.js 开始流行后不久,有 cake 。在许多其他(编译和非编译)语言中,有经典的 Make 文件。
但在Python中,似乎没有人需要这样的基础设施。我在GitHub上随机选择了Python项目,除setup.py
提供的安装外,它们没有自动化。
这背后的原因是什么?
没有什么可以自动化吗?大多数程序员是否喜欢手动运行样式检查,测试等?
一些例子:
dependencies
设置virtualenv并安装依赖项check
调用pep8
和pylint
命令行工具。test
任务取决于dependencies
启用virtualenv,启动selenium-server进行集成测试,并调用nosetest
coffeescript
任务将所有coffeescripts编译为minified javascript runserver
任务取决于dependencies
和coffeescript
deploy
任务取决于check
和test
并部署项目。docs
任务使用适当的参数调用sphinx 他们中的一些只是一两行,但恕我直言,他们加起来。由于Makefile,我不必记住它们。
澄清一下:我不是在寻找Rake的Python等价物。摊铺机我很高兴。我正在寻找原因。
答案 0 :(得分:11)
Setuptools
可以自动化很多东西,对于非内置的东西,它很容易扩展。
setup.py test
调用中添加test_suite
参数后使用setup()
命令。 (documentation)install_requires
调用添加extras_require
/ dependency_links
/ setup()
参数来处理依赖关系(即使在PyPI上不可用)。 (documentation).deb
包,您可以使用stdeb
模块。但是我同意S.Lott
,你希望自动化的大多数任务(除了依赖处理可能,它是我发现的唯一一个非常有用的任务)是你每天不运行的任务,所以不会通过自动化来提高生产力。
答案 1 :(得分:10)
实际上,自动化对Python开发人员也很有用!
对于常见的重复Python任务的自动化,调用可能是最接近你的想法的工具:https://github.com/pyinvoke/invoke
使用invoke,您可以像这样创建一个tasks.py(从调用文档中借用)
from invoke import run, task
@task
def clean(docs=False, bytecode=False, extra=''):
patterns = ['build']
if docs:
patterns.append('docs/_build')
if bytecode:
patterns.append('**/*.pyc')
if extra:
patterns.append(extra)
for pattern in patterns:
run("rm -rf %s" % pattern)
@task
def build(docs=False):
run("python setup.py build")
if docs:
run("sphinx-build docs docs/_build")
然后,您可以在命令行运行任务,例如:
$ invoke clean
$ invoke build --docs
另一种选择是简单地使用Makefile。例如,Python项目的Makefile可能如下所示:
docs:
$(MAKE) -C docs clean
$(MAKE) -C docs html
open docs/_build/html/index.html
release: clean
python setup.py sdist upload
sdist: clean
python setup.py sdist
ls -l dist
答案 2 :(得分:5)
Python中有许多自动化选项。我不认为存在反对自动化的文化,没有一种主导方式可以做到这一点。共同点是distutils。
与您的描述相关的那个是buildout。这主要用于Zope / Plone世界。
我自己使用以下各项的组合:Distribute,pip和Fabric。我主要使用具有manage.py自动命令的Django进行开发。
它也在Python 3.3
中积极开展工作答案 3 :(得分:2)
任何体面的测试工具都有一种在单个命令中运行整个套件的方法,没有什么能阻止你使用rake,make或其他任何东西。
当现有方法运作良好时,没有理由发明一种新的做事方式 - 为什么仅仅因为你没有发明它而重新发明一些东西? (NIH)。
答案 4 :(得分:1)
可以找到引发此问题的原始PEP here。 Distutils已成为分发和安装Python模块的标准方法。
为什么呢?恰好,python是一种很棒的语言,用于执行Python模块的安装。
答案 5 :(得分:0)
以下是一些使用python制作文件的示例:
https://blog.horejsek.com/makefile-with-python/
https://krzysztofzuraw.com/blog/2016/makefiles-in-python-projects.html
我认为大多数人都不知道“ python的makefile”情况。可能有用,但是“性感比”太小而无法快速传播(仅是我的PPOV)。
答案 6 :(得分:-1)
make
实用程序是一种优化工具,可减少构建软件映像所花费的时间。当以前构建的所有中间材料仍然可用并且仅对输入(例如源代码)进行了很小的更改时,就可以减少时间。在这种情况下,make
可以执行“增量构建”:仅重建受输入更改影响的中间部分的子集。
完成完整的构建后,make
所要做的全部工作就是执行一组脚本步骤。这些相同的步骤可以直接放入一个平面脚本中。实际上,-n
的{{1}}选项将打印这些步骤,这使之成为可能。
Makefile不是“自动化”;这是“以优化增量重建为目标的自动化”。用任何脚本工具编写的脚本都是自动化的。
那么,为什么Python项目会避开诸如make
之类的工具?可能是因为Python项目不会因为渴望优化而花费很长的构建时间。并且,make
到.py
文件的编译也没有像.pyc
到.c
那样的依赖关系网。
C源文件可以.o
数百个从属文件;这些文件中的任何一个字符更改一个字符都意味着必须重新编译源文件。正确编写的#include
将检测情况是否如此。
一个没有增量构建系统的大型C或C ++项目意味着开发人员必须等待小时才能弹出可执行映像进行测试。快速的增量构建至关重要。
就Python而言,您可能只需要担心Makefile
文件比其对应的.py
更新时,可以通过简单的脚本处理:遍历所有文件,并重新编译比其字节码新的内容。而且,编译首先是可选的!
因此,Python项目倾向于不使用.pyc
的原因是,他们执行增量重建优化的需求很低,并且他们使用其他自动化工具。 Python程序员更熟悉的工具,例如Python本身。
答案 7 :(得分:-4)
没有什么可以自动化吗?
不是真的。除了两个示例之外的所有示例都是单行命令。
tl; dr 这很少有趣或复杂。这似乎很少受益于“自动化”。
由于文档的原因,我不必记住执行此操作的命令。
大多数程序员是否喜欢手动运行样式,测试等?
是
生成文档, docs任务使用适当的参数调用sphinx
这是一行代码。自动化并没有多大帮助。
sphinx-build -b html source build/html
。那是一个剧本。用Python编写。
我们很少这样做。一周几次。在“重大”变化之后。
运行stylechecks(Pylint,Pyflakes和pep8-cmdtool)。 检查调用pep8和pylint命令行工具
我们不这样做。我们使用单元测试而不是pylint。 您可以自动完成这个三步过程。
但我可以看到SCons或make如何帮助这里的人。
测试
这里可能存在“自动化”的空间。这是两行:非Django单元测试(python test/main.py
)和Django测试。 (manage.py test
)。可以应用自动化来运行两条线。
我们每天都会这样做几十次。我们从来不知道我们需要“自动化”。
dependecies设置virtualenv并安装依赖项
完成这么简单的步骤就是我们所需要的所有步骤。我们非常非常仔细地跟踪我们的依赖关系,所以从来没有任何意外。
我们不这样做。
测试任务依赖于依赖关系启用virtualenv,启动selenium-server进行集成测试,并调用nosetest
start server & run nosetest
作为两步“自动化”是有道理的。它使您无需输入两个shell命令来运行这两个步骤。
coffeescript任务将所有coffeescripts编译为缩小的javascript
这对我们来说非常罕见。我想这是一个自动化的好例子。自动化单行脚本可能会有所帮助。
我可以看到SCons或make如何帮助这里的人。
runserver任务依赖于依赖项和coffeescript
除。依赖变化很少,这似乎有点矫枉过正。我认为你首先不能很好地跟踪依赖关系。
部署任务取决于检查和测试并部署项目。
服务器上有svn co
和python setup.py install
,然后是从subversion区域到客户/www
区域的一堆客户特定副本。那是一个剧本。用Python编写。
这不是一般制作或SCons类的东西。它只有一个actor(一个sysadmin)和一个用例。我们不会将部署与其他开发,QA或测试任务混合在一起。