{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 函数装饰器\n", "\n", "装饰器(Decorator)是 Python 中一个非常重要的概念,装饰器在不修改原函数代码的情况下,给原函数动态地增加功能。\n", "\n", "装饰器本质上是一个高阶函数,它接受一个函数作为参数并返回一个新的函数。\n", "\n", "装饰器的常见用途:日志记录、性能测试、权限验证、缓存、事务处理等\n", "\n", "装饰器是 Python 中非常强大的特性,合理使用可以让代码更加简洁、优雅,并且符合 DRY(Don't Repeat Yourself)原则。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 一、基本语法" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 基本装饰器" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "执行前\n", "Hello!\n", "执行后\n" ] } ], "source": [ "def my_decorator(func):\n", " def wrapper():\n", " print(\"执行前\")\n", " func()\n", " print(\"执行后\")\n", " return wrapper\n", "\n", "@my_decorator\n", "def say_hello():\n", " print(\"Hello!\")\n", "\n", "# 调用函数\n", "say_hello()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 带参数的装饰器" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "执行前\n", "执行后\n", "8\n", "执行前\n", "执行后\n", "ChinaLanzhou\n" ] } ], "source": [ "def my_decorator(func):\n", " def wrapper(*args, **kwargs):\n", " print(\"执行前\")\n", " result = func(*args, **kwargs)\n", " print(\"执行后\")\n", " return result\n", " return wrapper\n", "\n", "@my_decorator\n", "def add(a, b):\n", " return a + b\n", "\n", "# 调用函数\n", "print(add(3, 5))\n", "print(add('China', 'Lanzhou'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 装饰器带参数" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "你好,小明!\n", "你好,小明!\n", "你好,小明!\n" ] } ], "source": [ "def repeat(times):\n", " def decorator(func):\n", " def wrapper(*args, **kwargs):\n", " for _ in range(times):\n", " result = func(*args, **kwargs)\n", " return result\n", " return wrapper\n", " return decorator\n", "\n", "@repeat(3)\n", "def greet(name):\n", " print(f\"你好,{name}!\")\n", "\n", "# 调用函数\n", "greet(\"小明\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 二、语法设计动机" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "装饰器的基本语法如下\n", "\n", "\n", "@decorator\n", "def function_to_decorate(*args, **kwargs):\n", " # 函数体 \n", " \n", "\n", "这等同于:\n", "\n", "def function_to_decorate(*args, **kwargs):\n", " # 函数体 \n", "function_to_decorate = decorator(function_to_decorate)\n", " " ] }, { "cell_type": "raw", "metadata": {}, "source": [ "在下面例子中,uppercase_decorator 接受一个函数 func 作为参数,并返回一个新的函数 wrapper。\n", "wrapper 函数将 func 的结果转换为大写。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "HELLO, ALICE!\n" ] } ], "source": [ "# 高阶函数的写法\n", "\n", "def greet(name):\n", " return f\"Hello, {name}!\"\n", "\n", "def uppercase_decorator(func):\n", " def wrapper(name):\n", " result = func(name)\n", " return result.upper()\n", " return wrapper\n", "\n", "greet_uppercase = uppercase_decorator(greet)\n", "print(greet_uppercase(\"Alice\"))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "HELLO, ALICE!\n" ] } ], "source": [ "# 装饰器的写法\n", "\n", "def uppercase_decorator(func):\n", " def wrapper(name):\n", " result = func(name)\n", " return result.upper()\n", " return wrapper\n", "\n", "@uppercase_decorator\n", "def greet(name):\n", " return f\"Hello, {name}!\"\n", "\n", "print(greet(\"Alice\"))" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "在这个例子中,@uppercase_decorator 等价于 greet = uppercase_decorator(greet)。\n", "使用装饰器,结构更清楚,使用更方便。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 三、应用" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "函数执行完毕\n", "函数 slow_function 执行时间:1.0016472339630127秒\n" ] } ], "source": [ "# 一个简单的计时装饰器\n", "\n", "import time\n", "\n", "def timer(func):\n", " def wrapper(*args, **kwargs):\n", " start = time.time()\n", " result = func(*args, **kwargs)\n", " end = time.time()\n", " print(f\"函数 {func.__name__} 执行时间:{end - start}秒\")\n", " return result\n", " return wrapper\n", "\n", "@timer\n", "def slow_function():\n", " time.sleep(1)\n", " print(\"函数执行完毕\")\n", "\n", "# 调用函数\n", "slow_function()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "' hello china 2025 '" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### 一个标记文本生成工具\n", "\n", "def make_bold(fn): \n", " def inner(s): return \"\" + fn(s) + \"\" \n", " return inner\n", "def make_italic(fn): \n", " def inner(s): return \"\" + fn(s) + \"\" \n", " return inner\n", "\n", "@make_bold\n", "@make_italic\n", "def hello(s) : return s\n", "\n", "hello( ' hello china 2025 ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 其它\n", "\n", "- 当有多个装饰器时,装饰器的执行顺序是**从下到上**\n", "- Python 内置了很多实用的装饰器,如 @property、@staticmethod、@classmethod 等\n", "- 装饰器也可以使用类创建" ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }