标签 python 下的文章

在 Jupyter 里使用 Python 来分析日历,以了解你是如何使用时间的。

 title=

Python 在探索数据方面具有令人难以置信的可扩展性。利用 PandasDask,你可以将 Jupyter 扩展到大数据领域。但是小数据、个人资料、私人数据呢?

JupyterLab 和 Jupyter Notebook 为我提供了一个绝佳的环境,可以让我审视我的笔记本电脑生活。

我的探索是基于以下事实:我使用的几乎每个服务都有一个 Web API。我使用了诸多此类服务:待办事项列表、时间跟踪器、习惯跟踪器等。还有一个几乎每个人都会使用到:日历。相同的思路也可以应用于其他服务,但是日历具有一个很酷的功能:几乎所有 Web 日历都支持的开放标准 —— CalDAV。

在 Jupyter 中使用 Python 解析日历

大多数日历提供了导出为 CalDAV 格式的方法。你可能需要某种身份验证才能访问这些私有数据。按照你的服务说明进行操作即可。如何获得凭据取决于你的服务,但是最终,你应该能够将这些凭据存储在文件中。我将我的凭据存储在根目录下的一个名为 .caldav 的文件中:

import os
with open(os.path.expanduser("~/.caldav")) as fpin:
    username, password = fpin.read().split()

切勿将用户名和密码直接放在 Jupyter Notebook 的笔记本中!它们可能会很容易因 git push 的错误而导致泄漏。

下一步是使用方便的 PyPI caldav 库。我找到了我的电子邮件服务的 CalDAV 服务器(你可能有所不同):

import caldav
client = caldav.DAVClient(url="https://caldav.fastmail.com/dav/", username=username, password=password)

CalDAV 有一个称为 principal(主键)的概念。它是什么并不重要,只要知道它是你用来访问日历的东西就行了:

principal = client.principal()
calendars = principal.calendars()

从字面上讲,日历就是关于时间的。访问事件之前,你需要确定一个时间范围。默认一星期就好:

from dateutil import tz
import datetime
now = datetime.datetime.now(tz.tzutc())
since = now - datetime.timedelta(days=7)

大多数人使用的日历不止一个,并且希望所有事件都在一起出现。itertools.chain.from_iterable 方法使这一过程变得简单:

import itertools

raw_events = list(
    itertools.chain.from_iterable(
        calendar.date_search(start=since, end=now, expand=True)
        for calendar in calendars
    )
)

将所有事件读入内存很重要,以 API 原始的本地格式进行操作是重要的实践。这意味着在调整解析、分析和显示代码时,无需返回到 API 服务刷新数据。

但 “原始” 真的是原始,事件是以特定格式的字符串出现的:

print(raw_events[12].data)
    BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//CyrusIMAP.org/Cyrus
     3.3.0-232-g4bdb081-fm-20200825.002-g4bdb081a//EN
    BEGIN:VEVENT
    DTEND:20200825T230000Z
    DTSTAMP:20200825T181915Z
    DTSTART:20200825T220000Z
    SUMMARY:Busy
    UID:
     1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000
     000000010000000CD71CC3393651B419E9458134FE840F5
    END:VEVENT
    END:VCALENDAR

幸运的是,PyPI 可以再次使用另一个辅助库 vobject 解围:

import io
import vobject

def parse_event(raw_event):
    data = raw_event.data
    parsed = vobject.readOne(io.StringIO(data))
    contents = parsed.vevent.contents
    return contents
parse_event(raw_events[12])
    {'dtend': [<DTEND{}2020-08-25 23:00:00+00:00>],
     'dtstamp': [<DTSTAMP{}2020-08-25 18:19:15+00:00>],
     'dtstart': [<DTSTART{}2020-08-25 22:00:00+00:00>],
     'summary': [<SUMMARY{}Busy>],
     'uid': [<UID{}1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000000000010000000CD71CC3393651B419E9458134FE840F5>]}

好吧,至少好一点了。

仍有一些工作要做,将其转换为合理的 Python 对象。第一步是 拥有 一个合理的 Python 对象。attrs 库提供了一个不错的开始:

import attr
from __future__ import annotations
@attr.s(auto_attribs=True, frozen=True)
class Event:
    start: datetime.datetime
    end: datetime.datetime
    timezone: Any
    summary: str

是时候编写转换代码了!

第一个抽象从解析后的字典中获取值,不需要所有的装饰:

