diff --git a/4 装饰器-知识版.ipynb b/4 装饰器-知识版.ipynb new file mode 100644 index 0000000..bdef596 --- /dev/null +++ b/4 装饰器-知识版.ipynb @@ -0,0 +1,358 @@ +{ + "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 +}