Moshe Zadka 发布的文章

选择的这些工具将简化你的 Python 环境,以实现顺畅和一致的开发实践。

Python 是一门出色的通用编程语言,经常作为第一门编程语言来教授。二十年来,我为它撰写了很多本书,而它仍然是我的首选语言。虽然通常来说这门语言是简洁明了的,但是(正如 xkcd 讽刺的),从来没有人说过配置 Python 环境也是一样的简单。

 title=

一个复杂的Python环境。 xkcd

在日常生活中有很多使用 Python 的方法。我将解释我是如何使用这些 Python 生态系统工具的。但坦诚的说,我仍在寻找更好的替代品。

使用 pyenv 来管理 Python 版本

我发现在机器上运行一个特定版本的 Python 的最好方法是使用 pyenv。这个软件可以在 Linux、Mac OS X 和 WSL2 上工作:这是我通常关心的三个 “类 UNIX” 环境。

安装 pyenv 本身有时会有点棘手。一种方法是使用专用的 pyenv 安装程序,它使用 curl | bash 方法来进行(详见其说明)。

如果你是在 Mac 上(或者你运行 Homebrew 的其他系统),你可以按照这里的说明来安装和使用 pyenv

按照说明安装和设置了 pyenv 之后,你可以使用 pyenv global 来设置一个 “默认的” Python 版本。一般来说,你会选择你的 “首选” 版本。这通常是最新的稳定版本,但如果有其他考虑因素也可能做出不同的选择。

使用 virtualenvwrapper 让虚拟环境更简单

使用 pyenv 安装 Python 的一个好处是,你所有后继安装的 Python 解释器环境都是你自己的,而不是操作系统层面的。

虽然在 Python 本身内部安装东西通常不是最好的选择,但有一个例外:在上面选择的 “首选” Python 中,安装并配置 virtualenvwrapper。这样你就可以瞬间创建和切换到虚拟环境。

我在这篇文章中具体介绍了如何安装和使用 virtualenvwrapper

这里我推荐一个独特的工作流程:你可以制作一个可以大量重复运行的虚拟环境,用来做 运行器 runner 。在这个环境中,可以安装你最喜欢的运行器 —— 也就是你会经常用来运行其他软件的软件。就目前而言,我的首选是 tox

使用 tox 作为 Python 运行器

tox 是一个很好的工具,可以让你的 Python 测试自动化。在每个 Python 环境中,我都会创建一个 tox.ini 文件。无论我使用什么系统做持续集成,都可以运行它,我可以用上面文章中描述的 virtualenvwrapperworkon 语法在本地运行同样的东西:

$ workon runner
$ tox

这个工作流程之所以重要,是因为我要在多个版本的 Python 和多个版本的依赖库中测试我的代码。这意味着在 tox 运行器中会有多个环境。一些会尝试在最新的依赖关系中运行,一些会尝试在冻结的依赖关系中运行(接下来会有更多的介绍),我也可能会用 pip-compile 在本地生成这些环境。

附注:我目前正在研究使用 nox 作为 tox 的替代品。原因超出了本文的范畴,但值得一试。

使用 pip-compile 进行 Python 依赖性管理

Python 是一种动态编程语言,这意味着它在每次执行代码时都会加载其依赖关系。能否确切了解每个依赖项的具体运行版本可能意味着是平稳运行代码还是意外崩溃。这意味着我们必须考虑依赖管理工具。

对于每个新项目,我都会包含一个 requirements.in 文件,(通常)只有以下内容:

.

是的,没错。只有一个点的单行。我在 setup.py 文件中记录了 “宽松” 的依赖关系,比如 Twisted>=17.5。这与 Twisted==18.1 这样的确切依赖关系形成了鲜明对比,后者在需要一个特性或错误修复时,难以升级到新版本的库。

. 的意思是 “当前目录”,它使用当前目录下的 setup.py 作为依赖关系的来源。

这意味着使用 pip-compile requirements.in > requirements.txt 会创建一个冻结的依赖文件。你可以在 virtualenvwrapper 创建的虚拟环境中或者 tox.ini 中使用这个依赖文件。

有时,也可以从 requirements-dev.in(内容:.[dev])生成 requirements-dev.txt,或从 requirements-test.in(内容:.[test])生成 requirements-test.txt

我正在研究在这个流程中是否应该用 dephell 代替 pip-compiledephell 工具有许多有趣的功能,比如使用异步 HTTP 请求来下载依赖项。

结论

