标签 python 下的文章

借鉴 C 语言的历史,学习如何用 Python 编写有用的 CLI 程序。

本文的目标很简单:帮助新的 Python 开发者了解一些关于命令行接口(CLI)的历史和术语,并探讨如何在 Python 中编写这些有用的程序。

最初……

首先,从 Unix 的角度谈谈命令行界面设计。

Unix 是一种计算机操作系统,也是 Linux 和 macOS(以及许多其他操作系统)的祖先。在图形用户界面之前,用户通过命令行提示符与计算机进行交互(想想如今的 Bash 环境)。在 Unix 下开发这些程序的主要语言是 C),它的功能非常强大。

因此,我们至少应该了解 C 程序的基础知识。

假设你没有读过上面那个链接的内容,C 程序的基本架构是一个叫做 main 的函数,它的签名是这样的。

   int main(int argc, char **argv)
   {
   ...
   }

对于 Python 程序员来说,这应该不会显得太奇怪。C 函数首先有一个返回类型、一个函数名,然后是括号内的类型化参数。最后,函数的主体位于大括号之间。函数名 main运行时链接器(构造和运行程序的程序)如何决定从哪里开始执行你的程序。如果你写了一个 C 程序,而它没有包含一个名为 main 的函数,它将什么也做不了。伤心。

函数参数变量 argcargv 共同描述了程序被调用时用户在命令行输入的字符串列表。在典型的 Unix 命名传统中,argc 的意思是“ 参数计数 argument count ”,argv 的意思是“ 参数向量 argument vector ”。向量听起来比列表更酷,而 argl 听起来就像一个要勒死的求救声。我们是 Unix 系统的程序员,我们不求救。我们让其他人哭着求救。

再进一步

$ ./myprog foo bar -x baz

如果 myprog 是用 C 语言实现的,则 argc 的值是 5,而 argv 是一个有五个条目的字符指针数组。(不要担心,如果这听起来过于技术,那换句话说,这是一个由五个字符串组成的列表。)向量中的第一个条目 argv[0] 是程序的名称。argv 的其余部分包含参数。

   argv[0] == "./myprog"
   argv[1] == "foo"
   argv[2] == "bar"
   argv[3] == "-x"
   argv[4] == "baz"
   
   /* 注:不是有效的 C 代码 */

在 C 语言中,你有很多方法来处理 argv 中的字符串。你可以手动地循环处理数组 argv,并根据程序的需要解释每个字符串。这相对来说比较简单,但会导致程序的接口大相径庭,因为不同的程序员对什么是“好”有不同的想法。

include <stdio.h>

/* 一个打印 argv 内容的简单 C 程序。 */

int main(int argc, char **argv) {
    int i;
   
    for(i=0; i<argc; i++)
      printf("%s\n", argv[i]);
}

早期对命令行标准化的尝试

命令行武器库中的下一个武器是一个叫做 getoptC 标准库函数。这个函数允许程序员解析开关,即前面带破折号的参数(比如 -x),并且可以选择将后续参数与它们的开关配对。想想 /bin/ls -alSh 这样的命令调用,getopt 就是最初用来解析该参数串的函数。使用 getopt 使命令行的解析变得相当简单,并改善了用户体验(UX)。

include <stdio.h>
#include <getopt.h>

#define OPTSTR "b:f:"

extern char *optarg;

int main(int argc, char **argv) {
    int opt;
    char *bar = NULL;
    char *foo = NULL;
   
    while((opt=getopt(argc, argv, OPTSTR)) != EOF)
       switch(opt) {
          case 'b':
              bar = optarg;
              break;
          case 'f':
              foo = optarg;
              break;
          case 'h':
          default':
              fprintf(stderr, "Huh? try again.");
              exit(-1);
              /* NOTREACHED */
       }
    printf("%s\n", foo ? foo : "Empty foo");
    printf("%s\n", bar ? bar : "Empty bar");
}

就个人而言,我希望 Python 有开关,但这永远、永远不会发生

GNU 时代

GNU 项目出现了,并为他们实现的传统 Unix 命令行工具引入了更长的格式参数,比如--file-format foo。当然,我们这些 Unix 程序员很讨厌这样,因为打字太麻烦了,但是就像我们这些旧时代的恐龙一样,我们输了,因为用户喜欢更长的选项。我从来没有写过任何使用 GNU 风格选项解析的代码,所以这里没有代码示例。