def get_piece(contents, name):
    return contents[name][0].value
get_piece(_, "dtstart")
    datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc())

日历事件总有一个“开始”、有一个“结束”、有一个 “持续时间”。一些谨慎的解析逻辑可以将两者协调为同一个 Python 对象:

def from_calendar_event_and_timezone(event, timezone):
    contents = parse_event(event)
    start = get_piece(contents, "dtstart")
    summary = get_piece(contents, "summary")
    try:
        end = get_piece(contents, "dtend")
    except KeyError:
        end = start + get_piece(contents, "duration")
    return Event(start=start, end=end, summary=summary, timezone=timezone)

将事件放在 本地 时区而不是 UTC 中很有用,因此使用本地时区:

my_timezone = tz.gettz()
from_calendar_event_and_timezone(raw_events[12], my_timezone)
    Event(start=datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc()), end=datetime.datetime(2020, 8, 25, 23, 0, tzinfo=tzutc()), timezone=tzfile('/etc/localtime'), summary='Busy')

既然事件是真实的 Python 对象,那么它们实际上应该具有附加信息。幸运的是,可以将方法添加到类中。

但是要弄清楚哪个事件发生在哪一天不是很直接。你需要在 本地 时区中选择一天:

def day(self):
    offset = self.timezone.utcoffset(self.start)
    fixed = self.start + offset
    return fixed.date()
Event.day = property(day)
print(_.day)
    2020-08-25

事件在内部始终是以“开始”/“结束”的方式表示的,但是持续时间是有用的属性。持续时间也可以添加到现有类中:

def duration(self):
    return self.end - self.start
Event.duration = property(duration)
print(_.duration)
    1:00:00

现在到了将所有事件转换为有用的 Python 对象了:

all_events = [from_calendar_event_and_timezone(raw_event, my_timezone)
              for raw_event in raw_events]

全天事件是一种特例,可能对分析生活没有多大用处。现在,你可以忽略它们:

# ignore all-day events
all_events = [event for event in all_events if not type(event.start) == datetime.date]

事件具有自然顺序 —— 知道哪个事件最先发生可能有助于分析:

all_events.sort(key=lambda ev: ev.start)

现在,事件已排序,可以将它们加载到每天:

import collections
events_by_day = collections.defaultdict(list)
for event in all_events:
    events_by_day[event.day].append(event)

有了这些,你就有了作为 Python 对象的带有日期、持续时间和序列的日历事件。

用 Python 报到你的生活

现在是时候编写报告代码了!带有适当的标题、列表、重要内容以粗体显示等等,有醒目的格式是很意义。

这就是一些 HTML 和 HTML 模板。我喜欢使用 Chameleon

template_content = """
<html><body>
<div tal:repeat="item items">
<h2 tal:content="item[0]">Day</h2>
<ul>
    <li tal:repeat="event item[1]"><span tal:replace="event">Thing</span></li>
</ul>
</div>
</body></html>"""

Chameleon 的一个很酷的功能是使用它的 html 方法渲染对象。我将以两种方式使用它:

  • 摘要将以粗体显示
  • 对于大多数活动,我都会删除摘要(因为这是我的个人信息)
def __html__(self):
    offset = my_timezone.utcoffset(self.start)
    fixed = self.start + offset
    start_str = str(fixed).split("+")[0]
    summary = self.summary
    if summary != "Busy":
        summary = "&lt;REDACTED&gt;"
    return f"<b>{summary[:30]}</b> -- {start_str} ({self.duration})"
Event.__html__ = __html__

为了简洁起见,将该报告切成每天的:

import chameleon
from IPython.display import HTML
template = chameleon.PageTemplate(template_content)
html = template(items=itertools.islice(events_by_day.items(), 3, 4))
HTML(html)

渲染后,它将看起来像这样:

2020-08-25

  • -- 2020-08-25 08:30:00 (0:45:00)
  • -- 2020-08-25 10:00:00 (1:00:00)
  • -- 2020-08-25 11:30:00 (0:30:00)
  • -- 2020-08-25 13:00:00 (0:25:00)
  • Busy -- 2020-08-25 15:00:00 (1:00:00)
  • -- 2020-08-25 15:00:00 (1:00:00)
  • -- 2020-08-25 19:00:00 (1:00:00)
  • -- 2020-08-25 19:00:12 (1:00:00)

Python 和 Jupyter 的无穷选择

通过解析、分析和报告各种 Web 服务所拥有的数据,这只是你可以做的事情的表面。

