Python 3.3 为改进代码中的异常处理所做的工作
创始人
2024-03-02 07:24:47
0

探索异常处理和其他未被充分利用但仍然有用的 Python 特性。

这是 Python 3.x 首发特性系列文章的第四篇。Python 3.3 于 2012 年首次发布,尽管它已经发布了很长时间,但它引入的许多特性都没有得到充分利用,而且相当酷。下面是其中的三个。

yield from

yield 关键字使 Python 更加强大。可以预见的是,人们都开始使用它来创建整个迭代器的生态系统。itertools 模块和 more-itertools PyPI 包就是其中两个例子。

有时,一个新的生成器会想要使用一个现有的生成器。作为一个简单的(尽管有点故意设计)的例子,设想你想枚举所有的自然数对。

一种方法是按照“自然数对的和,自然数对的第一项”的顺序生成所有的自然数对。用 yield from 来实现这个方法是很自然的。

yield from 关键字是以下的简称:

for item in x:
    yield item
import itertools

def pairs():
    for n in itertools.count():
        yield from ((i, n-i) for i in range(n+1))
list(itertools.islice(pairs(), 6))
    [(0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0)]

隐式命名空间包

假设有一个叫 Parasol 的虚构公司,它制造了一堆东西。它的大部分内部软件都是用 Python 编写的。虽然 Parasol 已经开源了它的一些代码,但其中一些代码对于开源来说过于专有或专业。

该公司使用内部 DevPI 服务器来管理内部软件包。对于 Parasol 的每个 Python 程序员来说,在 PyPI 上找一个未使用的名字是没有意义的,所以所有的内部包都被称为 parasol..。遵守最佳实践,开发人员希望包的名字能反映出这个命名系统。

这一点很重要!如果 parasol.accounting.numeric_tricks 包安装了一个名为 numeric_tricks 的顶层模块,这意味着依赖这个包的人将无法使用名为 numeric_tricks 的 PyPI 包,不管它写的有多好。

然而,这给开发者留下了一个两难的选择:哪个包拥有 parasol/__init__.py 文件?从 Python 3.3 开始,最好的解决办法是把 parasol,可能还有 parasol.accounting,变成没有 __init__.py 文件的 命名空间包

抑制异常的上下文

有时,在从异常中恢复的过程中出现的异常是一个问题,有上下文来跟踪它是很有用的。然而,有时却不是这样:异常已经被处理了,而新的情况是一个不同的错误状况。

例如,想象一下,在字典中查找一个键失败后,如果不能分析它,则希望失败并返回 ValueError()

import time

def expensive_analysis(data):
    time.sleep(10)
    if data[0:1] == ">":
        return data[1:]
    return None

这个函数需要很长的时间,所以当你使用它时,想要对结果进行缓存:

cache = {}

def last_letter_analyzed(data):
    try:
        analyzed = cache[data]
    except KeyError:
        analyzed = expensive_analysis(data)
        if analyzed is None:
            raise ValueError("invalid data", data)
        cached[data] = analyzed
    return analyzed[-1]

不幸的是,当出现缓存没有命中时,回溯看起来很难看:

last_letter_analyzed("stuff")
    ---------------------------------------------------------------------------

    KeyError                                  Traceback (most recent call last)

     in last_letter_analyzed(data)
          4     try:
    ----> 5         analyzed = cache[data]
          6     except KeyError:


    KeyError: 'stuff'

在处理上述异常的过程中,发生了另一个异常:

    ValueError                                Traceback (most recent call last)

     in 
    ----> 1 last_letter_analyzed("stuff")
   

     in last_letter_analyzed(data)
          7         analyzed = expensive_analysis(data)
          8         if analyzed is None:
    ----> 9             raise ValueError("invalid data", data)
         10         cached[data] = analyzed
         11     return analyzed[-1]


    ValueError: ('invalid data', 'stuff')

如果你使用 raise ... from None,你可以得到更多可读的回溯:

def last_letter_analyzed(data):
    try:
        analyzed = cache[data]
    except KeyError:
        analyzed = expensive_analysis(data)
        if analyzed is None:
            raise ValueError("invalid data", data) from None
        cached[data] = analyzed
    return analyzed[-1]
last_letter_analyzed("stuff")
    ---------------------------------------------------------------------------

    ValueError                                Traceback (most recent call last)

     in 
    ----> 1 last_letter_analyzed("stuff")
   

     in last_letter_analyzed(data)
          5         analyzed = expensive_analysis(data)
          6         if analyzed is None:
    ----> 7             raise ValueError("invalid data", data) from None
          8         cached[data] = analyzed
          9     return analyzed[-1]


    ValueError: ('invalid data', 'stuff')

欢迎来到 2012 年

尽管 Python 3.3 在十年前就已经发布了,但它的许多功能仍然很酷,而且没有得到充分利用。如果你还没有,就把它们添加到你的工具箱中吧。


via: https://opensource.com/article/21/5/python-33

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

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

相关内容

python基础语法【迭代...
1.迭代器 1.什么是迭代器(iter)...
2025-06-01 20:30:55
手把手教你使用Flask框...
目录前言0、Flask框架的详细介绍一、Flask 框架封装接口1...
2025-06-01 17:11:00
【练习题】python函数...
写一个匿名函数,判断指定的年是否是闰年 (先直接用普...
2025-06-01 15:13:03
4年功能测试,我一进阶py...
目录:导读前言一、Python编程入门到精通二、接口...
2025-06-01 13:34:04
Python嵌套函数(Ne...
Python嵌套函数(Nested function...
2025-06-01 12:52:54
python 基础系列篇:...
python 基础系列篇:三、认识函数、方法...
2025-06-01 09:29:50

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
从 Yum 更新中排除特定/某... 作为系统更新的一部分,你也许需要在基于 Red Hat 系统中由于应用依赖排除一些软件包。如果是,如...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...
如何检查你的 Linux 系统... 不知道在使用哪个初始化系统?以下是方法。每个主流 Linux 发行版(包括 Ubuntu、Fedor...