GNU 风格的参数也接受像 -f foo 这样的短名,也必须支持。所有这些选择都给程序员带来了更多的工作量,因为他们只想知道用户要求的是什么,然后继续进行下去。但用户得到了更一致的用户体验:长格式选项、短格式选项和自动生成的帮助,使用户不必再试图阅读臭名昭著的难以解析的手册页面(参见 ps 这个特别糟糕的例子)。

但我们正在讨论 Python?

你现在已经接触了足够多(太多?)的命令行的历史,对如何用我们最喜欢的语言来编写 CLI 有了一些背景知识。Python 在命令行解析方面给出了类似的几个选择:自己解析, 自给自足 batteries-included 的方式,以及大量的第三方方式。你选择哪一种取决于你的特定情况和需求。

首先,自己解析

你可以从 sys 模块中获取程序的参数。

import sys

if __name__ == '__main__':
   for value in sys.argv:
       print(value)

自给自足

在 Python 标准库中已经有几个参数解析模块的实现:getoptoptparse,以及最近的 argparseargparse 允许程序员为用户提供一致的、有帮助的用户体验,但就像它的 GNU 前辈一样,它需要程序员做大量的工作和“模板代码”才能使它“奏效”。

from argparse import ArgumentParser

if __name__ == "__main__":

   argparser = ArgumentParser(description='My Cool Program')
   argparser.add_argument("--foo", "-f", help="A user supplied foo")
   argparser.add_argument("--bar", "-b", help="A user supplied bar")
   
   results = argparser.parse_args()
   print(results.foo, results.bar)

好处是当用户调用 --help 时,有自动生成的帮助。但是 自给自足 batteries included 的优势呢?有时,你的项目情况决定了你对第三方库的访问是有限的,或者说是没有,你不得不用 Python 标准库来“凑合”。

CLI 的现代方法

然后是 ClickClick 框架使用装饰器的方式来构建命令行解析。突然间,写一个丰富的命令行界面变得有趣而简单。在装饰器的酷炫和未来感的使用下,很多复杂的东西都消失了,用户惊叹于自动支持关键字补完以及上下文帮助。所有这些都比以前的解决方案写的代码更少。任何时候,只要你能写更少的代码,还能把事情做好,就是一种胜利。而我们都想要胜利。

import click

@click.command()
@click.option("-f", "--foo", default="foo", help="User supplied foo.")
@click.option("-b", "--bar", default="bar", help="User supplied bar.")
def echo(foo, bar):
    """My Cool Program
   
    It does stuff. Here is the documentation for it.
    """
    print(foo, bar)
   
if __name__ == "__main__":
    echo()

你可以在 @click.option 装饰器中看到一些与 argparse 相同的模板代码。但是创建和管理参数分析器的“工作”已经被抽象化了。现在,命令行参数被解析,而值被赋给函数参数,从而函数 echo魔法般地调用。

Click 接口中添加参数就像在堆栈中添加另一个装饰符并将新的参数添加到函数定义中一样简单。

但是,等等,还有更多!

Typer 建立在 Click 之上,是一个更新的 CLI 框架,它结合了 Click 的功能和现代 Python 类型提示。使用 Click 的缺点之一是必须在函数中添加一堆装饰符。CLI 参数必须在两个地方指定:装饰符和函数参数列表。Typer 免去你造轮子 去写 CLI 规范,让代码更容易阅读和维护。

import typer

cli = typer.Typer()

@cli.command()
def echo(foo: str = "foo", bar: str = "bar"):
    """My Cool Program
   
    It does stuff. Here is the documentation for it.
    """
    print(foo, bar)
   
if __name__ == "__main__":
    cli()

是时候开始写一些代码了

哪种方法是正确的?这取决于你的用例。你是在写一个只有你才会使用的快速而粗略的脚本吗?直接使用 sys.argv 然后继续编码。你需要更强大的命令行解析吗?也许 argparse 就够了。你是否有很多子命令和复杂的选项,你的团队是否会每天使用它?现在你一定要考虑一下 ClickTyper。作为一个程序员的乐趣之一就是魔改出替代实现,看看哪一个最适合你。

最后,在 Python 中有很多用于解析命令行参数的第三方软件包。我只介绍了我喜欢或使用过的那些。你喜欢和/或使用不同的包是完全可以的,也是我们所期望的。我的建议是先从这些包开始,然后看看你最终的结果。

去写一些很酷的东西吧。


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

作者:Erik O'Shaughnessy 选题: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中国 荣誉推出

如果你在 macOS 上运行的项目需要没有安装的 Python 版本,请试试 pyenv。

即使对于有经验的开发人员,管理本地 Python 开发环境仍然是一个挑战。尽管有详细的软件包管理策略,但仍需要采取另外的步骤来确保你在需要时运行所需的 Python 版本。