为什么不对你最喜欢的服务试试呢?


via: https://opensource.com/article/20/9/calendar-jupyter

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

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

Python & Poetry on Fedora

Python 开发人员经常创建一个新的虚拟环境来分离项目依赖,然后用 pippipenv 等工具来管理它们。Poetry 是一个简化 Python 中依赖管理和打包的工具。这篇文章将向你展示如何在 Fedora 上使用 Poetry 来管理你的 Python 项目。

与其他工具不同,Poetry 只使用一个配置文件来进行依赖管理、打包和发布。这消除了对不同文件的需求,如 PipfileMANIFEST.insetup.py 等。这也比使用多个工具更快。

下面详细介绍一下开始使用 Poetry 时使用的命令。

在 Fedora 上安装 Poetry

如果你已经使用 Fedora 32 或以上版本,你可以使用这个命令直接从命令行安装 Poetry:

$ sudo dnf install poetry

编者注:在 Fedora Silverblue 或 CoreOs上,Python 3.9.2 是核心提交的一部分,你可以用下面的命令安装 Poetry:

rpm-ostree install poetry

初始化一个项目

使用 new 命令创建一个新项目:

$ poetry new poetry-project

用 Poetry 创建的项目结构是这样的:

├── poetry_project
│   └── init.py
├── pyproject.toml
├── README.rst
└── tests
    ├── init.py
    └── test_poetry_project.py

Poetry 使用 pyproject.toml 来管理项目的依赖。最初,这个文件看起来类似于这样:

[tool.poetry]
name = "poetry-project"
version = "0.1.0"
description = ""
authors = ["Kadermiyanyedi <[email protected]>"]

[tool.poetry.dependencies]
python = "^3.9"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

这个文件包含 4 个部分:

  • 第一部分包含描述项目的信息,如项目名称、项目版本等。
  • 第二部分包含项目的依赖。这些依赖是构建项目所必需的。
  • 第三部分包含开发依赖。
  • 第四部分描述的是符合 PEP 517 的构建系统。

如果你已经有一个项目,或者创建了自己的项目文件夹,并且你想使用 Poetry,请在你的项目中运行 init 命令。

$ poetry init

在这个命令之后,你会看到一个交互式的 shell 来配置你的项目。

创建一个虚拟环境

如果你想创建一个虚拟环境或激活一个现有的虚拟环境,请使用以下命令:

$ poetry shell

Poetry 默认在 /home/username/.cache/pypoetry 项目中创建虚拟环境。你可以通过编辑 Poetry 配置来更改默认路径。使用下面的命令查看配置列表:

$ poetry config --list

cache-dir = "/home/username/.cache/pypoetry"
virtualenvs.create = true
virtualenvs.in-project = true
virtualenvs.path = "{cache-dir}/virtualenvs"

修改 virtualenvs.in-project 配置变量,在项目目录下创建一个虚拟环境。Poetry 命令是:

$ poetry config virtualenv.in-project true

添加依赖

使用 poetry add 命令为项目安装一个依赖:

$ poetry add django

你可以使用带有 --dev 选项的 add 命令来识别任何只用于开发环境的依赖:

$ poetry add black --dev

add 命令会创建一个 poetry.lock 文件,用来跟踪软件包的版本。如果 poetry.lock 文件不存在,那么会安装 pyproject.toml 中所有依赖项的最新版本。如果 poetry.lock 存在,Poetry 会使用文件中列出的确切版本,以确保每个使用这个项目的人的软件包版本是一致的。

使用 poetry install 命令来安装当前项目中的所有依赖:

$ poetry install

通过使用 --no-dev 选项防止安装开发依赖:

$ poetry install --no-dev

列出软件包

show 命令会列出所有可用的软件包。--tree 选项将以树状列出软件包:

$ poetry show --tree

django 3.1.7 A high-level Python Web framework that encourages rapid development and clean, pragmatic design.
├── asgiref >=3.2.10,<4
├── pytz *
└── sqlparse >=0.2.2

包含软件包名称,以列出特定软件包的详细信息:

$ poetry show requests

name         : requests
version      : 2.25.1
description  : Python HTTP for Humans.

dependencies
 - certifi >=2017.4.17
 - chardet >=3.0.2,<5
 - idna >=2.5,<3
 - urllib3 >=1.21.1,<1.27

最后,如果你想知道软件包的最新版本,你可以通过 --latest 选项:

