使用 attrs 告别 Python 中的样板代码

在我们的系列文章中了解更多关于解决常见 Python 问题的信息,该系列文章涵盖七个 PyPI 库。
134 位读者喜欢这个。
Programming at a browser, orange hands

opensource.com

Python 是当今使用最流行的编程语言之一,这有很多充分的理由:它是开源的,用途广泛(例如 Web 编程、商业应用程序、游戏、科学编程等等),并且拥有一个充满活力和专注的社区为其提供支持。这个社区是我们拥有如此庞大、多样化的软件包的原因,这些软件包可在 Python 包索引 (PyPI) 中获得,以扩展和改进 Python 并解决不可避免出现的小故障。

在本系列文章中,我们将介绍七个 PyPI 库,它们可以帮助您解决常见的 Python 问题。今天,我们将研究 attrs,这是一个 Python 包,可帮助您快速编写简洁、正确的代码。

attrs

如果您使用 Python 有一段时间了,您可能已经习惯于编写如下代码:

class Book(object):

    def __init__(self, isbn, name, author):
        self.isbn = isbn
        self.name = name
        self.author = author

然后您编写一个 __repr__ 函数;否则,将很难记录 Book 的实例

    def __repr__(self):
        return f"Book({self.isbn}, {self.name}, {self.author})"

接下来,您编写一个不错的文档字符串,记录预期的类型。但是您注意到您忘记添加 editionpublished_year 属性,因此您必须在五个位置修改它们。

如果您不必这样做呢?

@attr.s(auto_attribs=True)
class Book(object):
    isbn: str
    name: str
    author: str
    published_year: int
    edition: int

使用新的类型注释语法注释属性类型,attrs 检测到注释并创建一个类。

ISBN 有特定的格式。如果我们想强制执行该格式怎么办?

@attr.s(auto_attribs=True)
class Book(object):
    isbn: str = attr.ib()
    @isbn.validator
    def pattern_match(self, attribute, value):
        m = re.match(r"^(\d{3}-)\d{1,3}-\d{2,3}-\d{1,7}-\d$", value)
        if not m:
            raise ValueError("incorrect format for isbn", value)
    name: str 
    author: str
    published_year: int
    edition: int

attrs 库还对 不可变风格编程 提供强大的支持。将第一行更改为 @attr.s(auto_attribs=True, frozen=True) 意味着 Book 现在是不可变的:尝试修改属性将引发异常。相反,我们可以使用 attr.evolve(old_book, published_year=old_book.published_year+1) 获取带有修改的实例,例如,如果我们需要将出版时间提前一年。

在本系列文章的下一篇文章中,我们将介绍 singledispatch,这是一个允许您追溯地向 Python 库添加方法的库。

回顾本系列之前的文章

接下来阅读什么
标签
Moshe sitting down, head slightly to the side. His t-shirt has Guardians of the Galaxy silhoutes against a background of sound visualization bars.
自 1998 年以来,Moshe 一直参与 Linux 社区,帮助举办 Linux“安装派对”。自 1999 年以来,他一直在编写 Python 程序,并为核心 Python 解释器做出了贡献。Moshe 在这些术语出现之前就一直是 DevOps/SRE,他非常关心软件可靠性、构建可重现性以及其他此类事情。

评论已关闭。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.