为什么 Python 版本重要?

起初这是一个奇怪的概念,但是编程语言会像其他任何软件一样发生变化。它们有错误、修复和更新,就像你喜欢的 API 和任何其他软件一样。同样,不同的发行版由称为语义化版本的三位数标识。

??? pic.twitter.com/yt1Z2439W8

— Denny Perez (@dennyperez18) May 28, 2019

多年来,Python 2 是该语言的常用主要版本。在 2020 年 1 月,Python 2 到达最后寿命,此后,Python 的核心维护者将仅支持 Python 3。Python 3 稳步发展,并定期发布新更新。对我来说定期获取这些更新很重要。

最近,我试图在 macOS 上运行一个依赖于 Python 3.5.9 的项目,而我的系统上并没有安装这个版本。我认为 Python 包管理器 pip 可以安装它,但事实并非如此:

$ pip install python3.5.9
Collecting python3.5.9
  ERROR: Could not find a version that satisfies the requirement python3.5.9 (from versions: none)
ERROR: No matching distribution found for python3.5.9

或者,我也可以从官方 Python 网站下载该版本,但我如何在我的 Mac 上与现有的 Python 版本一起运行?每次运行时指定 Python 解释器版本(例如 python3.7 或 python3.5)似乎很容易出错。一定会有更好的方法。

(说明:我知道这对经验丰富的 Python 开发人员没有意义,但对当时的我来说是有意义的。我很乐意谈一谈为什么我仍然认为它应该这样做。)

安装和设置 pyenv

值得庆幸的是,pyenv 可以绕开这一系列复杂的问题。首先,我需要安装 pyenv。我可以从源码克隆并编译它,但是我更喜欢通过 Homebrew 包管理器来管理软件包:

$ brew install pyenv

为了通过 pyenv 使用 Python 版本,必须了解 shell 的 PATH 变量。PATH 决定了 shell 通过命令的名称来搜索文件的位置。你必须确保 shell 程序能够找到通过 pyenv 运行的 Python 版本,而不是默认安装的版本(通常称为系统版本)。如果不更改路径,那么结果如下:

$ which python
/usr/bin/python

这是 Python 的系统版本。

要正确设置 pyenv,可以在 Bash 或 zsh 中运行以下命令:

$ PATH=$(pyenv root)/shims:$PATH

现在,如果你检查 Python 的版本,你会看到它是 pyenv 管理的版本:

$ which python
/Users/my_username/.pyenv/shims/python

该导出语句(PATH=)仅会对该 shell 实例进行更改,为了使更改永久生效,你需要将它添加到点文件当中。由于 zsh 是 macOS 的默认 shell,因此我将重点介绍它。将相同的语法添加到 ~/.zshrc 文件中:

$ echo 'PATH=$(pyenv root)/shims:$PATH' >> ~/.zshrc

现在,每次我们在 zsh 中运行命令时,它将使用 pyenv 版本的 Python。请注意,我在 echo 中使用了单引号,因此它不会评估和扩展命令。

.zshrc 文件仅管理 zsh 实例,因此请确保检查你的 shell 程序并编辑关联的点文件。如果需要再次检查默认 shell 程序,可以运行 echo $SHELL。如果是 zsh,请使用上面的命令。如果你使用 Bash,请将 ~/.zshrc 更改为 ~/.bashrc。如果你想了解更多信息,可以在 pyenvREADME 中深入研究路径设置

使用 pyenv 管理 Python 版本

现在 pyenv 已经可用,我们可以看到它只有系统 Python 可用:

$ pyenv versions
system

如上所述,你绝对不想使用此版本(阅读更多有关信息)。现在 pyenv 已正确设置,我希望它能有我经常使用的几个不同版本的 Python。

有一种方法可以通过运行 pyenv install --list 来查看 pyenv 可以访问的所有仓库中的所有 Python 版本。这是一个很长的列表,将来回顾的时候可能会有所帮助。目前,我决定在 Python 下载页面找到的每个最新的“点版本”(3.5.x 或 3.6.x,其中 x 是最新的)。因此,我将安装 3.5.9 和 3.8.0:

$ pyenv install 3.5.9
$ pyenv install 3.8.0

这将需要一段时间,因此休息一会(或阅读上面的链接之一)。有趣的是,输出中显示了该版本的 Python 的下载和构建。例如,输出显示文件直接来自 Python.org

安装完成后,你可以设置默认值。我喜欢最新的,因此将全局默认 Python 版本设置为最新版本:

$ pyenv global 3.8.0

该版本立即在我的 shell 中设置完成。确认一下:

