装饰器是Python编程语言中相当高级的部分。与大多数事物一样,一旦掌握了它们的工作原理并使用了几次,它们就会非常简单,但作为初学者,它们可能会有点令人生畏和难以理解。只有理解了它解决的问题,你才能真正理解它。例如,我可以直接声明装饰器的定义:装饰器是一个函数,它将另一个函数作为参数并返回它的修改版本,以某种方式增强了它的功能。如果您已经知道装饰器是什么,那么定义就很清楚了,但如果您不知道,则可能不是。重要的是,这个定义本身并没有告诉你什么时候使用修饰符,或者没有它们Python会有多糟糕。示例我们将从一个假设场景开始,看看如果不使用装饰器会出现什么问题。在你上班的第一天,你的老板找到你并要求你编写一个将字符串转换为回文的函数:一个向前和向后读取相同内容的字符串。你可以这样写:defmake_palindrome(string):"""Makesapalindromicmirrorofastring."""returnstring+string[::-1]到目前为止一切顺利。一个小时后,老板要求提供更多功能:一个在任意字符串末尾添加一个字符串的credits函数,一个将一个字符串转换为另一个字符串的函数,以及一个在字符串中插入逗号的函数。您开始添加新函数:defadd_credits(string):"""将公司的信用添加到任何字符串的末尾。"""returnf"{string}(由ProStringInc.创建的字符串)"defsnake_to_camel(string):"""将snake_case中的字符串转换为驼峰命名法。"""words=string.split("_")iflen(words)>1:words=[words[0]]+[word.title()forwords[1:]]return"".join(words)definsert_commas(string,spacing=3):"""在每n个字符之间插入逗号。"""sections=[string[i:i+spacing]foriinrange(0,len(string),spacing)]return",".join(sections)但问题出现了。老板看了你的代码,提醒你这个函数必须能够接受整数作为输入,并且应该将它们转换为字符串。他建议在每个函数的开头添加一行,检查输入是否为整数,如果是则进行转换。这令人沮丧-你必须遍历每个函数并在开头添加类似这样的内容:ifisinstance(string,int):string=str(string)当我们有四个函数时这很好,但是如果我们有十个?让所有功能都以相同的两行开头违反了神圣的“不要重复自己”的法律格言。有没有办法只修改所有这些功能而不添加额外的代码?要了解如何做到这一点,让我们退后一步,看看Python函数。尽管Python函数有特殊的语法,但它只是一个对象,就像字符串或列表一样。您可以检查它们的属性,将它们分配给新变量,并且——至关重要的是——将它们作为参数传递给另一个函数。例如,你可以让一个函数接受另一个函数,并检查它是否有任何关键字参数:deffunc_has_kwargs(func):returnlen(func.__defaults__)>0不要担心__defaults__如果你还没有看到它,这里的要点是,一个将另一个函数作为参数的函数会检查它是否有任何关键字参数(即__default__属性的长度是否大于0)。否则,返回True,如果是,则返回False。现在回到我们的问题。我们有三个设计良好的字符串操作函数,我们需要修改它们,使它们也接受整数。我们需要的是一个新函数——一个将我们现有函数作为输入并创建一个检查整数的修改函数。我们需要一个装饰器函数:让我们仔细看看这里发生了什么。accept_integers是我们的修饰函数——它接受一个函数作为输入并返回另一个函数作为输出。在它的主体中,它创建了一个新函数,该函数应该完成输入函数所做的一切,但在开始时有一个额外的步骤。如果查看此函数的主体,您会发现它会检查给定的字符串是否为整数,如果是则进行转换,然后将此字符串传递给原始函数。这里缺少一个步骤——我们需要实际使用这个装饰器:标准形式最后,值得指出的是,虽然上述语法完全有效,但Python以@符号的形式提供了快捷方式。您可以将@accept_integers添加到任何函数之前来装饰它:这是将一个函数传递给另一个函数的另一种方式。在幕后,当Python看到@符号时,它会为您执行装饰器的调用。许多Python库提供装饰器来快速增强您编写的功能,而无需键入大量重复代码。我们对装饰器和所有新编程功能的建议是,首先学会识别您使用该功能的情况——它解决的问题,以及你没有解决的问题——然后了解它是如何工作的。像往常一样,真正理解的唯一方法是自己写一个。所以去吧,后浪。文渊网,仅供学习,侵删。学习Python的路上肯定会遇到困难,不要慌张,我这里有一套学习资料,包括40+电子书,800+教学视频,涉及Python基础、爬虫、框架、数据分析、机学习等等,别怕你学不会!https://shimo.im/docs/JWCghr8...《Python学习资料》关注公众号【蟒圈】,每日优质文章推送。