$ poetry show --latest

idna     2.10      3.1    Internationalized Domain Names in Applications
asgiref  3.3.1     3.3.1  ASGI specs, helper code, and adapters

更多信息

Poetry 的更多详情可在文档中获取。


via: https://fedoramagazine.org/how-to-use-poetry-to-manage-your-python-projects-on-fedora/

作者:Kader Miyanyedi 选题:lujun9972 译者:geekpi 校对:wxy

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

虚拟环境是安全地使用不同版本的 Python 和软件包组合的关键。

 title=

Python 对管理虚拟环境的支持,已经提供了一段时间了。Python 3.3 甚至增加了内置的 venv 模块,用于创建没有第三方库的环境。Python 程序员可以使用几种不同的工具来管理他们的环境,我使用的工具叫做 virtualenvwrapper

虚拟环境是将你的 Python 项目及其依赖关系与你的系统安装的 Python 分离的一种方式。如果你使用的是基于 macOS 或 Linux 的操作系统,它很可能在安装中附带了一个 Python 版本,事实上,它很可能依赖于那个特定版本的 Python 才能正常运行。但这是你的计算机,你可能想用它来达到自己的目的。你可能需要安装另一个版本的 Python,而不是操作系统提供的版本。你可能还需要安装一些额外的库。尽管你可以升级你的系统 Python,但不推荐这样做。你也可以安装其他库,但你必须注意不要干扰系统所依赖的任何东西。

虚拟环境是创建隔离的关键,你需要安全地修改不同版本的 Python 和不同组合的包。它们还允许你为不同的项目安装同一库的不同版本,这解决了在相同环境满足所有项目需求这个不可能的问题。

为什么选择 virtualenvwrapper 而不是其他工具?简而言之:

  • venv 需要在项目目录内或旁边有一个 venv 目录不同,virtualenvwrapper 将所有环境保存在一个地方:默认在 ~/.virtualenvs 中。
  • 它提供了用于创建和激活环境的命令,而且激活环境不依赖于找到正确的 activate 脚本。它只需要(从任何地方)workon projectname而不需要 source ~/Projects/flashylights-env/bin/activate

开始使用

首先,花点时间了解一下你的系统 Python 是如何配置的,以及 pip 工具是如何工作的。

以树莓派系统为例,该系统同时安装了 Python 2.7 和 3.7。它还提供了单独的 pip 实例,每个版本一个:

  • 命令 python 运行 Python 2.7,位于 /usr/bin/python
  • 命令 python3 运行 Python 3.7,位于 /usr/bin/python3
  • 命令 pip 安装 Python 2.7 的软件包,位于 /usr/bin/pip
  • 命令 pip3 安装 Python 3.7 的包,位于 /usr/bin/pip3

 title=

在开始使用虚拟环境之前,验证一下使用 pythonpip 命令的状态是很有用的。关于你的 pip 实例的更多信息可以通过运行 pip debugpip3 debug 命令找到。

在我运行 Ubuntu Linux 的电脑上几乎是相同的信息(除了它是 Python 3.8)。在我的 Macbook 上也很相似,除了唯一的系统 Python 是 2.6,而我用 brew 安装 Python 3.8,所以它位于 /usr/local/bin/python3(和 pip3 一起)。

安装 virtualenvwrapper

你需要使用系统 Python 3 的 pip 安装 virtualenvwrapper

sudo pip3 install virtualenvwrapper

下一步是配置你的 shell 来加载 virtualenvwrapper 命令。你可以通过编辑 shell 的 RC 文件(例如 .bashrc.bash_profile.zshrc)并添加以下几行:

export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export VIRTUALENVWRAPPER_VIRTUALENV=/usr/local/bin/virtualenv
source /usr/local/bin/virtualenvwrapper.sh

 title=

如果你的 Python 3 位于其他地方,请根据你的设置修改第一行。

关闭你的终端,然后重新打开它,这样才能生效。第一次打开终端时,你应该看到 virtualenvwrapper 的一些输出。这只会发生一次,因为一些目录是作为设置的一部分被创建的。

现在你应该可以输入 mkvirtualenv --version 命令来验证 virtualenvwrapper 是否已经安装。

创建一个新的虚拟环境

假设你正在进行一个名为 flashylights 的项目。要用这个名字创建一个虚拟环境,请运行该命令:

mkvirtualenv flashylights

环境已经创建并激活,所以你会看到 (flashlylights) 出现在你的提示前:

 title=