$ python -V
Python 3.8.0

我要运行的项目仅适于 Python 3.5,因此我将在本地设置该版本并确认:

$ pyenv local 3.5.9
$ python -V
Python 3.5.9

因为我在 pyenv 中使用了 local 选项,所以它向当前目录添加了一个文件来跟踪该信息。

$ cat .python-version
3.5.9

现在,我终于可以为想要的项目设置虚拟环境,并确保运行正确版本的 Python。

$ python -m venv venv
$ source ./venv/bin/activate
(venv) $ which python
/Users/mbbroberg/Develop/my_project/venv/bin/python

要了解更多信息,请查看有关在 Mac 上管理虚拟环境的教程。

总结

默认情况下,运行多个 Python 版本可能是一个挑战。我发现 pyenv 可以确保在我需要时可以有我需要的 Python 版本。

你还有其他初学者或中级 Python 问题吗? 请发表评论,我们将在以后的文章中考虑介绍它们。


via: https://opensource.com/article/20/4/pyenv

作者:Matthew Broberg 选题:lujun9972 译者:geekpi 校对:wxy

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

Python 开发者调查显示只有十分之一的人还在用 Python 2

Python 2 已经结束支持,根据 Python 软件基金会和 JetBrains 发布的第三年度 Python 开发者调查,被调查者中只有十分之一的人还在用 Python 2。这项调查收到了 2.4 万多名开发者的回应。

来源:solidot

硬核老王点评:看来 Python 2 终究会被淘汰,向前看总是社区潮流,虽然不能完全向后兼容的 Python 3 当时在社区中引来了很多争议,但目前看起来社区已经过渡到了 Python 3 时代。同样的,还有 systemd 的成功。与这些形成鲜明对比的是 Perl 6 的惨淡局面和 Perl 语言的整体衰落。所以,抛弃历史包袱的不破不立式进步,成功或失败的原因在哪里呢?

比特币第三次采矿回报减半

比特币第三次采矿回报减半提前于 5 月 12 日发生。比特币网络中运算难度是自动调节的,在最初的四年里会有 1050 0000 个 BTC 被制造出来,这个数值每四年减半,所以在第四到第八年中会有 525 0000 个BTC 被制造,在第 8 到第 12 年中会生产 262 5000 个BTC,以此类推。最终比特币的数额会趋近于 2100 0000 个BTC。区块的总数乘以每个区块的比特币值就是现存的比特币总数。2012 年 11 月 28 日,采矿回报从每区块 50 降至 25 BTC。第二次采矿回报减半发生在 2016 年 7 月 10 日。刚刚发生的是第三次,采矿回报从 12.5 减少到 6.25 BTC。第四次预计会在 2024 年 5 月 9 日发生。

来源:solidot

硬核老王点评:又一次减半,多少区块链圈的人如熬年般的关注这一刻。至于之后 BTC 乃至于区块链的发展,还需要拭目以待,不过我的看法总体是乐观的。

人社部拟发布 2 个区块链职业:区块链工程技术员、区块链运营操作员

5 月 11 日,人力资源社会保障部对拟发布新职业信息进行公示,其中包括两个区块链职业。区块链工程技术人员:从事区块链架构设计、底层技术、系统应用、系统测试、系统部署、运行维护的工程技术人员。区块链应用操作员:运用区块链技术及工具,从事政务、金融、医疗、教育、养老等场景系统应用操作的人员。

来源:人力资源社会保障部

硬核老王点评:区块链也有了“正当”职业了。

Swift 现支持更多 Linux 发行版本,包括 Ubuntu 20.04

苹果开源了 Swift 编程语言,但 Swift 跨平台的进展比较缓慢,目前仅支持 macOS 和 Ubuntu。在今年 3 月下旬,Swift 开发团队表示,其即将推出的 5.3 版本的目标包括“增加对 Windows 和其他 Linux 发行版的支持”。在目前支持的 Ubuntu 16.04/18.04 两个发行版本之外,Swift 项目现在添加了对 Ubuntu 20.04、CentOS 8 和 Amazon Linux 2 这三个发行版本的支持。项目团队表示,在未来几个月内将会添加对更多 Linux 发行版本的支持。

来源:cnBeta.COM

硬核老王点评:Swift 没有之前那么受关注了,但是作为一个优秀的编程语言,如果在跨平台方面能取得更多进展,想必能得到更多关注和应用。

罗永浩宣布 t.tt 域名新用途:曾花重金购买