Python 的功能既强大又赏心悦目。为了编写这些代码,我依靠了一个对我来说很有效的特定工具链。工具 pyenvvirtualenvwrappertoxpip-compile 都是独立的。但是,它们各有各的作用,没有重叠,它们一起打造了一个强大的 Python 工作流。


via: https://opensource.com/article/20/6/python-tools

作者:Moshe Zadka 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

包括这 3 个模板语言在内,Python 积累了许多模板语言。

当需要使用模板语言来编写 Python Web 应用时,有很多健壮的解决方案。

Jinja2Genshi 和 Mako。甚至还有 Chameleon 之类的解决方案,虽然有些陈旧,但仍被 Pyramid 框架推荐。

Python 已经存在了很长时间。此时,在系统的深处,它积累了一些几乎被遗忘的模板语言,它们都是值得一试的。

这些语言就像桉树上可爱的考拉一样,在自己的生态圈里快乐地生活着,有时也会有危险的工作,这些都是很少有人听说过的模板语言,使用过的应该更少。

3、string.Template

你是否曾经想过:“如何获得一种没有任何特性的模板语言,而且同时也不需要 pip install 安装任何东西?” Python 标准库已经为你提供了答案。虽然没有循环和条件,但 string.Template 类是一种最小的模板语言。

使用它很简单。

>>> import string
>>> greeting = string.Template("Hello, $name, good $time!")
>>> greeting.substitute(name="OpenSource.com", time="afternoon")
'Hello, OpenSource.com, good afternoon!'

2、twisted.web.template

你会给一个包罗万象的库送什么礼物?

当然,不是模板语言,因为它已经有了。twisted.web.template 中嵌套了两种模板语言。一种是基于 XML 的,并有一个很棒的文档

但是它还有另一种,一种基于使用 Python 作为领域特定语言(DSL)来生成 HTML 文档。

它基于两个原语:包含标签对象的 twisted.web.template.tags 和渲染它们的 twisted.web.template.flattenString。由于它是 Twisted 的一部分,因此它内置支持高效异步渲染。

此例将渲染一个小页面:

async def render(reactor):
    my_title = "A Fun page"
    things = ["one", "two", "red", "blue"]
    template = tags.html(
            tags.head(
                tags.title(my_title),
            ),
            tags.body(
                tags.h1(my_title),
                tags.ul(
                    [tags.li(thing) for thing in things],
                ),
                tags.p(
                    task.deferLater(reactor, 3, lambda: "Hello "),
                    task.deferLater(reactor, 3, lambda: "world!"),
                )
            )
    )
    res = await flattenString(None, template)
    res = res.decode('utf-8')
    with open("hello.html", 'w') as fpout:
        fpout.write(res)

该模板是使用 tags.<TAGNAME> 来指示层次结构的常规 Python 代码。原生支持渲染字符串,因此任何字符串都正常。

要渲染它,你需要做的是添加调用:

from twisted.internet import task, defer
from twisted.web.template import tags, flattenString

def main(reactor):
    return defer.ensureDeferred(render(reactor))

最后写上:

task.react(main)

只需 3 秒(而不是 6 秒),它将渲染一个不错的 HTML 页面。在实际中,这些 deferLater 可以是对 HTTP API 的调用:它们将并行发送和处理,而无需付出任何努力。我建议你阅读关于更好地使用 Twisted。不过,这已经可以工作了。

1、Quixote

你会说:“但是 Python 并不是针对 HTML 领域而优化的领域特定语言。” 如果有一种语言可以转化到 Python,但是更适合定义模板,而不是像 Python 那样按原样解决呢?如果可以的话,请使用“Python 模板语言”(PTL)。

编写自己的语言,有时被说成是一个攻击假想敌人的唐吉坷德项目。当 Quixote(可在 PyPI 中找到)的创造者决定这样做时,并没有受此影响。

以下将渲染与上面 Twisted 相同的模板。警告:以下不是有效的 Python 代码

import time

def render [html] ():
    my_title = "A Fun page"
    things = ["one", "two", "red", "blue"]
    "<html><head><title>"
    my_title
    "</head></title><body><h1>"
    my_title
    "</h1>"
    "<ul>"
    for thing in things:
        "<li>"
        thing
        "</li>"
    "<p>"
    time.sleep(3)
    (lambda: "Hello ")()
    time.sleep(3)
    (lambda: "world!")()
    "</p>"
    "</body></html>"

def write():
    result = render()
    with open("hello.html", 'w') as fpout:
        fpout.write(str(result))