现在环境被激活了,事情发生了变化。python 现在指向一个与你之前在系统中识别的 Python 实例完全不同的 Python 实例。它为你的环境创建了一个目录,并在其中放置了 Python 3 二进制文件、pip 命令等的副本。输入 which pythonwhich pip 来查看它们的位置。

 title=

如果你现在运行一个 Python 程序,你可以用 python 代替 python3 来运行,你可以用 pip 代替 pip3。你使用 pip安装的任何包都将只安装在这个环境中,它们不会干扰你的其他项目、其他环境或系统安装。

要停用这个环境,运行 deactivate 命令。要重新启用它,运行 workon flashylights

你可以用 workon 或使用 lsvirtualenv 列出所有可用的环境。你可以用 rmvirtualenv flashylights 删除一个环境。

在你的开发流程中添加虚拟环境是一件明智的事情。根据我的经验,它可以防止我在系统范围内安装我正在试验的库,这可能会导致问题。我发现 virtualenvwrapper 是最简单的可以让我进入流程的方法,并无忧无虑地管理我的项目环境,而不需要考虑太多,也不需要记住太多命令。

高级特性

  • 你可以在你的系统上安装多个 Python 版本(例如,在 Ubuntu 上使用 deadsnakes PPA),并使用该版本创建一个虚拟环境,例如,mkvirtualenv -p /usr/bin/python3.9 myproject
  • 可以在进入和离开目录时自动激活、停用。
  • 你可以使用 postmkvirtualenv 钩子在每次创建新环境时安装常用工具。

更多提示请参见文档

本文基于 Ben Nuttall 在 Tooling Tuesday 上关于 virtualenvwrapper 的帖子,经许可后重用。


via: https://opensource.com/article/21/2/python-virtualenvwrapper

作者:Ben Nuttall 选题:lujun9972 译者:geekpi 校对:wxy

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

美国 1800 台比特币 ATM 现已支持存取狗狗币

在马斯克等名人的推动下,原本只是一个玩笑下创立的狗狗币一飞冲天。近日,比特币 ATM 提供商 Coinflip 宣布其比特币 ATM 支持狗狗币。

自 2020 年 1 月以来,比特币 ATM 提供商 Coinflip 的 ATM 数量从 441 台增加到大约 1800 台。除了狗狗币,该公司 ATM 机还支持比特币、以太坊、币安币、达世币、莱特币等加密货币。

在加密的世界,有时候你分不清虚拟和现实,谁能想到一个创始人都视为玩笑而退出的狗狗币,居然成了不可忽视的加密货币。

Python 包仓库 PyPI 被上传了数千恶意软件包

像 NPM、PyPI 和 RubyGems 这样的软件包管理系统近几年都被上传 过大量恶意软件包。在最近,有数千个 CuPy 的篡改版本被上传到了 PyPI。这些软件包在一天后被检测到并删除。

这次攻击可能是恶意的,也可能是出于善意的提醒。因为短时间内上传数千个软件包,这种活动会很快被注意到,此外,该软件包的恶意代码也只是向一个 IP 地址发送了一个 GET 请求。

尽管开发者通常被建议审查他们从外部库导入的任何代码,但这个建议并不总是被遵循。关于使用来自公共软件仓库组件带来的安全隐患,应该有更好的防御和警告机制。

华为 EMUI 11 用户突破 1 亿,但可能很快就被替换

去年 9 月份,华为宣布了 EMUI,而半年后,华为透露 EMUI 升级用户已达 1 亿,并正式宣布,“下一站 HarmonyOS”!之前就有消息称,EMUI 11 将是 EMUI 最后一个大版本,EMUI 11.1 则为最后一个更新版本,接下来将不再会有新的 EMUI 系统,而是升级成 HarmonyOS。

据称,华为将在四月份向其旗下的手机产品逐批推送 HarmonyOS。华为消费者 BG 软件部总裁王成录也曾表示:“相信鸿蒙系统今年能覆盖 3 亿到 4 亿台设备,这其中包括了华为至少 2 亿台的自有设备。”

鸿蒙系统终究是要亮相的,到底如何自有公论。

Python 之禅 Zen of Python 最早由 Tim Peters 于 1999 年发表于 Python 邮件列表中,它包含了影响 Python 编程语言设计的 19 条软件编写原则。在最初及后来的一些版本中,一共包含 20 条,其中第 20 条是“这一条留空(...)请 Guido 来填写”。这留空的一条从未公布也可能并不存在。