“需要帮助的扶贫地区,如果你有好东西,想找人带货,我们很愿意义务做这样的事情。”今天罗永浩宣布了该域名的新用途——扶贫助农报名网址。罗永浩表示,接下来一段时期要做的是扶贫助农的活动,现在全国范围内,各地的那些县市,因为疫情经济活动受到很大的影响。所以他们手里有一些农产品、一些干货,那些好东西现在就不太好卖,所以呼吁让我们这行帮着做做扶贫助农活动,所以我们很愿意参与。

来源:快科技

硬核老王点评:至少从这个意义上看,还是值得支持的。

了解如何使用 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中国 荣誉推出

在 Linux 上安装最新 Python,替代或与老版本并存的分步说明。

Python 现在是最流行、最常用的编程语言。Python 的简单语法和较低的学习曲线使其成为初学者和专业开发人员的终极选择。Python 还是一种非常通用的编程语言。从 Web 开发到人工智能,它几乎在除了移动开发的所有地方都有使用。

如果你使用的是 Python,那么你很有可能是一名开发人员(或想成为一名开发人员),而 Linux 是创建软件的绝佳平台。但是,当你每天使用 Python 时,有时你希望使用最新版本。你可能不想仅仅为了测试最新版本的系统而替换了默认的 Python 安装,因此本文说明了如何在 Linux 上安装最新版本的 Python 3,而不替换发行版提供的版本。

使用 python --version 终端命令检查是否已安装 Python,如果已安装,那么检查是哪个版本。如果你的 Linux 系统上未安装 Python,或者你想安装更新的版本,请按照以下步骤操作。

分步安装说明

步骤 1:首先,安装构建 Python 所需的开发包

在 Debian 上

$ sudo apt update
$ sudo apt install build-essential zlib1g-dev \
libncurses5-dev libgdbm-dev libnss3-dev \
libssl-dev libreadline-dev libffi-dev curl

在 Fedora 上:

$ sudo dnf groupinstall development

步骤 2:下载最新的稳定版本的 Python 3

访问官方 Python 网站并下载最新版本的 Python 3。下载完成后,你会有一个 .tar.xz 归档文件(“tarball”),其中包含 Python 的源代码。

步骤 3:解压 tarball

下载完成后,使用解压程序或 Linux 的 tar 命令解压压缩包,例如:

$ tar -xf Python-3.?.?.tar.xz

步骤 4:配置脚本

解压 Python 压缩包后,进入 configure 脚本所在目录并在 Linux 终端中使用以下命令执行该脚本:

$ cd Python-3.*
./configure

配置可能需要一些时间。等待直到成功完成,然后再继续。

步骤 5:开始构建过程

如果你的系统上已经安装了某个版本的 Python,并且希望同时安装新版本的 Python,请使用以下命令:

$ sudo make altinstall

构建过程可能需要一些时间。

如果要使用此版本替换当前版本的 Python,那么应使用包管理器(例如 aptdnf)卸载当前的 Python 包,然后安装:

$ sudo make install

但是,通常最好以软件包的形式(例如 .deb.rpm 文件)来安装软件,以便系统可以为你跟踪和更新它。因为本文假设尚未打包最新的 Python,所以你可能没有这个选择。在这种情况下,你可以按照建议使用 altinstall 来安装 Python,或者使用最新的源代码重构现有的 Python 包。这是一个高级主题,并且特定于你的发行版,因此不在本文讨论范围之内。

步骤 6:验证安装

如果你没有遇到任何错误,那么现在你的 Linux 系统上已安装了最新的 Python。要进行验证,请在终端中输入以下命令之一:

python3 --version

或者

python --version

如果输出显示 Python 3.x,那么说明 Python 3 已成功安装。

创建虚拟环境(可选)

Python 提供了名为 venv(虚拟环境)的软件包,可帮助你将程序目录或软件包与其他目录或软件包隔离。

要创建虚拟环境,请在 Python 终端中输入以下内容(在此示例中,假定你安装的 Python 版本为 3.8 系列):

python3.8 -m venv example

该命令创建一个带有一些子目录的新目录(我将其命名为 example)。

要激活虚拟环境,请输入:

$ source example/bin/activate
(example) $

请注意,你的终端提示符($)现在以环境名称开头。

要停用虚拟环境,请使用 deactivate 命令:

(example) $ deactivate

总结

Python 是一种有趣的语言,它的开发和改进非常频繁。一旦了解了如何安装最新版本而又不干扰发行版提供的稳定版本,熟悉新功能将很容易。

如果你有任何反馈或问题,请在评论中提出。


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

作者:Vijay Singh Khatri 选题:lujun9972 译者:geekpi 校对:wxy

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