Python装饰器2025年4月17日 | 阅读 8 分钟 装饰器是 Python 中最有帮助和最强大的工具之一。它们用于修改函数的行为。装饰器提供了包装另一个函数以扩展被包装函数功能的灵活性,而无需永久修改它。 在装饰器中,函数作为参数传递给另一个函数,然后在包装函数内部调用。 它也被称为元编程,即程序的某一部分试图在编译时改变程序的另一部分。 在理解装饰器之前,我们需要了解一些 Python 的重要概念。 Python 中的函数是什么?Python 最有趣的特性是,一切都被视为对象,即使是类或我们在 Python 中定义的任何变量也都被视为对象。函数是 Python 中的一等公民对象,因为它们可以被引用、传递给变量,并作为其他函数的返回值。示例如下。 示例 输出 Hii, welcome to function Hii, welcome to function 在上面的程序中,当我们运行代码时,两个函数都会给出相同的输出。func2 引用了函数 func1 并像函数一样行事。我们需要理解以下函数概念:
内部函数Python 提供了在另一个函数内部定义函数的便利。这类函数称为内部函数。请看以下示例: 示例 输出 We are in first function This is first child function This is second child function 在上面的程序中,子函数的声明方式无关紧要。子函数的执行会影响输出。这些子函数与 func() 是局部绑定的,因此不能单独调用。 接受其他函数作为参数的函数也称为高阶函数。请看以下示例: 示例 输出 9 21 在上面的程序中,我们将 sub() 函数和 add() 函数作为参数传递给了 operator() 函数。 一个函数可以返回另一个函数。请看下面的例子: 示例 输出 Hello 在上面的程序中,hi() 函数嵌套在 hello() 函数内部。每次调用 hi() 时都会返回它。 使用参数装饰函数让我们举个例子来理解带参数的装饰器函数。 示例 输出 2.0 语法装饰器在上面的程序中,我们装饰了 out_div(),这有点繁琐。Python 允许使用 @ 符号以简单的方式使用装饰器,而不是使用上述方法。有时它被称为“派”(pie)语法。 输出 2.0 重用装饰器我们也可以通过重调用该装饰器函数来重用装饰器。让我们将装饰器放入自己的模块中,可以在许多其他函数中使用。创建一个名为 mod_decorator.py 的文件,其中包含以下代码: 我们可以在其他文件中导入 mod_decorator.py。 输出 Hello There Hello There 带参数的 Python 装饰器我们想向函数传递一些参数。让我们在以下代码中这样做: 输出 TypeError: display() missing 1 required positional argument: 'name' 正如我们所见,该函数不接受参数。运行此代码会引发错误。我们可以通过在内部包装函数中使用 \*args 和 \*\*kwargs 来修复此错误。修改 decorator.py 如下: 现在 wrapper_function() 可以接受任意数量的参数并将它们传递给函数。 输出 Hello John Hello John 从装饰函数返回值我们可以控制被装饰函数的返回类型。示例如下: 输出 We are created greeting We are created greeting 花式装饰器让我们通过以下主题来理解花式装饰器: 类装饰器Python 提供了两种装饰类的方法。首先,我们可以装饰类中的方法;Python 中有内置装饰器,如 @classmethod、@staticmethod 和 @property。@classmethod 和 @staticmethod 在类内部定义方法,这些方法与类的任何其他实例无关。@property 通常用于修改类属性的 getter 和 setter。让我们通过以下示例来理解它: 示例:1- @property 装饰器 - 使用它,我们可以将类函数用作属性。请看以下代码: 输出 Name of the student: John Grade of the student: B John got grade B 示例:2- @staticmethod 装饰器- @staticmethod 用于在类中定义静态方法。它可以通过类名或类的实例来调用。请看以下代码: 输出 Hello Peter Hello Peter 单例类单例类只有一个实例。Python 中有很多单例,包括 True、None 等。 嵌套装饰器我们可以通过将多个装饰器堆叠在一起使用它们。让我们看下面的例子: 在上面的代码中,我们通过将它们堆叠在一起来使用嵌套装饰器。 带参数的装饰器向装饰器传递参数总是很有用的。装饰器可以根据参数的给定值执行多次。让我们看下面的例子: 示例 输出 JavatPoint JavatPoint JavatPoint JavatPoint JavatPoint 在上面的例子中,@repeat 引用了一个可以被另一个函数调用的函数对象。@repeat(num = 5) 将返回一个充当装饰器的函数。 上面的代码可能看起来很复杂,但它是最常用的装饰器模式,其中我们使用了一个额外的 def 来处理传递给装饰器的参数。 注意:带参数的装饰器在编程中不常用,但它提供了灵活性。我们可以使用它,也可以不使用参数。有状态装饰器有状态装饰器用于跟踪装饰器的状态。让我们来看一个创建装饰器的例子,该装饰器计算函数被调用了多少次。 示例 输出 Call 1 of 'say_hello' Say Hello Call 2 of 'say_hello' Say Hello 在上面的程序中,状态表示在包装函数上存储的函数调用次数 .num_calls。当我们调用 say_hello() 时,它将显示函数被调用的次数。 类作为装饰器类是维护状态的最佳方式。在本节中,我们将学习如何使用类作为装饰器。这里我们将创建一个包含 \_\_init\_\_() 的类,并以 func 作为参数。该类需要是可调用的,以便它可以代替被装饰的函数。 为了使类可调用,我们实现了特殊的 \_\_call\_\_() 方法。 代码 输出 Call 1 of 'say_hello' Say Hello Call 2 of 'say_hello' Say Hello Call 3 of 'say_hello' Say Hello \_\_init\_\_() 方法存储对函数的引用,并且可以执行任何其他必需的初始化。 |
我们请求您订阅我们的新闻通讯以获取最新更新。