Python 之禅作为一个信息条款也被录入 Python 增强建议 Python Enhancement Proposals (PEP)的第 20 条,在 Python 语言的官方网站也能找到

此外,关于 Python 之禅,还有一件趣事。在 2001 召开第十届国际 Python 峰会(IPC 10,Pycon 的前身)前夕,会议主办方希望定制一件 T 恤,并绞尽脑汁地从投稿的标语中选择了一条 “import this”。然后,他们决定将这个语句实现在 Python 解释器中,于是将 Python 之禅的内容进行简单加密后放入到了 Python 2.2.1 中的 this.py 库当中。如果你在 Python 的解释器中输入 import this ,就会显示出来:

>>> import this;
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

作为 Python 之禅系列文章的总结,我在下面重新整理并链接了之前的各篇文章。对于 Python 之禅的理解大家各有不同,目前也有几个不同的中文翻译版本。为了避免雷同,我们在翻译这系列文章时有意没有参考现有的 Python 之禅中文译本。因此,这里是我们自行翻译选定的译本,可能在理解上有不到位的地方,也可能文字润色不够精要,大家也可以参考其他的译本形成你的理解和润色版本。

  1. 美观胜于丑陋 Beautiful is better than ugly.
  2. 明确胜于隐晦 Explicit is better than implicit.
  3. 简单胜过复杂 Simple is better than complex.
  4. 复杂胜过错综复杂 Complex is better than complicated.
  5. 扁平胜过嵌套 Flat is better than nested.
  6. 稀疏胜过密集 Sparse is better than dense.
  7. 可读性很重要 Readability counts.
  8. 特殊情况不足以违反规则 Special cases aren't special enough to break the rules.
  9. 虽然,实用性胜过纯洁性 Although practicality beats purity.
  10. 错误绝不应该悄悄传递 Errors should never pass silently.
  11. 除非显式消除 Unless explicitly silenced.
  12. 面对歧义 In the face of ambiguity, 要拒绝猜测的诱惑 refuse the temptation to guess.
  13. 尽量找一种 There should be one - 最好是唯一一种明显的解决方案 and preferably only one - obvious way to do it.
  14. 虽然这种方式一开始可能并不明显 Although that way may not be obvious at first. (除非你是荷兰人) unless you're Dutch.
  15. 现在有总比永远没有好 Now is better than never.
  16. 虽然将来总比现在好 Although never is often better than right now.
  17. 如果一个实现难以解释 If the implementation is hard to explain, 那就是个坏思路 it's a bad idea.
  18. 如果一个实现易于解释 If the implementation is easy to explain, 那它可能是一个好思路 it may be a good idea.
  19. 命名空间是一个非常棒的想法 Namespaces are one honking great idea— 让我们做更多的命名空间! let's do more of those!

这是 Python 之禅特别系列的一部分,重点是一个额外的原则:命名空间。

 title=

著名的 光明节 Hanukkah 有八个晚上的庆祝活动。然而,光明节的灯台有九根蜡烛:八根普通的蜡烛和总是偏移的第九根蜡烛。它被称为 “shamash” 或 “shamos”,大致可以翻译为“仆人”或“看门人”的意思。

shamos 是点燃所有其它蜡烛的蜡烛:它是唯一一支可以用火的蜡烛,而不仅仅是观看。当我们结束 Python 之禅系列时,我看到命名空间提供了类似的作用。

Python 中的命名空间

Python 使用命名空间来处理一切。虽然简单,但它们是稀疏的数据结构 —— 这通常是实现目标的最佳方式。

命名空间 是一个从名字到对象的映射。

—— Python.org

模块是命名空间。这意味着正确地预测模块语义通常只需要熟悉 Python 命名空间的工作方式。类是命名空间,对象是命名空间。函数可以访问它们的本地命名空间、父命名空间和全局命名空间。

这个简单的模型,即用 . 操作符访问一个对象,而这个对象又通常(但并不总是)会进行某种字典查找,这使得 Python 很难优化,但很容易解释。

事实上,一些第三方模块也采取了这个准则,并以此来运行。例如,variants 包把函数变成了“相关功能”的命名空间。这是一个很好的例子,说明 Python 之禅 是如何激发新的抽象的。

结语

感谢你和我一起参加这次以光明节为灵感的 我最喜欢的语言 的探索。

静心参禅,直至悟道。


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

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

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