但是,如果将它放到 template.ptl 文件中,那么可以将其导入到 Quixote 中,并写出可以渲染模板的版本:

>>> from quixote import enable_ptl
>>> enable_ptl()
>>> import template
>>> template.write()

Quixote 安装了一个导入钩子,它会将 PTL 文件转换为 Python。请注意,此渲染需要 6 秒,而不是 3 秒。你不再获得自由的异步性。

Python 中的模板太多

Python 库的历史悠久且曲折,其中一些库可以或多或少都能达到类似结果(例如,Python 包管理)。

我希望你喜欢探索这三种可以用 Python 创建模板的方式。另外,我建议从这三个库之一开始了解。

你是否有另一种深奥的模板方法?请在下面的评论中分享!


via: https://opensource.com/article/20/4/python-templating-languages

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解如何使用 dh\_virtualenv 来让你的 Python 应用可作为 .deb 包安装。

在基于 Debian 的操作系统(例如 Debian 或 Elementary OS)上安装 Python 应用的一种方法是使用 dh\_virtualenv 工具。它可以构建一个 .deb 包,在应用之外封装了一个 Python 虚拟环境,并在安装时进行部署。

在本文中,我将以构建一个包含 HTTPie 工具的包为例来解释如何使用它,以便在无需激活虚拟环境的情况下从命令行测试 HTTP API。

使用 dh\_virtualenv 打包

首先,你需要安装 dh_virtualenv 所需的工具。dh_virtualenv文档提供了所有安装选项。在基于 Debian 的系统上,我输入:

apt-get install dh-virtualenv devscripts

尽管不需要 devscripts 包,但它可以简化后续操作。

现在,创建一个目录来保存源码。由于这是一个本地的、非官方的 HTTPie 打包,因此我将其称为 myhttp。接下来,让我们在 myhttp 内创建一些文件,向 Debian 构建系统提供元数据。

首先,创建 debian/control 文件:

Source: myhttp
Section: python
Priority: extra
Maintainer: Jan Doe <[email protected]>
Build-Depends: debhelper (>= 9), python3.7, dh-virtualenv (>= 0.8)
Standards-Version: 3.9.5

Package: myhttp
Architecture: any
Pre-Depends: dpkg (>= 1.16.1), python3.7, ${misc:Pre-Depends}
Depends: ${misc:Depends}
Description: http client
 Useful for doing stuff

那么这些是什么信息呢?正如 Debian 文档指出的:

“第 1–7 行是源码包的控制信息。第 9–13 行是二进制包的控制信息。”

以下是我使用的:

  • Section 的值对于我们来说大多没有意义,但需要存在。它对给引导式 UI 安装程序提供信息是有意义的,但对于这个包来说,没有意义。
  • Priority 对像这样的第三方包的正确值是 extra
  • 强烈建议在 Maintainer 字段中填写正确的联系人信息。但不一定非得是你的个人电子邮件,如果包由团队维护,并且你希望将问题发送到团队的邮件别名,例如 Infrastructure Team <[email protected]>
  • Build-Depends 字段标识你需要 debhelperpythondh-virtualenv 来构建包:包构建过程中将确保这些依赖项在包构建时已安装。
  • Standards-Version 字段主要给人看。它表明你遵循的指南。本指南基于 dh-virtualenv 的官方文档,它是基于 Debian 的 3.9.5 指南。最好一直将源码包和二进制包命名相同。
  • Architecture 字段应为 Any,因为除非虚拟环境可能包含一些特定于体系结构的文件。否则,最好选择该字段为 any
  • 保持 Pre-Depends 列表不变:它是一种非常严格的依赖关系形式,你很少会需要比这里建议的最小依赖更多的依赖项。依赖项通常由构建系统准确计算,因此没有理由手动指定它们。
  • 如果你的包主要用于内部,那么 Description 字段可能只需要最少的信息或者指向公司 wiki 的链接,不然更多的信息会更有用。

然后创建 debian/compat 文件,它主要出于历史目的而存在

$ echo "9" > debian/compat

接下来,创建更新日志以告知包用户自上次发布以来发生了什么变化。最简单的方法是使用 dch --create 创建模板,然后填写值。

填写后,它看起来像:

myhttp (2.0.0-1) stable; urgency=medium

  * Initial release.

 -- Jan Doe <[email protected]>  Fri, 27 Mar 2020 01:09:22 +0000

现在你需要告诉工具安装 HTTPie,但是哪个版本?

