├── README.md └── 历史文章 ├── 「Python实用秘技01」复杂zip文件的解压 ├── 「Python实用秘技01」复杂zip文件的解压.ipynb └── 示例压缩包.zip ├── 「Python实用秘技02」给Python函数定“闹钟” └── 「Python实用秘技02」给Python函数定“闹钟”.ipynb ├── 「Python实用秘技03」导出项目的极简环境依赖 └── demo_projects │ ├── main.py │ ├── pip_requirements.txt │ ├── requirements.txt │ ├── sub_module1 │ └── __init__.py │ └── sub_module2 │ └── __init__.py ├── 「Python实用秘技04」为pdf文件批量添加文字水印 └── 「Python实用秘技04」为pdf文件批量添加文字水印.ipynb ├── 「Python实用秘技05」在Python中妙用短路机制 └── 「Python实用秘技05」在Python中妙用短路机制.ipynb ├── 「Python实用秘技06」逐行监听Python程序的内存消耗 └── demo.py ├── 「Python实用秘技07」在pandas中实现自然顺序排序 └── 「Python实用秘技07」在pandas中实现自然顺序排序.ipynb ├── 「Python实用秘技08」一行代码解析地址信息 └── 「Python实用秘技08」一行代码解析地址信息.ipynb ├── 「Python实用秘技09」更好用的函数运算缓存 └── 「Python实用秘技09」更好用的函数运算缓存.ipynb ├── 「Python实用秘技10」深度比较Python对象间差异 └── 「Python实用秘技10」深度比较Python对象间差异.ipynb ├── 「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密 └── 「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密.ipynb ├── 「Python实用秘技12」像导入模块一样导入ipynb文件 ├── demo.ipynb └── 「Python实用秘技12」像导入模块一样导入ipynb文件.ipynb ├── 「Python实用秘技13」Python中临时文件的妙用 └── 「Python实用秘技12」Python中临时文件的妙用.ipynb ├── 「Python实用秘技14」快速优化Python导包顺序 └── demo-projects │ ├── demo │ └── __init__.py │ └── main.py ├── 「Python实用秘技15」pandas中基于范围条件进行表连接 └── 「Python实用秘技15」pandas中基于范围条件进行表连接.ipynb ├── 「Python实用秘技16」快速提取字体子集 ├── demo_app │ ├── app.py │ ├── assets │ │ ├── custom.css │ │ ├── 金箔效果背景.jpg │ │ └── 钟齐志莽行书mini.ttf │ └── 将进酒.txt ├── 「Python实用秘技16」快速提取字体子集.ipynb ├── 将进酒.txt └── 钟齐志莽行书.ttf └── 「Python实用秘技17」快速获取国内节假日安排 └── 「Python实用秘技17」快速获取国内节假日安排.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # PythonPracticalSkills 2 | 这个仓库存放「Python实用秘技😎」系列文章对应附件 3 | 4 | 5 | 6 | ## 1 历史文章目录👨‍💻 7 | 8 | - [「Python实用秘技01」复杂zip文件的解压](https://www.cnblogs.com/feffery/p/15668669.html)  ✈️[仓库路径](./历史文章/「Python实用秘技01」复杂zip文件的解压) 9 | - [「Python实用秘技02」给Python函数定“闹钟”](https://www.cnblogs.com/feffery/p/15676516.html)  ✈️[仓库路径](./历史文章/「Python实用秘技02」给Python函数定“闹钟”) 10 | - [「Python实用秘技03」导出项目的极简环境依赖](https://www.cnblogs.com/feffery/p/15712273.html)  ✈️[仓库路径](./历史文章/「Python实用秘技03」导出项目的极简环境依赖) 11 | - [「Python实用秘技04」为pdf文件批量添加文字水印](https://www.cnblogs.com/feffery/p/15827573.html)  ✈️[仓库路径](./历史文章/「Python实用秘技04」为pdf文件批量添加文字水印) 12 | - [「Python实用秘技05」在Python中妙用短路机制](https://www.cnblogs.com/feffery/p/15906089.html)  ✈️[仓库路径](./历史文章/「Python实用秘技05」在Python中妙用短路机制) 13 | - [「Python实用秘技06」逐行监听Python程序的内存消耗](https://www.cnblogs.com/feffery/p/15928369.html)  ✈️[仓库路径](./历史文章/「Python实用秘技06」逐行监听Python程序的内存消耗) 14 | - [「Python实用秘技07」在pandas中实现自然顺序排序](https://www.cnblogs.com/feffery/p/16156984.html)  ✈️[仓库路径](./历史文章/「Python实用秘技07」在pandas中实现自然顺序排序) 15 | - [「Python实用秘技08」一行代码解析地址信息](https://www.cnblogs.com/feffery/p/16226067.html)  ✈️[仓库路径](./历史文章/「Python实用秘技08」一行代码解析地址信息) 16 | - [「Python实用秘技09」更好用的函数运算缓存](https://www.cnblogs.com/feffery/p/16515158.html)  ✈️[仓库路径](./历史文章/「Python实用秘技09」更好用的函数运算缓存) 17 | - [「Python实用秘技10」深度比较Python对象间差异](https://www.cnblogs.com/feffery/p/16557188.html)  ✈️[仓库路径](./历史文章/「Python实用秘技10」深度比较Python对象间差异) 18 | - [「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密](https://www.cnblogs.com/feffery/p/16886578.html)  ✈️[仓库路径](./历史文章/「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密) 19 | - [「Python实用秘技12」像导入模块一样导入ipynb文件](https://www.cnblogs.com/feffery/p/17047147.html)  ✈️[仓库路径](./历史文章/「Python实用秘技12」像导入模块一样导入ipynb文件) 20 | - [「Python实用秘技13」Python中临时文件的妙用](https://www.cnblogs.com/feffery/p/17157404.html)  ✈️[仓库路径](./历史文章/「Python实用秘技13」Python中临时文件的妙用) 21 | - [「Python实用秘技14」快速优化Python导包顺序](https://www.cnblogs.com/feffery/p/17483380.html)  ✈️[仓库路径](./历史文章/「Python实用秘技14」快速优化Python导包顺序) 22 | - [「Python实用秘技15」pandas中基于范围条件进行表连接](https://www.cnblogs.com/feffery/p/17537401.html)  ✈️[仓库路径](./历史文章/「Python实用秘技15」pandas中基于范围条件进行表连接) 23 | - [「Python实用秘技16」快速提取字体子集](https://www.cnblogs.com/feffery/p/17588053.html)  ✈️[仓库路径](./历史文章/「Python实用秘技16」快速提取字体子集) 24 | - [「Python实用秘技17」快速获取国内节假日安排](https://www.cnblogs.com/feffery/p/18205617.html)  ✈️[仓库路径](./历史文章/「Python实用秘技17」快速获取国内节假日安排) -------------------------------------------------------------------------------- /历史文章/「Python实用秘技01」复杂zip文件的解压/「Python实用秘技01」复杂zip文件的解压.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "3c43f80c-c33a-4a87-a7f6-1b39c0f6e95a", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "data": { 11 | "text/plain": [ 12 | "['Python.svg.png',\n", 13 | " '▓π╝╢1/',\n", 14 | " '▓π╝╢1/▓π╝╢1-1/',\n", 15 | " '▓π╝╢1/▓π╝╢1-1/test.txt',\n", 16 | " '▓π╝╢1/▓π╝╢1-2/',\n", 17 | " '▓π╝╢1/▓π╝╢1-2/test.txt',\n", 18 | " '▓π╝╢1/▓π╝╢1-2/▓π╝╢1-2-1/',\n", 19 | " '▓π╝╢1/▓π╝╢1-2/▓π╝╢1-2-1/test.txt',\n", 20 | " '▓π╝╢2/',\n", 21 | " '▓π╝╢2/Python.svg.png',\n", 22 | " '▓π╝╢3/',\n", 23 | " '▓π╝╢3/Python.svg.png',\n", 24 | " '▓π╝╢3/▓π╝╢3-1/',\n", 25 | " '▓π╝╢3/▓π╝╢3-1/Python.svg.png']" 26 | ] 27 | }, 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "output_type": "execute_result" 31 | } 32 | ], 33 | "source": [ 34 | "import os\n", 35 | "import shutil\n", 36 | "from zipfile import ZipFile\n", 37 | "from tqdm import tqdm\n", 38 | "\n", 39 | "# 读入压缩包文件\n", 40 | "file = ZipFile('示例压缩包.zip')\n", 41 | "\n", 42 | "# 查看压缩包内目录、文件名称\n", 43 | "file.namelist()" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "id": "f62002df-e159-4aba-9347-e3fad864dd06", 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "Python.svg.png -------> Python.svg.png\n", 57 | "▓π╝╢1/ -------> 层级1/\n", 58 | "▓π╝╢1/▓π╝╢1-1/ -------> 层级1/层级1-1/\n", 59 | "▓π╝╢1/▓π╝╢1-1/test.txt -------> 层级1/层级1-1/test.txt\n", 60 | "▓π╝╢1/▓π╝╢1-2/ -------> 层级1/层级1-2/\n", 61 | "▓π╝╢1/▓π╝╢1-2/test.txt -------> 层级1/层级1-2/test.txt\n", 62 | "▓π╝╢1/▓π╝╢1-2/▓π╝╢1-2-1/ -------> 层级1/层级1-2/层级1-2-1/\n", 63 | "▓π╝╢1/▓π╝╢1-2/▓π╝╢1-2-1/test.txt -------> 层级1/层级1-2/层级1-2-1/test.txt\n", 64 | "▓π╝╢2/ -------> 层级2/\n", 65 | "▓π╝╢2/Python.svg.png -------> 层级2/Python.svg.png\n", 66 | "▓π╝╢3/ -------> 层级3/\n", 67 | "▓π╝╢3/Python.svg.png -------> 层级3/Python.svg.png\n", 68 | "▓π╝╢3/▓π╝╢3-1/ -------> 层级3/层级3-1/\n", 69 | "▓π╝╢3/▓π╝╢3-1/Python.svg.png -------> 层级3/层级3-1/Python.svg.png\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "def recode(raw: str) -> str:\n", 75 | " '''\n", 76 | " 编码修正\n", 77 | " '''\n", 78 | " \n", 79 | " try:\n", 80 | " return raw.encode('cp437').decode('gbk')\n", 81 | " \n", 82 | " except:\n", 83 | " return raw.encode('utf-8').decode('utf-8')\n", 84 | " \n", 85 | "for file_or_path in file.namelist():\n", 86 | " \n", 87 | " print(file_or_path, ' -------> ' , recode(file_or_path))" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 3, 93 | "id": "75cc87ed-b835-45b2-8561-c2a4a6d115a3", 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "def zip_extract_all(src_zip_file: ZipFile, target_path: str) -> None:\n", 98 | " \n", 99 | " # 遍历压缩包内所有内容\n", 100 | " for file_or_path in file.namelist():\n", 101 | " \n", 102 | " # 若当前节点是文件夹\n", 103 | " if file_or_path.endswith('/'):\n", 104 | " try:\n", 105 | " # 基于当前文件夹节点创建多层文件夹\n", 106 | " os.makedirs(os.path.join(target_path, recode(file_or_path)))\n", 107 | " except FileExistsError:\n", 108 | " # 若已存在则跳过创建过程\n", 109 | " pass\n", 110 | " \n", 111 | " # 否则视作文件进行写出\n", 112 | " else:\n", 113 | " # 利用shutil.copyfileobj,从压缩包io流中提取目标文件内容写出到目标路径\n", 114 | " with open(os.path.join(target_path, recode(file_or_path)), 'wb') as z:\n", 115 | " # 这里基于Zipfile.open()提取文件内容时需要使用原始的乱码文件名\n", 116 | " shutil.copyfileobj(src_zip_file.open(file_or_path), z)\n", 117 | " \n", 118 | "# 向已存在的指定文件夹完整解压当前读入的zip文件\n", 119 | "zip_extract_all(file, '解压测试')" 120 | ] 121 | } 122 | ], 123 | "metadata": { 124 | "kernelspec": { 125 | "display_name": "Python 3 (ipykernel)", 126 | "language": "python", 127 | "name": "python3" 128 | }, 129 | "language_info": { 130 | "codemirror_mode": { 131 | "name": "ipython", 132 | "version": 3 133 | }, 134 | "file_extension": ".py", 135 | "mimetype": "text/x-python", 136 | "name": "python", 137 | "nbconvert_exporter": "python", 138 | "pygments_lexer": "ipython3", 139 | "version": "3.7.11" 140 | } 141 | }, 142 | "nbformat": 4, 143 | "nbformat_minor": 5 144 | } 145 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技01」复杂zip文件的解压/示例压缩包.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CNFeffery/PythonPracticalSkills/63dc27e41ed9492fc1e1461adabecc1319ba4420/历史文章/「Python实用秘技01」复杂zip文件的解压/示例压缩包.zip -------------------------------------------------------------------------------- /历史文章/「Python实用秘技02」给Python函数定“闹钟”/「Python实用秘技02」给Python函数定“闹钟”.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "8dad232f-4714-43aa-b7b0-de5dd20461cd", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "data": { 11 | "text/plain": [ 12 | "3" 13 | ] 14 | }, 15 | "execution_count": 1, 16 | "metadata": {}, 17 | "output_type": "execute_result" 18 | } 19 | ], 20 | "source": [ 21 | "from wrapt_timeout_decorator import timeout\n", 22 | "\n", 23 | "@timeout(5) # 设置超时时长为5秒\n", 24 | "def demo_func(seconds: float) -> float:\n", 25 | " # 此处time在函数中导入是为了绕开jupyter中wrapt_timeout_decorator与time模块的特殊错误\n", 26 | " # 详见https://github.com/bitranox/wrapt_timeout_decorator/issues/24\n", 27 | " import time \n", 28 | " time.sleep(seconds)\n", 29 | " \n", 30 | " return seconds\n", 31 | "\n", 32 | "# 未超时时正常运行\n", 33 | "demo_func(3)" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "id": "a05a476b-39e0-4b22-bfe3-02e98c9ae5e1", 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "ename": "TimeoutError", 44 | "evalue": "Function demo_func timed out after 5.0 seconds", 45 | "output_type": "error", 46 | "traceback": [ 47 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 48 | "\u001b[1;31mTimeoutError\u001b[0m Traceback (most recent call last)", 49 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_19632/3796805978.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# 超时报错\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mdemo_func\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m6\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 50 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrapt_timeout_decorator.py\u001b[0m in \u001b[0;36mwrapper\u001b[1;34m(wrapped, instance, args, kwargs)\u001b[0m\n\u001b[0;32m 121\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 122\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 123\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped_with_timeout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 124\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 125\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 51 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrapt_timeout_decorator.py\u001b[0m in \u001b[0;36mwrapped_with_timeout\u001b[1;34m(wrap_helper)\u001b[0m\n\u001b[0;32m 129\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped_with_timeout_signals\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 130\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 131\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped_with_timeout_process\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 132\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 133\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 52 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrapt_timeout_decorator.py\u001b[0m in \u001b[0;36mwrapped_with_timeout_process\u001b[1;34m(wrap_helper)\u001b[0m\n\u001b[0;32m 143\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 144\u001b[0m \u001b[0mtimeout_wrapper\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTimeout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 145\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mtimeout_wrapper\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 146\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mPicklingError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 147\u001b[0m \u001b[0mdetect_unpickable_objects_and_reraise\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrapped\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 53 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrap_function_multiprocess.py\u001b[0m in \u001b[0;36m__call__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 41\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 42\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 43\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcancel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 44\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcancel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 54 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrap_function_multiprocess.py\u001b[0m in \u001b[0;36mcancel\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__process\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1.0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__parent_conn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclose\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 51\u001b[1;33m \u001b[0mraise_exception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtimeout_exception\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexception_message\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 52\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 53\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwait_until_process_started\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 55 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrap_helper.py\u001b[0m in \u001b[0;36mraise_exception\u001b[1;34m(exception, exception_message)\u001b[0m\n\u001b[0;32m 176\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mexception\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 177\u001b[0m \u001b[0mexception\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTimeoutError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 178\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mexception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexception_message\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 179\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 180\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 56 | "\u001b[1;31mTimeoutError\u001b[0m: Function demo_func timed out after 5.0 seconds" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "# 超时报错\n", 62 | "demo_func(6)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "id": "feea8933-05d6-4b73-b488-6e6dbfe6c859", 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "3" 75 | ] 76 | }, 77 | "execution_count": 3, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "class Demo:\n", 84 | " \n", 85 | " @timeout(5) # 设置超时时长为5秒\n", 86 | " @staticmethod\n", 87 | " def demo_func(seconds: float) -> float:\n", 88 | " # 此处time在函数中导入是为了绕开jupyter中wrapt_timeout_decorator与time模块的特殊错误\n", 89 | " # 详见https://github.com/bitranox/wrapt_timeout_decorator/issues/24\n", 90 | " import time \n", 91 | " time.sleep(seconds)\n", 92 | "\n", 93 | " return seconds\n", 94 | " \n", 95 | "demo = Demo()\n", 96 | "demo.demo_func(3)" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 4, 102 | "id": "4ee8293f-b7bd-4303-9be6-f2e85f64ecd3", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "ename": "TimeoutError", 107 | "evalue": "Function demo_func timed out after 5.0 seconds", 108 | "output_type": "error", 109 | "traceback": [ 110 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 111 | "\u001b[1;31mTimeoutError\u001b[0m Traceback (most recent call last)", 112 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_19632/1652738282.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mDemo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdemo_func\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m6\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 113 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrapt_timeout_decorator.py\u001b[0m in \u001b[0;36mwrapper\u001b[1;34m(wrapped, instance, args, kwargs)\u001b[0m\n\u001b[0;32m 121\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 122\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 123\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped_with_timeout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 124\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 125\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 114 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrapt_timeout_decorator.py\u001b[0m in \u001b[0;36mwrapped_with_timeout\u001b[1;34m(wrap_helper)\u001b[0m\n\u001b[0;32m 129\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped_with_timeout_signals\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 130\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 131\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped_with_timeout_process\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 132\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 133\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 115 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrapt_timeout_decorator.py\u001b[0m in \u001b[0;36mwrapped_with_timeout_process\u001b[1;34m(wrap_helper)\u001b[0m\n\u001b[0;32m 143\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 144\u001b[0m \u001b[0mtimeout_wrapper\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTimeout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 145\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mtimeout_wrapper\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 146\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mPicklingError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 147\u001b[0m \u001b[0mdetect_unpickable_objects_and_reraise\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrapped\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 116 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrap_function_multiprocess.py\u001b[0m in \u001b[0;36m__call__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 41\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 42\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 43\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcancel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 44\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcancel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 117 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrap_function_multiprocess.py\u001b[0m in \u001b[0;36mcancel\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__process\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1.0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__parent_conn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclose\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 51\u001b[1;33m \u001b[0mraise_exception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtimeout_exception\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrap_helper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexception_message\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 52\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 53\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwait_until_process_started\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 118 | "\u001b[1;32mC:\\Conda\\envs\\data-science\\lib\\site-packages\\wrapt_timeout_decorator\\wrap_helper.py\u001b[0m in \u001b[0;36mraise_exception\u001b[1;34m(exception, exception_message)\u001b[0m\n\u001b[0;32m 176\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mexception\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 177\u001b[0m \u001b[0mexception\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTimeoutError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 178\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mexception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexception_message\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 179\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 180\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 119 | "\u001b[1;31mTimeoutError\u001b[0m: Function demo_func timed out after 5.0 seconds" 120 | ] 121 | } 122 | ], 123 | "source": [ 124 | "Demo().demo_func(6)" 125 | ] 126 | } 127 | ], 128 | "metadata": { 129 | "kernelspec": { 130 | "display_name": "Python 3 (ipykernel)", 131 | "language": "python", 132 | "name": "python3" 133 | }, 134 | "language_info": { 135 | "codemirror_mode": { 136 | "name": "ipython", 137 | "version": 3 138 | }, 139 | "file_extension": ".py", 140 | "mimetype": "text/x-python", 141 | "name": "python", 142 | "nbconvert_exporter": "python", 143 | "pygments_lexer": "ipython3", 144 | "version": "3.7.11" 145 | } 146 | }, 147 | "nbformat": 4, 148 | "nbformat_minor": 5 149 | } 150 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技03」导出项目的极简环境依赖/demo_projects/main.py: -------------------------------------------------------------------------------- 1 | import dash 2 | import pandas as pd 3 | from flask import Flask, request, send_from_directory 4 | from sklearn.model_selection import train_test_split -------------------------------------------------------------------------------- /历史文章/「Python实用秘技03」导出项目的极简环境依赖/demo_projects/pip_requirements.txt: -------------------------------------------------------------------------------- 1 | attrs @ file:///home/conda/feedstock_root/build_artifacts/attrs_1620387926260/work 2 | bleach==3.3.0 3 | branca @ file:///home/conda/feedstock_root/build_artifacts/branca_1609346930842/work 4 | Brotli==1.0.9 5 | brotlipy @ file:///D:/bld/brotlipy_1636012439160/work 6 | certifi==2021.10.8 7 | cffi @ file:///D:/bld/cffi_1636046306023/work 8 | chardet==4.0.0 9 | charset-normalizer @ file:///home/conda/feedstock_root/build_artifacts/charset-normalizer_1638815705608/work 10 | click==8.0.1 11 | click-plugins==1.1.1 12 | cligj @ file:///home/conda/feedstock_root/build_artifacts/cligj_1633637764473/work 13 | colorama==0.4.4 14 | cryptography @ file:///D:/bld/cryptography_1637649123707/work 15 | cycler @ file:///home/conda/feedstock_root/build_artifacts/cycler_1635519461629/work 16 | dash==2.0.0 17 | dash-core-components==2.0.0 18 | dash-html-components==2.0.0 19 | dash-table==5.0.0 20 | decorator==5.1.0 21 | Django==3.1.6 22 | docopt==0.6.2 23 | docutils==0.17.1 24 | et-xmlfile==1.1.0 25 | Faker==8.14.0 26 | feffery-antd-charts==0.0.1rc2 27 | feffery-antd-components @ git+https://github.com/CNFeffery/feffery-antd-components.git@6aaba1151c4a5fc5f421618504562c03610dd682 28 | feffery-utils-components @ git+https://github.com/CNFeffery/feffery-utils-components.git@499d7d7cff0b2b6e0749660d69c05c7bb2c60576 29 | Fiona==1.8.13.post1 30 | Flask==2.0.1 31 | Flask-Compress==1.10.1 32 | Flask-Cors==3.0.10 33 | Flask-Login==0.5.0 34 | folium @ file:///home/conda/feedstock_root/build_artifacts/folium_1638560701663/work 35 | fonttools @ file:///D:/bld/fonttools_1638544580851/work 36 | funcy==1.16 37 | GDAL==3.0.2 38 | GeoAlchemy2==0.9.4 39 | geopandas @ file:///home/conda/feedstock_root/build_artifacts/geopandas_1638382567988/work 40 | greenlet==1.1.2 41 | gunicorn==20.1.0 42 | idna==2.10 43 | image==1.5.33 44 | importlib-metadata==4.8.1 45 | itsdangerous==2.0.1 46 | jieba==0.42.1 47 | Jinja2 @ file:///home/conda/feedstock_root/build_artifacts/jinja2_1636510082894/work 48 | joblib @ file:///home/conda/feedstock_root/build_artifacts/joblib_1633637554808/work 49 | jsonpath-ng==1.5.3 50 | keyring==23.0.1 51 | kiwisolver @ file:///D:/bld/kiwisolver_1635836925049/work 52 | mapclassify @ file:///home/conda/feedstock_root/build_artifacts/mapclassify_1627363180059/work 53 | MarkupSafe @ file:///D:/bld/markupsafe_1635833748820/work 54 | matplotlib @ file:///D:/bld/matplotlib-suite_1639359207070/work 55 | munch==2.5.0 56 | munkres==1.1.4 57 | networkx @ file:///home/conda/feedstock_root/build_artifacts/networkx_1635253012265/work 58 | numpy @ file:///D:/bld/numpy_1636145475359/work 59 | olefile @ file:///home/conda/feedstock_root/build_artifacts/olefile_1602866521163/work 60 | openpyxl==3.0.9 61 | packaging==20.9 62 | palettable==3.3.0 63 | pandas @ file:///D:/bld/pandas_1639398349358/work 64 | peewee==3.14.8 65 | Pillow @ file:///D:/bld/pillow_1636559064986/work 66 | pipreqs==0.4.11 67 | pkginfo==1.8.2 68 | plotly==5.3.1 69 | ply==3.11 70 | psycopg2==2.9.2 71 | pycparser @ file:///home/conda/feedstock_root/build_artifacts/pycparser_1636257122734/work 72 | Pygments==2.9.0 73 | pymongo==4.0.1 74 | pyOpenSSL @ file:///home/conda/feedstock_root/build_artifacts/pyopenssl_1633192417276/work 75 | pyparsing==2.4.7 76 | pyproj==3.0.0.post1 77 | PySocks @ file:///D:/bld/pysocks_1635862618120/work 78 | python-dateutil @ file:///home/conda/feedstock_root/build_artifacts/python-dateutil_1626286286081/work 79 | pytz @ file:///home/conda/feedstock_root/build_artifacts/pytz_1633452062248/work 80 | pywin32-ctypes==0.2.0 81 | PyYAML==5.3.1 82 | qrcode==6.1 83 | readme-renderer==29.0 84 | requests==2.25.1 85 | requests-toolbelt==0.9.1 86 | rfc3986==1.5.0 87 | Rtree==0.9.7 88 | scikit-learn @ file:///D:/bld/scikit-learn_1639497841813/work 89 | scipy @ file:///C:/bld/scipy_1637806996411/work 90 | seaborn==0.11.2 91 | Shapely==1.7.1 92 | six @ file:///home/conda/feedstock_root/build_artifacts/six_1620240208055/work 93 | SQLAlchemy==1.4.28 94 | sqlparse==0.4.1 95 | tenacity==8.0.1 96 | text-unidecode==1.3 97 | textrank4zh==0.3 98 | threadpoolctl @ file:///home/conda/feedstock_root/build_artifacts/threadpoolctl_1633102299089/work 99 | tqdm==4.62.3 100 | twine==3.7.1 101 | typing-extensions==3.10.0.2 102 | unicodedata2 @ file:///D:/bld/unicodedata2_1637177797776/work 103 | urllib3==1.26.4 104 | webencodings==0.5.1 105 | Werkzeug==2.0.1 106 | win-inet-pton @ file:///D:/bld/win_inet_pton_1635832912576/work 107 | wincertstore==0.2 108 | xyzservices @ file:///home/conda/feedstock_root/build_artifacts/xyzservices_1638470968221/work 109 | yarg==0.1.9 110 | zipp==3.5.0 111 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技03」导出项目的极简环境依赖/demo_projects/requirements.txt: -------------------------------------------------------------------------------- 1 | dash==2.0.0 2 | Flask==2.0.1 3 | matplotlib==3.5.1 4 | palettable==3.3.0 5 | pandas==1.3.5 6 | scikit_learn==1.0.1 7 | seaborn==0.11.2 8 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技03」导出项目的极简环境依赖/demo_projects/sub_module1/__init__.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt -------------------------------------------------------------------------------- /历史文章/「Python实用秘技03」导出项目的极简环境依赖/demo_projects/sub_module2/__init__.py: -------------------------------------------------------------------------------- 1 | import seaborn as sns 2 | from palettable.cmocean import sequential -------------------------------------------------------------------------------- /历史文章/「Python实用秘技04」为pdf文件批量添加文字水印/「Python实用秘技04」为pdf文件批量添加文字水印.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "1ab977ad-257a-46e9-852b-d77b114c74f7", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "from typing import Union, Tuple\n", 11 | "from reportlab.lib import units\n", 12 | "from reportlab.pdfgen import canvas\n", 13 | "from reportlab.pdfbase import pdfmetrics\n", 14 | "from reportlab.pdfbase.ttfonts import TTFont\n", 15 | "\n", 16 | "# 注册字体,这里的字体是我从windows的字体目录下复制过来的\n", 17 | "pdfmetrics.registerFont(TTFont('msyh', r'./msyh.ttc'))\n", 18 | "\n", 19 | "def create_watermark(content: str,\n", 20 | " filename: str, \n", 21 | " width: Union[int, float], \n", 22 | " height: Union[int, float], \n", 23 | " font: str, \n", 24 | " fontsize: int,\n", 25 | " angle: Union[int, float] = 45,\n", 26 | " text_stroke_color_rgb: Tuple[int, int, int] = (0, 0, 0),\n", 27 | " text_fill_color_rgb: Tuple[int, int, int] = (0, 0, 0),\n", 28 | " text_fill_alpha: Union[int, float] = 1) -> None:\n", 29 | " '''\n", 30 | " 用于生成包含content文字内容的水印pdf文件\n", 31 | " content: 水印文本内容\n", 32 | " filename: 导出的水印文件名\n", 33 | " width: 画布宽度,单位:mm\n", 34 | " height: 画布高度,单位:mm\n", 35 | " font: 对应注册的字体代号\n", 36 | " fontsize: 字号大小\n", 37 | " angle: 旋转角度\n", 38 | " text_stroke_color_rgb: 文字轮廓rgb色\n", 39 | " text_fill_color_rgb: 文字填充rgb色\n", 40 | " text_fill_alpha: 文字透明度\n", 41 | " '''\n", 42 | "\n", 43 | " # 创建pdf文件,指定文件名及尺寸,这里以像素单位为例\n", 44 | " c = canvas.Canvas(f\"{filename}.pdf\", pagesize = (width*units.mm, height*units.mm))\n", 45 | " \n", 46 | " # 进行轻微的画布平移保证文字的完整\n", 47 | " c.translate(0.1*width*units.mm, 0.1*height*units.mm)\n", 48 | " \n", 49 | " # 设置旋转角度\n", 50 | " c.rotate(angle)\n", 51 | " \n", 52 | " # 设置字体及字号大小\n", 53 | " c.setFont(font, fontsize)\n", 54 | " \n", 55 | " # 设置文字轮廓色彩\n", 56 | " c.setStrokeColorRGB(*text_stroke_color_rgb)\n", 57 | " \n", 58 | " # 设置文字填充色\n", 59 | " c.setFillColorRGB(*text_fill_color_rgb)\n", 60 | " \n", 61 | " # 设置文字填充色透明度\n", 62 | " c.setFillAlpha(text_fill_alpha)\n", 63 | " \n", 64 | " # 绘制文字内容\n", 65 | " c.drawString(0, 0, content)\n", 66 | " \n", 67 | " # 保存水印pdf文件\n", 68 | " c.save()" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 2, 74 | "id": "19dcae9f-54e2-4db3-95bd-2ec95dd4e5b0", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "# 制造示例文字水印pdf文件\n", 79 | "create_watermark(content='公众号【Python大数据分析】作者:费弗里', \n", 80 | " filename='水印示例', \n", 81 | " width=200,\n", 82 | " height=200, \n", 83 | " font='msyh', \n", 84 | " fontsize=35,\n", 85 | " text_fill_alpha=0.3)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 3, 91 | "id": "6f27596b-5e0c-4424-8ad7-7ae595811efc", 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "from typing import List\n", 96 | "from pikepdf import Pdf, Page, Rectangle\n", 97 | "\n", 98 | "def add_watermark(target_pdf_path: str,\n", 99 | " watermark_pdf_path: str,\n", 100 | " nrow: int,\n", 101 | " ncol: int,\n", 102 | " skip_pages: List[int] = []) -> None:\n", 103 | " '''\n", 104 | " 向目标pdf文件中添加平铺水印\n", 105 | " target_pdf_path: 目标pdf文件的路径+文件名\n", 106 | " watermark_pdf_path: 水印pdf文件的路径+文件名\n", 107 | " nrow: 水印平铺的行数\n", 108 | " ncol:水印平铺的列数\n", 109 | " skip_pages: 需要跳过不添加水印的页面序号(从0开始)\n", 110 | " '''\n", 111 | " \n", 112 | " # 读入需要添加水印的pdf文件\n", 113 | " target_pdf = Pdf.open(target_pdf_path)\n", 114 | " \n", 115 | " # 读入水印pdf文件并提取水印页\n", 116 | " watermark_pdf = Pdf.open(watermark_pdf_path)\n", 117 | " watermark_page = watermark_pdf.pages[0]\n", 118 | " \n", 119 | " # 遍历目标pdf文件中的所有页(排除skip_pages指定的若干页)\n", 120 | " for idx, target_page in enumerate(target_pdf.pages):\n", 121 | " \n", 122 | " if idx not in skip_pages:\n", 123 | " for x in range(ncol):\n", 124 | " for y in range(nrow):\n", 125 | " # 向目标页指定范围添加水印\n", 126 | " target_page.add_overlay(watermark_page, Rectangle(target_page.trimbox[2] * x / ncol, \n", 127 | " target_page.trimbox[3] * y / nrow,\n", 128 | " target_page.trimbox[2] * (x + 1) / ncol, \n", 129 | " target_page.trimbox[3] * (y + 1) / nrow))\n", 130 | " \n", 131 | " # 将添加完水印后的结果保存为新的pdf\n", 132 | " target_pdf.save(target_pdf_path[:-4]+'_已添加水印.pdf')" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 4, 138 | "id": "ff62cf4f-1524-4a9b-b389-c3ba7254040c", 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [ 142 | "add_watermark(target_pdf_path='./【吴恩达】机器学习训练秘籍-中文版.pdf',\n", 143 | " watermark_pdf_path='./水印示例.pdf',\n", 144 | " nrow=3,\n", 145 | " ncol=2,\n", 146 | " skip_pages=[0])" 147 | ] 148 | } 149 | ], 150 | "metadata": { 151 | "kernelspec": { 152 | "display_name": "Python 3 (ipykernel)", 153 | "language": "python", 154 | "name": "python3" 155 | }, 156 | "language_info": { 157 | "codemirror_mode": { 158 | "name": "ipython", 159 | "version": 3 160 | }, 161 | "file_extension": ".py", 162 | "mimetype": "text/x-python", 163 | "name": "python", 164 | "nbconvert_exporter": "python", 165 | "pygments_lexer": "ipython3", 166 | "version": "3.7.11" 167 | } 168 | }, 169 | "nbformat": 4, 170 | "nbformat_minor": 5 171 | } 172 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技05」在Python中妙用短路机制/「Python实用秘技05」在Python中妙用短路机制.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "88571da6-7696-48ff-bebd-d4988752d880", 6 | "metadata": {}, 7 | "source": [ 8 | "- **X or Y**" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "693e98b6-1b75-42f5-b3b3-dee9afdab88f", 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "ename": "ZeroDivisionError", 19 | "evalue": "division by zero", 20 | "output_type": "error", 21 | "traceback": [ 22 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 23 | "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", 24 | "\u001b[1;32m~\\AppData\\Local\\Temp\\ipykernel_12268\\1455669704.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m1\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 25 | "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" 26 | ] 27 | } 28 | ], 29 | "source": [ 30 | "1 / 0" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "id": "8d23862c-2185-4e94-9af1-41356843a0f8", 37 | "metadata": { 38 | "tags": [] 39 | }, 40 | "outputs": [ 41 | { 42 | "data": { 43 | "text/plain": [ 44 | "True" 45 | ] 46 | }, 47 | "execution_count": 2, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "1 > 0 or 1 / 0" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 3, 59 | "id": "ca23e6f2-1f1d-4578-b66f-0c60e5e39b9a", 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": [ 65 | "999" 66 | ] 67 | }, 68 | "execution_count": 3, 69 | "metadata": {}, 70 | "output_type": "execute_result" 71 | } 72 | ], 73 | "source": [ 74 | "999 or 1 / 0" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 4, 80 | "id": "d836ce42-a5e9-4657-832d-dccaa48c0565", 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "data": { 85 | "text/plain": [ 86 | "False" 87 | ] 88 | }, 89 | "execution_count": 4, 90 | "metadata": {}, 91 | "output_type": "execute_result" 92 | } 93 | ], 94 | "source": [ 95 | "bool(0)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 5, 101 | "id": "48d6f173-eae9-4f1c-a1a3-f371ed475b78", 102 | "metadata": {}, 103 | "outputs": [ 104 | { 105 | "data": { 106 | "text/plain": [ 107 | "999" 108 | ] 109 | }, 110 | "execution_count": 5, 111 | "metadata": {}, 112 | "output_type": "execute_result" 113 | } 114 | ], 115 | "source": [ 116 | "0 or 999" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "id": "d9abd18f-77b8-429c-ac47-3b0778e4d058", 122 | "metadata": {}, 123 | "source": [ 124 | "- **X and Y**" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 6, 130 | "id": "5eb5abad-742d-489f-bc33-108a73993fa5", 131 | "metadata": {}, 132 | "outputs": [ 133 | { 134 | "data": { 135 | "text/plain": [ 136 | "False" 137 | ] 138 | }, 139 | "execution_count": 6, 140 | "metadata": {}, 141 | "output_type": "execute_result" 142 | } 143 | ], 144 | "source": [ 145 | "bool([])" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 7, 151 | "id": "17e52d91-c9b0-4d2f-a04c-e4da67746042", 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "data": { 156 | "text/plain": [ 157 | "[]" 158 | ] 159 | }, 160 | "execution_count": 7, 161 | "metadata": {}, 162 | "output_type": "execute_result" 163 | } 164 | ], 165 | "source": [ 166 | "[] and print(1)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "id": "63cd0eec-2052-446e-88a3-b483760e9cf8", 172 | "metadata": {}, 173 | "source": [ 174 | "- **any()**" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 8, 180 | "id": "05a3525a-3195-41dd-8581-ae04a5fa3b9d", 181 | "metadata": {}, 182 | "outputs": [ 183 | { 184 | "name": "stdout", 185 | "output_type": "stream", 186 | "text": [ 187 | "0\n", 188 | "0\n", 189 | "1\n", 190 | "耗时:3.028966\n" 191 | ] 192 | } 193 | ], 194 | "source": [ 195 | "import time\n", 196 | "\n", 197 | "def any_demo(i):\n", 198 | " time.sleep(1)\n", 199 | " print(i)\n", 200 | " \n", 201 | " return i\n", 202 | "\n", 203 | "start_time = time.time()\n", 204 | "any(any_demo(i) for i in [0, 0, 1, 2, 3, 4, 5])\n", 205 | "print('耗时:%f' % (time.time() - start_time))" 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "id": "8e997b95-96b9-4c49-9eb8-9de43e4b7f0c", 211 | "metadata": {}, 212 | "source": [ 213 | "- **all()**" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 9, 219 | "id": "b6d48b56-7313-45cd-b2d8-a325d8667ae0", 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "1\n", 227 | "2\n", 228 | "0\n", 229 | "耗时:3.018476\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "import time\n", 235 | "\n", 236 | "def any_demo(i):\n", 237 | " time.sleep(1)\n", 238 | " print(i)\n", 239 | " \n", 240 | " return i\n", 241 | "\n", 242 | "start_time = time.time()\n", 243 | "all(any_demo(i) for i in [1, 2, 0, 3, 4, 5])\n", 244 | "print('耗时:%f' % (time.time() - start_time))" 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "id": "f74ec017-7d4d-4569-a0e3-6523ca83f836", 250 | "metadata": {}, 251 | "source": [ 252 | "- **比较运算符**" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 10, 258 | "id": "52aaa9e8-2d16-475a-9a90-dfbeec8f5fc1", 259 | "metadata": {}, 260 | "outputs": [ 261 | { 262 | "name": "stdout", 263 | "output_type": "stream", 264 | "text": [ 265 | "0\n", 266 | "-1\n" 267 | ] 268 | }, 269 | { 270 | "data": { 271 | "text/plain": [ 272 | "False" 273 | ] 274 | }, 275 | "execution_count": 10, 276 | "metadata": {}, 277 | "output_type": "execute_result" 278 | } 279 | ], 280 | "source": [ 281 | "any_demo(0) < any_demo(-1) < any_demo(-2) < any_demo(-3)" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": 11, 287 | "id": "55daf81b-267e-414c-a714-771992062ff0", 288 | "metadata": {}, 289 | "outputs": [ 290 | { 291 | "name": "stdout", 292 | "output_type": "stream", 293 | "text": [ 294 | "0\n", 295 | "-1\n" 296 | ] 297 | }, 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "False" 302 | ] 303 | }, 304 | "execution_count": 11, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "any_demo(0) == any_demo(-1) == any_demo(-2) == any_demo(-3)" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 12, 316 | "id": "414cb93d-45da-4500-bb01-cea05492e08d", 317 | "metadata": {}, 318 | "outputs": [ 319 | { 320 | "name": "stdout", 321 | "output_type": "stream", 322 | "text": [ 323 | "-3\n", 324 | "-2\n" 325 | ] 326 | }, 327 | { 328 | "data": { 329 | "text/plain": [ 330 | "False" 331 | ] 332 | }, 333 | "execution_count": 12, 334 | "metadata": {}, 335 | "output_type": "execute_result" 336 | } 337 | ], 338 | "source": [ 339 | "any_demo(-3) > any_demo(-2) > any_demo(-1) > any_demo(0)" 340 | ] 341 | }, 342 | { 343 | "cell_type": "markdown", 344 | "id": "c120f8f8-fd07-4be4-98ba-e7470904ec5b", 345 | "metadata": {}, 346 | "source": [ 347 | "- **实际使用示例**" 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "execution_count": 13, 353 | "id": "a350491d-2af0-45e7-86be-39116b1b8478", 354 | "metadata": {}, 355 | "outputs": [], 356 | "source": [ 357 | "def api1(id_):\n", 358 | " \n", 359 | " time.sleep(1)\n", 360 | " \n", 361 | " return id_ in ['admin1', 'admin2']\n", 362 | "\n", 363 | "def api2(id_):\n", 364 | " \n", 365 | " time.sleep(1)\n", 366 | " \n", 367 | " return id_ in ['admin1', 'admin2', 'su1', 'su2']\n", 368 | "\n", 369 | "def api3(id_):\n", 370 | " \n", 371 | " time.sleep(1)\n", 372 | " \n", 373 | " return id_ not in ['ban1', 'ban2', 'ban3']" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 14, 379 | "id": "07d3b919-9ea8-4b47-84c2-a00605d2944a", 380 | "metadata": {}, 381 | "outputs": [ 382 | { 383 | "name": "stdout", 384 | "output_type": "stream", 385 | "text": [ 386 | "非超级权限\n", 387 | "耗时:1.001034\n" 388 | ] 389 | } 390 | ], 391 | "source": [ 392 | "start_time = time.time()\n", 393 | "\n", 394 | "# 判断第一位用户的权限\n", 395 | "username1 = 'visitor1'\n", 396 | "if api1(username1) and api2(username1) and api3(username1):\n", 397 | " print('超级权限')\n", 398 | "else:\n", 399 | " print('非超级权限')\n", 400 | "print('耗时:%f' % (time.time() - start_time))" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": 15, 406 | "id": "1de9508b-9c03-44ba-b03c-5f92b62e5ac2", 407 | "metadata": {}, 408 | "outputs": [ 409 | { 410 | "name": "stdout", 411 | "output_type": "stream", 412 | "text": [ 413 | "超级权限\n", 414 | "耗时:3.024951\n" 415 | ] 416 | } 417 | ], 418 | "source": [ 419 | "start_time = time.time()\n", 420 | "\n", 421 | "# 判断第二位用户的权限\n", 422 | "username2 = 'admin2'\n", 423 | "if api1(username2) and api2(username2) and api3(username2):\n", 424 | " print('超级权限')\n", 425 | "else:\n", 426 | " print('非超级权限')\n", 427 | "print('耗时:%f' % (time.time() - start_time))" 428 | ] 429 | } 430 | ], 431 | "metadata": { 432 | "kernelspec": { 433 | "display_name": "Python 3 (ipykernel)", 434 | "language": "python", 435 | "name": "python3" 436 | }, 437 | "language_info": { 438 | "codemirror_mode": { 439 | "name": "ipython", 440 | "version": 3 441 | }, 442 | "file_extension": ".py", 443 | "mimetype": "text/x-python", 444 | "name": "python", 445 | "nbconvert_exporter": "python", 446 | "pygments_lexer": "ipython3", 447 | "version": "3.7.11" 448 | } 449 | }, 450 | "nbformat": 4, 451 | "nbformat_minor": 5 452 | } 453 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技06」逐行监听Python程序的内存消耗/demo.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from memory_profiler import profile 3 | 4 | @profile 5 | def demo(): 6 | a = np.random.rand(10000000) 7 | b = np.random.rand(10000000) 8 | 9 | a_ = a[a < b] 10 | b_ = b[a < b] 11 | 12 | del a, b 13 | 14 | return a_, b_ 15 | 16 | 17 | if __name__ == '__main__': 18 | demo() -------------------------------------------------------------------------------- /历史文章/「Python实用秘技07」在pandas中实现自然顺序排序/「Python实用秘技07」在pandas中实现自然顺序排序.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "id": "08655edd-e11a-42ab-b5e6-76f9861cd3eb", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import numpy as np\n", 11 | "import pandas as pd\n", 12 | "from natsort import index_natsorted" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "id": "f7a6a636-3285-4ca5-866c-2537e6bacb2e", 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "data": { 23 | "text/html": [ 24 | "
\n", 25 | "\n", 38 | "\n", 39 | " \n", 40 | " \n", 41 | " \n", 42 | " \n", 43 | " \n", 44 | " \n", 45 | " \n", 46 | " \n", 47 | " \n", 48 | " \n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | "
indexvalue
0018.67%
1131.5%
223.25%
3377.02%
4449.33%
5529.28%
6650.33%
7794.57%
8884.02%
9961.07%
\n", 99 | "
" 100 | ], 101 | "text/plain": [ 102 | " index value\n", 103 | "0 0 18.67%\n", 104 | "1 1 31.5%\n", 105 | "2 2 3.25%\n", 106 | "3 3 77.02%\n", 107 | "4 4 49.33%\n", 108 | "5 5 29.28%\n", 109 | "6 6 50.33%\n", 110 | "7 7 94.57%\n", 111 | "8 8 84.02%\n", 112 | "9 9 61.07%" 113 | ] 114 | }, 115 | "execution_count": 1, 116 | "metadata": {}, 117 | "output_type": "execute_result" 118 | } 119 | ], 120 | "source": [ 121 | "demo = pd.DataFrame({\n", 122 | " 'index': range(10),\n", 123 | " 'value': np.random.rand(10)\n", 124 | "})\n", 125 | "demo['value'] = demo['value'].map(lambda x: f'{round(x*100, 2)}%')\n", 126 | "demo" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 2, 132 | "id": "97522733-0fa5-44c2-9120-90bfa44c1c66", 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/html": [ 138 | "
\n", 139 | "\n", 152 | "\n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | "
indexvalue
0018.67%
5529.28%
223.25%
1131.5%
4449.33%
6650.33%
9961.07%
3377.02%
8884.02%
7794.57%
\n", 213 | "
" 214 | ], 215 | "text/plain": [ 216 | " index value\n", 217 | "0 0 18.67%\n", 218 | "5 5 29.28%\n", 219 | "2 2 3.25%\n", 220 | "1 1 31.5%\n", 221 | "4 4 49.33%\n", 222 | "6 6 50.33%\n", 223 | "9 9 61.07%\n", 224 | "3 3 77.02%\n", 225 | "8 8 84.02%\n", 226 | "7 7 94.57%" 227 | ] 228 | }, 229 | "execution_count": 2, 230 | "metadata": {}, 231 | "output_type": "execute_result" 232 | } 233 | ], 234 | "source": [ 235 | "demo.sort_values('value')" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 8, 241 | "id": "9db12aa3-ca9e-4604-9519-f22752807af3", 242 | "metadata": {}, 243 | "outputs": [ 244 | { 245 | "data": { 246 | "text/plain": [ 247 | "[2, 0, 5, 1, 4, 6, 9, 3, 8, 7]" 248 | ] 249 | }, 250 | "execution_count": 8, 251 | "metadata": {}, 252 | "output_type": "execute_result" 253 | } 254 | ], 255 | "source": [ 256 | "index_natsorted(demo['value'])" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 9, 262 | "id": "6c295c7d-cd61-427e-916d-3ff1e038bd1b", 263 | "metadata": {}, 264 | "outputs": [ 265 | { 266 | "data": { 267 | "text/plain": [ 268 | "array([1, 3, 0, 7, 4, 2, 5, 9, 8, 6], dtype=int64)" 269 | ] 270 | }, 271 | "execution_count": 9, 272 | "metadata": {}, 273 | "output_type": "execute_result" 274 | } 275 | ], 276 | "source": [ 277 | "np.argsort(index_natsorted(demo['value']))" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 10, 283 | "id": "3b9d5a37-02b9-44b4-8648-a8159558fdd9", 284 | "metadata": {}, 285 | "outputs": [ 286 | { 287 | "data": { 288 | "text/html": [ 289 | "
\n", 290 | "\n", 303 | "\n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | "
indexvalue
223.25%
0018.67%
5529.28%
1131.5%
4449.33%
6650.33%
9961.07%
3377.02%
8884.02%
7794.57%
\n", 364 | "
" 365 | ], 366 | "text/plain": [ 367 | " index value\n", 368 | "2 2 3.25%\n", 369 | "0 0 18.67%\n", 370 | "5 5 29.28%\n", 371 | "1 1 31.5%\n", 372 | "4 4 49.33%\n", 373 | "6 6 50.33%\n", 374 | "9 9 61.07%\n", 375 | "3 3 77.02%\n", 376 | "8 8 84.02%\n", 377 | "7 7 94.57%" 378 | ] 379 | }, 380 | "execution_count": 10, 381 | "metadata": {}, 382 | "output_type": "execute_result" 383 | } 384 | ], 385 | "source": [ 386 | "demo.sort_values('value', key=lambda by: np.argsort(index_natsorted(by)))" 387 | ] 388 | } 389 | ], 390 | "metadata": { 391 | "kernelspec": { 392 | "display_name": "Python 3 (ipykernel)", 393 | "language": "python", 394 | "name": "python3" 395 | }, 396 | "language_info": { 397 | "codemirror_mode": { 398 | "name": "ipython", 399 | "version": 3 400 | }, 401 | "file_extension": ".py", 402 | "mimetype": "text/x-python", 403 | "name": "python", 404 | "nbconvert_exporter": "python", 405 | "pygments_lexer": "ipython3", 406 | "version": "3.8.12" 407 | } 408 | }, 409 | "nbformat": 4, 410 | "nbformat_minor": 5 411 | } 412 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技08」一行代码解析地址信息/「Python实用秘技08」一行代码解析地址信息.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "9b63bf9b-5d1e-4265-994e-cf98bfec97fa", 7 | "metadata": { 8 | "execution": { 9 | "iopub.execute_input": "2022-05-05T11:33:19.582949Z", 10 | "iopub.status.busy": "2022-05-05T11:33:19.582949Z", 11 | "iopub.status.idle": "2022-05-05T11:33:20.295338Z", 12 | "shell.execute_reply": "2022-05-05T11:33:20.294339Z", 13 | "shell.execute_reply.started": "2022-05-05T11:33:19.582949Z" 14 | }, 15 | "tags": [] 16 | }, 17 | "outputs": [ 18 | { 19 | "name": "stdout", 20 | "output_type": "stream", 21 | "text": [ 22 | "`jio.help()` is provided to search how to use jio functions.\n", 23 | "Or browse `https://github.com/dongrixinyu/JioNLP` to get help.\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "import jionlp as jio" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "id": "6b156875-a0f6-448e-a964-e1f701129a44", 35 | "metadata": { 36 | "execution": { 37 | "iopub.execute_input": "2022-05-05T11:33:20.295338Z", 38 | "iopub.status.busy": "2022-05-05T11:33:20.295338Z", 39 | "iopub.status.idle": "2022-05-05T11:33:24.055846Z", 40 | "shell.execute_reply": "2022-05-05T11:33:24.054849Z", 41 | "shell.execute_reply.started": "2022-05-05T11:33:20.295338Z" 42 | }, 43 | "tags": [] 44 | }, 45 | "outputs": [ 46 | { 47 | "data": { 48 | "text/plain": [ 49 | "{'province': '北京市',\n", 50 | " 'city': '北京市',\n", 51 | " 'county': '海淀区',\n", 52 | " 'detail': '万寿路街道翠微路社区居委会',\n", 53 | " 'full_location': '北京市海淀区万寿路街道翠微路社区居委会',\n", 54 | " 'orig_location': '北京市海淀区万寿路街道翠微路社区居委会'}" 55 | ] 56 | }, 57 | "execution_count": 2, 58 | "metadata": {}, 59 | "output_type": "execute_result" 60 | } 61 | ], 62 | "source": [ 63 | "raw_address = '北京市海淀区万寿路街道翠微路社区居委会'\n", 64 | "jio.parse_location(raw_address)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 3, 70 | "id": "953b1216-7d13-4861-9b0c-df4289d584a3", 71 | "metadata": { 72 | "execution": { 73 | "iopub.execute_input": "2022-05-05T11:33:24.056844Z", 74 | "iopub.status.busy": "2022-05-05T11:33:24.056844Z", 75 | "iopub.status.idle": "2022-05-05T11:33:24.071243Z", 76 | "shell.execute_reply": "2022-05-05T11:33:24.070246Z", 77 | "shell.execute_reply.started": "2022-05-05T11:33:24.056844Z" 78 | }, 79 | "tags": [] 80 | }, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/plain": [ 85 | "{'province': '北京市',\n", 86 | " 'city': '北京市',\n", 87 | " 'county': '海淀区',\n", 88 | " 'detail': '万寿路街道翠微路社区居委会',\n", 89 | " 'full_location': '北京市海淀区万寿路街道翠微路社区居委会',\n", 90 | " 'orig_location': '北京海淀万寿路街道翠微路社区居委会'}" 91 | ] 92 | }, 93 | "execution_count": 3, 94 | "metadata": {}, 95 | "output_type": "execute_result" 96 | } 97 | ], 98 | "source": [ 99 | "raw_address = '北京海淀万寿路街道翠微路社区居委会'\n", 100 | "jio.parse_location(raw_address)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 4, 106 | "id": "c3eab733-4fe0-4adf-b15e-06c315833eac", 107 | "metadata": { 108 | "execution": { 109 | "iopub.execute_input": "2022-05-05T11:33:24.074239Z", 110 | "iopub.status.busy": "2022-05-05T11:33:24.073240Z", 111 | "iopub.status.idle": "2022-05-05T11:33:29.283291Z", 112 | "shell.execute_reply": "2022-05-05T11:33:29.282284Z", 113 | "shell.execute_reply.started": "2022-05-05T11:33:24.073240Z" 114 | }, 115 | "tags": [] 116 | }, 117 | "outputs": [ 118 | { 119 | "data": { 120 | "text/plain": [ 121 | "{'province': '北京市',\n", 122 | " 'city': '北京市',\n", 123 | " 'county': '海淀区',\n", 124 | " 'detail': '万寿路街道翠微路社区居委会',\n", 125 | " 'full_location': '北京市海淀区万寿路街道翠微路社区居委会',\n", 126 | " 'orig_location': '北京市海淀区万寿路街道翠微路社区居委会',\n", 127 | " 'town': '万寿路街道',\n", 128 | " 'village': '翠微路社区'}" 129 | ] 130 | }, 131 | "execution_count": 4, 132 | "metadata": {}, 133 | "output_type": "execute_result" 134 | } 135 | ], 136 | "source": [ 137 | "raw_address = '北京市海淀区万寿路街道翠微路社区居委会'\n", 138 | "jio.parse_location(raw_address, town_village=True)" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 5, 144 | "id": "ff8d699e-05c6-40f2-99da-1ee9464dc234", 145 | "metadata": { 146 | "execution": { 147 | "iopub.execute_input": "2022-05-05T11:33:29.284287Z", 148 | "iopub.status.busy": "2022-05-05T11:33:29.284287Z", 149 | "iopub.status.idle": "2022-05-05T11:33:29.297254Z", 150 | "shell.execute_reply": "2022-05-05T11:33:29.297254Z", 151 | "shell.execute_reply.started": "2022-05-05T11:33:29.284287Z" 152 | }, 153 | "tags": [] 154 | }, 155 | "outputs": [ 156 | { 157 | "data": { 158 | "text/plain": [ 159 | "{'province': '北京市',\n", 160 | " 'city': '北京市',\n", 161 | " 'county': '海淀区',\n", 162 | " 'detail': '万寿路街道翠微路社区居委会',\n", 163 | " 'full_location': '北京市海淀区万寿路街道翠微路社区居委会',\n", 164 | " 'orig_location': '海淀区万寿路街道翠微路社区居委会'}" 165 | ] 166 | }, 167 | "execution_count": 5, 168 | "metadata": {}, 169 | "output_type": "execute_result" 170 | } 171 | ], 172 | "source": [ 173 | "raw_address = '海淀区万寿路街道翠微路社区居委会'\n", 174 | "jio.parse_location(raw_address)" 175 | ] 176 | } 177 | ], 178 | "metadata": { 179 | "kernelspec": { 180 | "display_name": "Python 3 (ipykernel)", 181 | "language": "python", 182 | "name": "python3" 183 | }, 184 | "language_info": { 185 | "codemirror_mode": { 186 | "name": "ipython", 187 | "version": 3 188 | }, 189 | "file_extension": ".py", 190 | "mimetype": "text/x-python", 191 | "name": "python", 192 | "nbconvert_exporter": "python", 193 | "pygments_lexer": "ipython3", 194 | "version": "3.8.12" 195 | } 196 | }, 197 | "nbformat": 4, 198 | "nbformat_minor": 5 199 | } 200 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技09」更好用的函数运算缓存/「Python实用秘技09」更好用的函数运算缓存.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "418f25a1-393e-4a05-9dba-f6091985e78b", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "name": "stdout", 11 | "output_type": "stream", 12 | "text": [ 13 | "--------------------------------------------------\n", 14 | "第1次执行\n", 15 | "耗时2.17秒\n", 16 | "--------------------------------------------------\n", 17 | "第2次执行\n", 18 | "耗时0.0秒\n", 19 | "--------------------------------------------------\n", 20 | "第3次执行\n", 21 | "耗时0.0秒\n", 22 | "--------------------------------------------------\n", 23 | "第4次执行\n", 24 | "耗时0.0秒\n", 25 | "--------------------------------------------------\n", 26 | "第5次执行\n", 27 | "耗时0.0秒\n", 28 | "--------------------------------------------------\n", 29 | "第6次执行\n", 30 | "耗时2.01秒\n", 31 | "--------------------------------------------------\n", 32 | "第7次执行\n", 33 | "耗时0.0秒\n", 34 | "--------------------------------------------------\n", 35 | "第8次执行\n", 36 | "耗时0.0秒\n", 37 | "--------------------------------------------------\n", 38 | "第9次执行\n", 39 | "耗时0.0秒\n", 40 | "--------------------------------------------------\n", 41 | "第10次执行\n", 42 | "耗时0.0秒\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "import time\n", 48 | "from cachier import cachier\n", 49 | "from datetime import timedelta\n", 50 | "\n", 51 | "@cachier(stale_after=timedelta(seconds=10))\n", 52 | "def demo(x: int, y: int):\n", 53 | " \n", 54 | " time.sleep(2)\n", 55 | " \n", 56 | " return x * y\n", 57 | "\n", 58 | "for i in range(10):\n", 59 | " print('-'*50)\n", 60 | " print(f'第{i+1}次执行')\n", 61 | " start = time.time()\n", 62 | " demo(1, 1)\n", 63 | " print(f'耗时{round(time.time() - start, 2)}秒')\n", 64 | "\n", 65 | " time.sleep(2)" 66 | ] 67 | } 68 | ], 69 | "metadata": { 70 | "kernelspec": { 71 | "display_name": "Python 3 (ipykernel)", 72 | "language": "python", 73 | "name": "python3" 74 | }, 75 | "language_info": { 76 | "codemirror_mode": { 77 | "name": "ipython", 78 | "version": 3 79 | }, 80 | "file_extension": ".py", 81 | "mimetype": "text/x-python", 82 | "name": "python", 83 | "nbconvert_exporter": "python", 84 | "pygments_lexer": "ipython3", 85 | "version": "3.8.13" 86 | } 87 | }, 88 | "nbformat": 4, 89 | "nbformat_minor": 5 90 | } 91 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技10」深度比较Python对象间差异/「Python实用秘技10」深度比较Python对象间差异.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "3bb7eb57-014e-4f30-8a69-c321faa69401", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "data": { 11 | "text/plain": [ 12 | "{'values_changed': {\"root['level1'][0]['level1-3'][0]['level1-3-1'][2]\": {'new_value': 1,\n", 13 | " 'old_value': 3},\n", 14 | " \"root['level2']\": {'new_value': 'b', 'old_value': 'a'}}}" 15 | ] 16 | }, 17 | "execution_count": 1, 18 | "metadata": {}, 19 | "output_type": "execute_result" 20 | } 21 | ], 22 | "source": [ 23 | "from deepdiff import DeepDiff\n", 24 | "\n", 25 | "obj1 = {\n", 26 | " 'level1': [\n", 27 | " {\n", 28 | " 'level1-1': 1,\n", 29 | " 'level1-2': 1,\n", 30 | " 'level1-3': [\n", 31 | " {\n", 32 | " 'level1-3-1': [1, 2, 3]\n", 33 | " }\n", 34 | " ]\n", 35 | " }\n", 36 | " ],\n", 37 | " 'level2': 'a'\n", 38 | "}\n", 39 | "\n", 40 | "obj2 = {\n", 41 | " 'level1': [\n", 42 | " {\n", 43 | " 'level1-1': 1,\n", 44 | " 'level1-2': 1,\n", 45 | " 'level1-3': [\n", 46 | " {\n", 47 | " 'level1-3-1': [1, 2, 1]\n", 48 | " }\n", 49 | " ]\n", 50 | " }\n", 51 | " ],\n", 52 | " 'level2': 'b'\n", 53 | "}\n", 54 | "\n", 55 | "DeepDiff(obj1, obj2)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 2, 61 | "id": "e2159394-48af-40f3-bed3-5378c306838f", 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "data": { 66 | "text/plain": [ 67 | "{}" 68 | ] 69 | }, 70 | "execution_count": 2, 71 | "metadata": {}, 72 | "output_type": "execute_result" 73 | } 74 | ], 75 | "source": [ 76 | "from datetime import datetime, timedelta\n", 77 | "\n", 78 | "obj1 = {\n", 79 | " 'timestamp': datetime.strptime('2022-08-06', '%Y-%m-%d'),\n", 80 | " 'duration': timedelta(seconds=100)\n", 81 | "}\n", 82 | "\n", 83 | "obj2 = {\n", 84 | " 'timestamp': datetime.strptime('2022-08-05', '%Y-%m-%d'),\n", 85 | " 'duration': timedelta(seconds=99)\n", 86 | "}\n", 87 | "\n", 88 | "DeepDiff(obj1, obj2, exclude_types=[datetime, timedelta])" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 3, 94 | "id": "3fd9e900-d43d-490d-b70d-0a7f45b72475", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "{'values_changed': {\"root['level1']\": {'new_value': 1, 'old_value': 0}}}" 101 | ] 102 | }, 103 | "execution_count": 3, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "obj1 = {\n", 110 | " 'level1': 0,\n", 111 | " 'level2': {\n", 112 | " 'level3': 998\n", 113 | " }\n", 114 | "}\n", 115 | "\n", 116 | "obj2 = {\n", 117 | " 'level1': 1,\n", 118 | " 'level2': {\n", 119 | " 'level3': 999\n", 120 | " }\n", 121 | "}\n", 122 | "\n", 123 | "DeepDiff(obj1, obj2, exclude_paths=[\"root['level2']['level3']\"])" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 4, 129 | "id": "38aff41c-ef07-4c6f-a6e5-267df78291f1", 130 | "metadata": {}, 131 | "outputs": [ 132 | { 133 | "data": { 134 | "text/plain": [ 135 | "{'values_changed': {\"root['_nodex']\": {'new_value': 999, 'old_value': 998}}}" 136 | ] 137 | }, 138 | "execution_count": 4, 139 | "metadata": {}, 140 | "output_type": "execute_result" 141 | } 142 | ], 143 | "source": [ 144 | "obj1 = {\n", 145 | " 'node1': 1,\n", 146 | " 'node2': 2,\n", 147 | " 'node3': 3,\n", 148 | " '_nodex': 998\n", 149 | "}\n", 150 | "\n", 151 | "obj2 = {\n", 152 | " 'node1': 10,\n", 153 | " 'node2': 20,\n", 154 | " 'node3': 30,\n", 155 | " '_nodex': 999\n", 156 | "}\n", 157 | "\n", 158 | "DeepDiff(obj1, obj2, exclude_regex_paths=[r\"root\\['node\\d'\\]\"])" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 5, 164 | "id": "3c2b4746-1556-43c2-9b80-1a4f4072d7b4", 165 | "metadata": {}, 166 | "outputs": [ 167 | { 168 | "data": { 169 | "text/plain": [ 170 | "{}" 171 | ] 172 | }, 173 | "execution_count": 5, 174 | "metadata": {}, 175 | "output_type": "execute_result" 176 | } 177 | ], 178 | "source": [ 179 | "obj1 = {\n", 180 | " 'level1': 0.998\n", 181 | "}\n", 182 | "\n", 183 | "obj2 = {\n", 184 | " 'level1': 0.999\n", 185 | "}\n", 186 | "\n", 187 | "DeepDiff(obj1, obj2, significant_digits=2)" 188 | ] 189 | } 190 | ], 191 | "metadata": { 192 | "kernelspec": { 193 | "display_name": "Python 3 (ipykernel)", 194 | "language": "python", 195 | "name": "python3" 196 | }, 197 | "language_info": { 198 | "codemirror_mode": { 199 | "name": "ipython", 200 | "version": 3 201 | }, 202 | "file_extension": ".py", 203 | "mimetype": "text/x-python", 204 | "name": "python", 205 | "nbconvert_exporter": "python", 206 | "pygments_lexer": "ipython3", 207 | "version": "3.8.13" 208 | } 209 | }, 210 | "nbformat": 4, 211 | "nbformat_minor": 5 212 | } 213 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密/「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "55103e82-c1c5-4854-b855-420ff5597cea", 6 | "metadata": {}, 7 | "source": [ 8 | "- **常规的数据加密/解密**" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "a3cc2ed8-61fa-43ef-ae08-58c90fe0fe3d", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from itsdangerous import URLSafeSerializer\n", 19 | "\n", 20 | "# 示例用密钥,正式使用请妥善存储密钥,请勿、体现在代码明文中\n", 21 | "SECRET_KEY = '968ce7c0-920c-45d8-ae3a-9eb76cb9a628'" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "id": "caaf6403-47c5-46d0-8766-6fb95c7e9f0b", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# 基于密钥构建序列化器\n", 32 | "s = URLSafeSerializer(secret_key=SECRET_KEY)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "id": "75204523-327a-4dbc-aa3e-2f35dbe41572", 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "data": { 43 | "text/plain": [ 44 | "'NDI.wck0XaLsshrl-v10xWQu6KwbOW8'" 45 | ] 46 | }, 47 | "execution_count": 3, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "# 对常见的数据格式进行加密\n", 54 | "s.dumps(42)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "id": "227128a0-8b37-4637-a678-f84b04a12c92", 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "text/plain": [ 66 | "'My4xNDE1OTI2NTM1ODk3OTM.cIFZyed8SwDq7SGK_92AlazhrnQ'" 67 | ] 68 | }, 69 | "execution_count": 4, 70 | "metadata": {}, 71 | "output_type": "execute_result" 72 | } 73 | ], 74 | "source": [ 75 | "s.dumps(3.141592653589793)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 5, 81 | "id": "38b5adad-a56c-49ef-a74b-e2eb297285a5", 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "text/plain": [ 87 | "'Iua1i-ivlSI.wABdLOAmEft0bzhQh_j5M-dAECg'" 88 | ] 89 | }, 90 | "execution_count": 5, 91 | "metadata": {}, 92 | "output_type": "execute_result" 93 | } 94 | ], 95 | "source": [ 96 | "s.dumps('测试')" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 6, 102 | "id": "1c5ef4df-139d-46fc-ab9c-ec0c743e5a87", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "'eyJ1c2VybmFtZSI6ImZlZmZlcnkiLCJnZW5kZXIiOiLnlLcifQ.xZjUy_yFgT4d1Kklc5pV6Wu-QZY'" 109 | ] 110 | }, 111 | "execution_count": 6, 112 | "metadata": {}, 113 | "output_type": "execute_result" 114 | } 115 | ], 116 | "source": [ 117 | "s.dumps(\n", 118 | " {\n", 119 | " 'username': 'feffery',\n", 120 | " 'gender': '男'\n", 121 | " }\n", 122 | ")" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 7, 128 | "id": "3269f6c6-5a10-45fa-a56c-6c5aa17c43ca", 129 | "metadata": {}, 130 | "outputs": [ 131 | { 132 | "data": { 133 | "text/plain": [ 134 | "'eyJ1c2VybmFtZSI6ImZlZmZlcnkiLCJnZW5kZXIiOiLnlLcifQ.xZjUy_yFgT4d1Kklc5pV6Wu-QZY'" 135 | ] 136 | }, 137 | "execution_count": 7, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | } 141 | ], 142 | "source": [ 143 | "demo_data = s.dumps(\n", 144 | " {\n", 145 | " 'username': 'feffery',\n", 146 | " 'gender': '男'\n", 147 | " }\n", 148 | ")\n", 149 | "demo_data" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 8, 155 | "id": "1ab82b39-88b7-4ceb-8b8d-69408d6e3dac", 156 | "metadata": {}, 157 | "outputs": [ 158 | { 159 | "data": { 160 | "text/plain": [ 161 | "{'username': 'feffery', 'gender': '男'}" 162 | ] 163 | }, 164 | "execution_count": 8, 165 | "metadata": {}, 166 | "output_type": "execute_result" 167 | } 168 | ], 169 | "source": [ 170 | "# 基于相同的密钥参数,对已加密的数据进行解密\n", 171 | "another_s = URLSafeSerializer(secret_key=SECRET_KEY)\n", 172 | "\n", 173 | "another_s.loads(demo_data)" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "id": "c1435340-7624-4c4d-ae2e-0383a12debaf", 179 | "metadata": {}, 180 | "source": [ 181 | "- **可超时失效的数据加密/解密**" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 9, 187 | "id": "afffb937-0a72-4903-bc0d-1e940c69d301", 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [ 191 | "import time\n", 192 | "from itsdangerous import URLSafeTimedSerializer\n", 193 | "\n", 194 | "# 基于密钥构建超时序列化器\n", 195 | "s_timed = URLSafeTimedSerializer(secret_key=SECRET_KEY)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 10, 201 | "id": "b6b47e7f-0b22-41c6-878e-41b0f1777e4e", 202 | "metadata": {}, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "42\n", 209 | "42\n", 210 | "42\n", 211 | "错误:Signature age 4 > 3 seconds\n", 212 | "错误:Signature age 5 > 3 seconds\n" 213 | ] 214 | } 215 | ], 216 | "source": [ 217 | "demo_data_timed = s_timed.dumps(42)\n", 218 | "\n", 219 | "for i in range(5):\n", 220 | " time.sleep(1)\n", 221 | " try:\n", 222 | " print(s_timed.loads(demo_data_timed, max_age=3))\n", 223 | " except Exception as e:\n", 224 | " print(f'错误:{e}')" 225 | ] 226 | } 227 | ], 228 | "metadata": { 229 | "kernelspec": { 230 | "display_name": "Python 3 (ipykernel)", 231 | "language": "python", 232 | "name": "python3" 233 | }, 234 | "language_info": { 235 | "codemirror_mode": { 236 | "name": "ipython", 237 | "version": 3 238 | }, 239 | "file_extension": ".py", 240 | "mimetype": "text/x-python", 241 | "name": "python", 242 | "nbconvert_exporter": "python", 243 | "pygments_lexer": "ipython3", 244 | "version": "3.11.0" 245 | } 246 | }, 247 | "nbformat": 4, 248 | "nbformat_minor": 5 249 | } 250 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技12」像导入模块一样导入ipynb文件/demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "04d8e4b2-3be7-460c-b92e-8b6d563e9a34", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "def demo_func():\n", 11 | " \n", 12 | " print('我是demo_func')" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "id": "a4335323-1ec7-41b8-84b6-147d177bea26", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "class DemoClass:\n", 23 | " \n", 24 | " def __init__(self):\n", 25 | " \n", 26 | " print('我是DemoClass')" 27 | ] 28 | } 29 | ], 30 | "metadata": { 31 | "kernelspec": { 32 | "display_name": "Python 3 (ipykernel)", 33 | "language": "python", 34 | "name": "python3" 35 | }, 36 | "language_info": { 37 | "codemirror_mode": { 38 | "name": "ipython", 39 | "version": 3 40 | }, 41 | "file_extension": ".py", 42 | "mimetype": "text/x-python", 43 | "name": "python", 44 | "nbconvert_exporter": "python", 45 | "pygments_lexer": "ipython3", 46 | "version": "3.11.0" 47 | } 48 | }, 49 | "nbformat": 4, 50 | "nbformat_minor": 5 51 | } 52 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技12」像导入模块一样导入ipynb文件/「Python实用秘技12」像导入模块一样导入ipynb文件.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "a1d5c978-30e7-4052-be0a-296b325b81ee", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# !pip install import-ipynb" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "288eb894-78aa-471b-bf54-ef059bcad2cf", 16 | "metadata": {}, 17 | "source": [ 18 | "# 基于`import-ipynb`实现从`ipynb`文件中导入各种对象" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "id": "f3fe8a08-9de8-4ab7-baf2-d2db13a51f64", 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "importing Jupyter notebook from demo.ipynb\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "import import_ipynb # 必须首先执行import_ipynb的导入\n", 37 | "import demo" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "id": "fe4dd9f6-76da-4d06-9a91-8a679f48f734", 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "我是demo_func\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "demo.demo_func()" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 4, 61 | "id": "80bc2abe-40ce-4e14-95b2-362c082cd3f3", 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "我是DemoClass\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "demo_class = demo.DemoClass()" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 5, 79 | "id": "91d984ba-ac79-43ea-ac97-d7c125f77da5", 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "from demo import *" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 6, 89 | "id": "d57a0861-67f1-4fcc-9744-48539e7dbde2", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "我是demo_func\n" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "demo_func()" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 7, 107 | "id": "d32cbfe3-5d81-410e-9223-001a0231777e", 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "name": "stdout", 112 | "output_type": "stream", 113 | "text": [ 114 | "我是DemoClass\n" 115 | ] 116 | } 117 | ], 118 | "source": [ 119 | "demo_class = DemoClass()" 120 | ] 121 | } 122 | ], 123 | "metadata": { 124 | "kernelspec": { 125 | "display_name": "Python 3 (ipykernel)", 126 | "language": "python", 127 | "name": "python3" 128 | }, 129 | "language_info": { 130 | "codemirror_mode": { 131 | "name": "ipython", 132 | "version": 3 133 | }, 134 | "file_extension": ".py", 135 | "mimetype": "text/x-python", 136 | "name": "python", 137 | "nbconvert_exporter": "python", 138 | "pygments_lexer": "ipython3", 139 | "version": "3.11.0" 140 | } 141 | }, 142 | "nbformat": 4, 143 | "nbformat_minor": 5 144 | } 145 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技13」Python中临时文件的妙用/「Python实用秘技12」Python中临时文件的妙用.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "c407f976-b0c8-4d1f-b38c-bc39ad62f0be", 7 | "metadata": { 8 | "tags": [] 9 | }, 10 | "outputs": [], 11 | "source": [ 12 | "import os\n", 13 | "import shutil\n", 14 | "import zipfile\n", 15 | "import tempfile\n", 16 | "import numpy as np\n", 17 | "import pandas as pd" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "id": "38f45931-fbc5-43c6-84cb-b87ed9c4392b", 23 | "metadata": {}, 24 | "source": [ 25 | "- **创建临时文件**" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "id": "2c27d0f7-266b-440e-8364-cd86fb25c906", 32 | "metadata": { 33 | "tags": [] 34 | }, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "C:\\Users\\CNFEFF~1\\AppData\\Local\\Temp\\tmpow0_v_ok\n", 41 | "True\n", 42 | "False\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "with tempfile.TemporaryFile() as f:\n", 48 | " print(f.name)\n", 49 | " print(os.path.exists(f.name))\n", 50 | "\n", 51 | "print(os.path.exists(f.name))" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 3, 57 | "id": "60d131a9-386b-4f03-a368-8cc8114e093a", 58 | "metadata": { 59 | "tags": [] 60 | }, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/html": [ 65 | "
\n", 66 | "\n", 79 | "\n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | "
abc
0111
1222
2333
3444
\n", 115 | "
" 116 | ], 117 | "text/plain": [ 118 | " a b c\n", 119 | "0 1 1 1\n", 120 | "1 2 2 2\n", 121 | "2 3 3 3\n", 122 | "3 4 4 4" 123 | ] 124 | }, 125 | "execution_count": 3, 126 | "metadata": {}, 127 | "output_type": "execute_result" 128 | } 129 | ], 130 | "source": [ 131 | "raw_string = '''a,b,c\n", 132 | "1,1,1\n", 133 | "2,2,2\n", 134 | "3,3,3\n", 135 | "4,4,4\n", 136 | "'''\n", 137 | "\n", 138 | "with tempfile.TemporaryFile('w+') as f:\n", 139 | "\n", 140 | " f.write(raw_string)\n", 141 | " f.seek(0) # 将指针移回文件开头\n", 142 | " \n", 143 | " demo_df = pd.read_csv(f)\n", 144 | " \n", 145 | "demo_df" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "id": "1fd41810-dfb7-4eef-b046-d62c0825278d", 151 | "metadata": {}, 152 | "source": [ 153 | "- **创建临时目录**" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 4, 159 | "id": "b6655071-d009-46ae-a598-202bc3c5451e", 160 | "metadata": { 161 | "tags": [] 162 | }, 163 | "outputs": [ 164 | { 165 | "name": "stdout", 166 | "output_type": "stream", 167 | "text": [ 168 | "C:\\Users\\CNFEFF~1\\AppData\\Local\\Temp\\tmpos8yb86d\n", 169 | "True\n", 170 | "False\n" 171 | ] 172 | } 173 | ], 174 | "source": [ 175 | "with tempfile.TemporaryDirectory() as p:\n", 176 | " \n", 177 | " print(p)\n", 178 | " print(os.path.exists(p))\n", 179 | " \n", 180 | "print(os.path.exists(p))" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 5, 186 | "id": "83af221c-46d2-4ad1-9482-4bddd9420cb0", 187 | "metadata": { 188 | "tags": [] 189 | }, 190 | "outputs": [ 191 | { 192 | "data": { 193 | "text/plain": [ 194 | "['demo1.csv',\n", 195 | " 'demo10.csv',\n", 196 | " 'demo100.csv',\n", 197 | " 'demo11.csv',\n", 198 | " 'demo12.csv',\n", 199 | " 'demo13.csv',\n", 200 | " 'demo14.csv',\n", 201 | " 'demo15.csv',\n", 202 | " 'demo16.csv',\n", 203 | " 'demo17.csv',\n", 204 | " 'demo18.csv',\n", 205 | " 'demo19.csv',\n", 206 | " 'demo2.csv',\n", 207 | " 'demo20.csv',\n", 208 | " 'demo21.csv',\n", 209 | " 'demo22.csv',\n", 210 | " 'demo23.csv',\n", 211 | " 'demo24.csv',\n", 212 | " 'demo25.csv',\n", 213 | " 'demo26.csv',\n", 214 | " 'demo27.csv',\n", 215 | " 'demo28.csv',\n", 216 | " 'demo29.csv',\n", 217 | " 'demo3.csv',\n", 218 | " 'demo30.csv',\n", 219 | " 'demo31.csv',\n", 220 | " 'demo32.csv',\n", 221 | " 'demo33.csv',\n", 222 | " 'demo34.csv',\n", 223 | " 'demo35.csv',\n", 224 | " 'demo36.csv',\n", 225 | " 'demo37.csv',\n", 226 | " 'demo38.csv',\n", 227 | " 'demo39.csv',\n", 228 | " 'demo4.csv',\n", 229 | " 'demo40.csv',\n", 230 | " 'demo41.csv',\n", 231 | " 'demo42.csv',\n", 232 | " 'demo43.csv',\n", 233 | " 'demo44.csv',\n", 234 | " 'demo45.csv',\n", 235 | " 'demo46.csv',\n", 236 | " 'demo47.csv',\n", 237 | " 'demo48.csv',\n", 238 | " 'demo49.csv',\n", 239 | " 'demo5.csv',\n", 240 | " 'demo50.csv',\n", 241 | " 'demo51.csv',\n", 242 | " 'demo52.csv',\n", 243 | " 'demo53.csv',\n", 244 | " 'demo54.csv',\n", 245 | " 'demo55.csv',\n", 246 | " 'demo56.csv',\n", 247 | " 'demo57.csv',\n", 248 | " 'demo58.csv',\n", 249 | " 'demo59.csv',\n", 250 | " 'demo6.csv',\n", 251 | " 'demo60.csv',\n", 252 | " 'demo61.csv',\n", 253 | " 'demo62.csv',\n", 254 | " 'demo63.csv',\n", 255 | " 'demo64.csv',\n", 256 | " 'demo65.csv',\n", 257 | " 'demo66.csv',\n", 258 | " 'demo67.csv',\n", 259 | " 'demo68.csv',\n", 260 | " 'demo69.csv',\n", 261 | " 'demo7.csv',\n", 262 | " 'demo70.csv',\n", 263 | " 'demo71.csv',\n", 264 | " 'demo72.csv',\n", 265 | " 'demo73.csv',\n", 266 | " 'demo74.csv',\n", 267 | " 'demo75.csv',\n", 268 | " 'demo76.csv',\n", 269 | " 'demo77.csv',\n", 270 | " 'demo78.csv',\n", 271 | " 'demo79.csv',\n", 272 | " 'demo8.csv',\n", 273 | " 'demo80.csv',\n", 274 | " 'demo81.csv',\n", 275 | " 'demo82.csv',\n", 276 | " 'demo83.csv',\n", 277 | " 'demo84.csv',\n", 278 | " 'demo85.csv',\n", 279 | " 'demo86.csv',\n", 280 | " 'demo87.csv',\n", 281 | " 'demo88.csv',\n", 282 | " 'demo89.csv',\n", 283 | " 'demo9.csv',\n", 284 | " 'demo90.csv',\n", 285 | " 'demo91.csv',\n", 286 | " 'demo92.csv',\n", 287 | " 'demo93.csv',\n", 288 | " 'demo94.csv',\n", 289 | " 'demo95.csv',\n", 290 | " 'demo96.csv',\n", 291 | " 'demo97.csv',\n", 292 | " 'demo98.csv',\n", 293 | " 'demo99.csv']" 294 | ] 295 | }, 296 | "execution_count": 5, 297 | "metadata": {}, 298 | "output_type": "execute_result" 299 | } 300 | ], 301 | "source": [ 302 | "with tempfile.TemporaryDirectory() as p:\n", 303 | " \n", 304 | " # 模拟向当前临时目录下写出多个文件\n", 305 | " for i in range(100):\n", 306 | " (\n", 307 | " pd\n", 308 | " .DataFrame(np.random.rand(10, 3), columns=list('ABC'))\n", 309 | " .to_csv(os.path.join(p, f'demo{i+1}.csv'), index=False)\n", 310 | " )\n", 311 | " \n", 312 | " # 将当前临时目录转为zip压缩包\n", 313 | " shutil.make_archive('./demo', 'zip', p)\n", 314 | "\n", 315 | "# 查看目标压缩文件内的文件\n", 316 | "[file.filename for file in zipfile.ZipFile('demo.zip').filelist]" 317 | ] 318 | } 319 | ], 320 | "metadata": { 321 | "kernelspec": { 322 | "display_name": "Python 3 (ipykernel)", 323 | "language": "python", 324 | "name": "python3" 325 | }, 326 | "language_info": { 327 | "codemirror_mode": { 328 | "name": "ipython", 329 | "version": 3 330 | }, 331 | "file_extension": ".py", 332 | "mimetype": "text/x-python", 333 | "name": "python", 334 | "nbconvert_exporter": "python", 335 | "pygments_lexer": "ipython3", 336 | "version": "3.11.0" 337 | } 338 | }, 339 | "nbformat": 4, 340 | "nbformat_minor": 5 341 | } 342 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技14」快速优化Python导包顺序/demo-projects/demo/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | class Demo: 3 | 4 | value = 1 5 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技14」快速优化Python导包顺序/demo-projects/main.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | warnings.filterwarnings(...) 3 | import pandas as pd 4 | import numpy as np 5 | import feffery_antd_components as fac 6 | import feffery_utils_components as fuc 7 | import re 8 | import dash 9 | from demo import Demo 10 | from dash import html, dcc 11 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技15」pandas中基于范围条件进行表连接/「Python实用秘技15」pandas中基于范围条件进行表连接.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "75d9d9f5-4391-46b5-828e-2dd8e254361f", 7 | "metadata": { 8 | "tags": [] 9 | }, 10 | "outputs": [ 11 | { 12 | "data": { 13 | "text/plain": [ 14 | "'1.5.2'" 15 | ] 16 | }, 17 | "execution_count": 1, 18 | "metadata": {}, 19 | "output_type": "execute_result" 20 | } 21 | ], 22 | "source": [ 23 | "import pandas as pd\n", 24 | "\n", 25 | "pd.__version__" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "id": "daea1bb9-c962-4f18-a9d7-7af9e3d81acf", 32 | "metadata": { 33 | "tags": [] 34 | }, 35 | "outputs": [], 36 | "source": [ 37 | "# 示例数据框\n", 38 | "demo_left = pd.DataFrame(\n", 39 | " {\n", 40 | " 'left_id': ['a', 'b', 'c'],\n", 41 | " 'datetime': ['2023-01-01', '2023-02-01', '2023-03-01']\n", 42 | " }\n", 43 | ")\n", 44 | "demo_right = pd.DataFrame(\n", 45 | " {\n", 46 | " 'right_id': ['a', 'a', 'b', 'b'],\n", 47 | " 'datetime': ['2022-12-28', '2023-01-06', '2023-02-15', '2023-02-02']\n", 48 | " }\n", 49 | ")\n", 50 | "demo_left['datetime'], demo_right['datetime'] = pd.to_datetime(demo_left['datetime']), pd.to_datetime(demo_right['datetime'])" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "id": "6441b59f-21df-4dc6-83ec-587c724de88c", 57 | "metadata": { 58 | "tags": [] 59 | }, 60 | "outputs": [ 61 | { 62 | "data": { 63 | "text/html": [ 64 | "
\n", 65 | "\n", 78 | "\n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | "
left_iddatetime
0a2023-01-01
1b2023-02-01
2c2023-03-01
\n", 104 | "
" 105 | ], 106 | "text/plain": [ 107 | " left_id datetime\n", 108 | "0 a 2023-01-01\n", 109 | "1 b 2023-02-01\n", 110 | "2 c 2023-03-01" 111 | ] 112 | }, 113 | "execution_count": 3, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "demo_left" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 4, 125 | "id": "0ea8bd2d-7d39-41fb-9800-438b2f3de47f", 126 | "metadata": { 127 | "tags": [] 128 | }, 129 | "outputs": [ 130 | { 131 | "data": { 132 | "text/html": [ 133 | "
\n", 134 | "\n", 147 | "\n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | "
right_iddatetime
0a2022-12-28
1a2023-01-06
2b2023-02-15
3b2023-02-02
\n", 178 | "
" 179 | ], 180 | "text/plain": [ 181 | " right_id datetime\n", 182 | "0 a 2022-12-28\n", 183 | "1 a 2023-01-06\n", 184 | "2 b 2023-02-15\n", 185 | "3 b 2023-02-02" 186 | ] 187 | }, 188 | "execution_count": 4, 189 | "metadata": {}, 190 | "output_type": "execute_result" 191 | } 192 | ], 193 | "source": [ 194 | "demo_right" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "id": "ff150c29-ff72-40f3-8968-be9cc3750858", 200 | "metadata": { 201 | "tags": [] 202 | }, 203 | "source": [ 204 | "- 通常做法" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 5, 210 | "id": "cc1e3cbe-42a2-4aaf-85fb-24eacda42b23", 211 | "metadata": { 212 | "tags": [] 213 | }, 214 | "outputs": [ 215 | { 216 | "data": { 217 | "text/html": [ 218 | "
\n", 219 | "\n", 232 | "\n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | "
left_iddatetime_leftright_iddatetime_right
0a2023-01-01a2022-12-28
1a2023-01-01a2023-01-06
3b2023-02-01b2023-02-02
\n", 266 | "
" 267 | ], 268 | "text/plain": [ 269 | " left_id datetime_left right_id datetime_right\n", 270 | "0 a 2023-01-01 a 2022-12-28\n", 271 | "1 a 2023-01-01 a 2023-01-06\n", 272 | "3 b 2023-02-01 b 2023-02-02" 273 | ] 274 | }, 275 | "execution_count": 5, 276 | "metadata": {}, 277 | "output_type": "execute_result" 278 | } 279 | ], 280 | "source": [ 281 | "(\n", 282 | " demo_left\n", 283 | " .merge(\n", 284 | " demo_right,\n", 285 | " left_on='left_id',\n", 286 | " right_on='right_id',\n", 287 | " suffixes=['_left', '_right']\n", 288 | " )\n", 289 | " .groupby('left_id', group_keys=False)\n", 290 | " .apply(\n", 291 | " lambda df: df.loc[(df.datetime_left - df.datetime_right).dt.days.abs() <= 7, :]\n", 292 | " )\n", 293 | ")" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "id": "9138ca42-2dd8-4796-9bc0-0393b2cb0ece", 299 | "metadata": {}, 300 | "source": [ 301 | "- 特殊做法" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 6, 307 | "id": "0606531d-9b12-435d-a7de-48314c77da42", 308 | "metadata": { 309 | "tags": [] 310 | }, 311 | "outputs": [ 312 | { 313 | "data": { 314 | "text/html": [ 315 | "
\n", 316 | "\n", 329 | "\n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | "
leftright
left_iddatetimedatetime_past_limitdatetime_future_limitright_iddatetime
0a2023-01-012022-12-252023-01-08a2022-12-28
1a2023-01-012022-12-252023-01-08a2023-01-06
2b2023-02-012023-01-252023-02-08b2023-02-02
\n", 376 | "
" 377 | ], 378 | "text/plain": [ 379 | " left right \\\n", 380 | " left_id datetime datetime_past_limit datetime_future_limit right_id \n", 381 | "0 a 2023-01-01 2022-12-25 2023-01-08 a \n", 382 | "1 a 2023-01-01 2022-12-25 2023-01-08 a \n", 383 | "2 b 2023-02-01 2023-01-25 2023-02-08 b \n", 384 | "\n", 385 | " \n", 386 | " datetime \n", 387 | "0 2022-12-28 \n", 388 | "1 2023-01-06 \n", 389 | "2 2023-02-02 " 390 | ] 391 | }, 392 | "execution_count": 6, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "# pip install pyjanitor\n", 399 | "import janitor\n", 400 | "\n", 401 | "(\n", 402 | " demo_left\n", 403 | " # 添加辅助范围判断用上下限字段\n", 404 | " .assign(\n", 405 | " datetime_past_limit=demo_left['datetime'] - pd.Timedelta(days=7),\n", 406 | " datetime_future_limit=demo_left['datetime'] + pd.Timedelta(days=7)\n", 407 | " )\n", 408 | " # 执行条件连接\n", 409 | " .conditional_join(\n", 410 | " demo_right,\n", 411 | " ('left_id', 'right_id', '=='),\n", 412 | " ('datetime_past_limit', 'datetime', '<='),\n", 413 | " ('datetime_future_limit', 'datetime', '>=')\n", 414 | " )\n", 415 | ")" 416 | ] 417 | } 418 | ], 419 | "metadata": { 420 | "kernelspec": { 421 | "display_name": "Python 3 (ipykernel)", 422 | "language": "python", 423 | "name": "python3" 424 | }, 425 | "language_info": { 426 | "codemirror_mode": { 427 | "name": "ipython", 428 | "version": 3 429 | }, 430 | "file_extension": ".py", 431 | "mimetype": "text/x-python", 432 | "name": "python", 433 | "nbconvert_exporter": "python", 434 | "pygments_lexer": "ipython3", 435 | "version": "3.11.0" 436 | } 437 | }, 438 | "nbformat": 4, 439 | "nbformat_minor": 5 440 | } 441 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/demo_app/app.py: -------------------------------------------------------------------------------- 1 | import dash 2 | from dash import html 3 | import feffery_antd_components as fac 4 | import feffery_utils_components as fuc 5 | 6 | app = dash.Dash(__name__) 7 | 8 | # 读入示例文本内容 9 | with open('./将进酒.txt', encoding='utf-8') as t: 10 | source_text = t.read() 11 | 12 | app.layout = html.Div( 13 | [ 14 | fuc.FefferyDiv( 15 | fac.AntdSpace( 16 | [ 17 | fac.AntdText( 18 | line, 19 | style={ 20 | 'fontFamily': '钟齐志莽行书mini', 21 | 'fontSize': 38 22 | } 23 | ) 24 | for line in 25 | source_text.split('\n') 26 | ], 27 | direction='vertical', 28 | style={ 29 | 'width': '100%' 30 | } 31 | ), 32 | shadow='always-shadow-light', 33 | style={ 34 | 'padding': '24px', 35 | 'borderRadius': 10, 36 | 'width': 'fit-content', 37 | 'margin': '0 auto', 38 | 'backgroundImage': 'url("assets/金箔效果背景.jpg")', 39 | '-webkit-background-clip': 'text', 40 | '-webkit-text-fill-color': 'transparent' 41 | } 42 | ) 43 | ], 44 | style={ 45 | 'paddingTop': 40 46 | } 47 | ) 48 | 49 | 50 | if __name__ == '__main__': 51 | app.run() 52 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/demo_app/assets/custom.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "钟齐志莽行书mini"; 3 | src: url("./钟齐志莽行书mini.ttf"); 4 | } -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/demo_app/assets/金箔效果背景.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CNFeffery/PythonPracticalSkills/63dc27e41ed9492fc1e1461adabecc1319ba4420/历史文章/「Python实用秘技16」快速提取字体子集/demo_app/assets/金箔效果背景.jpg -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/demo_app/assets/钟齐志莽行书mini.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CNFeffery/PythonPracticalSkills/63dc27e41ed9492fc1e1461adabecc1319ba4420/历史文章/「Python实用秘技16」快速提取字体子集/demo_app/assets/钟齐志莽行书mini.ttf -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/demo_app/将进酒.txt: -------------------------------------------------------------------------------- 1 | 君不见黄河之水天上来,奔流到海不复回。 2 | 君不见高堂明镜悲白发,朝如青丝暮成雪。 3 | 人生得意须尽欢,莫使金樽空对月。 4 | 天生我材必有用,千金散尽还复来。 5 | 烹羊宰牛且为乐,会须一饮三百杯。 6 | 岑夫子,丹丘生,将进酒,杯莫停。 7 | 与君歌一曲,请君为我倾耳听。 8 | 钟鼓馔玉不足贵,但愿长醉不愿醒。 9 | 古来圣贤皆寂寞,惟有饮者留其名。 10 | 陈王昔时宴平乐,斗酒十千恣欢谑。 11 | 主人何为言少钱,径须沽取对君酌。 12 | 五花马、千金裘,呼儿将出换美酒, 13 | 与尔同销万古愁。 -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/「Python实用秘技16」快速提取字体子集.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "23441f87-1fd9-4239-b371-d2a18cdd98ae", 7 | "metadata": { 8 | "tags": [] 9 | }, 10 | "outputs": [ 11 | { 12 | "data": { 13 | "text/plain": [ 14 | "'4.38.0'" 15 | ] 16 | }, 17 | "execution_count": 1, 18 | "metadata": {}, 19 | "output_type": "execute_result" 20 | } 21 | ], 22 | "source": [ 23 | "import fontTools;fontTools.__version__" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "id": "ca51c99b-d3cf-417a-828d-478c158c957f", 30 | "metadata": { 31 | "tags": [] 32 | }, 33 | "outputs": [], 34 | "source": [ 35 | "import os\n", 36 | "import re\n", 37 | "\n", 38 | "# 读入目标文本内容\n", 39 | "with open('./将进酒.txt', encoding='utf-8') as t:\n", 40 | " source_content = t.read()" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 3, 46 | "id": "0d120472-5efd-4e4e-8ae6-825db15a0acb", 47 | "metadata": { 48 | "tags": [] 49 | }, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "text/plain": [ 54 | "0" 55 | ] 56 | }, 57 | "execution_count": 3, 58 | "metadata": {}, 59 | "output_type": "execute_result" 60 | } 61 | ], 62 | "source": [ 63 | "# 模拟执行pyftsubset命令生成字体子集\n", 64 | "os.system(\n", 65 | " 'pyftsubset 钟齐志莽行书.ttf --text={} --output-file=钟齐志莽行书mini.ttf'.format(\n", 66 | " # 去除空白字符后去重\n", 67 | " ''.join(set(re.sub('\\s', '', source_content)))\n", 68 | " )\n", 69 | ")" 70 | ] 71 | } 72 | ], 73 | "metadata": { 74 | "kernelspec": { 75 | "display_name": "Python 3 (ipykernel)", 76 | "language": "python", 77 | "name": "python3" 78 | }, 79 | "language_info": { 80 | "codemirror_mode": { 81 | "name": "ipython", 82 | "version": 3 83 | }, 84 | "file_extension": ".py", 85 | "mimetype": "text/x-python", 86 | "name": "python", 87 | "nbconvert_exporter": "python", 88 | "pygments_lexer": "ipython3", 89 | "version": "3.11.0" 90 | } 91 | }, 92 | "nbformat": 4, 93 | "nbformat_minor": 5 94 | } 95 | -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/将进酒.txt: -------------------------------------------------------------------------------- 1 | 君不见黄河之水天上来,奔流到海不复回。 2 | 君不见高堂明镜悲白发,朝如青丝暮成雪。 3 | 人生得意须尽欢,莫使金樽空对月。 4 | 天生我材必有用,千金散尽还复来。 5 | 烹羊宰牛且为乐,会须一饮三百杯。 6 | 岑夫子,丹丘生,将进酒,杯莫停。 7 | 与君歌一曲,请君为我倾耳听。 8 | 钟鼓馔玉不足贵,但愿长醉不愿醒。 9 | 古来圣贤皆寂寞,惟有饮者留其名。 10 | 陈王昔时宴平乐,斗酒十千恣欢谑。 11 | 主人何为言少钱,径须沽取对君酌。 12 | 五花马、千金裘,呼儿将出换美酒, 13 | 与尔同销万古愁。 -------------------------------------------------------------------------------- /历史文章/「Python实用秘技16」快速提取字体子集/钟齐志莽行书.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CNFeffery/PythonPracticalSkills/63dc27e41ed9492fc1e1461adabecc1319ba4420/历史文章/「Python实用秘技16」快速提取字体子集/钟齐志莽行书.ttf -------------------------------------------------------------------------------- /历史文章/「Python实用秘技17」快速获取国内节假日安排/「Python实用秘技17」快速获取国内节假日安排.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "a26b0fbd-cf3f-4986-b037-dc6cd214cce1", 7 | "metadata": { 8 | "execution": { 9 | "iopub.execute_input": "2024-05-22T02:05:48.724101Z", 10 | "iopub.status.busy": "2024-05-22T02:05:48.724101Z", 11 | "iopub.status.idle": "2024-05-22T02:05:50.257371Z", 12 | "shell.execute_reply": "2024-05-22T02:05:50.256860Z", 13 | "shell.execute_reply.started": "2024-05-22T02:05:48.724101Z" 14 | } 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import requests\n", 19 | "\n", 20 | "# 查询目标网址,基于开源项目:https://github.com/NateScarlet/holiday-cn\n", 21 | "target_url = 'https://fastly.jsdelivr.net/gh/NateScarlet/holiday-cn@master/{}.json'\n", 22 | "\n", 23 | "# 请求目标年份数据\n", 24 | "response = requests.get(target_url.format(2024), timeout=10)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 2, 30 | "id": "41117722-9e66-44c8-8f07-5bf21a725afb", 31 | "metadata": { 32 | "execution": { 33 | "iopub.execute_input": "2024-05-22T02:05:50.259480Z", 34 | "iopub.status.busy": "2024-05-22T02:05:50.259480Z", 35 | "iopub.status.idle": "2024-05-22T02:05:50.289987Z", 36 | "shell.execute_reply": "2024-05-22T02:05:50.287856Z", 37 | "shell.execute_reply.started": "2024-05-22T02:05:50.259480Z" 38 | } 39 | }, 40 | "outputs": [ 41 | { 42 | "data": { 43 | "text/plain": [ 44 | "{'$schema': 'https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json',\n", 45 | " '$id': 'https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2024.json',\n", 46 | " 'year': 2024,\n", 47 | " 'papers': ['https://www.gov.cn/zhengce/zhengceku/202310/content_6911528.htm'],\n", 48 | " 'days': [{'name': '元旦', 'date': '2024-01-01', 'isOffDay': True},\n", 49 | " {'name': '春节', 'date': '2024-02-04', 'isOffDay': False},\n", 50 | " {'name': '春节', 'date': '2024-02-10', 'isOffDay': True},\n", 51 | " {'name': '春节', 'date': '2024-02-11', 'isOffDay': True},\n", 52 | " {'name': '春节', 'date': '2024-02-12', 'isOffDay': True},\n", 53 | " {'name': '春节', 'date': '2024-02-13', 'isOffDay': True},\n", 54 | " {'name': '春节', 'date': '2024-02-14', 'isOffDay': True},\n", 55 | " {'name': '春节', 'date': '2024-02-15', 'isOffDay': True},\n", 56 | " {'name': '春节', 'date': '2024-02-16', 'isOffDay': True},\n", 57 | " {'name': '春节', 'date': '2024-02-17', 'isOffDay': True},\n", 58 | " {'name': '春节', 'date': '2024-02-18', 'isOffDay': False},\n", 59 | " {'name': '清明节', 'date': '2024-04-04', 'isOffDay': True},\n", 60 | " {'name': '清明节', 'date': '2024-04-05', 'isOffDay': True},\n", 61 | " {'name': '清明节', 'date': '2024-04-06', 'isOffDay': True},\n", 62 | " {'name': '清明节', 'date': '2024-04-07', 'isOffDay': False},\n", 63 | " {'name': '劳动节', 'date': '2024-04-28', 'isOffDay': False},\n", 64 | " {'name': '劳动节', 'date': '2024-05-01', 'isOffDay': True},\n", 65 | " {'name': '劳动节', 'date': '2024-05-02', 'isOffDay': True},\n", 66 | " {'name': '劳动节', 'date': '2024-05-03', 'isOffDay': True},\n", 67 | " {'name': '劳动节', 'date': '2024-05-04', 'isOffDay': True},\n", 68 | " {'name': '劳动节', 'date': '2024-05-05', 'isOffDay': True},\n", 69 | " {'name': '劳动节', 'date': '2024-05-11', 'isOffDay': False},\n", 70 | " {'name': '端午节', 'date': '2024-06-10', 'isOffDay': True},\n", 71 | " {'name': '中秋节', 'date': '2024-09-14', 'isOffDay': False},\n", 72 | " {'name': '中秋节', 'date': '2024-09-15', 'isOffDay': True},\n", 73 | " {'name': '中秋节', 'date': '2024-09-16', 'isOffDay': True},\n", 74 | " {'name': '中秋节', 'date': '2024-09-17', 'isOffDay': True},\n", 75 | " {'name': '国庆节', 'date': '2024-09-29', 'isOffDay': False},\n", 76 | " {'name': '国庆节', 'date': '2024-10-01', 'isOffDay': True},\n", 77 | " {'name': '国庆节', 'date': '2024-10-02', 'isOffDay': True},\n", 78 | " {'name': '国庆节', 'date': '2024-10-03', 'isOffDay': True},\n", 79 | " {'name': '国庆节', 'date': '2024-10-04', 'isOffDay': True},\n", 80 | " {'name': '国庆节', 'date': '2024-10-05', 'isOffDay': True},\n", 81 | " {'name': '国庆节', 'date': '2024-10-06', 'isOffDay': True},\n", 82 | " {'name': '国庆节', 'date': '2024-10-07', 'isOffDay': True},\n", 83 | " {'name': '国庆节', 'date': '2024-10-12', 'isOffDay': False}]}" 84 | ] 85 | }, 86 | "execution_count": 2, 87 | "metadata": {}, 88 | "output_type": "execute_result" 89 | } 90 | ], 91 | "source": [ 92 | "response.json()" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "id": "c13700c0-b0b7-4905-8c16-a2735ba98089", 98 | "metadata": {}, 99 | "source": [ 100 | "### 判断某个日期是否为法定节假休息日" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 3, 106 | "id": "78dd272d-4510-46b4-99c0-ed3356e8f46d", 107 | "metadata": { 108 | "execution": { 109 | "iopub.execute_input": "2024-05-22T02:05:50.293293Z", 110 | "iopub.status.busy": "2024-05-22T02:05:50.292292Z", 111 | "iopub.status.idle": "2024-05-22T02:05:50.817658Z", 112 | "shell.execute_reply": "2024-05-22T02:05:50.817152Z", 113 | "shell.execute_reply.started": "2024-05-22T02:05:50.293293Z" 114 | } 115 | }, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "text/html": [ 120 | "
\n", 121 | "\n", 134 | "\n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | "
namedateisOffDay
0元旦2024-01-01True
\n", 152 | "
" 153 | ], 154 | "text/plain": [ 155 | " name date isOffDay\n", 156 | "0 元旦 2024-01-01 True" 157 | ] 158 | }, 159 | "execution_count": 3, 160 | "metadata": {}, 161 | "output_type": "execute_result" 162 | } 163 | ], 164 | "source": [ 165 | "import pandas as pd\n", 166 | "\n", 167 | "holidays_df = pd.DataFrame(response.json()['days'])\n", 168 | "holidays_df.head(1)" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 4, 174 | "id": "5b75b67b-7f38-4cb6-8eda-7ccce92e7d7b", 175 | "metadata": { 176 | "execution": { 177 | "iopub.execute_input": "2024-05-22T02:05:50.820670Z", 178 | "iopub.status.busy": "2024-05-22T02:05:50.819667Z", 179 | "iopub.status.idle": "2024-05-22T02:05:50.850344Z", 180 | "shell.execute_reply": "2024-05-22T02:05:50.849217Z", 181 | "shell.execute_reply.started": "2024-05-22T02:05:50.820670Z" 182 | } 183 | }, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "text/html": [ 188 | "
\n", 189 | "\n", 202 | "\n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | "
namedateisOffDay
16劳动节2024-05-01True
\n", 220 | "
" 221 | ], 222 | "text/plain": [ 223 | " name date isOffDay\n", 224 | "16 劳动节 2024-05-01 True" 225 | ] 226 | }, 227 | "execution_count": 4, 228 | "metadata": {}, 229 | "output_type": "execute_result" 230 | } 231 | ], 232 | "source": [ 233 | "holidays_df.query('date == \"%s\" and isOffDay' % '2024-05-01')" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 5, 239 | "id": "01e9cbb4-e759-485b-a165-aaf131002e61", 240 | "metadata": { 241 | "execution": { 242 | "iopub.execute_input": "2024-05-22T02:05:50.852655Z", 243 | "iopub.status.busy": "2024-05-22T02:05:50.851573Z", 244 | "iopub.status.idle": "2024-05-22T02:05:50.865923Z", 245 | "shell.execute_reply": "2024-05-22T02:05:50.864919Z", 246 | "shell.execute_reply.started": "2024-05-22T02:05:50.852655Z" 247 | } 248 | }, 249 | "outputs": [ 250 | { 251 | "data": { 252 | "text/html": [ 253 | "
\n", 254 | "\n", 267 | "\n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | "
namedateisOffDay
\n", 279 | "
" 280 | ], 281 | "text/plain": [ 282 | "Empty DataFrame\n", 283 | "Columns: [name, date, isOffDay]\n", 284 | "Index: []" 285 | ] 286 | }, 287 | "execution_count": 5, 288 | "metadata": {}, 289 | "output_type": "execute_result" 290 | } 291 | ], 292 | "source": [ 293 | "holidays_df.query('date == \"%s\" and isOffDay' % '2024-09-01')" 294 | ] 295 | } 296 | ], 297 | "metadata": { 298 | "kernelspec": { 299 | "display_name": "Python 3 (ipykernel)", 300 | "language": "python", 301 | "name": "python3" 302 | }, 303 | "language_info": { 304 | "codemirror_mode": { 305 | "name": "ipython", 306 | "version": 3 307 | }, 308 | "file_extension": ".py", 309 | "mimetype": "text/x-python", 310 | "name": "python", 311 | "nbconvert_exporter": "python", 312 | "pygments_lexer": "ipython3", 313 | "version": "3.9.19" 314 | } 315 | }, 316 | "nbformat": 4, 317 | "nbformat_minor": 5 318 | } 319 | --------------------------------------------------------------------------------