创建一个宽松版本的 requirements.in 文件:

httpie

通常,宽松的需求文件将仅包含项目的直接依赖项,并在需要时指定最低版本。不一定总是需要指定最低版本:这些工具通常偏向于将依赖关系转化为“可能的最新版本”。如果你的 Debian 包与一个内部 Python 包相对应,这是内部应用中的一种常见情况,那么宽松的需求文件看起来将很相似:仅包含包名的一行。

然后使用 pip-compile(可通过安装 PyPI 包 pip-tools 获得):

$ pip-compile requirements.in > requirements.txt

这会生成一个严格的依赖文件,名为 requirements.txt

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile requirements.in
#
certifi==2019.11.28       # via requests
chardet==3.0.4            # via requests
httpie==2.0.0             # via -r requirements.in
idna==2.9                 # via requests
pygments==2.6.1           # via httpie
requests==2.23.0          # via httpie
urllib3==1.25.8           # via requests

最后,写一个 debian/rules 文件来创建包。因为 dh_virtualenv 会处理所有困难的事,因此规则文件很简单:

#!/usr/bin/make -f

%:
        dh $@ --with python-virtualenv --python /usr/bin/python3.7

确保指定 Python 解释器。默认它会使用 /usr/bin/python,这是 Python2,但是你应该使用一个受支持的 Python 版本

完成了,接下来就是构建包:

$ debuild -b -us -uc

这会在父目录生成一个类似 myhttp_2.0.0-1_amd64.deb 的文件。该文件可在任何兼容的系统上安装。

通常,最好在同一平台上构建用于特定平台(例如 Debian 10.0)的 Debian 包。

你可以将此 Debian 包保存在软件仓库中,并使用例如 Ansible 的工具将其安装在所有相关系统上。

总结

给基于 Debian 的系统的打包应用是一个有着多个步骤的过程。使用 dh_virtualenv 将使过程变得简单明了。


via: https://opensource.com/article/20/4/package-python-applications-linux

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

本文是 Python 之禅特别系列的第三篇,此篇着眼于其中第五与第六条原则:扁平与稀疏。

Python 之禅 之所以得名,正是由于它那简明扼要的规则被设计出的意图在于让读者进行深入地思考,而绝不单是为编程提供一份易于遵守的指南。

读后不去三思其意,断然难以体会 Python 之禅的妙处。倘若 Python 之禅仅仅罗列出一组清晰的法则,那法则之间的矛盾是一种缺憾,然而作为引导读者沉思最优方案沉思的工具,矛盾却是绝佳的。

扁平胜过嵌套 Flat is better than nested

迫于对缩进的强硬要求,Python 对“扁平化”的需求显然远超它者。其余编程语言为了缓解对缩进的需求,通常会在嵌套结构里加入一种“作弊”的手段。为了理解这一点,不妨一同来看看 JavaScript。

JavaScript 本质上是异步的,这意味着程序员用 JavaScript 写的代码会用到大量的回调函数。

a(function(resultsFromA) {
  b(resultsFromA, function(resultsfromB) {
    c(resultsFromC, function(resultsFromC) {
      console.log(resultsFromC)
   }
  }
}

忽略这段代码的具体内容,只去观察这段代码的形状与缩进带来一个最右边的点的方式。这种独特的“箭头”图形在我们扫看代码时格外扎眼,这种写法也因此被视作不可取,甚至得到了“回调地狱”的绰号。不过,在 JavaScript 中,这种反映嵌套关系的缩进可以通过“作弊”来回避。

a(function(resultsFromA) {
b(resultsFromA,
  function(resultsfromB) {
c(resultsFromC,
  function(resultsFromC) {
    console.log(resultsFromC)
}}}

Python 并没有提供这种作弊手段:每一级嵌套在代码中都如实的对应着一层缩进。因此,Python 深层的嵌套关系在视觉上也一定是深层嵌套的。这使得“回调地狱”的问题对于 Python 而言要比在 JavaScript 中严重得多:嵌套的回调函数必定带来缩进,而绝无使用花括号来“作弊”的可能。

这项挑战与 Python 之禅的指导原则相结合后,在我参与的库中催生出了一个优雅的解决方案。我们在 Twisted 框架里提出了 deferred 抽象,日后 JavaScript 中流行的 promise 抽象亦是受其启发而生。正是由于 Python 对整洁代码的坚守,方能推动 Python 开发者去发掘新的、强力的抽象。

future_value = future_result()
future_value.addCallback(a)
future_value.addCallback(b)
future_value.addCallback(c)

(现代 JavaScript 程序员也许会觉得这段代码十分眼熟:promise 着实受到了 Twisted 里 deferred 抽象的深远影响。)

稀疏胜过密集 Sparse is better than dense

最易降低代码密集程度的方法是引入嵌套。这种习惯也正是有关稀疏的原则要随着前一条提出的原因:在竭尽所能地减少嵌套之后,我们往往会遗留下密集的代码或数据结构。此处的密集,是指塞进过量信息的小段代码,它们会导致错误发生后的解析变得困难。

这种密集性唯有通过创造性的思考方可改善,此外别无捷径。Python 之禅并不为我们提供简单的解决方案,它只会指明改善代码的方向,而非提供“如何”去做的向导。

起身走走,泡个热水澡,抑或是闻闻花香。盘坐冥思,直至灵感袭来。当你终于得到启发,便是动身写代码之时。


via: https://opensource.com/article/19/12/zen-python-flat-sparse

作者:Moshe Zadka 选题:lujun9972 译者:caiichenr 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在这有关 Linux 命令的十大文章中,了解如何使 Linux 发挥所需的作用。

很好地使用 Linux 意味着了解有哪些命令以及它们可以为你执行的功能。

《在 Linux 命令行下使用“原力”》

原力 force 有光明的一面和黑暗的一面。正确理解这个对于真正掌握它至关重要。Alan Formy-Duval 在他的文章《在 Linux 命令行下使用“原力”》中,解释了一些流行的、有时是危险的命令的 -f 选项(也称为 --force)。

《Linux useradd 命令介绍》

共享帐户是一个坏主意。相反,请使用典型的 useradd 命令为不同的人(甚至是不同的角色)分配单独的帐户。作为其经典的 Linux 管理基础系列的一部分,Alan Formy-Duval 提供了《Linux useradd 命令介绍》,并且像往常一样,他用朴实明白的语言对其进行了解释,以便新老管理员都可以理解。

《用 Linux 命令显示硬件信息》

机器里面是什么?有时不使用螺丝刀检查硬件很有用。无论是你正在使用的计算机,还是在商店购买前进行测试的计算机、或者是正在尝试维修的计算机,在《用 Linux 命令显示硬件信息》中,Howard Fosdick 提供了或流行或晦涩难懂的命令,以帮助你深入了解计算机的硬件信息。

《如何在 Linux 上使用 gocryptfs 加密文件》

从社会保险号到个人信件再到亲人,我们的文件中包含了许多私人数据。在《如何在 Linux 上使用 gocryptfs 加密文件》中,Brian Bex Exelbierd 解释了如何保持*隐私的私密性。此外,他展示了一种加密文件的方式,这种方式对你现有的工作流程几乎没有影响。这不是复杂的 PGP 风格的密钥管理和后台密钥代理的难题,这是快速、无缝和安全的文件加密。

《如何使用 rsync 的高级用法进行大型备份》

在新的一年中,许多人会下定决心要更加努力地进行备份。Alan Formy-Duval 早在几年前就已经做出了解决方案,因为在《如何使用 rsync 的高级用法进行大型备份》中,他表现出对文件同步命令的极其熟悉。你可能不会马上记住所有语法,但其思路是读取和处理选项、构造备份命令,然后使其自动化。这是使用 rsync 的明智方法,也是可靠地执行备份的唯一方法。

《在 Linux 命令行使用 more 查看文本文件》

在 Scott Nesbitt 的文章《在 Linux 命令行使用 more 查看文本文件》中,古老而良好的默认分页器 more 引起了人们的关注。许多人安装和使用 less,因为它比 more 更灵活。但是,随着越来越多的系统在新出现的容器中实现,有时甚至不存在像 lessmost 之类的新颖的豪华工具。了解和使用more 很简单,这是常见的默认设置,并且是生产系统最后的调试工具。

《关于 sudo 你可能不知道的》

sudo 命令因其过失而闻名。人们知道 sudo 一词,我们大多数人认为我们知道它的作用。我们的观点是正确的,但是正如 Peter Czanik 在他的文章《关于 sudo 你可能不知道的》中所揭示的那样,该命令所包含的不仅仅是“ 西蒙说的 Simon says ”(LCTT 译注:国外的一个儿童游戏)。就像这个经典的童年游戏一样,sudo 命令功能强大,也容易犯愚蠢的错误 —— 有更多的可能产生可怕都后果,而这是你绝不想遇上的事情!

《怎样用 Bash 编程:语法和工具》

如果你是 Linux、BSD 或 Mac(以及近来的 Windows)用户,你也许使用过交互式 Bash shell。它是快速的、一次性命令的绝佳 shell,这就是为什么这么多 Linux 用户喜欢将其用作主要用户界面的原因。但是,Bash 不仅仅是个命令提示符。它也是一种编程语言,如果你已经在使用 Bash 命令,那么自动化的道路从未如此简单过。在 David Both 的出色作品《怎样用 Bash 编程:语法和工具》中对其进行全面了解。

《精通 Linux 的 ls 命令》

ls 命令是那些两个字母的命令之一。单字母命令是针对慢速终端的优化,因为慢速终端的输入的每个字母都会导致明显的延迟,而这对于懒惰的打字员来说也是不错的奖励。一如既往地,Seth Kenlon 清晰实用地解释了你可以怎样《精通 Linux 的 ls 命令》。最重要的是,在“一切都是文件”的系统中,列出文件至关重要。

《Linux cat 命令入门》

cat 命令(concatenate 的缩写)看似简单。无论是使用它来快速查看文件的内容还是将内容通过管道传输到另一个命令,你都可能没有充分利用 cat 的功能。Alan Formy-Duval 的《Linux cat 命令入门》提供了一些新思路,可以使你没有打开文件的感觉就可以看到文件内容。另外,了解各种有关 zcat 的知识,这样你就可以无需解压缩就可以得到压缩文件的内容!这是一件小而简单的事情,但是是使 Linux 很棒的原因。

继续旅程

不要让这些关于 Linux 命令的 10 篇最佳文章成为你的旅程终点。关于 Linux 及其多才多艺的提示符,还有更多值得去发现,因此,请继续关注以获取更多知识。而且,如果你想让我们介绍一个 Linux 命令,请在评论中告诉我们。


via: https://opensource.com/article/19/12/linux-commands

作者:Moshe Zadka 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

本文是 Python 之禅特别系列的第二篇,我们将要关注其中第三与第四条原则:简单与复杂。

Il semble que la perfection soit atteinte non quand il n'y a plus rien à ajouter, mais quand il n'y plus rien à retrancher.

It seems that perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away.

“完美并非无可增,而是不可减。”

—Antoine de Saint-Exupéry, Terre des Hommes, 1939

编程时最常有的考量是与复杂性的斗争,只想写出让旁人无从下手的繁杂代码,对每个程序员来讲都算不上难事。倘若未能触及代码的简繁取舍,那么 《Python 之禅》 就有了一角残缺。

简单胜过复杂 Simple is better than complex

尚有选择余地时,应该选简单的方案。Python 少有不可为之事,这意味着设计出巴洛克风格(LCTT 译注:即夸张和不理性)的程序只为解决浅显的问题不仅有可能,甚至很简单。

正因如此,编程时应当谨记,代码的简单性是最易丢失,却最难复得的。

这意味着,在可以选用函数来表达时不要去引入额外的类;避免使用强力的第三方库往往有助于你针对迫切的问题场景设计更妥当的简短函数。不过其根本的意图,旨在让你减少对将来的盘算,而去着重解决手头的问题。

以简单和优美作为指导原则的代码相比那些想要囊括将来一切变数的,在日后要容易修改得多。

复杂胜过错综复杂 Complex is better than complicated

把握用词的精确含义对于理解这条令人费解的原则是至关重要的。形容某事 复杂 complex ,是说它由许多部分组成,着重组成成分之多;而形容某事 错综复杂 complicated ,则是指其包含着差异巨大、难以预料的行为,强调的是各组成部分之间的杂乱联系。

解决困难问题时,往往没有可行的简单方案。此时,最 Python 化的策略是“ 自底向上 bottom-up ”地构建出简单的工具,之后将其组合用以解决该问题。

这正是 对象组合 object composition 这类技术的闪耀之处,它避免了错综复杂的继承体系,转而由独立的对象把一些方法调用传递给别的独立对象。这些对象都能独立地测试与部署,最终却可以组成一体。

“自底建造” 的另一例即是 单分派泛函数 singledispatch 的使用,抛弃了错综复杂的对象之后,我们得到是简单、几乎无行为的对象以及独立的行为。


via: https://opensource.com/article/19/12/zen-python-simplicity-complexity

作者:Moshe Zadka 选题:lujun9972 译者:caiichenr 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出