[{"data":1,"prerenderedAt":16005},["ShallowReactive",2],{"post-python-modules-import-name":3,"sidebar-posts":296,"post-related-source":9196},{"id":4,"title":5,"body":6,"category":281,"cover":282,"description":12,"extension":283,"meta":284,"navigation":109,"path":285,"pinned":286,"publishedAt":287,"seo":288,"slug":289,"stem":290,"summary":291,"tags":292,"updatedAt":287,"visible":109,"__hash__":295},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":8,"toc":269},"minimark",[9,13,17,25,28,35,47,50,71,74,81,123,130,149,160,163,171,174,177,201,205,208,214,220,223,239,242,256,259,262,265],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,15,16],"h2",{"id":16},"本篇要解决的问题",[10,18,19,20,24],{},"本篇只处理“模块、import 与 ",[21,22,23],"strong",{},"name","”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,26,27],{"id":27},"先看清一个容易误解的细节",[10,29,30],{},[31,32],"img",{"alt":33,"src":34},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,36,37,38,42,43,46],{},"同一个文件直接运行时 ",[39,40,41],"code",{},"__name__"," 等于 ",[39,44,45],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,48,49],{"id":49},"核心概念",[51,52,53,61,64],"ul",{},[54,55,56,57,60],"li",{},"一个 ",[39,58,59],{},".py"," 文件就是一个模块。",[54,62,63],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[54,65,66,67,70],{},"避免使用 ",[39,68,69],{},"from module import *","，它会让名字来源不清楚。",[14,72,73],{"id":73},"跟着示例运行",[10,75,76,77,80],{},"先在同一个目录中创建两个文件。把函数放进 ",[39,78,79],{},"calculator.py","：",[82,83,88],"pre",{"className":84,"code":85,"language":86,"meta":87,"style":87},"language-python shiki shiki-themes github-dark","def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n","python","",[39,89,90,98,104,111,117],{"__ignoreMap":87},[91,92,95],"span",{"class":93,"line":94},"line",1,[91,96,97],{},"def add(left, right):\n",[91,99,101],{"class":93,"line":100},2,[91,102,103],{},"    return left + right\n",[91,105,107],{"class":93,"line":106},3,[91,108,110],{"emptyLinePlaceholder":109},true,"\n",[91,112,114],{"class":93,"line":113},4,[91,115,116],{},"if __name__ == \"__main__\":\n",[91,118,120],{"class":93,"line":119},5,[91,121,122],{},"    print(add(2, 3))\n",[10,124,125,126,129],{},"再创建 ",[39,127,128],{},"app.py","，从模块中导入函数：",[82,131,133],{"className":84,"code":132,"language":86,"meta":87,"style":87},"from calculator import add\n\nprint(add(10, 20))\n",[39,134,135,140,144],{"__ignoreMap":87},[91,136,137],{"class":93,"line":94},[91,138,139],{},"from calculator import add\n",[91,141,142],{"class":93,"line":100},[91,143,110],{"emptyLinePlaceholder":109},[91,145,146],{"class":93,"line":106},[91,147,148],{},"print(add(10, 20))\n",[10,150,151,152,155,156,159],{},"分别执行 ",[39,153,154],{},"python3 calculator.py"," 和 ",[39,157,158],{},"python3 app.py","。",[10,161,162],{},"预期结果：",[82,164,169],{"className":165,"code":167,"language":168,"meta":87},[166],"language-text","直接运行 calculator.py 输出 5；运行 app.py 输出 30\n","text",[39,170,167],{"__ignoreMap":87},[10,172,173],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,175,176],{"id":176},"按执行顺序拆开看",[178,179,180,190],"ol",{},[54,181,182,183,185,186,189],{},"直接运行 ",[39,184,79],{}," 时，模块名是 ",[39,187,188],{},"__main__","，入口代码输出 5。",[54,191,192,194,195,197,198,200],{},[39,193,128],{}," 导入模块时，",[39,196,79],{}," 的函数定义会执行，但入口判断为假；随后 ",[39,199,128],{}," 调用函数输出 30。",[202,203,204],"h3",{"id":204},"再看一个具体细节",[10,206,207],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,209,210],{},[31,211],{"alt":212,"src":213},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,215,216,217,219],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[39,218,188],{}," 保护下的演示代码。",[14,221,222],{"id":222},"初学者容易混淆的地方",[51,224,225,232],{},[54,226,227,228,155,230,159],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[39,229,79],{},[39,231,128],{},[54,233,234,235,238],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[39,236,237],{},"json.py","，导致导入目标被遮蔽。",[14,240,241],{"id":241},"练习",[178,243,244,251],{},[54,245,246,247,250],{},"创建 ",[39,248,249],{},"text_tools.py"," 并导出一个格式化函数。",[54,252,253,254,159],{},"分别直接运行模块和从另一个脚本导入，输出 ",[39,255,41],{},[10,257,258],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,260,261],{"id":261},"本篇边界",[10,263,264],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,267,268],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":87,"searchDepth":100,"depth":100,"links":270},[271,272,273,274,275,278,279,280],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":276},[277],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",false,"2026-08-17",{"title":5,"description":12},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[281,293,294],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",[297,1108,1444,1579,1731,1910,2098,2263,2446,2629,2821,3052,3236,3413,3570,3741,3906,4121,4350,4532,4696,4885,5073,5228,5388,5585,5782,5996,6162,6343,6524,6729,6924,7108,7309,7599,7791,8020,8215,8435,8675,8879],{"id":298,"title":299,"body":300,"category":281,"cover":282,"description":87,"extension":283,"meta":1097,"navigation":109,"path":1098,"pinned":286,"publishedAt":1099,"seo":1100,"slug":1101,"stem":1102,"summary":1103,"tags":1104,"updatedAt":1099,"visible":109,"__hash__":1107},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":301,"toc":1073},[302,305,308,311,318,321,324,362,378,382,386,397,402,408,425,431,436,442,446,492,495,501,507,510,541,586,603,617,627,631,642,658,661,667,672,675,693,703,724,728,732,735,747,754,758,773,780,784,787,808,814,818,821,825,828,848,851,855,858,892,895,914,917,938,943,947,950,970,973,976,980,987,1001,1004,1008,1011,1021,1032,1036,1039,1054,1070],[14,303,304],{"id":304},"引言",[10,306,307],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,309,310],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,312,313,314,317],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[39,315,316],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,319,320],{"id":320},"扫盲",[10,322,323],{},"那么这里有几个概念：",[325,326,327,330],"blockquote",{},[10,328,329],{},"为什么需要安装python解释器？",[325,331,332,343,346,353,356],{},[10,333,334,335,338,339,342],{},"我们写的代码，电脑其实看不懂，电脑只认识",[39,336,337],{},"0","和",[39,340,341],{},"1","组成的机器指令。",[10,344,345],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,347,348,349,352],{},"这样，我们就能用",[21,350,351],{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,354,355],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,357,358],{},[31,359],{"alt":360,"src":361},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[325,363,364,367],{},[10,365,366],{},"pip又是什么？",[325,368,369,372],{},[10,370,371],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,373,374],{},[31,375],{"alt":376,"src":377},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,379,381],{"id":380},"windows-安装","Windows 安装",[202,383,385],{"id":384},"_1-下载官方安装程序","1. 下载官方安装程序",[10,387,388,389,396],{},"打开 ",[390,391,395],"a",{"href":392,"rel":393},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[394],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[325,398,399],{},[10,400,401],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,403,404],{},[31,405],{"alt":406,"src":407},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[51,409,410,416,422],{},[54,411,412,413,159],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[21,414,415],{},"Windows installer (64-bit)",[54,417,418,419,159],{},"搭载 ARM 处理器的 Windows 设备选择 ",[21,420,421],{},"Windows installer (ARM64)",[54,423,424],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,426,427],{},[31,428],{"alt":429,"src":430},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[325,432,433],{},[10,434,435],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,437,438],{},[31,439],{"alt":440,"src":441},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[202,443,445],{"id":444},"_2-安装并加入-path","2. 安装并加入 PATH",[325,447,448,453,460,485],{},[325,449,450],{},[10,451,452],{},"PATH 环境变量",[10,454,455,456,459],{},"Windows 有一个特殊的变量叫 ",[21,457,458],{},"PATH","，它里面存了一串文件夹路径，比如：",[82,461,463],{"className":84,"code":462,"language":86,"meta":87,"style":87},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[39,464,465,470,475,480],{"__ignoreMap":87},[91,466,467],{"class":93,"line":94},[91,468,469],{},"D:\\Python313\\\n",[91,471,472],{"class":93,"line":100},[91,473,474],{},"D:\\Python313\\Scripts\\\n",[91,476,477],{"class":93,"line":106},[91,478,479],{},"C:\\Windows\\System32\\\n",[91,481,482],{"class":93,"line":113},[91,483,484],{},"...\n",[10,486,487,488,491],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[21,489,490],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,493,494],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,496,497,498,500],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[39,499,86],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,502,503],{},[31,504],{"alt":505,"src":506},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,508,509],{},"对安装界面最底部的两个勾选项分别解释 :",[325,511,512,515,520],{},[10,513,514],{},"Add python.exe to PATH",[10,516,517],{},[21,518,519],{},"把 Python 添加到系统环境变量",[325,521,522,528,534],{},[10,523,524,525,527],{},"勾选后，你可以在命令行任意位置直接输入 ",[39,526,86],{}," 就能运行",[10,529,530,531,533],{},"不勾选的话，命令行输入 ",[39,532,86],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,535,536,537,540],{},"必须",[21,538,539],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[325,542,543,546,551],{},[10,544,545],{},"Use admin privileges when installing py.exe",[10,547,548],{},[21,549,550],{},"使用管理员权限安装 py.exe（Python 启动器）",[325,552,553,563,577,580],{},[10,554,555,558,559,562],{},[39,556,557],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[39,560,561],{},"py"," 来启动 Python。",[10,564,565,566,568,569,572,573,576],{},"勾选后，",[39,567,557],{}," 会安装到",[21,570,571],{},"系统级目录","，电脑上",[21,574,575],{},"所有用户账户","都能用",[10,578,579],{},"不勾选，只有当前用户能用",[10,581,582,585],{},[21,583,584],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[325,587,588,591],{},[10,589,590],{},"操作建议",[325,592,593,600],{},[10,594,595,596,599],{},"两个都勾上之后，再点 ",[21,597,598],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,601,602],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[325,604,605,611],{},[10,606,607,608],{},"Python 安装的",[21,609,610],{},"可选功能页",[10,612,613],{},[31,614],{"alt":615,"src":616},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[325,618,619,622],{},[10,620,621],{},"高级选项页",[10,623,624],{},[31,625],{"alt":615,"src":626},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[202,628,630],{"id":629},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,632,633,634,637,638,641],{},"按 ",[39,635,636],{},"Win + R","，输入 ",[39,639,640],{},"cmd"," 并回车，然后执行：",[82,643,647],{"className":644,"code":645,"language":646,"meta":87,"style":87},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[39,648,649],{"__ignoreMap":87},[91,650,651,654],{"class":93,"line":94},[91,652,86],{"class":653},"svObZ",[91,655,657],{"class":656},"sDLfK"," --version\n",[10,659,660],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[82,662,665],{"className":663,"code":664,"language":168,"meta":87},[166],"Python 3.x.x\n",[39,666,664],{"__ignoreMap":87},[10,668,669],{},[31,670],{"alt":615,"src":671},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,673,674],{},"继续检查 pip：",[82,676,678],{"className":644,"code":677,"language":646,"meta":87,"style":87},"python -m pip --version\n",[39,679,680],{"__ignoreMap":87},[91,681,682,684,687,691],{"class":93,"line":94},[91,683,86],{"class":653},[91,685,686],{"class":656}," -m",[91,688,690],{"class":689},"sU2Wk"," pip",[91,692,657],{"class":656},[10,694,695,696,698,699,702],{},"如果 ",[39,697,86],{}," 无法识别，但 ",[39,700,701],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[82,704,706],{"className":644,"code":705,"language":646,"meta":87,"style":87},"py --version\npy -m pip --version\n",[39,707,708,714],{"__ignoreMap":87},[91,709,710,712],{"class":93,"line":94},[91,711,561],{"class":653},[91,713,657],{"class":656},[91,715,716,718,720,722],{"class":93,"line":100},[91,717,561],{"class":653},[91,719,686],{"class":656},[91,721,690],{"class":689},[91,723,657],{"class":656},[14,725,727],{"id":726},"macos-安装","macOS 安装",[202,729,731],{"id":730},"_1-先检查现有环境","1. 先检查现有环境",[10,733,734],{},"打开“终端”应用，执行：",[82,736,738],{"className":644,"code":737,"language":646,"meta":87,"style":87},"python3 --version\n",[39,739,740],{"__ignoreMap":87},[91,741,742,745],{"class":93,"line":94},[91,743,744],{"class":653},"python3",[91,746,657],{"class":656},[10,748,749,750,753],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[39,751,752],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[202,755,757],{"id":756},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,759,388,760,765,766,159,769,772],{},[390,761,764],{"href":762,"rel":763},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[394],"Python macOS 下载页","，下载当前稳定版的 ",[21,767,768],{},"macOS 64-bit universal2 installer",[39,770,771],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,774,775,776,779],{},"下载完成后打开 ",[39,777,778],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[202,781,783],{"id":782},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,785,786],{},"安装完成后重新打开终端，执行：",[82,788,790],{"className":644,"code":789,"language":646,"meta":87,"style":87},"python3 --version\npython3 -m pip --version\n",[39,791,792,798],{"__ignoreMap":87},[91,793,794,796],{"class":93,"line":94},[91,795,744],{"class":653},[91,797,657],{"class":656},[91,799,800,802,804,806],{"class":93,"line":100},[91,801,744],{"class":653},[91,803,686],{"class":656},[91,805,690],{"class":689},[91,807,657],{"class":656},[10,809,810,811,813],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[39,812,744],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,815,817],{"id":816},"linux-安装","Linux 安装",[10,819,820],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[202,822,824],{"id":823},"_1-检查是否已经安装","1. 检查是否已经安装",[10,826,827],{},"打开终端，执行：",[82,829,830],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,831,832,838],{"__ignoreMap":87},[91,833,834,836],{"class":93,"line":94},[91,835,744],{"class":653},[91,837,657],{"class":656},[91,839,840,842,844,846],{"class":93,"line":100},[91,841,744],{"class":653},[91,843,686],{"class":656},[91,845,690],{"class":689},[91,847,657],{"class":656},[10,849,850],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[202,852,854],{"id":853},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,856,857],{},"Ubuntu 或 Debian：",[82,859,861],{"className":644,"code":860,"language":646,"meta":87,"style":87},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[39,862,863,874],{"__ignoreMap":87},[91,864,865,868,871],{"class":93,"line":94},[91,866,867],{"class":653},"sudo",[91,869,870],{"class":689}," apt",[91,872,873],{"class":689}," update\n",[91,875,876,878,880,883,886,889],{"class":93,"line":100},[91,877,867],{"class":653},[91,879,870],{"class":689},[91,881,882],{"class":689}," install",[91,884,885],{"class":689}," python3",[91,887,888],{"class":689}," python3-pip",[91,890,891],{"class":689}," python3-venv\n",[10,893,894],{},"Fedora：",[82,896,898],{"className":644,"code":897,"language":646,"meta":87,"style":87},"sudo dnf install python3 python3-pip\n",[39,899,900],{"__ignoreMap":87},[91,901,902,904,907,909,911],{"class":93,"line":94},[91,903,867],{"class":653},[91,905,906],{"class":689}," dnf",[91,908,882],{"class":689},[91,910,885],{"class":689},[91,912,913],{"class":689}," python3-pip\n",[10,915,916],{},"Arch Linux：",[82,918,920],{"className":644,"code":919,"language":646,"meta":87,"style":87},"sudo pacman -S python python-pip\n",[39,921,922],{"__ignoreMap":87},[91,923,924,926,929,932,935],{"class":93,"line":94},[91,925,867],{"class":653},[91,927,928],{"class":689}," pacman",[91,930,931],{"class":656}," -S",[91,933,934],{"class":689}," python",[91,936,937],{"class":689}," python-pip\n",[10,939,940,942],{},[39,941,867],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[202,944,946],{"id":945},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,948,949],{},"安装结束后执行：",[82,951,952],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,953,954,960],{"__ignoreMap":87},[91,955,956,958],{"class":93,"line":94},[91,957,744],{"class":653},[91,959,657],{"class":656},[91,961,962,964,966,968],{"class":93,"line":100},[91,963,744],{"class":653},[91,965,686],{"class":656},[91,967,690],{"class":689},[91,969,657],{"class":656},[10,971,972],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,974,975],{"id":975},"常见问题",[202,977,979],{"id":978},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,981,982,983,986],{},"先关闭当前命令提示符并重新打开，再执行 ",[39,984,985],{},"python --version","。如果仍然失败，按下面的顺序检查：",[178,988,989,995,998],{},[54,990,991,992,994],{},"执行 ",[39,993,701],{},"，确认 Python Launcher 是否可用。",[54,996,997],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[54,999,1000],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,1002,1003],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[202,1005,1007],{"id":1006},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,1009,1010],{},"先尝试：",[82,1012,1013],{"className":644,"code":737,"language":646,"meta":87,"style":87},[39,1014,1015],{"__ignoreMap":87},[91,1016,1017,1019],{"class":93,"line":94},[91,1018,744],{"class":653},[91,1020,657],{"class":656},[10,1022,1023,1024,1026,1027,1029,1030,159],{},"在这两个系统中，只有 ",[39,1025,744],{}," 命令而没有 ",[39,1028,86],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[39,1031,744],{},[202,1033,1035],{"id":1034},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,1037,1038],{},"先使用模块方式检查：",[82,1040,1042],{"className":644,"code":1041,"language":646,"meta":87,"style":87},"python3 -m pip --version\n",[39,1043,1044],{"__ignoreMap":87},[91,1045,1046,1048,1050,1052],{"class":93,"line":94},[91,1047,744],{"class":653},[91,1049,686],{"class":656},[91,1051,690],{"class":689},[91,1053,657],{"class":656},[10,1055,1056,1057,1059,1060,1062,1063,1065,1066,1069],{},"Windows 用户将命令中的 ",[39,1058,744],{}," 换成 ",[39,1061,86],{}," 或 ",[39,1064,561],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[39,1067,1068],{},"python3-pip","；不要直接使用其他系统的安装命令。",[266,1071,1072],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}",{"title":87,"searchDepth":100,"depth":100,"links":1074},[1075,1076,1077,1082,1087,1092],{"id":304,"depth":100,"text":304},{"id":320,"depth":100,"text":320},{"id":380,"depth":100,"text":381,"children":1078},[1079,1080,1081],{"id":384,"depth":106,"text":385},{"id":444,"depth":106,"text":445},{"id":629,"depth":106,"text":630},{"id":726,"depth":100,"text":727,"children":1083},[1084,1085,1086],{"id":730,"depth":106,"text":731},{"id":756,"depth":106,"text":757},{"id":782,"depth":106,"text":783},{"id":816,"depth":100,"text":817,"children":1088},[1089,1090,1091],{"id":823,"depth":106,"text":824},{"id":853,"depth":106,"text":854},{"id":945,"depth":106,"text":946},{"id":975,"depth":100,"text":975,"children":1093},[1094,1095,1096],{"id":978,"depth":106,"text":979},{"id":1006,"depth":106,"text":1007},{"id":1034,"depth":106,"text":1035},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":299,"description":87},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[281,1105,1106],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1109,"title":1110,"body":1111,"category":281,"cover":1118,"description":87,"extension":283,"meta":1433,"navigation":109,"path":1434,"pinned":286,"publishedAt":1435,"seo":1436,"slug":1437,"stem":1438,"summary":1439,"tags":1440,"updatedAt":1435,"visible":109,"__hash__":1443},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1112,"toc":1418},[1113,1119,1122,1125,1129,1132,1156,1159,1165,1168,1171,1206,1215,1219,1225,1228,1253,1256,1268,1271,1275,1278,1281,1284,1287,1290,1293,1296,1320,1323,1326,1332,1335,1338,1341,1345,1351,1354,1380,1383,1387,1390,1393,1397,1400,1403,1406,1409,1412,1415],[10,1114,1115],{},[31,1116],{"alt":1117,"src":1118},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1120,1121],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1123,1124],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1126,1128],{"id":1127},"python-代码是什么样的","Python 代码是什么样的",[10,1130,1131],{},"下面是一段简单的 Python 代码：",[82,1133,1135],{"className":84,"code":1134,"language":86,"meta":87,"style":87},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[39,1136,1137,1142,1147,1151],{"__ignoreMap":87},[91,1138,1139],{"class":93,"line":94},[91,1140,1141],{},"name = \"Python\"\n",[91,1143,1144],{"class":93,"line":100},[91,1145,1146],{},"year = 2026\n",[91,1148,1149],{"class":93,"line":106},[91,1150,110],{"emptyLinePlaceholder":109},[91,1152,1153],{"class":93,"line":113},[91,1154,1155],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1157,1158],{},"运行结果：",[82,1160,1163],{"className":1161,"code":1162,"language":168,"meta":87},[166],"正在学习 Python，当前年份是 2026\n",[39,1164,1162],{"__ignoreMap":87},[10,1166,1167],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1169,1170],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[82,1172,1174],{"className":84,"code":1173,"language":86,"meta":87,"style":87},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[39,1175,1176,1181,1185,1190,1195,1200],{"__ignoreMap":87},[91,1177,1178],{"class":93,"line":94},[91,1179,1180],{},"score = 85\n",[91,1182,1183],{"class":93,"line":100},[91,1184,110],{"emptyLinePlaceholder":109},[91,1186,1187],{"class":93,"line":106},[91,1188,1189],{},"if score >= 60:\n",[91,1191,1192],{"class":93,"line":113},[91,1193,1194],{},"    print(\"成绩合格\")\n",[91,1196,1197],{"class":93,"line":119},[91,1198,1199],{},"else:\n",[91,1201,1203],{"class":93,"line":1202},6,[91,1204,1205],{},"    print(\"需要继续学习\")\n",[10,1207,1208,155,1211,1214],{},[39,1209,1210],{},"if",[39,1212,1213],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1216,1218],{"id":1217},"python-如何运行代码","Python 如何运行代码",[10,1220,1221,1222,1224],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[39,1223,59],{}," 文件，也可以进入交互式环境逐行执行代码。",[10,1226,1227],{},"交互式环境适合快速验证一个表达式：",[82,1229,1231],{"className":84,"code":1230,"language":86,"meta":87,"style":87},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[39,1232,1233,1238,1243,1248],{"__ignoreMap":87},[91,1234,1235],{"class":93,"line":94},[91,1236,1237],{},">>> 10 + 20\n",[91,1239,1240],{"class":93,"line":100},[91,1241,1242],{},"30\n",[91,1244,1245],{"class":93,"line":106},[91,1246,1247],{},">>> \"Python\".lower()\n",[91,1249,1250],{"class":93,"line":113},[91,1251,1252],{},"'python'\n",[10,1254,1255],{},"需要保存和重复运行的程序，则可以写入文件：",[82,1257,1259],{"className":644,"code":1258,"language":646,"meta":87,"style":87},"python3 hello.py\n",[39,1260,1261],{"__ignoreMap":87},[91,1262,1263,1265],{"class":93,"line":94},[91,1264,744],{"class":653},[91,1266,1267],{"class":689}," hello.py\n",[10,1269,1270],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1272,1274],{"id":1273},"python-的特点","Python 的特点",[202,1276,1277],{"id":1277},"语法相对简洁",[10,1279,1280],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[202,1282,1283],{"id":1283},"支持多种编程方式",[10,1285,1286],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[202,1288,1289],{"id":1289},"标准库比较完整",[10,1291,1292],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1294,1295],{},"例如，获取当前时间：",[82,1297,1299],{"className":84,"code":1298,"language":86,"meta":87,"style":87},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[39,1300,1301,1306,1310,1315],{"__ignoreMap":87},[91,1302,1303],{"class":93,"line":94},[91,1304,1305],{},"from datetime import datetime\n",[91,1307,1308],{"class":93,"line":100},[91,1309,110],{"emptyLinePlaceholder":109},[91,1311,1312],{"class":93,"line":106},[91,1313,1314],{},"now = datetime.now()\n",[91,1316,1317],{"class":93,"line":113},[91,1318,1319],{},"print(now)\n",[10,1321,1322],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[202,1324,1325],{"id":1325},"第三方工具丰富",[10,1327,1328,1329,1331],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[39,1330,316],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1333,1334],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[202,1336,1337],{"id":1337},"支持多个操作系统",[10,1339,1340],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1342,1344],{"id":1343},"python-可以做什么","Python 可以做什么",[10,1346,1347],{},[31,1348],{"alt":1349,"src":1350},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1352,1353],{},"Python 的应用范围比较广，常见方向包括：",[51,1355,1356,1359,1362,1365,1368,1371,1374,1377],{},[54,1357,1358],{},"编写自动化脚本，批量处理文件和重复任务；",[54,1360,1361],{},"开发网站后端和 API 服务；",[54,1363,1364],{},"进行数据清洗、统计分析和图表展示；",[54,1366,1367],{},"编写网络爬虫和信息采集工具；",[54,1369,1370],{},"开发自动化测试程序；",[54,1372,1373],{},"进行机器学习和人工智能开发；",[54,1375,1376],{},"编写运维、监控和辅助开发工具；",[54,1378,1379],{},"开发部分桌面应用和插件。",[10,1381,1382],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1384,1386],{"id":1385},"python-的发展","Python 的发展",[10,1388,1389],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1391,1392],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1394,1396],{"id":1395},"python-也有局限","Python 也有局限",[10,1398,1399],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1401,1402],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1404,1405],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1407,1408],{"id":1408},"写在最后",[10,1410,1411],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1413,1414],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[266,1416,1417],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}",{"title":87,"searchDepth":100,"depth":100,"links":1419},[1420,1421,1422,1429,1430,1431,1432],{"id":1127,"depth":100,"text":1128},{"id":1217,"depth":100,"text":1218},{"id":1273,"depth":100,"text":1274,"children":1423},[1424,1425,1426,1427,1428],{"id":1277,"depth":106,"text":1277},{"id":1283,"depth":106,"text":1283},{"id":1289,"depth":106,"text":1289},{"id":1325,"depth":106,"text":1325},{"id":1337,"depth":106,"text":1337},{"id":1343,"depth":100,"text":1344},{"id":1385,"depth":100,"text":1386},{"id":1395,"depth":100,"text":1396},{"id":1408,"depth":100,"text":1408},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1110,"description":87},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[281,1441,1442],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1445,"title":1446,"body":1447,"category":281,"cover":282,"description":1451,"extension":283,"meta":1570,"navigation":109,"path":1571,"pinned":286,"publishedAt":287,"seo":1572,"slug":1573,"stem":1574,"summary":1575,"tags":1576,"updatedAt":287,"visible":109,"__hash__":1578},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1448,"toc":1560},[1449,1452,1454,1457,1459,1465,1470,1472,1486,1488,1491,1500,1502,1508,1510,1512,1528,1530,1541,1543,1551,1553,1555,1558],[10,1450,1451],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1453,16],{"id":16},[10,1455,1456],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1458,27],{"id":27},[10,1460,1461],{},[31,1462],{"alt":1463,"src":1464},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1466,1467,1469],{},[39,1468,59],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1471,49],{"id":49},[51,1473,1474,1480,1483],{},[54,1475,1476,1477,1479],{},"源代码是人编写的文本，通常保存在 ",[39,1478,59],{}," 文件中。",[54,1481,1482],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[54,1484,1485],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1487,73],{"id":73},[10,1489,1490],{},"把下面代码保存到本课脚本并运行：",[82,1492,1494],{"className":84,"code":1493,"language":86,"meta":87,"style":87},"print(\"你好，Python\")\n",[39,1495,1496],{"__ignoreMap":87},[91,1497,1498],{"class":93,"line":94},[91,1499,1493],{},[10,1501,162],{},[82,1503,1506],{"className":1504,"code":1505,"language":168,"meta":87},[166],"你好，Python\n",[39,1507,1505],{"__ignoreMap":87},[10,1509,173],{},[14,1511,176],{"id":176},[178,1513,1514,1521],{},[54,1515,1516,1517,1520],{},"终端启动解释器后，解释器读取 ",[39,1518,1519],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[54,1522,1523,1524,1527],{},"字符串对象先准备好，再交给 ",[39,1525,1526],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1529,222],{"id":222},[51,1531,1532,1535],{},[54,1533,1534],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[54,1536,1537,1538,1540],{},"认为 ",[39,1539,59],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1542,241],{"id":241},[178,1544,1545,1548],{},[54,1546,1547],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[54,1549,1550],{},"把示例文字改成自己的学习目标并重新运行。",[10,1552,258],{},[14,1554,261],{"id":261},[10,1556,1557],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,1559,268],{},{"title":87,"searchDepth":100,"depth":100,"links":1561},[1562,1563,1564,1565,1566,1567,1568,1569],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1446,"description":1451},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[281,1441,1577],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1580,"title":1581,"body":1582,"category":281,"cover":282,"description":1586,"extension":283,"meta":1722,"navigation":109,"path":1723,"pinned":286,"publishedAt":287,"seo":1724,"slug":1725,"stem":1726,"summary":1727,"tags":1728,"updatedAt":287,"visible":109,"__hash__":1730},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1583,"toc":1712},[1584,1587,1589,1592,1594,1600,1606,1608,1623,1625,1628,1648,1650,1656,1658,1660,1673,1675,1689,1691,1702,1704,1706,1709],[10,1585,1586],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1588,16],{"id":16},[10,1590,1591],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1593,27],{"id":27},[10,1595,1596],{},[31,1597],{"alt":1598,"src":1599},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1601,1602,1603,1605],{},"终端收到 ",[39,1604,744],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1607,49],{"id":49},[51,1609,1610,1613,1616],{},[54,1611,1612],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[54,1614,1615],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[54,1617,1618,1619,1622],{},"检查 pip 时使用 ",[39,1620,1621],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1624,73],{"id":73},[10,1626,1627],{},"在 macOS 终端执行：",[82,1629,1630],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,1631,1632,1638],{"__ignoreMap":87},[91,1633,1634,1636],{"class":93,"line":94},[91,1635,744],{"class":653},[91,1637,657],{"class":656},[91,1639,1640,1642,1644,1646],{"class":93,"line":100},[91,1641,744],{"class":653},[91,1643,686],{"class":656},[91,1645,690],{"class":689},[91,1647,657],{"class":656},[10,1649,162],{},[82,1651,1654],{"className":1652,"code":1653,"language":168,"meta":87},[166],"Python 3.14.x\npip 版本信息与安装路径\n",[39,1655,1653],{"__ignoreMap":87},[10,1657,173],{},[14,1659,176],{"id":176},[178,1661,1662,1668],{},[54,1663,1664,1667],{},[39,1665,1666],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[54,1669,1670,1672],{},[39,1671,752],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1674,222],{"id":222},[51,1676,1677,1683],{},[54,1678,1679,1680,1682],{},"看到系统已有 ",[39,1681,744],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[54,1684,1685,1686,1688],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[39,1687,744],{},"，不修改系统自带工具。",[14,1690,241],{"id":241},[178,1692,1693,1699],{},[54,1694,991,1695,1698],{},[39,1696,1697],{},"which python3","，记录当前解释器路径。",[54,1700,1701],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1703,258],{},[14,1705,261],{"id":261},[10,1707,1708],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,1710,1711],{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":87,"searchDepth":100,"depth":100,"links":1713},[1714,1715,1716,1717,1718,1719,1720,1721],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1581,"description":1586},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[281,1729,1105],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1732,"title":1733,"body":1734,"category":281,"cover":282,"description":1899,"extension":283,"meta":1900,"navigation":109,"path":1901,"pinned":286,"publishedAt":287,"seo":1902,"slug":1903,"stem":1904,"summary":1905,"tags":1906,"updatedAt":287,"visible":109,"__hash__":1909},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1735,"toc":1889},[1736,1742,1744,1747,1749,1755,1758,1760,1784,1786,1788,1815,1817,1823,1825,1827,1845,1847,1861,1863,1877,1879,1881,1887],[10,1737,1738,1739,1741],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[39,1740,59],{}," 脚本。",[14,1743,16],{"id":16},[10,1745,1746],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1748,27],{"id":27},[10,1750,1751],{},[31,1752],{"alt":1753,"src":1754},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1756,1757],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1759,49],{"id":49},[51,1761,1762,1771,1778],{},[54,1763,1764,1765,1767,1768,159],{},"在终端输入 ",[39,1766,744],{}," 进入 REPL，提示符通常是 ",[39,1769,1770],{},">>>",[54,1772,1773,1774,1777],{},"输入 ",[39,1775,1776],{},"exit()"," 或按 Control-D 退出 REPL。",[54,1779,1780,1781,1783],{},"需要保存、复查或多次运行的代码应写入 ",[39,1782,59],{}," 文件。",[14,1785,73],{"id":73},[10,1787,1490],{},[82,1789,1793],{"className":1790,"code":1791,"language":1792,"meta":87,"style":87},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[39,1794,1795,1800,1805,1810],{"__ignoreMap":87},[91,1796,1797],{"class":93,"line":94},[91,1798,1799],{},">>> 2 + 3\n",[91,1801,1802],{"class":93,"line":100},[91,1803,1804],{},"5\n",[91,1806,1807],{"class":93,"line":106},[91,1808,1809],{},">>> \"python\".upper()\n",[91,1811,1812],{"class":93,"line":113},[91,1813,1814],{},"'PYTHON'\n",[10,1816,162],{},[82,1818,1821],{"className":1819,"code":1820,"language":168,"meta":87},[166],"REPL 会直接显示表达式结果\n",[39,1822,1820],{"__ignoreMap":87},[10,1824,173],{},[14,1826,176],{"id":176},[178,1828,1829,1839],{},[54,1830,1831,1832,1835,1836,159],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[39,1833,1834],{},"2 + 3"," 能直接看到 ",[39,1837,1838],{},"5",[54,1840,1841,1842,1844],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[39,1843,1526],{}," 才会写到标准输出。",[14,1846,222],{"id":222},[51,1848,1849,1858],{},[54,1850,1851,1852,1854,1855,1857],{},"把提示符 ",[39,1853,1770],{}," 复制进 ",[39,1856,59],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[54,1859,1860],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1862,241],{"id":241},[178,1864,1865,1871],{},[54,1866,1867,1868,159],{},"在 REPL 计算 ",[39,1869,1870],{},"12 * 8",[54,1872,1873,1874,1876],{},"把同一表达式写入脚本；观察脚本中不调用 ",[39,1875,1526],{}," 时是否显示结果。",[10,1878,258],{},[14,1880,261],{"id":261},[10,1882,1883,1884,1886],{},"本篇目标是根据任务选择 REPL 或 ",[39,1885,59],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,1888,268],{},{"title":87,"searchDepth":100,"depth":100,"links":1890},[1891,1892,1893,1894,1895,1896,1897,1898],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1733,"description":1899},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[281,1907,1908],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1911,"title":1912,"body":1913,"category":281,"cover":282,"description":1917,"extension":283,"meta":2088,"navigation":109,"path":2089,"pinned":286,"publishedAt":287,"seo":2090,"slug":2091,"stem":2092,"summary":2093,"tags":2094,"updatedAt":287,"visible":109,"__hash__":2097},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1914,"toc":2078},[1915,1918,1920,1923,1925,1931,1937,1939,1957,1959,1961,2006,2008,2014,2016,2018,2040,2042,2054,2056,2068,2070,2072,2075],[10,1916,1917],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1919,16],{"id":16},[10,1921,1922],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1924,27],{"id":27},[10,1926,1927],{},[31,1928],{"alt":1929,"src":1930},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1932,1933,1936],{},[39,1934,1935],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1938,49],{"id":49},[51,1940,1941,1944,1954],{},[54,1942,1943],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[54,1945,1946,1949,1950,1953],{},[39,1947,1948],{},"pwd"," 显示当前目录，",[39,1951,1952],{},"ls"," 显示目录里的文件。",[54,1955,1956],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1958,73],{"id":73},[10,1960,1627],{},[82,1962,1964],{"className":644,"code":1963,"language":646,"meta":87,"style":87},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[39,1965,1966,1974,1981,1986,2000],{"__ignoreMap":87},[91,1967,1968,1971],{"class":93,"line":94},[91,1969,1970],{"class":653},"mkdir",[91,1972,1973],{"class":689}," python-study\n",[91,1975,1976,1979],{"class":93,"line":100},[91,1977,1978],{"class":656},"cd",[91,1980,1973],{"class":689},[91,1982,1983],{"class":93,"line":106},[91,1984,1985],{"class":656},"pwd\n",[91,1987,1988,1991,1994,1998],{"class":93,"line":113},[91,1989,1990],{"class":656},"printf",[91,1992,1993],{"class":689}," 'print(\"项目已经运行\")\\n'",[91,1995,1997],{"class":1996},"snl16"," >",[91,1999,1267],{"class":689},[91,2001,2002,2004],{"class":93,"line":119},[91,2003,744],{"class":653},[91,2005,1267],{"class":689},[10,2007,162],{},[82,2009,2012],{"className":2010,"code":2011,"language":168,"meta":87},[166],"项目已经运行\n",[39,2013,2011],{"__ignoreMap":87},[10,2015,173],{},[14,2017,176],{"id":176},[178,2019,2020,2031],{},[54,2021,2022,2024,2025,2027,2028,2030],{},[39,2023,1970],{}," 创建目录，",[39,2026,1978],{}," 改变终端当前目录，",[39,2029,1948],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[54,2032,2033,2035,2036,2039],{},[39,2034,1935],{}," 会在当前目录寻找 ",[39,2037,2038],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,2041,222],{"id":222},[51,2043,2044,2051],{},[54,2045,2046,2047,155,2049,159],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[39,2048,1948],{},[39,2050,1952],{},[54,2052,2053],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2055,241],{"id":241},[178,2057,2058,2065],{},[54,2059,2060,2061,2064],{},"新建 ",[39,2062,2063],{},"lesson01.py"," 并输出课程编号。",[54,2066,2067],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2069,258],{},[14,2071,261],{"id":261},[10,2073,2074],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,2076,2077],{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":87,"searchDepth":100,"depth":100,"links":2079},[2080,2081,2082,2083,2084,2085,2086,2087],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1912,"description":1917},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[281,2095,2096],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2099,"title":2100,"body":2101,"category":281,"cover":282,"description":2105,"extension":283,"meta":2253,"navigation":109,"path":2254,"pinned":286,"publishedAt":287,"seo":2255,"slug":2256,"stem":2257,"summary":2258,"tags":2259,"updatedAt":287,"visible":109,"__hash__":2262},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2102,"toc":2243},[2103,2106,2108,2111,2113,2119,2130,2132,2152,2154,2156,2176,2178,2184,2186,2188,2207,2209,2217,2219,2234,2236,2238,2241],[10,2104,2105],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2107,16],{"id":16},[10,2109,2110],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2112,27],{"id":27},[10,2114,2115],{},[31,2116],{"alt":2117,"src":2118},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2120,2121,2122,159,2124,2127,2128,159],{},"Python 先计算表达式，再把得到的对象交给 ",[39,2123,1526],{},[39,2125,2126],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[39,2129,1834],{},[14,2131,49],{"id":49},[51,2133,2134,2140,2149],{},[54,2135,2136,2139],{},[39,2137,2138],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[54,2141,2142,2145,2146,159],{},[39,2143,2144],{},"7 + 5"," 是表达式，运行时先求值得到 ",[39,2147,2148],{},"12",[54,2150,2151],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2153,73],{"id":73},[10,2155,1490],{},[82,2157,2159],{"className":84,"code":2158,"language":86,"meta":87,"style":87},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[39,2160,2161,2166,2171],{"__ignoreMap":87},[91,2162,2163],{"class":93,"line":94},[91,2164,2165],{},"print(42)\n",[91,2167,2168],{"class":93,"line":100},[91,2169,2170],{},"print(7 + 5)\n",[91,2172,2173],{"class":93,"line":106},[91,2174,2175],{},"print(\"Python 基础课\")\n",[10,2177,162],{},[82,2179,2182],{"className":2180,"code":2181,"language":168,"meta":87},[166],"42\n12\nPython 基础课\n",[39,2183,2181],{"__ignoreMap":87},[10,2185,173],{},[14,2187,176],{"id":176},[178,2189,2190,2198],{},[54,2191,2192,2195,2196,159],{},[39,2193,2194],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[39,2197,2148],{},[54,2199,2200,2202,2203,2206],{},[39,2201,1526],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[39,2204,2205],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2208,222],{"id":222},[51,2210,2211,2214],{},[54,2212,2213],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[54,2215,2216],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2218,241],{"id":241},[178,2220,2221,2224],{},[54,2222,2223],{},"分别输出一个整数、一个小数和一段文本。",[54,2225,2226,2227,2229,2230,2233],{},"比较 ",[39,2228,2126],{}," 与 ",[39,2231,2232],{},"print(\"2 + 3\")"," 的结果。",[10,2235,258],{},[14,2237,261],{"id":261},[10,2239,2240],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,2242,268],{},{"title":87,"searchDepth":100,"depth":100,"links":2244},[2245,2246,2247,2248,2249,2250,2251,2252],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2100,"description":2105},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[281,2260,2261],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2264,"title":2265,"body":2266,"category":281,"cover":282,"description":2270,"extension":283,"meta":2436,"navigation":109,"path":2437,"pinned":286,"publishedAt":287,"seo":2438,"slug":2439,"stem":2440,"summary":2441,"tags":2442,"updatedAt":287,"visible":109,"__hash__":2445},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2267,"toc":2426},[2268,2271,2273,2276,2278,2284,2287,2289,2315,2317,2319,2347,2349,2355,2357,2359,2383,2385,2401,2403,2417,2419,2421,2424],[10,2269,2270],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2272,16],{"id":16},[10,2274,2275],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2277,27],{"id":27},[10,2279,2280],{},[31,2281],{"alt":2282,"src":2283},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2285,2286],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2288,49],{"id":49},[51,2290,2291,2294,2304],{},[54,2292,2293],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[54,2295,2296,2297,2229,2300,2303],{},"变量名区分大小写，",[39,2298,2299],{},"score",[39,2301,2302],{},"Score"," 是两个名字。",[54,2305,2306,2307,2310,2311,2314],{},"使用能表达含义的名称；不要用 ",[39,2308,2309],{},"list","、",[39,2312,2313],{},"str"," 等内置名称作为普通变量名。",[14,2316,73],{"id":73},[10,2318,1490],{},[82,2320,2322],{"className":84,"code":2321,"language":86,"meta":87,"style":87},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[39,2323,2324,2329,2334,2338,2343],{"__ignoreMap":87},[91,2325,2326],{"class":93,"line":94},[91,2327,2328],{},"score = 90\n",[91,2330,2331],{"class":93,"line":100},[91,2332,2333],{},"print(score)\n",[91,2335,2336],{"class":93,"line":106},[91,2337,110],{"emptyLinePlaceholder":109},[91,2339,2340],{"class":93,"line":113},[91,2341,2342],{},"score = 95\n",[91,2344,2345],{"class":93,"line":119},[91,2346,2333],{},[10,2348,162],{},[82,2350,2353],{"className":2351,"code":2352,"language":168,"meta":87},[166],"90\n95\n",[39,2354,2352],{"__ignoreMap":87},[10,2356,173],{},[14,2358,176],{"id":176},[178,2360,2361,2370],{},[54,2362,991,2363,2366,2367,2369],{},[39,2364,2365],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[39,2368,2299],{}," 再绑定到它。",[54,2371,991,2372,2375,2376,2379,2380,159],{},[39,2373,2374],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[39,2377,2378],{},"90"," 没有被改造成 ",[39,2381,2382],{},"95",[14,2384,222],{"id":222},[51,2386,2387,2390],{},[54,2388,2389],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[54,2391,2392,2393,2310,2395,2310,2397,2400],{},"使用 ",[39,2394,2309],{},[39,2396,2313],{},[39,2398,2399],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2402,241],{"id":241},[178,2404,2405,2414],{},[54,2406,246,2407,155,2410,2413],{},[39,2408,2409],{},"course_name",[39,2411,2412],{},"lesson_count"," 两个变量并输出。",[54,2415,2416],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2418,258],{},[14,2420,261],{"id":261},[10,2422,2423],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,2425,268],{},{"title":87,"searchDepth":100,"depth":100,"links":2427},[2428,2429,2430,2431,2432,2433,2434,2435],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2265,"description":2270},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[281,2443,2444],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2447,"title":2448,"body":2449,"category":281,"cover":282,"description":2453,"extension":283,"meta":2619,"navigation":109,"path":2620,"pinned":286,"publishedAt":287,"seo":2621,"slug":2622,"stem":2623,"summary":2624,"tags":2625,"updatedAt":287,"visible":109,"__hash__":2628},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2450,"toc":2609},[2451,2454,2456,2459,2461,2467,2470,2472,2501,2503,2505,2551,2553,2559,2561,2563,2577,2579,2590,2592,2600,2602,2604,2607],[10,2452,2453],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2455,16],{"id":16},[10,2457,2458],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2460,27],{"id":27},[10,2462,2463],{},[31,2464],{"alt":2465,"src":2466},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2468,2469],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2471,49],{"id":49},[51,2473,2474,2484,2498],{},[54,2475,2476,2479,2480,2483],{},[39,2477,2478],{},"int"," 表示整数，",[39,2481,2482],{},"float"," 表示浮点数。",[54,2485,2486,2489,2490,2493,2494,2497],{},[39,2487,2488],{},"\u002F"," 总是进行真除法；",[39,2491,2492],{},"\u002F\u002F"," 是向下取整除法，",[39,2495,2496],{},"%"," 得到余数。",[54,2499,2500],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2502,73],{"id":73},[10,2504,1490],{},[82,2506,2508],{"className":84,"code":2507,"language":86,"meta":87,"style":87},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[39,2509,2510,2515,2520,2525,2529,2534,2539,2545],{"__ignoreMap":87},[91,2511,2512],{"class":93,"line":94},[91,2513,2514],{},"price = 25\n",[91,2516,2517],{"class":93,"line":100},[91,2518,2519],{},"count = 4\n",[91,2521,2522],{"class":93,"line":106},[91,2523,2524],{},"discount = 0.9\n",[91,2526,2527],{"class":93,"line":113},[91,2528,110],{"emptyLinePlaceholder":109},[91,2530,2531],{"class":93,"line":119},[91,2532,2533],{},"total = price * count * discount\n",[91,2535,2536],{"class":93,"line":1202},[91,2537,2538],{},"average = total \u002F count\n",[91,2540,2542],{"class":93,"line":2541},7,[91,2543,2544],{},"print(total)\n",[91,2546,2548],{"class":93,"line":2547},8,[91,2549,2550],{},"print(average)\n",[10,2552,162],{},[82,2554,2557],{"className":2555,"code":2556,"language":168,"meta":87},[166],"90.0\n22.5\n",[39,2558,2556],{"__ignoreMap":87},[10,2560,173],{},[14,2562,176],{"id":176},[178,2564,2565,2571],{},[54,2566,2567,2570],{},[39,2568,2569],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[54,2572,2573,2576],{},[39,2574,2575],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2578,222],{"id":222},[51,2580,2581,2587],{},[54,2582,2583,2584,159],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[39,2585,2586],{},"decimal.Decimal",[54,2588,2589],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2591,241],{"id":241},[178,2593,2594,2597],{},[54,2595,2596],{},"计算 137 除以 10 的商和余数。",[54,2598,2599],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2601,258],{},[14,2603,261],{"id":261},[10,2605,2606],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,2608,268],{},{"title":87,"searchDepth":100,"depth":100,"links":2610},[2611,2612,2613,2614,2615,2616,2617,2618],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2448,"description":2453},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[281,2626,2627],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2630,"title":2631,"body":2632,"category":281,"cover":282,"description":2636,"extension":283,"meta":2811,"navigation":109,"path":2812,"pinned":286,"publishedAt":287,"seo":2813,"slug":2814,"stem":2815,"summary":2816,"tags":2817,"updatedAt":287,"visible":109,"__hash__":2820},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2633,"toc":2799},[2634,2637,2639,2642,2644,2650,2660,2662,2673,2675,2677,2707,2709,2715,2717,2719,2749,2751,2754,2760,2763,2765,2773,2775,2790,2792,2794,2797],[10,2635,2636],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2638,16],{"id":16},[10,2640,2641],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2643,27],{"id":27},[10,2645,2646],{},[31,2647],{"alt":2648,"src":2649},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2651,2652,2653,2656,2657,159],{},"切片 ",[39,2654,2655],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[39,2658,2659],{},"stop - start",[14,2661,49],{"id":49},[51,2663,2664,2667,2670],{},[54,2665,2666],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[54,2668,2669],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[54,2671,2672],{},"切片会创建新的字符串，不会修改原字符串。",[14,2674,73],{"id":73},[10,2676,1490],{},[82,2678,2680],{"className":84,"code":2679,"language":86,"meta":87,"style":87},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[39,2681,2682,2687,2692,2697,2702],{"__ignoreMap":87},[91,2683,2684],{"class":93,"line":94},[91,2685,2686],{},"language = \"Python\"\n",[91,2688,2689],{"class":93,"line":100},[91,2690,2691],{},"print(language[0])\n",[91,2693,2694],{"class":93,"line":106},[91,2695,2696],{},"print(language[-1])\n",[91,2698,2699],{"class":93,"line":113},[91,2700,2701],{},"print(language[0:3])\n",[91,2703,2704],{"class":93,"line":119},[91,2705,2706],{},"print(language + \" 3.14\")\n",[10,2708,162],{},[82,2710,2713],{"className":2711,"code":2712,"language":168,"meta":87},[166],"P\nn\nPyt\nPython 3.14\n",[39,2714,2712],{"__ignoreMap":87},[10,2716,173],{},[14,2718,176],{"id":176},[178,2720,2721,2735],{},[54,2722,2723,2724,2726,2727,2730,2731,2734],{},"字符串 ",[39,2725,281],{}," 的正索引从 ",[39,2728,2729],{},"P"," 的 0 开始，负索引从末尾 ",[39,2732,2733],{},"n"," 的 -1 开始。",[54,2736,2737,2740,2741,2744,2745,2748],{},[39,2738,2739],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[39,2742,2743],{},"Pyt","；索引 3 的 ",[39,2746,2747],{},"h"," 不在结果中。",[202,2750,204],{"id":204},[10,2752,2753],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2755,2756],{},[31,2757],{"alt":2758,"src":2759},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2761,2762],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2764,222],{"id":222},[51,2766,2767,2770],{},[54,2768,2769],{},"把第一个字符写成索引 1，造成整体偏移一位。",[54,2771,2772],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2774,241],{"id":241},[178,2776,2777,2787],{},[54,2778,2779,2780,2783,2784,159],{},"从 ",[39,2781,2782],{},"\"programming\""," 中切出 ",[39,2785,2786],{},"\"gram\"",[54,2788,2789],{},"使用负索引取得字符串倒数第二个字符。",[10,2791,258],{},[14,2793,261],{"id":261},[10,2795,2796],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,2798,268],{},{"title":87,"searchDepth":100,"depth":100,"links":2800},[2801,2802,2803,2804,2805,2808,2809,2810],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":2806},[2807],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2631,"description":2636},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[281,2818,2819],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2822,"title":2823,"body":2824,"category":281,"cover":282,"description":2828,"extension":283,"meta":3042,"navigation":109,"path":3043,"pinned":286,"publishedAt":287,"seo":3044,"slug":3045,"stem":3046,"summary":3047,"tags":3048,"updatedAt":287,"visible":109,"__hash__":3051},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2825,"toc":3030},[2826,2829,2831,2834,2836,2842,2852,2854,2887,2889,2891,2935,2937,2943,2945,2947,2968,2970,2973,2979,2987,2989,3003,3005,3021,3023,3025,3028],[10,2827,2828],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2830,16],{"id":16},[10,2832,2833],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2835,27],{"id":27},[10,2837,2838],{},[31,2839],{"alt":2840,"src":2841},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2843,2844,2845,1062,2848,2851],{},"比较表达式先产生 ",[39,2846,2847],{},"True",[39,2849,2850],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2853,49],{"id":49},[51,2855,2856,2870,2884],{},[54,2857,2858,2861,2862,2865,2866,2869],{},[39,2859,2860],{},"=="," 判断是否相等，",[39,2863,2864],{},"!="," 判断是否不等；单个 ",[39,2867,2868],{},"="," 是赋值。",[54,2871,2872,2875,2876,2879,2880,2883],{},[39,2873,2874],{},"and"," 要求两侧都为真，",[39,2877,2878],{},"or"," 只需一侧为真，",[39,2881,2882],{},"not"," 取反。",[54,2885,2886],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2888,73],{"id":73},[10,2890,1490],{},[82,2892,2894],{"className":84,"code":2893,"language":86,"meta":87,"style":87},"age = 20\nhas_ticket = True\n\nis_adult = age >= 18\ncan_enter = is_adult and has_ticket\nprint(is_adult)\nprint(can_enter)\nprint(not has_ticket)\n",[39,2895,2896,2901,2906,2910,2915,2920,2925,2930],{"__ignoreMap":87},[91,2897,2898],{"class":93,"line":94},[91,2899,2900],{},"age = 20\n",[91,2902,2903],{"class":93,"line":100},[91,2904,2905],{},"has_ticket = True\n",[91,2907,2908],{"class":93,"line":106},[91,2909,110],{"emptyLinePlaceholder":109},[91,2911,2912],{"class":93,"line":113},[91,2913,2914],{},"is_adult = age >= 18\n",[91,2916,2917],{"class":93,"line":119},[91,2918,2919],{},"can_enter = is_adult and has_ticket\n",[91,2921,2922],{"class":93,"line":1202},[91,2923,2924],{},"print(is_adult)\n",[91,2926,2927],{"class":93,"line":2541},[91,2928,2929],{},"print(can_enter)\n",[91,2931,2932],{"class":93,"line":2547},[91,2933,2934],{},"print(not has_ticket)\n",[10,2936,162],{},[82,2938,2941],{"className":2939,"code":2940,"language":168,"meta":87},[166],"True\nTrue\nFalse\n",[39,2942,2940],{"__ignoreMap":87},[10,2944,173],{},[14,2946,176],{"id":176},[178,2948,2949,2959],{},[54,2950,2951,2954,2955,2958],{},[39,2952,2953],{},"age >= 18"," 先产生布尔值并绑定给 ",[39,2956,2957],{},"is_adult","，这一步没有任何分支跳转。",[54,2960,2961,2964,2965,2967],{},[39,2962,2963],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[39,2966,2882],{}," 只对紧随其后的值取反。",[202,2969,204],{"id":204},[10,2971,2972],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2974,2975],{},[31,2976],{"alt":2977,"src":2978},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2980,2981,2983,2984,2986],{},[39,2982,2874],{}," 只有“真、真”得到真；",[39,2985,2878],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2988,222],{"id":222},[51,2990,2991,3000],{},[54,2992,2993,2994,2996,2997,2999],{},"用单个等号判断相等。",[39,2995,2868],{}," 是赋值，",[39,2998,2860],{}," 才是相等比较。",[54,3001,3002],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,3004,241],{"id":241},[178,3006,3007,3014],{},[54,3008,3009,3010,3013],{},"判断数字 ",[39,3011,3012],{},"15"," 是否同时大于 10 且小于 20。",[54,3015,3016,3017,3020],{},"分别修改年龄和票据状态，记录 ",[39,3018,3019],{},"can_enter"," 的四种组合结果。",[10,3022,258],{},[14,3024,261],{"id":261},[10,3026,3027],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,3029,268],{},{"title":87,"searchDepth":100,"depth":100,"links":3031},[3032,3033,3034,3035,3036,3039,3040,3041],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":3037},[3038],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2823,"description":2828},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[281,3049,3050],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3053,"title":3054,"body":3055,"category":281,"cover":282,"description":3059,"extension":283,"meta":3227,"navigation":109,"path":3228,"pinned":286,"publishedAt":287,"seo":3229,"slug":3230,"stem":3231,"summary":3232,"tags":3233,"updatedAt":287,"visible":109,"__hash__":3235},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3056,"toc":3217},[3057,3060,3062,3065,3067,3073,3091,3093,3106,3108,3110,3144,3146,3152,3154,3156,3178,3180,3192,3194,3208,3210,3212,3215],[10,3058,3059],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3061,16],{"id":16},[10,3063,3064],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3066,27],{"id":27},[10,3068,3069],{},[31,3070],{"alt":3071,"src":3072},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3074,3075,3078,3079,3082,3083,3086,3087,3090],{},[39,3076,3077],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[39,3080,3081],{},"18","，程序首先得到的也是 ",[39,3084,3085],{},"\"18\"","，需要 ",[39,3088,3089],{},"int()"," 后才能按整数参与计算。",[14,3092,49],{"id":49},[51,3094,3095,3098,3103],{},[54,3096,3097],{},"提示文字应告诉用户需要输入什么。",[54,3099,3100,3102],{},[39,3101,3089],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[54,3104,3105],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3107,73],{"id":73},[10,3109,1490],{},[82,3111,3113],{"className":84,"code":3112,"language":86,"meta":87,"style":87},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[39,3114,3115,3120,3125,3130,3134,3139],{"__ignoreMap":87},[91,3116,3117],{"class":93,"line":94},[91,3118,3119],{},"name = input(\"请输入姓名：\")\n",[91,3121,3122],{"class":93,"line":100},[91,3123,3124],{},"age_text = input(\"请输入年龄：\")\n",[91,3126,3127],{"class":93,"line":106},[91,3128,3129],{},"age = int(age_text)\n",[91,3131,3132],{"class":93,"line":113},[91,3133,110],{"emptyLinePlaceholder":109},[91,3135,3136],{"class":93,"line":119},[91,3137,3138],{},"print(\"你好，\" + name)\n",[91,3140,3141],{"class":93,"line":1202},[91,3142,3143],{},"print(age + 1)\n",[10,3145,162],{},[82,3147,3150],{"className":3148,"code":3149,"language":168,"meta":87},[166],"根据输入显示姓名，并输出下一年的年龄\n",[39,3151,3149],{"__ignoreMap":87},[10,3153,173],{},[14,3155,176],{"id":176},[178,3157,3158,3168],{},[54,3159,3160,3161,3163,3164,3167],{},"两次 ",[39,3162,3077],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[39,3165,3166],{},"age_text"," 用来提醒这仍是文本。",[54,3169,3170,3173,3174,3177],{},[39,3171,3172],{},"int(age_text)"," 创建整数对象，后面的 ",[39,3175,3176],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3179,222],{"id":222},[51,3181,3182,3189],{},[54,3183,3184,3185,3188],{},"直接计算 ",[39,3186,3187],{},"input(...) + 1","，忽略输入结果是字符串。",[54,3190,3191],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3193,241],{"id":241},[178,3195,3196,3199],{},[54,3197,3198],{},"接收两个整数并输出它们的和。",[54,3200,1773,3201,3204,3205,3207],{},[39,3202,3203],{},"18.5"," 给 ",[39,3206,3089],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3209,258],{},[14,3211,261],{"id":261},[10,3213,3214],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,3216,268],{},{"title":87,"searchDepth":100,"depth":100,"links":3218},[3219,3220,3221,3222,3223,3224,3225,3226],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3054,"description":3059},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[281,2399,3234],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3237,"title":3238,"body":3239,"category":281,"cover":282,"description":3243,"extension":283,"meta":3403,"navigation":109,"path":3404,"pinned":286,"publishedAt":287,"seo":3405,"slug":3406,"stem":3407,"summary":3408,"tags":3409,"updatedAt":287,"visible":109,"__hash__":3412},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3240,"toc":3393},[3241,3244,3246,3249,3251,3257,3264,3266,3280,3282,3284,3323,3325,3331,3333,3335,3354,3356,3371,3373,3384,3386,3388,3391],[10,3242,3243],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3245,16],{"id":16},[10,3247,3248],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3250,27],{"id":27},[10,3252,3253],{},[31,3254],{"alt":3255,"src":3256},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3258,3259,3260,3263],{},"列表为元素维护从 0 开始的位置索引。修改 ",[39,3261,3262],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3265,49],{"id":49},[51,3267,3268,3271,3274],{},[54,3269,3270],{},"列表使用方括号，元素之间用逗号分隔。",[54,3272,3273],{},"列表可变，可以替换、追加和删除元素。",[54,3275,3276,3277,159],{},"访问不存在的索引会产生 ",[39,3278,3279],{},"IndexError",[14,3281,73],{"id":73},[10,3283,1490],{},[82,3285,3287],{"className":84,"code":3286,"language":86,"meta":87,"style":87},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[39,3288,3289,3294,3299,3303,3308,3313,3318],{"__ignoreMap":87},[91,3290,3291],{"class":93,"line":94},[91,3292,3293],{},"scores = [82, 90, 76]\n",[91,3295,3296],{"class":93,"line":100},[91,3297,3298],{},"print(scores[0])\n",[91,3300,3301],{"class":93,"line":106},[91,3302,110],{"emptyLinePlaceholder":109},[91,3304,3305],{"class":93,"line":113},[91,3306,3307],{},"scores[1] = 95\n",[91,3309,3310],{"class":93,"line":119},[91,3311,3312],{},"scores.append(88)\n",[91,3314,3315],{"class":93,"line":1202},[91,3316,3317],{},"print(scores)\n",[91,3319,3320],{"class":93,"line":2541},[91,3321,3322],{},"print(len(scores))\n",[10,3324,162],{},[82,3326,3329],{"className":3327,"code":3328,"language":168,"meta":87},[166],"82\n[82, 95, 76, 88]\n4\n",[39,3330,3328],{"__ignoreMap":87},[10,3332,173],{},[14,3334,176],{"id":176},[178,3336,3337,3340],{},[54,3338,3339],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[54,3341,3342,3345,3346,3349,3350,3353],{},[39,3343,3344],{},"scores[1] = 95"," 替换第二个位置，",[39,3347,3348],{},"append(88)"," 在末尾增加新位置，",[39,3351,3352],{},"len()"," 因而从 3 变为 4。",[14,3355,222],{"id":222},[51,3357,3358,3368],{},[54,3359,3360,3361,3364,3365,159],{},"访问 ",[39,3362,3363],{},"scores[len(scores)]","。最后一个合法正索引是 ",[39,3366,3367],{},"len(scores) - 1",[54,3369,3370],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3372,241],{"id":241},[178,3374,3375,3378],{},[54,3376,3377],{},"建立三项学习任务列表，再追加第四项。",[54,3379,3380,3381,3383],{},"修改第二项，并用 ",[39,3382,3352],{}," 检查元素数量。",[10,3385,258],{},[14,3387,261],{"id":261},[10,3389,3390],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,3392,268],{},{"title":87,"searchDepth":100,"depth":100,"links":3394},[3395,3396,3397,3398,3399,3400,3401,3402],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3238,"description":3243},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[281,3410,3411],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3414,"title":3415,"body":3416,"category":281,"cover":282,"description":3420,"extension":283,"meta":3561,"navigation":109,"path":3562,"pinned":286,"publishedAt":287,"seo":3563,"slug":3564,"stem":3565,"summary":3566,"tags":3567,"updatedAt":287,"visible":109,"__hash__":3569},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3417,"toc":3551},[3418,3421,3423,3426,3428,3434,3437,3439,3450,3452,3454,3488,3490,3496,3498,3500,3514,3516,3528,3530,3542,3544,3546,3549],[10,3419,3420],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3422,16],{"id":16},[10,3424,3425],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3427,27],{"id":27},[10,3429,3430],{},[31,3431],{"alt":3432,"src":3433},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3435,3436],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3438,49],{"id":49},[51,3440,3441,3444,3447],{},[54,3442,3443],{},"元组常用来表达固定数量、固定含义的一组值。",[54,3445,3446],{},"只有一个元素的元组必须保留尾随逗号。",[54,3448,3449],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3451,73],{"id":73},[10,3453,1490],{},[82,3455,3457],{"className":84,"code":3456,"language":86,"meta":87,"style":87},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[39,3458,3459,3464,3469,3474,3478,3483],{"__ignoreMap":87},[91,3460,3461],{"class":93,"line":94},[91,3462,3463],{},"point = (120, 80)\n",[91,3465,3466],{"class":93,"line":100},[91,3467,3468],{},"print(point[0])\n",[91,3470,3471],{"class":93,"line":106},[91,3472,3473],{},"print(point[1])\n",[91,3475,3476],{"class":93,"line":113},[91,3477,110],{"emptyLinePlaceholder":109},[91,3479,3480],{"class":93,"line":119},[91,3481,3482],{},"single = (5,)\n",[91,3484,3485],{"class":93,"line":1202},[91,3486,3487],{},"print(single)\n",[10,3489,162],{},[82,3491,3494],{"className":3492,"code":3493,"language":168,"meta":87},[166],"120\n80\n(5,)\n",[39,3495,3493],{"__ignoreMap":87},[10,3497,173],{},[14,3499,176],{"id":176},[178,3501,3502,3508],{},[54,3503,3504,3507],{},[39,3505,3506],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[54,3509,3510,3513],{},[39,3511,3512],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3515,222],{"id":222},[51,3517,3518,3525],{},[54,3519,3520,3521,3524],{},"把 ",[39,3522,3523],{},"(5)"," 当作元组，实际它仍是整数。",[54,3526,3527],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3529,241],{"id":241},[178,3531,3532,3535],{},[54,3533,3534],{},"用元组表示宽度和高度。",[54,3536,2226,3537,2229,3539,3541],{},[39,3538,3523],{},[39,3540,3512],{}," 的类型。",[10,3543,258],{},[14,3545,261],{"id":261},[10,3547,3548],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,3550,268],{},{"title":87,"searchDepth":100,"depth":100,"links":3552},[3553,3554,3555,3556,3557,3558,3559,3560],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3415,"description":3420},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[281,3568,3411],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3571,"title":3572,"body":3573,"category":281,"cover":282,"description":3577,"extension":283,"meta":3732,"navigation":109,"path":3733,"pinned":286,"publishedAt":287,"seo":3734,"slug":3735,"stem":3736,"summary":3737,"tags":3738,"updatedAt":287,"visible":109,"__hash__":3740},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3574,"toc":3722},[3575,3578,3580,3583,3585,3591,3601,3603,3617,3619,3621,3655,3657,3663,3665,3667,3682,3684,3703,3705,3713,3715,3717,3720],[10,3576,3577],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3579,16],{"id":16},[10,3581,3582],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3584,27],{"id":27},[10,3586,3587],{},[31,3588],{"alt":3589,"src":3590},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3592,3593,3594,3597,3598,3600],{},"字典通过键定位值，不使用连续位置表达含义。",[39,3595,3596],{},"student[\"score\"]"," 读取的是键 ",[39,3599,2299],{}," 对应的值，而不是“第几个元素”。",[14,3602,49],{"id":49},[51,3604,3605,3608,3614],{},[54,3606,3607],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[54,3609,2392,3610,3613],{},[39,3611,3612],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[54,3615,3616],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3618,73],{"id":73},[10,3620,1490],{},[82,3622,3624],{"className":84,"code":3623,"language":86,"meta":87,"style":87},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[39,3625,3626,3631,3636,3640,3645,3650],{"__ignoreMap":87},[91,3627,3628],{"class":93,"line":94},[91,3629,3630],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[91,3632,3633],{"class":93,"line":100},[91,3634,3635],{},"print(student[\"name\"])\n",[91,3637,3638],{"class":93,"line":106},[91,3639,110],{"emptyLinePlaceholder":109},[91,3641,3642],{"class":93,"line":113},[91,3643,3644],{},"student[\"score\"] = 95\n",[91,3646,3647],{"class":93,"line":119},[91,3648,3649],{},"student[\"city\"] = \"郑州\"\n",[91,3651,3652],{"class":93,"line":1202},[91,3653,3654],{},"print(student)\n",[10,3656,162],{},[82,3658,3661],{"className":3659,"code":3660,"language":168,"meta":87},[166],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[39,3662,3660],{"__ignoreMap":87},[10,3664,173],{},[14,3666,176],{"id":176},[178,3668,3669,3672],{},[54,3670,3671],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[54,3673,3674,3675,3677,3678,3681],{},"给已有键 ",[39,3676,2299],{}," 赋值会更新映射，给新键 ",[39,3679,3680],{},"city"," 赋值会增加映射。",[14,3683,222],{"id":222},[51,3685,3686,3693],{},[54,3687,3688,3689,3692],{},"按位置理解字典并尝试 ",[39,3690,3691],{},"student[0]","，而实际键是字符串。",[54,3694,3695,3696,3699,3700,159],{},"直接读取不确定存在的键并忽略 ",[39,3697,3698],{},"KeyError","；后续可根据场景使用成员检查或 ",[39,3701,3702],{},"get()",[14,3704,241],{"id":241},[178,3706,3707,3710],{},[54,3708,3709],{},"建立一本书的标题、作者和页数字典。",[54,3711,3712],{},"添加分类键，再修改页数。",[10,3714,258],{},[14,3716,261],{"id":261},[10,3718,3719],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,3721,268],{},{"title":87,"searchDepth":100,"depth":100,"links":3723},[3724,3725,3726,3727,3728,3729,3730,3731],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3572,"description":3577},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[281,3739,3411],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3742,"title":3743,"body":3744,"category":281,"cover":282,"description":3748,"extension":283,"meta":3897,"navigation":109,"path":3898,"pinned":286,"publishedAt":287,"seo":3899,"slug":3900,"stem":3901,"summary":3902,"tags":3903,"updatedAt":287,"visible":109,"__hash__":3905},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3745,"toc":3887},[3746,3749,3751,3754,3756,3762,3765,3767,3786,3788,3790,3824,3826,3832,3834,3836,3851,3853,3865,3867,3878,3880,3882,3885],[10,3747,3748],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3750,16],{"id":16},[10,3752,3753],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3755,27],{"id":27},[10,3757,3758],{},[31,3759],{"alt":3760,"src":3761},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3763,3764],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3766,49],{"id":49},[51,3768,3769,3772,3775],{},[54,3770,3771],{},"集合中的元素不重复。",[54,3773,3774],{},"集合是无序容器，不要依赖打印顺序或索引。",[54,3776,3777,3778,3781,3782,3785],{},"创建空集合必须写 ",[39,3779,3780],{},"set()","；",[39,3783,3784],{},"{}"," 创建的是空字典。",[14,3787,73],{"id":73},[10,3789,1490],{},[82,3791,3793],{"className":84,"code":3792,"language":86,"meta":87,"style":87},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[39,3794,3795,3800,3805,3809,3814,3819],{"__ignoreMap":87},[91,3796,3797],{"class":93,"line":94},[91,3798,3799],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[91,3801,3802],{"class":93,"line":100},[91,3803,3804],{},"right = {\"Python\", \"Docker\"}\n",[91,3806,3807],{"class":93,"line":106},[91,3808,110],{"emptyLinePlaceholder":109},[91,3810,3811],{"class":93,"line":113},[91,3812,3813],{},"print(left & right)\n",[91,3815,3816],{"class":93,"line":119},[91,3817,3818],{},"print(left | right)\n",[91,3820,3821],{"class":93,"line":1202},[91,3822,3823],{},"print(\"Git\" in left)\n",[10,3825,162],{},[82,3827,3830],{"className":3828,"code":3829,"language":168,"meta":87},[166],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[39,3831,3829],{"__ignoreMap":87},[10,3833,173],{},[14,3835,176],{"id":176},[178,3837,3838,3841],{},[54,3839,3840],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[54,3842,3843,3846,3847,3850],{},[39,3844,3845],{},"&"," 计算交集，",[39,3848,3849],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3852,222],{"id":222},[51,3854,3855,3862],{},[54,3856,2392,3857,3859,3860,159],{},[39,3858,3784],{}," 创建空集合，实际得到空字典；空集合应写 ",[39,3861,3780],{},[54,3863,3864],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3866,241],{"id":241},[178,3868,3869,3875],{},[54,3870,3871,3872,3874],{},"把包含重复标签的列表交给 ",[39,3873,3780],{}," 去重。",[54,3876,3877],{},"计算两组课程标签的交集和差集。",[10,3879,258],{},[14,3881,261],{"id":261},[10,3883,3884],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,3886,268],{},{"title":87,"searchDepth":100,"depth":100,"links":3888},[3889,3890,3891,3892,3893,3894,3895,3896],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3743,"description":3748},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[281,3904,3411],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3907,"title":3908,"body":3909,"category":281,"cover":282,"description":3913,"extension":283,"meta":4111,"navigation":109,"path":4112,"pinned":286,"publishedAt":287,"seo":4113,"slug":4114,"stem":4115,"summary":4116,"tags":4117,"updatedAt":287,"visible":109,"__hash__":4120},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3910,"toc":4099},[3911,3914,3916,3919,3921,3927,3937,3939,3956,3958,3960,4010,4012,4018,4020,4022,4044,4046,4049,4055,4058,4060,4073,4075,4090,4092,4094,4097],[10,3912,3913],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3915,16],{"id":16},[10,3917,3918],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3920,27],{"id":27},[10,3922,3923],{},[31,3924],{"alt":3925,"src":3926},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3928,3929,3932,3933,3936],{},[39,3930,3931],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[39,3934,3935],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3938,49],{"id":49},[51,3940,3941,3950,3953],{},[54,3942,3943,3945,3946,3949],{},[39,3944,2860],{}," 比较内容是否相等，",[39,3947,3948],{},"is"," 比较是否为同一个对象。",[54,3951,3952],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[54,3954,3955],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3957,73],{"id":73},[10,3959,1490],{},[82,3961,3963],{"className":84,"code":3962,"language":86,"meta":87,"style":87},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[39,3964,3965,3970,3975,3980,3984,3989,3994,3999,4004],{"__ignoreMap":87},[91,3966,3967],{"class":93,"line":94},[91,3968,3969],{},"tasks = [\"变量\", \"字符串\"]\n",[91,3971,3972],{"class":93,"line":100},[91,3973,3974],{},"shared = tasks\n",[91,3976,3977],{"class":93,"line":106},[91,3978,3979],{},"backup = tasks.copy()\n",[91,3981,3982],{"class":93,"line":113},[91,3983,110],{"emptyLinePlaceholder":109},[91,3985,3986],{"class":93,"line":119},[91,3987,3988],{},"tasks.append(\"列表\")\n",[91,3990,3991],{"class":93,"line":1202},[91,3992,3993],{},"print(shared)\n",[91,3995,3996],{"class":93,"line":2541},[91,3997,3998],{},"print(backup)\n",[91,4000,4001],{"class":93,"line":2547},[91,4002,4003],{},"print(tasks is shared)\n",[91,4005,4007],{"class":93,"line":4006},9,[91,4008,4009],{},"print(tasks is backup)\n",[10,4011,162],{},[82,4013,4016],{"className":4014,"code":4015,"language":168,"meta":87},[166],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[39,4017,4015],{"__ignoreMap":87},[10,4019,173],{},[14,4021,176],{"id":176},[178,4023,4024,4030],{},[54,4025,4026,4029],{},[39,4027,4028],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[54,4031,4032,4035,4036,4039,4040,4043],{},[39,4033,4034],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[39,4037,4038],{},"shared"," 能观察到变化，",[39,4041,4042],{},"backup"," 不会。",[202,4045,204],{"id":204},[10,4047,4048],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4050,4051],{},[31,4052],{"alt":4053,"src":4054},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4056,4057],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4059,222],{"id":222},[51,4061,4062,4070],{},[54,4063,4064,4065,4067,4068,159],{},"用 ",[39,4066,2860],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[39,4069,3948],{},[54,4071,4072],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4074,241],{"id":241},[178,4076,4077,4080],{},[54,4078,4079],{},"让两个变量引用同一个字典并修改其中一个。",[54,4081,2392,4082,4085,4086,155,4088,159],{},[39,4083,4084],{},"copy()"," 创建外层副本，再比较 ",[39,4087,3948],{},[39,4089,2860],{},[10,4091,258],{},[14,4093,261],{"id":261},[10,4095,4096],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,4098,268],{},{"title":87,"searchDepth":100,"depth":100,"links":4100},[4101,4102,4103,4104,4105,4108,4109,4110],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":4106},[4107],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3908,"description":3913},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[281,4118,4119],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4122,"title":4123,"body":4124,"category":281,"cover":282,"description":4128,"extension":283,"meta":4341,"navigation":109,"path":4342,"pinned":286,"publishedAt":287,"seo":4343,"slug":4344,"stem":4345,"summary":4346,"tags":4347,"updatedAt":287,"visible":109,"__hash__":4349},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4125,"toc":4328},[4126,4129,4131,4134,4136,4142,4152,4154,4165,4167,4169,4222,4224,4230,4232,4234,4252,4254,4257,4263,4271,4274,4277,4283,4289,4291,4309,4311,4319,4321,4323,4326],[10,4127,4128],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4130,16],{"id":16},[10,4132,4133],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4135,27],{"id":27},[10,4137,4138],{},[31,4139],{"alt":4140,"src":4141},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4143,4144,2310,4146,2310,4149,4151],{},[39,4145,1210],{},[39,4147,4148],{},"elif",[39,4150,1213],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4153,49],{"id":49},[51,4155,4156,4159,4162],{},[54,4157,4158],{},"冒号表示接下来开始一个代码块。",[54,4160,4161],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[54,4163,4164],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4166,73],{"id":73},[10,4168,1490],{},[82,4170,4172],{"className":84,"code":4171,"language":86,"meta":87,"style":87},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[39,4173,4174,4179,4183,4188,4193,4198,4203,4207,4212,4216],{"__ignoreMap":87},[91,4175,4176],{"class":93,"line":94},[91,4177,4178],{},"score = int(input(\"请输入分数：\"))\n",[91,4180,4181],{"class":93,"line":100},[91,4182,110],{"emptyLinePlaceholder":109},[91,4184,4185],{"class":93,"line":106},[91,4186,4187],{},"if score >= 90:\n",[91,4189,4190],{"class":93,"line":113},[91,4191,4192],{},"    level = \"优秀\"\n",[91,4194,4195],{"class":93,"line":119},[91,4196,4197],{},"elif score >= 60:\n",[91,4199,4200],{"class":93,"line":1202},[91,4201,4202],{},"    level = \"合格\"\n",[91,4204,4205],{"class":93,"line":2541},[91,4206,1199],{},[91,4208,4209],{"class":93,"line":2547},[91,4210,4211],{},"    level = \"需要继续学习\"\n",[91,4213,4214],{"class":93,"line":4006},[91,4215,110],{"emptyLinePlaceholder":109},[91,4217,4219],{"class":93,"line":4218},10,[91,4220,4221],{},"print(level)\n",[10,4223,162],{},[82,4225,4228],{"className":4226,"code":4227,"language":168,"meta":87},[166],"输入 85 时输出：合格\n",[39,4229,4227],{"__ignoreMap":87},[10,4231,173],{},[14,4233,176],{"id":176},[178,4235,4236,4243],{},[54,4237,4238,4239,4242],{},"输入先转换为整数，程序从 ",[39,4240,4241],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[54,4244,4245,4248,4249,4251],{},[39,4246,4247],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[39,4250,1213],{}," 被跳过；最终三个分支只会选择一个。",[202,4253,204],{"id":204},[10,4255,4256],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4258,4259],{},[31,4260],{"alt":4261,"src":4262},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4264,4265,4267,4268,4270],{},[39,4266,4241],{}," 必须放在 ",[39,4269,4247],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[202,4272,204],{"id":4273},"再看一个具体细节-1",[10,4275,4276],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4278,4279],{},[31,4280],{"alt":4281,"src":4282},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4284,4285,4286,4288],{},"同一缩进层级属于同一个代码块；回到 ",[39,4287,1210],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4290,222],{"id":222},[51,4292,4293,4299],{},[54,4294,4295,4296,4298],{},"先写 ",[39,4297,4247],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[54,4300,4301,4302,4304,4305,4308],{},"混用多个独立 ",[39,4303,1210],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[39,4306,4307],{},"if\u002Felif\u002Felse"," 链。",[14,4310,241],{"id":241},[178,4312,4313,4316],{},[54,4314,4315],{},"根据温度输出“冷、适中、热”三个等级。",[54,4317,4318],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4320,258],{},[14,4322,261],{"id":261},[10,4324,4325],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,4327,268],{},{"title":87,"searchDepth":100,"depth":100,"links":4329},[4330,4331,4332,4333,4334,4338,4339,4340],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":4335},[4336,4337],{"id":204,"depth":106,"text":204},{"id":4273,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4123,"description":4128},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[281,1210,4348],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4351,"title":4352,"body":4353,"category":281,"cover":282,"description":4357,"extension":283,"meta":4523,"navigation":109,"path":4524,"pinned":286,"publishedAt":287,"seo":4525,"slug":4526,"stem":4527,"summary":4528,"tags":4529,"updatedAt":287,"visible":109,"__hash__":4531},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4354,"toc":4511},[4355,4358,4360,4363,4365,4371,4377,4379,4394,4396,4398,4436,4438,4444,4446,4448,4463,4465,4468,4474,4480,4482,4490,4492,4502,4504,4506,4509],[10,4356,4357],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4359,16],{"id":16},[10,4361,4362],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4364,27],{"id":27},[10,4366,4367],{},[31,4368],{"alt":4369,"src":4370},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4372,4373,4376],{},[39,4374,4375],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4378,49],{"id":49},[51,4380,4381,4384,4387],{},[54,4382,4383],{},"进入循环前先准备参与条件判断的状态。",[54,4385,4386],{},"循环体中必须有机会让条件变为假。",[54,4388,4389,4390,4393],{},"能够预先确定遍历对象时，后续介绍的 ",[39,4391,4392],{},"for"," 通常更直接。",[14,4395,73],{"id":73},[10,4397,1490],{},[82,4399,4401],{"className":84,"code":4400,"language":86,"meta":87,"style":87},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[39,4402,4403,4408,4412,4417,4422,4427,4431],{"__ignoreMap":87},[91,4404,4405],{"class":93,"line":94},[91,4406,4407],{},"count = 1\n",[91,4409,4410],{"class":93,"line":100},[91,4411,110],{"emptyLinePlaceholder":109},[91,4413,4414],{"class":93,"line":106},[91,4415,4416],{},"while count \u003C= 3:\n",[91,4418,4419],{"class":93,"line":113},[91,4420,4421],{},"    print(\"第\", count, \"次练习\")\n",[91,4423,4424],{"class":93,"line":119},[91,4425,4426],{},"    count = count + 1\n",[91,4428,4429],{"class":93,"line":1202},[91,4430,110],{"emptyLinePlaceholder":109},[91,4432,4433],{"class":93,"line":2541},[91,4434,4435],{},"print(\"练习结束\")\n",[10,4437,162],{},[82,4439,4442],{"className":4440,"code":4441,"language":168,"meta":87},[166],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[39,4443,4441],{"__ignoreMap":87},[10,4445,173],{},[14,4447,176],{"id":176},[178,4449,4450,4457],{},[54,4451,4452,4453,4456],{},"进入循环前 ",[39,4454,4455],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[54,4458,4459,4460,4462],{},"循环体末尾把 ",[39,4461,4455],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[202,4464,204],{"id":204},[10,4466,4467],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4469,4470],{},[31,4471],{"alt":4472,"src":4473},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4475,4476,4477,4479],{},"第4次检查时 ",[39,4478,4455],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4481,222],{"id":222},[51,4483,4484,4487],{},[54,4485,4486],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[54,4488,4489],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4491,241],{"id":241},[178,4493,4494,4499],{},[54,4495,2392,4496,4498],{},[39,4497,4375],{}," 输出 1 到 5。",[54,4500,4501],{},"计算 1 到 10 的累加和。",[10,4503,258],{},[14,4505,261],{"id":261},[10,4507,4508],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,4510,268],{},{"title":87,"searchDepth":100,"depth":100,"links":4512},[4513,4514,4515,4516,4517,4520,4521,4522],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":4518},[4519],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4352,"description":4357},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[281,4375,4530],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4533,"title":4534,"body":4535,"category":281,"cover":282,"description":4539,"extension":283,"meta":4687,"navigation":109,"path":4688,"pinned":286,"publishedAt":287,"seo":4689,"slug":4690,"stem":4691,"summary":4692,"tags":4693,"updatedAt":287,"visible":109,"__hash__":4695},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4536,"toc":4677},[4537,4540,4542,4545,4547,4553,4558,4560,4574,4576,4578,4616,4618,4624,4626,4628,4645,4647,4655,4657,4668,4670,4672,4675],[10,4538,4539],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4541,16],{"id":16},[10,4543,4544],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4546,27],{"id":27},[10,4548,4549],{},[31,4550],{"alt":4551,"src":4552},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4554,4555,4557],{},[39,4556,4392],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4559,49],{"id":49},[51,4561,4562,4568,4571],{},[54,4563,4564,4567],{},[39,4565,4566],{},"range(1, 4)"," 包含 1，不包含 4。",[54,4569,4570],{},"只需要元素时直接遍历元素，不必手工维护索引。",[54,4572,4573],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4575,73],{"id":73},[10,4577,1490],{},[82,4579,4581],{"className":84,"code":4580,"language":86,"meta":87,"style":87},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[39,4582,4583,4588,4592,4597,4602,4606,4611],{"__ignoreMap":87},[91,4584,4585],{"class":93,"line":94},[91,4586,4587],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[91,4589,4590],{"class":93,"line":100},[91,4591,110],{"emptyLinePlaceholder":109},[91,4593,4594],{"class":93,"line":106},[91,4595,4596],{},"for course in courses:\n",[91,4598,4599],{"class":93,"line":113},[91,4600,4601],{},"    print(course)\n",[91,4603,4604],{"class":93,"line":119},[91,4605,110],{"emptyLinePlaceholder":109},[91,4607,4608],{"class":93,"line":1202},[91,4609,4610],{},"for number in range(1, 4):\n",[91,4612,4613],{"class":93,"line":2541},[91,4614,4615],{},"    print(number)\n",[10,4617,162],{},[82,4619,4622],{"className":4620,"code":4621,"language":168,"meta":87},[166],"变量\n字符串\n列表\n1\n2\n3\n",[39,4623,4621],{"__ignoreMap":87},[10,4625,173],{},[14,4627,176],{"id":176},[178,4629,4630,4640],{},[54,4631,4632,4633,4635,4636,4639],{},"第一个 ",[39,4634,4392],{}," 依次从列表取得字符串，循环变量 ",[39,4637,4638],{},"course"," 每轮重新绑定。",[54,4641,4642,4644],{},[39,4643,4566],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4646,222],{"id":222},[51,4648,4649,4652],{},[54,4650,4651],{},"只需要元素却手工维护索引，增加越界风险。",[54,4653,4654],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4656,241],{"id":241},[178,4658,4659,4662],{},[54,4660,4661],{},"逐项输出一个字符串中的字符。",[54,4663,2392,4664,4667],{},[39,4665,4666],{},"range()"," 输出 2、4、6、8。",[10,4669,258],{},[14,4671,261],{"id":261},[10,4673,4674],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,4676,268],{},{"title":87,"searchDepth":100,"depth":100,"links":4678},[4679,4680,4681,4682,4683,4684,4685,4686],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4534,"description":4539},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[281,4392,4694],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4697,"title":4698,"body":4699,"category":281,"cover":282,"description":4703,"extension":283,"meta":4877,"navigation":109,"path":4878,"pinned":286,"publishedAt":287,"seo":4879,"slug":4880,"stem":4881,"summary":4882,"tags":4883,"updatedAt":287,"visible":109,"__hash__":4884},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4700,"toc":4867},[4701,4704,4706,4709,4711,4717,4727,4729,4748,4750,4752,4804,4806,4812,4814,4816,4830,4832,4848,4850,4858,4860,4862,4865],[10,4702,4703],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4705,16],{"id":16},[10,4707,4708],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4710,27],{"id":27},[10,4712,4713],{},[31,4714],{"alt":4715,"src":4716},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4718,4719,4722,4723,4726],{},[39,4720,4721],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[39,4724,4725],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4728,49],{"id":49},[51,4730,4731,4734,4742],{},[54,4732,4733],{},"先写普通循环，再在确有需要时加入流程控制语句。",[54,4735,4736,4738,4739,4741],{},[39,4737,4721],{}," 前要确认不会跳过 ",[39,4740,4375],{}," 循环中的状态更新。",[54,4743,4744,4745,4747],{},"多层嵌套中 ",[39,4746,4725],{}," 只结束它所在的最内层循环。",[14,4749,73],{"id":73},[10,4751,1490],{},[82,4753,4755],{"className":84,"code":4754,"language":86,"meta":87,"style":87},"numbers = [3, -1, 0, 8, 12]\n\nfor number in numbers:\n    if number \u003C 0:\n        continue\n    if number == 0:\n        break\n    print(number)\n\nprint(\"循环结束\")\n",[39,4756,4757,4762,4766,4771,4776,4781,4786,4791,4795,4799],{"__ignoreMap":87},[91,4758,4759],{"class":93,"line":94},[91,4760,4761],{},"numbers = [3, -1, 0, 8, 12]\n",[91,4763,4764],{"class":93,"line":100},[91,4765,110],{"emptyLinePlaceholder":109},[91,4767,4768],{"class":93,"line":106},[91,4769,4770],{},"for number in numbers:\n",[91,4772,4773],{"class":93,"line":113},[91,4774,4775],{},"    if number \u003C 0:\n",[91,4777,4778],{"class":93,"line":119},[91,4779,4780],{},"        continue\n",[91,4782,4783],{"class":93,"line":1202},[91,4784,4785],{},"    if number == 0:\n",[91,4787,4788],{"class":93,"line":2541},[91,4789,4790],{},"        break\n",[91,4792,4793],{"class":93,"line":2547},[91,4794,4615],{},[91,4796,4797],{"class":93,"line":4006},[91,4798,110],{"emptyLinePlaceholder":109},[91,4800,4801],{"class":93,"line":4218},[91,4802,4803],{},"print(\"循环结束\")\n",[10,4805,162],{},[82,4807,4810],{"className":4808,"code":4809,"language":168,"meta":87},[166],"3\n循环结束\n",[39,4811,4809],{"__ignoreMap":87},[10,4813,173],{},[14,4815,176],{"id":176},[178,4817,4818,4824],{},[54,4819,4820,4821,4823],{},"遇到 -1 时 ",[39,4822,4721],{}," 立即结束本轮，后面的判断和输出都不执行。",[54,4825,4826,4827,4829],{},"遇到 0 时 ",[39,4828,4725],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4831,222],{"id":222},[51,4833,4834,4839],{},[54,4835,3520,4836,4838],{},[39,4837,4721],{}," 当作结束循环，实际它只跳到下一轮。",[54,4840,4841,4842,4844,4845,4847],{},"在 ",[39,4843,4375],{}," 中把状态更新放在可能被 ",[39,4846,4721],{}," 跳过的位置，造成无限循环。",[14,4849,241],{"id":241},[178,4851,4852,4855],{},[54,4853,4854],{},"跳过列表中的空字符串并输出其他内容。",[54,4856,4857],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4859,258],{},[14,4861,261],{"id":261},[10,4863,4864],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,4866,268],{},{"title":87,"searchDepth":100,"depth":100,"links":4868},[4869,4870,4871,4872,4873,4874,4875,4876],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4698,"description":4703},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[281,4725,4721],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4886,"title":4887,"body":4888,"category":281,"cover":282,"description":4892,"extension":283,"meta":5063,"navigation":109,"path":5064,"pinned":286,"publishedAt":287,"seo":5065,"slug":5066,"stem":5067,"summary":5068,"tags":5069,"updatedAt":287,"visible":109,"__hash__":5072},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4889,"toc":5051},[4890,4893,4895,4898,4900,4906,4909,4911,4935,4937,4939,4973,4975,4981,4983,4985,5002,5004,5007,5013,5016,5018,5032,5034,5042,5044,5046,5049],[10,4891,4892],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4894,16],{"id":16},[10,4896,4897],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4899,27],{"id":27},[10,4901,4902],{},[31,4903],{"alt":4904,"src":4905},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4907,4908],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4910,49],{"id":49},[51,4912,4913,4916,4919],{},[54,4914,4915],{},"每增加一层嵌套，阅读成本都会上升。",[54,4917,4918],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[54,4920,4921,4922,2310,4925,4928,4929,2310,4932,159],{},"变量名使用 ",[39,4923,4924],{},"row",[39,4926,4927],{},"cell"," 等层级含义，避免全部写成 ",[39,4930,4931],{},"i",[39,4933,4934],{},"j",[14,4936,73],{"id":73},[10,4938,1490],{},[82,4940,4942],{"className":84,"code":4941,"language":86,"meta":87,"style":87},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[39,4943,4944,4949,4953,4958,4963,4968],{"__ignoreMap":87},[91,4945,4946],{"class":93,"line":94},[91,4947,4948],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[91,4950,4951],{"class":93,"line":100},[91,4952,110],{"emptyLinePlaceholder":109},[91,4954,4955],{"class":93,"line":106},[91,4956,4957],{},"for row in table:\n",[91,4959,4960],{"class":93,"line":113},[91,4961,4962],{},"    for cell in row:\n",[91,4964,4965],{"class":93,"line":119},[91,4966,4967],{},"        print(cell)\n",[91,4969,4970],{"class":93,"line":1202},[91,4971,4972],{},"    print(\"一行结束\")\n",[10,4974,162],{},[82,4976,4979],{"className":4977,"code":4978,"language":168,"meta":87},[166],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[39,4980,4978],{"__ignoreMap":87},[10,4982,173],{},[14,4984,176],{"id":176},[178,4986,4987,4999],{},[54,4988,4989,4990,4992,4993,155,4996,159],{},"外层变量 ",[39,4991,4924],{}," 先引用第一行列表，内层才依次处理 ",[39,4994,4995],{},"A1",[39,4997,4998],{},"A2",[54,5000,5001],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[202,5003,204],{"id":204},[10,5005,5006],{},"二维列表的输出顺序可以展开成一条时间线。",[10,5008,5009],{},[31,5010],{"alt":5011,"src":5012},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,5014,5015],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,5017,222],{"id":222},[51,5019,5020,5029],{},[54,5021,5022,5023,1062,5026,5028],{},"把两层循环变量都叫 ",[39,5024,5025],{},"item",[39,5027,4931],{},"，难以确认当前层级。",[54,5030,5031],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,5033,241],{"id":241},[178,5035,5036,5039],{},[54,5037,5038],{},"打印一个 2×3 数字表。",[54,5040,5041],{},"在内层增加条件，只输出大于 3 的元素。",[10,5043,258],{},[14,5045,261],{"id":261},[10,5047,5048],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,5050,268],{},{"title":87,"searchDepth":100,"depth":100,"links":5052},[5053,5054,5055,5056,5057,5060,5061,5062],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":5058},[5059],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4887,"description":4892},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[281,5070,5071],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5074,"title":5075,"body":5076,"category":281,"cover":282,"description":5080,"extension":283,"meta":5218,"navigation":109,"path":5219,"pinned":286,"publishedAt":287,"seo":5220,"slug":5221,"stem":5222,"summary":5223,"tags":5224,"updatedAt":287,"visible":109,"__hash__":5227},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5077,"toc":5208},[5078,5081,5083,5086,5088,5094,5097,5099,5110,5112,5114,5152,5154,5160,5162,5164,5176,5178,5189,5191,5199,5201,5203,5206],[10,5079,5080],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5082,16],{"id":16},[10,5084,5085],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5087,27],{"id":27},[10,5089,5090],{},[31,5091],{"alt":5092,"src":5093},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5095,5096],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5098,49],{"id":49},[51,5100,5101,5104,5107],{},[54,5102,5103],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[54,5105,5106],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[54,5108,5109],{},"推导式创建新列表，不修改输入列表。",[14,5111,73],{"id":73},[10,5113,1490],{},[82,5115,5117],{"className":84,"code":5116,"language":86,"meta":87,"style":87},"numbers = [1, 2, 3, 4, 5]\n\nsquares = [number * number for number in numbers]\neven_squares = [number * number for number in numbers if number % 2 == 0]\n\nprint(squares)\nprint(even_squares)\n",[39,5118,5119,5124,5128,5133,5138,5142,5147],{"__ignoreMap":87},[91,5120,5121],{"class":93,"line":94},[91,5122,5123],{},"numbers = [1, 2, 3, 4, 5]\n",[91,5125,5126],{"class":93,"line":100},[91,5127,110],{"emptyLinePlaceholder":109},[91,5129,5130],{"class":93,"line":106},[91,5131,5132],{},"squares = [number * number for number in numbers]\n",[91,5134,5135],{"class":93,"line":113},[91,5136,5137],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[91,5139,5140],{"class":93,"line":119},[91,5141,110],{"emptyLinePlaceholder":109},[91,5143,5144],{"class":93,"line":1202},[91,5145,5146],{},"print(squares)\n",[91,5148,5149],{"class":93,"line":2541},[91,5150,5151],{},"print(even_squares)\n",[10,5153,162],{},[82,5155,5158],{"className":5156,"code":5157,"language":168,"meta":87},[166],"[1, 4, 9, 16, 25]\n[4, 16]\n",[39,5159,5157],{"__ignoreMap":87},[10,5161,173],{},[14,5163,176],{"id":176},[178,5165,5166,5169],{},[54,5167,5168],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[54,5170,5171,5172,5175],{},"第二条先用 ",[39,5173,5174],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5177,222],{"id":222},[51,5179,5180,5186],{},[54,5181,5182,5183,5185],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[39,5184,4392],{}," 开始找输入。",[54,5187,5188],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5190,241],{"id":241},[178,5192,5193,5196],{},[54,5194,5195],{},"把字符串列表转换为长度列表。",[54,5197,5198],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5200,258],{},[14,5202,261],{"id":261},[10,5204,5205],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,5207,268],{},{"title":87,"searchDepth":100,"depth":100,"links":5209},[5210,5211,5212,5213,5214,5215,5216,5217],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5075,"description":5080},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[281,5225,5226],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5229,"title":5230,"body":5231,"category":281,"cover":282,"description":5235,"extension":283,"meta":5378,"navigation":109,"path":5379,"pinned":286,"publishedAt":287,"seo":5380,"slug":5381,"stem":5382,"summary":5383,"tags":5384,"updatedAt":287,"visible":109,"__hash__":5387},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5232,"toc":5368},[5233,5236,5238,5241,5243,5249,5252,5254,5265,5267,5269,5308,5310,5316,5318,5320,5335,5337,5345,5347,5359,5361,5363,5366],[10,5234,5235],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5237,16],{"id":16},[10,5239,5240],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5242,27],{"id":27},[10,5244,5245],{},[31,5246],{"alt":5247,"src":5248},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5250,5251],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5253,49],{"id":49},[51,5255,5256,5259,5262],{},[54,5257,5258],{},"函数名描述动作，使用小写字母和下划线。",[54,5260,5261],{},"函数定义要先执行，之后才能调用。",[54,5263,5264],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5266,73],{"id":73},[10,5268,1490],{},[82,5270,5272],{"className":84,"code":5271,"language":86,"meta":87,"style":87},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[39,5273,5274,5279,5284,5289,5293,5298,5303],{"__ignoreMap":87},[91,5275,5276],{"class":93,"line":94},[91,5277,5278],{},"def show_progress():\n",[91,5280,5281],{"class":93,"line":100},[91,5282,5283],{},"    print(\"正在学习函数\")\n",[91,5285,5286],{"class":93,"line":106},[91,5287,5288],{},"    print(\"本节完成 50%\")\n",[91,5290,5291],{"class":93,"line":113},[91,5292,110],{"emptyLinePlaceholder":109},[91,5294,5295],{"class":93,"line":119},[91,5296,5297],{},"print(\"调用前\")\n",[91,5299,5300],{"class":93,"line":1202},[91,5301,5302],{},"show_progress()\n",[91,5304,5305],{"class":93,"line":2541},[91,5306,5307],{},"print(\"调用后\")\n",[10,5309,162],{},[82,5311,5314],{"className":5312,"code":5313,"language":168,"meta":87},[166],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[39,5315,5313],{"__ignoreMap":87},[10,5317,173],{},[14,5319,176],{"id":176},[178,5321,5322,5328],{},[54,5323,991,5324,5327],{},[39,5325,5326],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[54,5329,5330,5331,5334],{},"运行到 ",[39,5332,5333],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5336,222],{"id":222},[51,5338,5339,5342],{},[54,5340,5341],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[54,5343,5344],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5346,241],{"id":241},[178,5348,5349,5356],{},[54,5350,5351,5352,5355],{},"定义 ",[39,5353,5354],{},"show_plan()"," 输出两行学习计划。",[54,5357,5358],{},"连续调用同一个函数两次，观察执行顺序。",[10,5360,258],{},[14,5362,261],{"id":261},[10,5364,5365],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,5367,268],{},{"title":87,"searchDepth":100,"depth":100,"links":5369},[5370,5371,5372,5373,5374,5375,5376,5377],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5230,"description":5235},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[281,5385,5386],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5389,"title":5390,"body":5391,"category":281,"cover":282,"description":5395,"extension":283,"meta":5575,"navigation":109,"path":5576,"pinned":286,"publishedAt":287,"seo":5577,"slug":5578,"stem":5579,"summary":5580,"tags":5581,"updatedAt":287,"visible":109,"__hash__":5584},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5392,"toc":5563},[5393,5396,5398,5401,5403,5409,5416,5418,5435,5437,5439,5473,5475,5481,5483,5485,5506,5508,5511,5517,5527,5529,5544,5546,5554,5556,5558,5561],[10,5394,5395],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5397,16],{"id":16},[10,5399,5400],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5402,27],{"id":27},[10,5404,5405],{},[31,5406],{"alt":5407,"src":5408},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5410,5411,5412,5415],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[39,5413,5414],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5417,49],{"id":49},[51,5419,5420,5423,5426],{},[54,5421,5422],{},"形参出现在函数定义中，实参出现在函数调用中。",[54,5424,5425],{},"局部变量默认只在函数内部可见。",[54,5427,5428,5429,5431,5432,159],{},"没有显式 ",[39,5430,5414],{}," 的函数会返回 ",[39,5433,5434],{},"None",[14,5436,73],{"id":73},[10,5438,1490],{},[82,5440,5442],{"className":84,"code":5441,"language":86,"meta":87,"style":87},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[39,5443,5444,5449,5454,5459,5463,5468],{"__ignoreMap":87},[91,5445,5446],{"class":93,"line":94},[91,5447,5448],{},"def calculate_total(price, count):\n",[91,5450,5451],{"class":93,"line":100},[91,5452,5453],{},"    total = price * count\n",[91,5455,5456],{"class":93,"line":106},[91,5457,5458],{},"    return total\n",[91,5460,5461],{"class":93,"line":113},[91,5462,110],{"emptyLinePlaceholder":109},[91,5464,5465],{"class":93,"line":119},[91,5466,5467],{},"result = calculate_total(25, 4)\n",[91,5469,5470],{"class":93,"line":1202},[91,5471,5472],{},"print(result)\n",[10,5474,162],{},[82,5476,5479],{"className":5477,"code":5478,"language":168,"meta":87},[166],"100\n",[39,5480,5478],{"__ignoreMap":87},[10,5482,173],{},[14,5484,176],{"id":176},[178,5486,5487,5496],{},[54,5488,5489,5490,2310,5493,5495],{},"调用时 25 和 4 分别绑定到 ",[39,5491,5492],{},"price",[39,5494,4455],{},"，它们只在本次函数调用的局部范围中使用。",[54,5497,5498,5501,5502,5505],{},[39,5499,5500],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[39,5503,5504],{},"result"," 并输出。",[202,5507,204],{"id":204},[10,5509,5510],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5512,5513],{},[31,5514],{"alt":5515,"src":5516},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5518,5519,2310,5521,155,5523,5526],{},[39,5520,5492],{},[39,5522,4455],{},[39,5524,5525],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5528,222],{"id":222},[51,5530,5531,5538],{},[54,5532,5533,5534,5537],{},"在函数内部只 ",[39,5535,5536],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[54,5539,5540,5541,5543],{},"试图在函数外直接访问局部变量 ",[39,5542,5525],{},"，它的名字只在调用期间的局部作用域存在。",[14,5545,241],{"id":241},[178,5547,5548,5551],{},[54,5549,5550],{},"编写计算长方形面积的函数。",[54,5552,5553],{},"让函数返回结果后在调用方加上单位再输出。",[10,5555,258],{},[14,5557,261],{"id":261},[10,5559,5560],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,5562,268],{},{"title":87,"searchDepth":100,"depth":100,"links":5564},[5565,5566,5567,5568,5569,5572,5573,5574],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":5570},[5571],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5390,"description":5395},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[281,5582,5583],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5586,"title":5587,"body":5588,"category":281,"cover":282,"description":5592,"extension":283,"meta":5772,"navigation":109,"path":5773,"pinned":286,"publishedAt":287,"seo":5774,"slug":5775,"stem":5776,"summary":5777,"tags":5778,"updatedAt":287,"visible":109,"__hash__":5781},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5589,"toc":5760},[5590,5593,5595,5598,5600,5606,5609,5611,5628,5630,5632,5684,5686,5692,5694,5696,5714,5716,5719,5725,5728,5730,5741,5743,5751,5753,5755,5758],[10,5591,5592],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5594,16],{"id":16},[10,5596,5597],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5599,27],{"id":27},[10,5601,5602],{},[31,5603],{"alt":5604,"src":5605},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5607,5608],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5610,49],{"id":49},[51,5612,5613,5616,5622],{},[54,5614,5615],{},"必需参数应放在有默认值的参数之前。",[54,5617,5618,5621],{},[39,5619,5620],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[54,5623,5624,5627],{},[39,5625,5626],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5629,73],{"id":73},[10,5631,1490],{},[82,5633,5635],{"className":84,"code":5634,"language":86,"meta":87,"style":87},"def build_title(name, level=\"基础\"):\n    return name + \"｜\" + level\n\nprint(build_title(\"Python\"))\nprint(build_title(name=\"异常处理\", level=\"进阶\"))\n\ndef total(*numbers):\n    return sum(numbers)\n\nprint(total(10, 20, 30))\n",[39,5636,5637,5642,5647,5651,5656,5661,5665,5670,5675,5679],{"__ignoreMap":87},[91,5638,5639],{"class":93,"line":94},[91,5640,5641],{},"def build_title(name, level=\"基础\"):\n",[91,5643,5644],{"class":93,"line":100},[91,5645,5646],{},"    return name + \"｜\" + level\n",[91,5648,5649],{"class":93,"line":106},[91,5650,110],{"emptyLinePlaceholder":109},[91,5652,5653],{"class":93,"line":113},[91,5654,5655],{},"print(build_title(\"Python\"))\n",[91,5657,5658],{"class":93,"line":119},[91,5659,5660],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[91,5662,5663],{"class":93,"line":1202},[91,5664,110],{"emptyLinePlaceholder":109},[91,5666,5667],{"class":93,"line":2541},[91,5668,5669],{},"def total(*numbers):\n",[91,5671,5672],{"class":93,"line":2547},[91,5673,5674],{},"    return sum(numbers)\n",[91,5676,5677],{"class":93,"line":4006},[91,5678,110],{"emptyLinePlaceholder":109},[91,5680,5681],{"class":93,"line":4218},[91,5682,5683],{},"print(total(10, 20, 30))\n",[10,5685,162],{},[82,5687,5690],{"className":5688,"code":5689,"language":168,"meta":87},[166],"Python｜基础\n异常处理｜进阶\n60\n",[39,5691,5689],{"__ignoreMap":87},[10,5693,173],{},[14,5695,176],{"id":176},[178,5697,5698,5705],{},[54,5699,5700,5701,5704],{},"第一次调用只提供必需参数，",[39,5702,5703],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[54,5706,5707,5710,5711,159],{},[39,5708,5709],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[39,5712,5713],{},"sum()",[202,5715,204],{"id":204},[10,5717,5718],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5720,5721],{},[31,5722],{"alt":5723,"src":5724},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5726,5727],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5729,222],{"id":222},[51,5731,5732,5738],{},[54,5733,5734,5735,5737],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[39,5736,5434],{}," 再在函数内创建。",[54,5739,5740],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5742,241],{"id":241},[178,5744,5745,5748],{},[54,5746,5747],{},"给问候函数增加默认称呼。",[54,5749,5750],{},"编写接收任意数量分数并返回总分的函数。",[10,5752,258],{},[14,5754,261],{"id":261},[10,5756,5757],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,5759,268],{},{"title":87,"searchDepth":100,"depth":100,"links":5761},[5762,5763,5764,5765,5766,5769,5770,5771],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":5767},[5768],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5587,"description":5592},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[281,5779,5780],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5783,"title":5784,"body":5785,"category":281,"cover":282,"description":5789,"extension":283,"meta":5986,"navigation":109,"path":5987,"pinned":286,"publishedAt":287,"seo":5988,"slug":5989,"stem":5990,"summary":5991,"tags":5992,"updatedAt":287,"visible":109,"__hash__":5995},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5786,"toc":5974},[5787,5790,5792,5795,5797,5803,5806,5808,5825,5827,5829,5892,5894,5900,5902,5904,5931,5933,5936,5942,5945,5947,5955,5957,5965,5967,5969,5972],[10,5788,5789],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5791,16],{"id":16},[10,5793,5794],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5796,27],{"id":27},[10,5798,5799],{},[31,5800],{"alt":5801,"src":5802},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5804,5805],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5807,49],{"id":49},[51,5809,5810,5813,5816],{},[54,5811,5812],{},"函数内部赋值默认创建局部变量。",[54,5814,5815],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[54,5817,5818,2229,5821,5824],{},[39,5819,5820],{},"global",[39,5822,5823],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5826,73],{"id":73},[10,5828,1490],{},[82,5830,5832],{"className":84,"code":5831,"language":86,"meta":87,"style":87},"course = \"Python\"\n\ndef outer():\n    level = \"基础\"\n\n    def show():\n        lesson = \"作用域\"\n        print(course, level, lesson)\n\n    show()\n\nouter()\n",[39,5833,5834,5839,5843,5848,5853,5857,5862,5867,5872,5876,5881,5886],{"__ignoreMap":87},[91,5835,5836],{"class":93,"line":94},[91,5837,5838],{},"course = \"Python\"\n",[91,5840,5841],{"class":93,"line":100},[91,5842,110],{"emptyLinePlaceholder":109},[91,5844,5845],{"class":93,"line":106},[91,5846,5847],{},"def outer():\n",[91,5849,5850],{"class":93,"line":113},[91,5851,5852],{},"    level = \"基础\"\n",[91,5854,5855],{"class":93,"line":119},[91,5856,110],{"emptyLinePlaceholder":109},[91,5858,5859],{"class":93,"line":1202},[91,5860,5861],{},"    def show():\n",[91,5863,5864],{"class":93,"line":2541},[91,5865,5866],{},"        lesson = \"作用域\"\n",[91,5868,5869],{"class":93,"line":2547},[91,5870,5871],{},"        print(course, level, lesson)\n",[91,5873,5874],{"class":93,"line":4006},[91,5875,110],{"emptyLinePlaceholder":109},[91,5877,5878],{"class":93,"line":4218},[91,5879,5880],{},"    show()\n",[91,5882,5884],{"class":93,"line":5883},11,[91,5885,110],{"emptyLinePlaceholder":109},[91,5887,5889],{"class":93,"line":5888},12,[91,5890,5891],{},"outer()\n",[10,5893,162],{},[82,5895,5898],{"className":5896,"code":5897,"language":168,"meta":87},[166],"Python 基础 作用域\n",[39,5899,5897],{"__ignoreMap":87},[10,5901,173],{},[14,5903,176],{"id":176},[178,5905,5906,5923],{},[54,5907,5908,5911,5912,5915,5916,5918,5919,5922],{},[39,5909,5910],{},"show()"," 中查找 ",[39,5913,5914],{},"lesson"," 时先在局部找到，查找 ",[39,5917,5703],{}," 时到外层 ",[39,5920,5921],{},"outer()"," 找到。",[54,5924,5925,5927,5928,5930],{},[39,5926,4638],{}," 在局部和外层都不存在，继续到模块全局找到；",[39,5929,2261],{}," 最后在内置作用域找到。",[202,5932,204],{"id":204},[10,5934,5935],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5937,5938],{},[31,5939],{"alt":5940,"src":5941},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5943,5944],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5946,222],{"id":222},[51,5948,5949,5952],{},[54,5950,5951],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[54,5953,5954],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5956,241],{"id":241},[178,5958,5959,5962],{},[54,5960,5961],{},"在内外层定义同名变量，观察最近作用域优先。",[54,5963,5964],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5966,258],{},[14,5968,261],{"id":261},[10,5970,5971],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,5973,268],{},{"title":87,"searchDepth":100,"depth":100,"links":5975},[5976,5977,5978,5979,5980,5983,5984,5985],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":5981},[5982],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5784,"description":5789},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[281,5993,5994],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5997,"title":5998,"body":5999,"category":281,"cover":282,"description":6003,"extension":283,"meta":6152,"navigation":109,"path":6153,"pinned":286,"publishedAt":287,"seo":6154,"slug":6155,"stem":6156,"summary":6157,"tags":6158,"updatedAt":287,"visible":109,"__hash__":6161},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":6000,"toc":6142},[6001,6004,6006,6009,6011,6017,6020,6022,6041,6043,6045,6079,6081,6087,6089,6091,6105,6107,6119,6121,6133,6135,6137,6140],[10,6002,6003],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,6005,16],{"id":16},[10,6007,6008],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6010,27],{"id":27},[10,6012,6013],{},[31,6014],{"alt":6015,"src":6016},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,6018,6019],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,6021,49],{"id":49},[51,6023,6024,6027,6030],{},[54,6025,6026],{},"文档字符串紧跟在函数定义后的第一条语句。",[54,6028,6029],{},"注解表达接口意图，不代替输入校验和测试。",[54,6031,6032,6033,2310,6035,2310,6037,6040],{},"基础注解优先使用 ",[39,6034,2313],{},[39,6036,2478],{},[39,6038,6039],{},"list[str]"," 等直接写法。",[14,6042,73],{"id":73},[10,6044,1490],{},[82,6046,6048],{"className":84,"code":6047,"language":86,"meta":87,"style":87},"def format_score(name: str, score: int) -> str:\n    \"\"\"返回带姓名的分数文本。\"\"\"\n    return name + \"：\" + str(score)\n\nprint(format_score(\"小郑\", 95))\nprint(format_score.__doc__)\n",[39,6049,6050,6055,6060,6065,6069,6074],{"__ignoreMap":87},[91,6051,6052],{"class":93,"line":94},[91,6053,6054],{},"def format_score(name: str, score: int) -> str:\n",[91,6056,6057],{"class":93,"line":100},[91,6058,6059],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[91,6061,6062],{"class":93,"line":106},[91,6063,6064],{},"    return name + \"：\" + str(score)\n",[91,6066,6067],{"class":93,"line":113},[91,6068,110],{"emptyLinePlaceholder":109},[91,6070,6071],{"class":93,"line":119},[91,6072,6073],{},"print(format_score(\"小郑\", 95))\n",[91,6075,6076],{"class":93,"line":1202},[91,6077,6078],{},"print(format_score.__doc__)\n",[10,6080,162],{},[82,6082,6085],{"className":6083,"code":6084,"language":168,"meta":87},[166],"小郑：95\n返回带姓名的分数文本。\n",[39,6086,6084],{"__ignoreMap":87},[10,6088,173],{},[14,6090,176],{"id":176},[178,6092,6093,6102],{},[54,6094,6095,6096,6098,6099,6101],{},"函数签名说明 ",[39,6097,23],{}," 预期为字符串、",[39,6100,2299],{}," 预期为整数，返回值预期为字符串。",[54,6103,6104],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6106,222],{"id":222},[51,6108,6109,6116],{},[54,6110,6111,6112,6115],{},"认为加了 ",[39,6113,6114],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[54,6117,6118],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6120,241],{"id":241},[178,6122,6123,6126],{},[54,6124,6125],{},"为面积函数补充参数和返回值注解。",[54,6127,6128,6129,6132],{},"通过 ",[39,6130,6131],{},"函数名.__doc__"," 查看文档字符串。",[10,6134,258],{},[14,6136,261],{"id":261},[10,6138,6139],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,6141,268],{},{"title":87,"searchDepth":100,"depth":100,"links":6143},[6144,6145,6146,6147,6148,6149,6150,6151],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5998,"description":6003},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[281,6159,6160],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":4,"title":5,"body":6163,"category":281,"cover":282,"description":12,"extension":283,"meta":6340,"navigation":109,"path":285,"pinned":286,"publishedAt":287,"seo":6341,"slug":289,"stem":290,"summary":291,"tags":6342,"updatedAt":287,"visible":109,"__hash__":295},{"type":7,"value":6164,"toc":6328},[6165,6167,6169,6173,6175,6179,6185,6187,6199,6201,6205,6229,6233,6249,6255,6257,6262,6264,6266,6282,6284,6286,6290,6294,6296,6308,6310,6320,6322,6324,6326],[10,6166,12],{},[14,6168,16],{"id":16},[10,6170,19,6171,24],{},[21,6172,23],{},[14,6174,27],{"id":27},[10,6176,6177],{},[31,6178],{"alt":33,"src":34},[10,6180,37,6181,42,6183,46],{},[39,6182,41],{},[39,6184,45],{},[14,6186,49],{"id":49},[51,6188,6189,6193,6195],{},[54,6190,56,6191,60],{},[39,6192,59],{},[54,6194,63],{},[54,6196,66,6197,70],{},[39,6198,69],{},[14,6200,73],{"id":73},[10,6202,76,6203,80],{},[39,6204,79],{},[82,6206,6207],{"className":84,"code":85,"language":86,"meta":87,"style":87},[39,6208,6209,6213,6217,6221,6225],{"__ignoreMap":87},[91,6210,6211],{"class":93,"line":94},[91,6212,97],{},[91,6214,6215],{"class":93,"line":100},[91,6216,103],{},[91,6218,6219],{"class":93,"line":106},[91,6220,110],{"emptyLinePlaceholder":109},[91,6222,6223],{"class":93,"line":113},[91,6224,116],{},[91,6226,6227],{"class":93,"line":119},[91,6228,122],{},[10,6230,125,6231,129],{},[39,6232,128],{},[82,6234,6235],{"className":84,"code":132,"language":86,"meta":87,"style":87},[39,6236,6237,6241,6245],{"__ignoreMap":87},[91,6238,6239],{"class":93,"line":94},[91,6240,139],{},[91,6242,6243],{"class":93,"line":100},[91,6244,110],{"emptyLinePlaceholder":109},[91,6246,6247],{"class":93,"line":106},[91,6248,148],{},[10,6250,151,6251,155,6253,159],{},[39,6252,154],{},[39,6254,158],{},[10,6256,162],{},[82,6258,6260],{"className":6259,"code":167,"language":168,"meta":87},[166],[39,6261,167],{"__ignoreMap":87},[10,6263,173],{},[14,6265,176],{"id":176},[178,6267,6268,6274],{},[54,6269,182,6270,185,6272,189],{},[39,6271,79],{},[39,6273,188],{},[54,6275,6276,194,6278,197,6280,200],{},[39,6277,128],{},[39,6279,79],{},[39,6281,128],{},[202,6283,204],{"id":204},[10,6285,207],{},[10,6287,6288],{},[31,6289],{"alt":212,"src":213},[10,6291,216,6292,219],{},[39,6293,188],{},[14,6295,222],{"id":222},[51,6297,6298,6304],{},[54,6299,227,6300,155,6302,159],{},[39,6301,79],{},[39,6303,128],{},[54,6305,234,6306,238],{},[39,6307,237],{},[14,6309,241],{"id":241},[178,6311,6312,6316],{},[54,6313,246,6314,250],{},[39,6315,249],{},[54,6317,253,6318,159],{},[39,6319,41],{},[10,6321,258],{},[14,6323,261],{"id":261},[10,6325,264],{},[266,6327,268],{},{"title":87,"searchDepth":100,"depth":100,"links":6329},[6330,6331,6332,6333,6334,6337,6338,6339],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":6335},[6336],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5,"description":12},[281,293,294],{"id":6344,"title":6345,"body":6346,"category":281,"cover":282,"description":6350,"extension":283,"meta":6515,"navigation":109,"path":6516,"pinned":286,"publishedAt":287,"seo":6517,"slug":6518,"stem":6519,"summary":6520,"tags":6521,"updatedAt":287,"visible":109,"__hash__":6523},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6347,"toc":6505},[6348,6351,6353,6356,6358,6364,6367,6369,6383,6385,6387,6433,6435,6441,6443,6445,6471,6473,6483,6485,6496,6498,6500,6503],[10,6349,6350],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6352,16],{"id":16},[10,6354,6355],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6357,27],{"id":27},[10,6359,6360],{},[31,6361],{"alt":6362,"src":6363},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6365,6366],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6368,49],{"id":49},[51,6370,6371,6377,6380],{},[54,6372,6373,6376],{},[39,6374,6375],{},".venv"," 是常见目录名，不应提交到 Git。",[54,6378,6379],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[54,6381,6382],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6384,73],{"id":73},[10,6386,1627],{},[82,6388,6390],{"className":644,"code":6389,"language":646,"meta":87,"style":87},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[39,6391,6392,6404,6412,6418,6428],{"__ignoreMap":87},[91,6393,6394,6396,6398,6401],{"class":93,"line":94},[91,6395,744],{"class":653},[91,6397,686],{"class":656},[91,6399,6400],{"class":689}," venv",[91,6402,6403],{"class":689}," .venv\n",[91,6405,6406,6409],{"class":93,"line":100},[91,6407,6408],{"class":656},"source",[91,6410,6411],{"class":689}," .venv\u002Fbin\u002Factivate\n",[91,6413,6414,6416],{"class":93,"line":106},[91,6415,86],{"class":653},[91,6417,657],{"class":656},[91,6419,6420,6422,6424,6426],{"class":93,"line":113},[91,6421,86],{"class":653},[91,6423,686],{"class":656},[91,6425,690],{"class":689},[91,6427,657],{"class":656},[91,6429,6430],{"class":93,"line":119},[91,6431,6432],{"class":653},"deactivate\n",[10,6434,162],{},[82,6436,6439],{"className":6437,"code":6438,"language":168,"meta":87},[166],"Python 和 pip 的路径应指向当前项目的 .venv\n",[39,6440,6438],{"__ignoreMap":87},[10,6442,173],{},[14,6444,176],{"id":176},[178,6446,6447,6456],{},[54,6448,6449,6452,6453,6455],{},[39,6450,6451],{},"venv"," 根据当前 ",[39,6454,744],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[54,6457,6458,6459,2229,6461,6464,6465,3781,6467,6470],{},"激活后 ",[39,6460,86],{},[39,6462,6463],{},"python -m pip"," 优先指向 ",[39,6466,6375],{},[39,6468,6469],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6472,222],{"id":222},[51,6474,6475,6478],{},[54,6476,6477],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[54,6479,3520,6480,6482],{},[39,6481,6375],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6484,241],{"id":241},[178,6486,6487,6493],{},[54,6488,6489,6490,159],{},"创建虚拟环境并记录激活前后的 ",[39,6491,6492],{},"which python",[54,6494,6495],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6497,258],{},[14,6499,261],{"id":261},[10,6501,6502],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,6504,1711],{},{"title":87,"searchDepth":100,"depth":100,"links":6506},[6507,6508,6509,6510,6511,6512,6513,6514],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6345,"description":6350},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[281,6522,316],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6525,"title":6526,"body":6527,"category":281,"cover":282,"description":6531,"extension":283,"meta":6719,"navigation":109,"path":6720,"pinned":286,"publishedAt":287,"seo":6721,"slug":6722,"stem":6723,"summary":6724,"tags":6725,"updatedAt":287,"visible":109,"__hash__":6728},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6528,"toc":6709},[6529,6532,6534,6537,6539,6545,6554,6556,6580,6582,6584,6637,6639,6645,6647,6649,6665,6667,6686,6688,6700,6702,6704,6707],[10,6530,6531],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6533,16],{"id":16},[10,6535,6536],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6538,27],{"id":27},[10,6540,6541],{},[31,6542],{"alt":6543,"src":6544},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6546,6547,6550,6551,6553],{},[39,6548,6549],{},"Path"," 使用 ",[39,6552,2488],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6555,49],{"id":49},[51,6557,6558,6561,6573],{},[54,6559,6560],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[54,6562,6563,2310,6566,2310,6569,6572],{},[39,6564,6565],{},"exists()",[39,6567,6568],{},"is_file()",[39,6570,6571],{},"is_dir()"," 检查真实文件系统状态。",[54,6574,6575,6576,6579],{},"创建目录前明确目标；",[39,6577,6578],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6581,73],{"id":73},[10,6583,1490],{},[82,6585,6587],{"className":84,"code":6586,"language":86,"meta":87,"style":87},"from pathlib import Path\n\nproject = Path.cwd()\ndata_dir = project \u002F \"data\"\nfile_path = data_dir \u002F \"records.json\"\n\nprint(project)\nprint(file_path.name)\nprint(file_path.suffix)\nprint(file_path.exists())\n",[39,6588,6589,6594,6598,6603,6608,6613,6617,6622,6627,6632],{"__ignoreMap":87},[91,6590,6591],{"class":93,"line":94},[91,6592,6593],{},"from pathlib import Path\n",[91,6595,6596],{"class":93,"line":100},[91,6597,110],{"emptyLinePlaceholder":109},[91,6599,6600],{"class":93,"line":106},[91,6601,6602],{},"project = Path.cwd()\n",[91,6604,6605],{"class":93,"line":113},[91,6606,6607],{},"data_dir = project \u002F \"data\"\n",[91,6609,6610],{"class":93,"line":119},[91,6611,6612],{},"file_path = data_dir \u002F \"records.json\"\n",[91,6614,6615],{"class":93,"line":1202},[91,6616,110],{"emptyLinePlaceholder":109},[91,6618,6619],{"class":93,"line":2541},[91,6620,6621],{},"print(project)\n",[91,6623,6624],{"class":93,"line":2547},[91,6625,6626],{},"print(file_path.name)\n",[91,6628,6629],{"class":93,"line":4006},[91,6630,6631],{},"print(file_path.suffix)\n",[91,6633,6634],{"class":93,"line":4218},[91,6635,6636],{},"print(file_path.exists())\n",[10,6638,162],{},[82,6640,6643],{"className":6641,"code":6642,"language":168,"meta":87},[166],"显示当前项目路径、records.json、.json 和存在状态\n",[39,6644,6642],{"__ignoreMap":87},[10,6646,173],{},[14,6648,176],{"id":176},[178,6650,6651,6657],{},[54,6652,6653,6656],{},[39,6654,6655],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[54,6658,2392,6659,6661,6662,6664],{},[39,6660,2488],{}," 组合路径片段只创建新的 ",[39,6663,6549],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6666,222],{"id":222},[51,6668,6669,6677],{},[54,6670,3520,6671,6673,6674,6676],{},[39,6672,6549],{}," 对象存在当成真实文件存在，仍需调用 ",[39,6675,6565],{}," 等方法确认。",[54,6678,6679,6680,1062,6682,6685],{},"手工拼接 ",[39,6681,2488],{},[39,6683,6684],{},"\\"," 分隔符，降低跨平台可读性。",[14,6687,241],{"id":241},[178,6689,6690,6697],{},[54,6691,6692,6693,6696],{},"组合 ",[39,6694,6695],{},"output\u002Freport.txt"," 路径但先不创建文件。",[54,6698,6699],{},"输出路径的父目录、文件名和扩展名。",[10,6701,258],{},[14,6703,261],{"id":261},[10,6705,6706],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,6708,268],{},{"title":87,"searchDepth":100,"depth":100,"links":6710},[6711,6712,6713,6714,6715,6716,6717,6718],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6526,"description":6531},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[281,6726,6727],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6730,"title":6731,"body":6732,"category":281,"cover":282,"description":6736,"extension":283,"meta":6914,"navigation":109,"path":6915,"pinned":286,"publishedAt":287,"seo":6916,"slug":6917,"stem":6918,"summary":6919,"tags":6920,"updatedAt":287,"visible":109,"__hash__":6923},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6733,"toc":6904},[6734,6737,6739,6742,6744,6750,6753,6755,6783,6785,6787,6844,6846,6852,6854,6856,6867,6869,6882,6884,6895,6897,6899,6902],[10,6735,6736],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6738,16],{"id":16},[10,6740,6741],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6743,27],{"id":27},[10,6745,6746],{},[31,6747],{"alt":6748,"src":6749},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6751,6752],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6754,49],{"id":49},[51,6756,6757,6763,6772],{},[54,6758,6759,6762],{},[39,6760,6761],{},"w"," 模式会截断原文件，写入前必须确认目标。",[54,6764,6765,6768,6769,159],{},[39,6766,6767],{},"r"," 模式读取不存在文件会产生 ",[39,6770,6771],{},"FileNotFoundError",[54,6773,6774,6775,6778,6779,6782],{},"本篇显式调用 ",[39,6776,6777],{},"close()","；第 34 篇会用 ",[39,6780,6781],{},"with"," 更可靠地管理关闭动作。",[14,6784,73],{"id":73},[10,6786,1490],{},[82,6788,6790],{"className":84,"code":6789,"language":86,"meta":87,"style":87},"from pathlib import Path\n\nfile_path = Path(\"notes.txt\")\nwriter = file_path.open(\"w\", encoding=\"utf-8\")\nwriter.write(\"变量\\n循环\\n函数\\n\")\nwriter.close()\n\nreader = file_path.open(\"r\", encoding=\"utf-8\")\ncontent = reader.read()\nreader.close()\nprint(content)\n",[39,6791,6792,6796,6800,6805,6810,6815,6820,6824,6829,6834,6839],{"__ignoreMap":87},[91,6793,6794],{"class":93,"line":94},[91,6795,6593],{},[91,6797,6798],{"class":93,"line":100},[91,6799,110],{"emptyLinePlaceholder":109},[91,6801,6802],{"class":93,"line":106},[91,6803,6804],{},"file_path = Path(\"notes.txt\")\n",[91,6806,6807],{"class":93,"line":113},[91,6808,6809],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[91,6811,6812],{"class":93,"line":119},[91,6813,6814],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[91,6816,6817],{"class":93,"line":1202},[91,6818,6819],{},"writer.close()\n",[91,6821,6822],{"class":93,"line":2541},[91,6823,110],{"emptyLinePlaceholder":109},[91,6825,6826],{"class":93,"line":2547},[91,6827,6828],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[91,6830,6831],{"class":93,"line":4006},[91,6832,6833],{},"content = reader.read()\n",[91,6835,6836],{"class":93,"line":4218},[91,6837,6838],{},"reader.close()\n",[91,6840,6841],{"class":93,"line":5883},[91,6842,6843],{},"print(content)\n",[10,6845,162],{},[82,6847,6850],{"className":6848,"code":6849,"language":168,"meta":87},[166],"变量\n循环\n函数\n",[39,6851,6849],{"__ignoreMap":87},[10,6853,173],{},[14,6855,176],{"id":176},[178,6857,6858,6864],{},[54,6859,6860,6861,6863],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[39,6862,6777],{}," 确保缓冲内容交给文件系统。",[54,6865,6866],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6868,222],{"id":222},[51,6870,6871,6876],{},[54,6872,2392,6873,6875],{},[39,6874,6761],{}," 模式打开重要文件却未确认覆盖风险。",[54,6877,6878,6879,159],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[39,6880,6881],{},"encoding=\"utf-8\"",[14,6883,241],{"id":241},[178,6885,6886,6889],{},[54,6887,6888],{},"写入三行学习记录并读取。",[54,6890,6891,6892,6894],{},"改用 ",[39,6893,390],{}," 模式追加一行，确认原内容仍保留。",[10,6896,258],{},[14,6898,261],{"id":261},[10,6900,6901],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,6903,268],{},{"title":87,"searchDepth":100,"depth":100,"links":6905},[6906,6907,6908,6909,6910,6911,6912,6913],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6731,"description":6736},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[281,6921,6922],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6925,"title":6926,"body":6927,"category":281,"cover":282,"description":6931,"extension":283,"meta":7098,"navigation":109,"path":7099,"pinned":286,"publishedAt":287,"seo":7100,"slug":7101,"stem":7102,"summary":7103,"tags":7104,"updatedAt":287,"visible":109,"__hash__":7107},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6928,"toc":7088},[6929,6932,6934,6937,6939,6945,6955,6957,6971,6973,6975,7035,7037,7043,7045,7047,7059,7061,7069,7071,7079,7081,7083,7086],[10,6930,6931],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6933,16],{"id":16},[10,6935,6936],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6938,27],{"id":27},[10,6940,6941],{},[31,6942],{"alt":6943,"src":6944},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,6946,6947,6950,6951,6954],{},[39,6948,6949],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[39,6952,6953],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,6956,49],{"id":49},[51,6958,6959,6962,6968],{},[54,6960,6961],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[54,6963,6964,6967],{},[39,6965,6966],{},"ensure_ascii=False"," 让中文以可读字符写入。",[54,6969,6970],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,6972,73],{"id":73},[10,6974,1490],{},[82,6976,6978],{"className":84,"code":6977,"language":86,"meta":87,"style":87},"import json\n\nrecord = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n\nwriter = open(\"record.json\", \"w\", encoding=\"utf-8\")\njson.dump(record, writer, ensure_ascii=False, indent=2)\nwriter.close()\n\nreader = open(\"record.json\", \"r\", encoding=\"utf-8\")\nloaded = json.load(reader)\nreader.close()\nprint(loaded[\"course\"], loaded[\"progress\"])\n",[39,6979,6980,6985,6989,6994,6998,7003,7008,7012,7016,7021,7026,7030],{"__ignoreMap":87},[91,6981,6982],{"class":93,"line":94},[91,6983,6984],{},"import json\n",[91,6986,6987],{"class":93,"line":100},[91,6988,110],{"emptyLinePlaceholder":109},[91,6990,6991],{"class":93,"line":106},[91,6992,6993],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[91,6995,6996],{"class":93,"line":113},[91,6997,110],{"emptyLinePlaceholder":109},[91,6999,7000],{"class":93,"line":119},[91,7001,7002],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[91,7004,7005],{"class":93,"line":1202},[91,7006,7007],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[91,7009,7010],{"class":93,"line":2541},[91,7011,6819],{},[91,7013,7014],{"class":93,"line":2547},[91,7015,110],{"emptyLinePlaceholder":109},[91,7017,7018],{"class":93,"line":4006},[91,7019,7020],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[91,7022,7023],{"class":93,"line":4218},[91,7024,7025],{},"loaded = json.load(reader)\n",[91,7027,7028],{"class":93,"line":5883},[91,7029,6838],{},[91,7031,7032],{"class":93,"line":5888},[91,7033,7034],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7036,162],{},[82,7038,7041],{"className":7039,"code":7040,"language":168,"meta":87},[166],"Python 60\n",[39,7042,7040],{"__ignoreMap":87},[10,7044,173],{},[14,7046,176],{"id":176},[178,7048,7049,7054],{},[54,7050,7051,7053],{},[39,7052,6949],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[54,7055,7056,7058],{},[39,7057,6953],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7060,222],{"id":222},[51,7062,7063,7066],{},[54,7064,7065],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[54,7067,7068],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7070,241],{"id":241},[178,7072,7073,7076],{},[54,7074,7075],{},"保存包含两条学习记录的列表。",[54,7077,7078],{},"读取后修改进度，再重新写回文件。",[10,7080,258],{},[14,7082,261],{"id":261},[10,7084,7085],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,7087,268],{},{"title":87,"searchDepth":100,"depth":100,"links":7089},[7090,7091,7092,7093,7094,7095,7096,7097],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6926,"description":6931},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[281,7105,7106],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7109,"title":7110,"body":7111,"category":281,"cover":282,"description":7115,"extension":283,"meta":7299,"navigation":109,"path":7300,"pinned":286,"publishedAt":287,"seo":7301,"slug":7302,"stem":7303,"summary":7304,"tags":7305,"updatedAt":287,"visible":109,"__hash__":7308},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7112,"toc":7289},[7113,7116,7118,7121,7123,7129,7135,7137,7159,7161,7163,7226,7228,7234,7236,7238,7254,7256,7270,7272,7280,7282,7284,7287],[10,7114,7115],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7117,16],{"id":16},[10,7119,7120],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7122,27],{"id":27},[10,7124,7125],{},[31,7126],{"alt":7127,"src":7128},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7130,7131,7134],{},[39,7132,7133],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7136,49],{"id":49},[51,7138,7139,7149,7156],{},[54,7140,2392,7141,7144,7145,7148],{},[39,7142,7143],{},"newline=\"\""," 让 ",[39,7146,7147],{},"csv"," 模块正确处理换行。",[54,7150,7151,7152,7155],{},"字段顺序由 ",[39,7153,7154],{},"fieldnames"," 决定，字典键需要与字段名一致。",[54,7157,7158],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7160,73],{"id":73},[10,7162,1490],{},[82,7164,7166],{"className":84,"code":7165,"language":86,"meta":87,"style":87},"import csv\n\nwriter_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\nwriter = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\nwriter.writeheader()\nwriter.writerow({\"name\": \"小郑\", \"score\": 95})\nwriter_file.close()\n\nreader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\nfor row in csv.DictReader(reader_file):\n    print(row[\"name\"], row[\"score\"])\nreader_file.close()\n",[39,7167,7168,7173,7177,7182,7187,7192,7197,7202,7206,7211,7216,7221],{"__ignoreMap":87},[91,7169,7170],{"class":93,"line":94},[91,7171,7172],{},"import csv\n",[91,7174,7175],{"class":93,"line":100},[91,7176,110],{"emptyLinePlaceholder":109},[91,7178,7179],{"class":93,"line":106},[91,7180,7181],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[91,7183,7184],{"class":93,"line":113},[91,7185,7186],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[91,7188,7189],{"class":93,"line":119},[91,7190,7191],{},"writer.writeheader()\n",[91,7193,7194],{"class":93,"line":1202},[91,7195,7196],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[91,7198,7199],{"class":93,"line":2541},[91,7200,7201],{},"writer_file.close()\n",[91,7203,7204],{"class":93,"line":2547},[91,7205,110],{"emptyLinePlaceholder":109},[91,7207,7208],{"class":93,"line":4006},[91,7209,7210],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[91,7212,7213],{"class":93,"line":4218},[91,7214,7215],{},"for row in csv.DictReader(reader_file):\n",[91,7217,7218],{"class":93,"line":5883},[91,7219,7220],{},"    print(row[\"name\"], row[\"score\"])\n",[91,7222,7223],{"class":93,"line":5888},[91,7224,7225],{},"reader_file.close()\n",[10,7227,162],{},[82,7229,7232],{"className":7230,"code":7231,"language":168,"meta":87},[166],"小郑 95\n",[39,7233,7231],{"__ignoreMap":87},[10,7235,173],{},[14,7237,176],{"id":176},[178,7239,7240,7249],{},[54,7241,7242,7245,7246,7248],{},[39,7243,7244],{},"DictWriter"," 按 ",[39,7247,7154],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[54,7250,7251,7253],{},[39,7252,7133],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7255,222],{"id":222},[51,7257,7258,7261],{},[54,7259,7260],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[54,7262,7263,7264,7266,7267,7269],{},"在 macOS 以外环境忽略 ",[39,7265,7143],{}," 可能出现额外空行；统一交给 ",[39,7268,7147],{}," 模块管理换行。",[14,7271,241],{"id":241},[178,7273,7274,7277],{},[54,7275,7276],{},"写入三名学习者的课程和分数。",[54,7278,7279],{},"读取 CSV 后把分数字符串转换为整数。",[10,7281,258],{},[14,7283,261],{"id":261},[10,7285,7286],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,7288,268],{},{"title":87,"searchDepth":100,"depth":100,"links":7290},[7291,7292,7293,7294,7295,7296,7297,7298],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7110,"description":7115},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[281,7306,7307],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7310,"title":7311,"body":7312,"category":281,"cover":282,"description":7316,"extension":283,"meta":7589,"navigation":109,"path":7590,"pinned":286,"publishedAt":287,"seo":7591,"slug":7592,"stem":7593,"summary":7594,"tags":7595,"updatedAt":287,"visible":109,"__hash__":7598},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7313,"toc":7576},[7314,7317,7319,7322,7324,7330,7341,7343,7360,7362,7364,7439,7441,7447,7449,7451,7476,7478,7487,7493,7504,7506,7512,7518,7527,7529,7544,7546,7567,7569,7571,7574],[10,7315,7316],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7318,16],{"id":16},[10,7320,7321],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7323,27],{"id":27},[10,7325,7326],{},[31,7327],{"alt":7328,"src":7329},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7331,7332,7333,7336,7337,7340],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[39,7334,7335],{},"except","；无论是否异常，",[39,7338,7339],{},"finally"," 都会在离开结构前执行。",[14,7342,49],{"id":49},[51,7344,7345,7351,7357],{},[54,7346,7347,7348,7350],{},"只捕获能够处理的具体异常，不使用空的 ",[39,7349,7335],{}," 吞掉全部错误。",[54,7352,7353,7356],{},[39,7354,7355],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[54,7358,7359],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7361,73],{"id":73},[10,7363,1490],{},[82,7365,7367],{"className":84,"code":7366,"language":86,"meta":87,"style":87},"def parse_age(text):\n    age = int(text)\n    if age \u003C 0:\n        raise ValueError(\"年龄不能为负数\")\n    return age\n\ntry:\n    age = parse_age(\"18\")\nexcept ValueError as error:\n    print(\"输入错误：\", error)\nelse:\n    print(\"年龄：\", age)\nfinally:\n    print(\"处理结束\")\n",[39,7368,7369,7374,7379,7384,7389,7394,7398,7403,7408,7413,7418,7422,7427,7433],{"__ignoreMap":87},[91,7370,7371],{"class":93,"line":94},[91,7372,7373],{},"def parse_age(text):\n",[91,7375,7376],{"class":93,"line":100},[91,7377,7378],{},"    age = int(text)\n",[91,7380,7381],{"class":93,"line":106},[91,7382,7383],{},"    if age \u003C 0:\n",[91,7385,7386],{"class":93,"line":113},[91,7387,7388],{},"        raise ValueError(\"年龄不能为负数\")\n",[91,7390,7391],{"class":93,"line":119},[91,7392,7393],{},"    return age\n",[91,7395,7396],{"class":93,"line":1202},[91,7397,110],{"emptyLinePlaceholder":109},[91,7399,7400],{"class":93,"line":2541},[91,7401,7402],{},"try:\n",[91,7404,7405],{"class":93,"line":2547},[91,7406,7407],{},"    age = parse_age(\"18\")\n",[91,7409,7410],{"class":93,"line":4006},[91,7411,7412],{},"except ValueError as error:\n",[91,7414,7415],{"class":93,"line":4218},[91,7416,7417],{},"    print(\"输入错误：\", error)\n",[91,7419,7420],{"class":93,"line":5883},[91,7421,1199],{},[91,7423,7424],{"class":93,"line":5888},[91,7425,7426],{},"    print(\"年龄：\", age)\n",[91,7428,7430],{"class":93,"line":7429},13,[91,7431,7432],{},"finally:\n",[91,7434,7436],{"class":93,"line":7435},14,[91,7437,7438],{},"    print(\"处理结束\")\n",[10,7440,162],{},[82,7442,7445],{"className":7443,"code":7444,"language":168,"meta":87},[166],"年龄： 18\n处理结束\n",[39,7446,7444],{"__ignoreMap":87},[10,7448,173],{},[14,7450,176],{"id":176},[178,7452,7453,7465],{},[54,7454,7455,7457,7458,7460,7461,7464],{},[39,7456,3089],{}," 或主动 ",[39,7459,7355],{}," 都可能产生 ",[39,7462,7463],{},"ValueError","，控制流立即离开当前正常路径。",[54,7466,7467,7468,7470,7471,7473,7474,159],{},"有异常时进入匹配的 ",[39,7469,7335],{},"；没有异常时执行 ",[39,7472,1213],{},"；两种情况最后都会执行 ",[39,7475,7339],{},[202,7477,204],{"id":204},[10,7479,7480,2310,7482,155,7484,7486],{},[39,7481,7335],{},[39,7483,1213],{},[39,7485,7339],{}," 的职责不同，不能只看它们出现的顺序。",[10,7488,7489],{},[31,7490],{"alt":7491,"src":7492},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7494,7495,7497,7498,7500,7501,7503],{},[39,7496,7335],{}," 处理匹配异常，",[39,7499,1213],{}," 只在无异常时运行，",[39,7502,7339],{}," 负责两条路径都需要的清理动作。",[202,7505,204],{"id":4273},[10,7507,7508,7511],{},[39,7509,7510],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7513,7514],{},[31,7515],{"alt":7516,"src":7517},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7519,7520,7521,7523,7524,7526],{},"只把可能产生预期异常的操作放进 ",[39,7522,7510],{},"，后续正常业务放进 ",[39,7525,1213],{},"，错误边界会更清楚。",[14,7528,222],{"id":222},[51,7530,7531,7538],{},[54,7532,7533,7534,7537],{},"使用裸 ",[39,7535,7536],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[54,7539,7540,7541,7543],{},"把整个程序包在一个巨大 ",[39,7542,7510],{}," 中，无法判断究竟哪一步允许失败。",[14,7545,241],{"id":241},[178,7547,7548,7561],{},[54,7549,7550,7551,7554,7555,155,7558,159],{},"让 ",[39,7552,7553],{},"parse_age"," 分别处理 ",[39,7556,7557],{},"\"abc\"",[39,7559,7560],{},"\"-1\"",[54,7562,7563,7564,7566],{},"为文件读取捕获 ",[39,7565,6771],{}," 并给出清晰提示。",[10,7568,258],{},[14,7570,261],{"id":261},[10,7572,7573],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,7575,268],{},{"title":87,"searchDepth":100,"depth":100,"links":7577},[7578,7579,7580,7581,7582,7586,7587,7588],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":7583},[7584,7585],{"id":204,"depth":106,"text":204},{"id":4273,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7311,"description":7316},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[281,7596,7597],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7600,"title":7601,"body":7602,"category":281,"cover":282,"description":7606,"extension":283,"meta":7782,"navigation":109,"path":7783,"pinned":286,"publishedAt":287,"seo":7784,"slug":7785,"stem":7786,"summary":7787,"tags":7788,"updatedAt":287,"visible":109,"__hash__":7790},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7603,"toc":7772},[7604,7607,7609,7612,7614,7620,7626,7628,7644,7646,7648,7702,7704,7710,7712,7714,7727,7729,7742,7744,7763,7765,7767,7770],[10,7605,7606],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7608,16],{"id":16},[10,7610,7611],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7613,27],{"id":27},[10,7615,7616],{},[31,7617],{"alt":7618,"src":7619},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7621,7622,7623,7625],{},"进入 ",[39,7624,6781],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7627,49],{"id":49},[51,7629,7630,7635,7641],{},[54,7631,7632,7634],{},[39,7633,6781],{}," 把资源获取和释放配成一个清晰边界。",[54,7636,7637,7640],{},[39,7638,7639],{},"as file"," 得到的是上下文返回的资源对象。",[54,7642,7643],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7645,73],{"id":73},[10,7647,1490],{},[82,7649,7651],{"className":84,"code":7650,"language":86,"meta":87,"style":87},"from pathlib import Path\n\nfile_path = Path(\"notes.txt\")\n\nwith file_path.open(\"w\", encoding=\"utf-8\") as file:\n    file.write(\"上下文管理器\\n\")\n\nwith file_path.open(\"r\", encoding=\"utf-8\") as file:\n    print(file.read())\n\nprint(file.closed)\n",[39,7652,7653,7657,7661,7665,7669,7674,7679,7683,7688,7693,7697],{"__ignoreMap":87},[91,7654,7655],{"class":93,"line":94},[91,7656,6593],{},[91,7658,7659],{"class":93,"line":100},[91,7660,110],{"emptyLinePlaceholder":109},[91,7662,7663],{"class":93,"line":106},[91,7664,6804],{},[91,7666,7667],{"class":93,"line":113},[91,7668,110],{"emptyLinePlaceholder":109},[91,7670,7671],{"class":93,"line":119},[91,7672,7673],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[91,7675,7676],{"class":93,"line":1202},[91,7677,7678],{},"    file.write(\"上下文管理器\\n\")\n",[91,7680,7681],{"class":93,"line":2541},[91,7682,110],{"emptyLinePlaceholder":109},[91,7684,7685],{"class":93,"line":2547},[91,7686,7687],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[91,7689,7690],{"class":93,"line":4006},[91,7691,7692],{},"    print(file.read())\n",[91,7694,7695],{"class":93,"line":4218},[91,7696,110],{"emptyLinePlaceholder":109},[91,7698,7699],{"class":93,"line":5883},[91,7700,7701],{},"print(file.closed)\n",[10,7703,162],{},[82,7705,7708],{"className":7706,"code":7707,"language":168,"meta":87},[166],"上下文管理器\n\nTrue\n",[39,7709,7707],{"__ignoreMap":87},[10,7711,173],{},[14,7713,176],{"id":176},[178,7715,7716,7724],{},[54,7717,7622,7718,7720,7721,159],{},[39,7719,6781],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[39,7722,7723],{},"file",[54,7725,7726],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7728,222],{"id":222},[51,7730,7731,7736],{},[54,7732,4841,7733,7735],{},[39,7734,6781],{}," 代码块外继续读写已经关闭的文件对象。",[54,7737,7738,7739,7741],{},"误以为 ",[39,7740,6781],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7743,241],{"id":241},[178,7745,7746,7755],{},[54,7747,7748,7749,7752,7753,159],{},"把第 30 篇的手动 ",[39,7750,7751],{},"open\u002Fclose"," 改写为 ",[39,7754,6781],{},[54,7756,4841,7757,7759,7760,159],{},[39,7758,6781],{}," 块后检查 ",[39,7761,7762],{},"file.closed",[10,7764,258],{},[14,7766,261],{"id":261},[10,7768,7769],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,7771,268],{},{"title":87,"searchDepth":100,"depth":100,"links":7773},[7774,7775,7776,7777,7778,7779,7780,7781],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7601,"description":7606},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[281,6781,7789],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7792,"title":7793,"body":7794,"category":281,"cover":282,"description":7798,"extension":283,"meta":8010,"navigation":109,"path":8011,"pinned":286,"publishedAt":287,"seo":8012,"slug":8013,"stem":8014,"summary":8015,"tags":8016,"updatedAt":287,"visible":109,"__hash__":8019},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7795,"toc":7998},[7796,7799,7801,7804,7806,7812,7815,7817,7834,7836,7838,7906,7908,7914,7916,7918,7943,7945,7948,7954,7963,7965,7976,7978,7989,7991,7993,7996],[10,7797,7798],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7800,16],{"id":16},[10,7802,7803],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7805,27],{"id":27},[10,7807,7808],{},[31,7809],{"alt":7810,"src":7811},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7813,7814],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7816,49],{"id":49},[51,7818,7819,7825,7831],{},[54,7820,7821,7824],{},[39,7822,7823],{},"self"," 表示当前实例，由方法调用自动传入。",[54,7826,7827,7830],{},[39,7828,7829],{},"__init__"," 在实例创建过程中初始化属性。",[54,7832,7833],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7835,73],{"id":73},[10,7837,1490],{},[82,7839,7841],{"className":84,"code":7840,"language":86,"meta":87,"style":87},"class LearningRecord:\n    def __init__(self, course, progress=0):\n        self.course = course\n        self.progress = progress\n\n    def advance(self, amount):\n        self.progress = self.progress + amount\n        if self.progress > 100:\n            self.progress = 100\n\nrecord = LearningRecord(\"Python\", 40)\nrecord.advance(15)\nprint(record.course, record.progress)\n",[39,7842,7843,7848,7853,7858,7863,7867,7872,7877,7882,7887,7891,7896,7901],{"__ignoreMap":87},[91,7844,7845],{"class":93,"line":94},[91,7846,7847],{},"class LearningRecord:\n",[91,7849,7850],{"class":93,"line":100},[91,7851,7852],{},"    def __init__(self, course, progress=0):\n",[91,7854,7855],{"class":93,"line":106},[91,7856,7857],{},"        self.course = course\n",[91,7859,7860],{"class":93,"line":113},[91,7861,7862],{},"        self.progress = progress\n",[91,7864,7865],{"class":93,"line":119},[91,7866,110],{"emptyLinePlaceholder":109},[91,7868,7869],{"class":93,"line":1202},[91,7870,7871],{},"    def advance(self, amount):\n",[91,7873,7874],{"class":93,"line":2541},[91,7875,7876],{},"        self.progress = self.progress + amount\n",[91,7878,7879],{"class":93,"line":2547},[91,7880,7881],{},"        if self.progress > 100:\n",[91,7883,7884],{"class":93,"line":4006},[91,7885,7886],{},"            self.progress = 100\n",[91,7888,7889],{"class":93,"line":4218},[91,7890,110],{"emptyLinePlaceholder":109},[91,7892,7893],{"class":93,"line":5883},[91,7894,7895],{},"record = LearningRecord(\"Python\", 40)\n",[91,7897,7898],{"class":93,"line":5888},[91,7899,7900],{},"record.advance(15)\n",[91,7902,7903],{"class":93,"line":7429},[91,7904,7905],{},"print(record.course, record.progress)\n",[10,7907,162],{},[82,7909,7912],{"className":7910,"code":7911,"language":168,"meta":87},[166],"Python 55\n",[39,7913,7911],{"__ignoreMap":87},[10,7915,173],{},[14,7917,176],{"id":176},[178,7919,7920,7930],{},[54,7921,7922,7923,7926,7927,7929],{},"调用 ",[39,7924,7925],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[39,7928,7829],{}," 把课程和进度保存在该实例属性中。",[54,7931,7932,7935,7936,7939,7940,7942],{},[39,7933,7934],{},"record.advance(15)"," 自动把 ",[39,7937,7938],{},"record"," 作为 ",[39,7941,7823],{},"，方法更新同一实例的进度并限制上限。",[202,7944,204],{"id":204},[10,7946,7947],{},"类是共同定义，实例则各自保存状态。",[10,7949,7950],{},[31,7951],{"alt":7952,"src":7953},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7955,7956,7957,155,7959,7962],{},"两个实例共享同一套方法定义，但 ",[39,7958,4638],{},[39,7960,7961],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,7964,222],{"id":222},[51,7966,7967,7973],{},[54,7968,7969,7970,7972],{},"调用实例方法时手工再传一次 ",[39,7971,7823],{},"。通过实例调用时 Python 会自动绑定。",[54,7974,7975],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,7977,241],{"id":241},[178,7979,7980,7986],{},[54,7981,5351,7982,7985],{},[39,7983,7984],{},"Book"," 类，保存标题和阅读页数。",[54,7987,7988],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,7990,258],{},[14,7992,261],{"id":261},[10,7994,7995],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,7997,268],{},{"title":87,"searchDepth":100,"depth":100,"links":7999},[8000,8001,8002,8003,8004,8007,8008,8009],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":8005},[8006],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7793,"description":7798},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[281,8017,8018],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":8021,"title":8022,"body":8023,"category":281,"cover":282,"description":8027,"extension":283,"meta":8205,"navigation":109,"path":8206,"pinned":286,"publishedAt":287,"seo":8207,"slug":8208,"stem":8209,"summary":8210,"tags":8211,"updatedAt":287,"visible":109,"__hash__":8214},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8024,"toc":8195},[8025,8028,8030,8033,8035,8041,8044,8046,8057,8059,8061,8128,8130,8136,8138,8140,8159,8161,8169,8171,8186,8188,8190,8193],[10,8026,8027],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,8029,16],{"id":16},[10,8031,8032],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8034,27],{"id":27},[10,8036,8037],{},[31,8038],{"alt":8039,"src":8040},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8042,8043],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8045,49],{"id":49},[51,8047,8048,8051,8054],{},[54,8049,8050],{},"封装让对象通过方法维护自己的有效状态。",[54,8052,8053],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[54,8055,8056],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8058,73],{"id":73},[10,8060,1490],{},[82,8062,8064],{"className":84,"code":8063,"language":86,"meta":87,"style":87},"class Storage:\n    def save(self, text):\n        print(\"保存：\", text)\n\nclass LearningService:\n    def __init__(self, storage):\n        self.storage = storage\n\n    def finish_lesson(self, title):\n        self.storage.save(title)\n\nservice = LearningService(Storage())\nservice.finish_lesson(\"异常处理\")\n",[39,8065,8066,8071,8076,8081,8085,8090,8095,8100,8104,8109,8114,8118,8123],{"__ignoreMap":87},[91,8067,8068],{"class":93,"line":94},[91,8069,8070],{},"class Storage:\n",[91,8072,8073],{"class":93,"line":100},[91,8074,8075],{},"    def save(self, text):\n",[91,8077,8078],{"class":93,"line":106},[91,8079,8080],{},"        print(\"保存：\", text)\n",[91,8082,8083],{"class":93,"line":113},[91,8084,110],{"emptyLinePlaceholder":109},[91,8086,8087],{"class":93,"line":119},[91,8088,8089],{},"class LearningService:\n",[91,8091,8092],{"class":93,"line":1202},[91,8093,8094],{},"    def __init__(self, storage):\n",[91,8096,8097],{"class":93,"line":2541},[91,8098,8099],{},"        self.storage = storage\n",[91,8101,8102],{"class":93,"line":2547},[91,8103,110],{"emptyLinePlaceholder":109},[91,8105,8106],{"class":93,"line":4006},[91,8107,8108],{},"    def finish_lesson(self, title):\n",[91,8110,8111],{"class":93,"line":4218},[91,8112,8113],{},"        self.storage.save(title)\n",[91,8115,8116],{"class":93,"line":5883},[91,8117,110],{"emptyLinePlaceholder":109},[91,8119,8120],{"class":93,"line":5888},[91,8121,8122],{},"service = LearningService(Storage())\n",[91,8124,8125],{"class":93,"line":7429},[91,8126,8127],{},"service.finish_lesson(\"异常处理\")\n",[10,8129,162],{},[82,8131,8134],{"className":8132,"code":8133,"language":168,"meta":87},[166],"保存： 异常处理\n",[39,8135,8133],{"__ignoreMap":87},[10,8137,173],{},[14,8139,176],{"id":176},[178,8141,8142,8152],{},[54,8143,8144,8147,8148,8151],{},[39,8145,8146],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[39,8149,8150],{},"save()"," 的协作对象。",[54,8153,8154,8155,8158],{},"调用业务方法时，服务把保存动作委托给 ",[39,8156,8157],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8160,222],{"id":222},[51,8162,8163,8166],{},[54,8164,8165],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[54,8167,8168],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8170,241],{"id":241},[178,8172,8173,8183],{},[54,8174,8175,8176,8179,8180,159],{},"用组合让 ",[39,8177,8178],{},"OrderService"," 使用一个 ",[39,8181,8182],{},"Notifier",[54,8184,8185],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8187,258],{},[14,8189,261],{"id":261},[10,8191,8192],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,8194,268],{},{"title":87,"searchDepth":100,"depth":100,"links":8196},[8197,8198,8199,8200,8201,8202,8203,8204],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":8022,"description":8027},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[281,8212,8213],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8216,"title":8217,"body":8218,"category":281,"cover":282,"description":8222,"extension":283,"meta":8425,"navigation":109,"path":8426,"pinned":286,"publishedAt":287,"seo":8427,"slug":8428,"stem":8429,"summary":8430,"tags":8431,"updatedAt":287,"visible":109,"__hash__":8434},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8219,"toc":8413},[8220,8223,8225,8228,8230,8236,8243,8245,8270,8272,8274,8326,8328,8334,8336,8338,8359,8361,8367,8373,8379,8381,8389,8391,8404,8406,8408,8411],[10,8221,8222],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8224,16],{"id":16},[10,8226,8227],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8229,27],{"id":27},[10,8231,8232],{},[31,8233],{"alt":8234,"src":8235},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8237,8238,8239,8242],{},"生成器运行到 ",[39,8240,8241],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8244,49],{"id":49},[51,8246,8247,8257,8267],{},[54,8248,8249,8252,8253,8256],{},[39,8250,8251],{},"iter()"," 从可迭代对象取得迭代器，",[39,8254,8255],{},"next()"," 请求下一个值。",[54,8258,8259,8260,8263,8264,8266],{},"没有更多值时迭代器抛出 ",[39,8261,8262],{},"StopIteration","，",[39,8265,4392],{}," 会自动处理。",[54,8268,8269],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8271,73],{"id":73},[10,8273,1490],{},[82,8275,8277],{"className":84,"code":8276,"language":86,"meta":87,"style":87},"def countdown(start):\n    current = start\n    while current > 0:\n        yield current\n        current = current - 1\n\niterator = countdown(3)\nprint(next(iterator))\nprint(next(iterator))\nprint(next(iterator))\n",[39,8278,8279,8284,8289,8294,8299,8304,8308,8313,8318,8322],{"__ignoreMap":87},[91,8280,8281],{"class":93,"line":94},[91,8282,8283],{},"def countdown(start):\n",[91,8285,8286],{"class":93,"line":100},[91,8287,8288],{},"    current = start\n",[91,8290,8291],{"class":93,"line":106},[91,8292,8293],{},"    while current > 0:\n",[91,8295,8296],{"class":93,"line":113},[91,8297,8298],{},"        yield current\n",[91,8300,8301],{"class":93,"line":119},[91,8302,8303],{},"        current = current - 1\n",[91,8305,8306],{"class":93,"line":1202},[91,8307,110],{"emptyLinePlaceholder":109},[91,8309,8310],{"class":93,"line":2541},[91,8311,8312],{},"iterator = countdown(3)\n",[91,8314,8315],{"class":93,"line":2547},[91,8316,8317],{},"print(next(iterator))\n",[91,8319,8320],{"class":93,"line":4006},[91,8321,8317],{},[91,8323,8324],{"class":93,"line":4218},[91,8325,8317],{},[10,8327,162],{},[82,8329,8332],{"className":8330,"code":8331,"language":168,"meta":87},[166],"3\n2\n1\n",[39,8333,8331],{"__ignoreMap":87},[10,8335,173],{},[14,8337,176],{"id":176},[178,8339,8340,8346],{},[54,8341,7922,8342,8345],{},[39,8343,8344],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[54,8347,8348,8349,8351,8352,8354,8355,8358],{},"每次 ",[39,8350,8255],{}," 运行到下一个 ",[39,8353,8241],{}," 并暂停，局部变量 ",[39,8356,8357],{},"current"," 和执行位置被保留。",[202,8360,204],{"id":204},[10,8362,8363,8364,8366],{},"生成器的暂停位置可以展开成多次 ",[39,8365,8255],{}," 的时间线。",[10,8368,8369],{},[31,8370],{"alt":8371,"src":8372},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8374,8375,8376,8378],{},"每次请求只推进到下一个 ",[39,8377,8241],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8380,222],{"id":222},[51,8382,8383,8386],{},[54,8384,8385],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[54,8387,8388],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8390,241],{"id":241},[178,8392,8393,8396],{},[54,8394,8395],{},"编写产生 1 到指定上限偶数的生成器。",[54,8397,4064,8398,8400,8401,8403],{},[39,8399,4392],{}," 遍历生成器，比较手动 ",[39,8402,8255],{}," 的差异。",[10,8405,258],{},[14,8407,261],{"id":261},[10,8409,8410],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,8412,268],{},{"title":87,"searchDepth":100,"depth":100,"links":8414},[8415,8416,8417,8418,8419,8422,8423,8424],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":8420},[8421],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8217,"description":8222},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[281,8432,8433],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8436,"title":8437,"body":8438,"category":281,"cover":282,"description":8442,"extension":283,"meta":8666,"navigation":109,"path":8667,"pinned":286,"publishedAt":287,"seo":8668,"slug":8669,"stem":8670,"summary":8671,"tags":8672,"updatedAt":287,"visible":109,"__hash__":8674},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8439,"toc":8654},[8440,8443,8445,8448,8450,8456,8459,8461,8481,8483,8485,8567,8569,8575,8577,8579,8601,8603,8606,8612,8619,8621,8631,8633,8645,8647,8649,8652],[10,8441,8442],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8444,16],{"id":16},[10,8446,8447],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8449,27],{"id":27},[10,8451,8452],{},[31,8453],{"alt":8454,"src":8455},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8457,8458],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8460,49],{"id":49},[51,8462,8463,8472,8475],{},[54,8464,8465,8468,8469,159],{},[39,8466,8467],{},"@trace"," 等价于 ",[39,8470,8471],{},"add = trace(add)",[54,8473,8474],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[54,8476,8477,8480],{},[39,8478,8479],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8482,73],{"id":73},[10,8484,1490],{},[82,8486,8488],{"className":84,"code":8487,"language":86,"meta":87,"style":87},"from functools import wraps\n\ndef trace(function):\n    @wraps(function)\n    def wrapper(*args, **kwargs):\n        print(\"开始：\", function.__name__)\n        result = function(*args, **kwargs)\n        print(\"结束：\", function.__name__)\n        return result\n    return wrapper\n\n@trace\ndef add(left, right):\n    return left + right\n\nprint(add(2, 3))\n",[39,8489,8490,8495,8499,8504,8509,8514,8519,8524,8529,8534,8539,8543,8548,8552,8556,8561],{"__ignoreMap":87},[91,8491,8492],{"class":93,"line":94},[91,8493,8494],{},"from functools import wraps\n",[91,8496,8497],{"class":93,"line":100},[91,8498,110],{"emptyLinePlaceholder":109},[91,8500,8501],{"class":93,"line":106},[91,8502,8503],{},"def trace(function):\n",[91,8505,8506],{"class":93,"line":113},[91,8507,8508],{},"    @wraps(function)\n",[91,8510,8511],{"class":93,"line":119},[91,8512,8513],{},"    def wrapper(*args, **kwargs):\n",[91,8515,8516],{"class":93,"line":1202},[91,8517,8518],{},"        print(\"开始：\", function.__name__)\n",[91,8520,8521],{"class":93,"line":2541},[91,8522,8523],{},"        result = function(*args, **kwargs)\n",[91,8525,8526],{"class":93,"line":2547},[91,8527,8528],{},"        print(\"结束：\", function.__name__)\n",[91,8530,8531],{"class":93,"line":4006},[91,8532,8533],{},"        return result\n",[91,8535,8536],{"class":93,"line":4218},[91,8537,8538],{},"    return wrapper\n",[91,8540,8541],{"class":93,"line":5883},[91,8542,110],{"emptyLinePlaceholder":109},[91,8544,8545],{"class":93,"line":5888},[91,8546,8547],{},"@trace\n",[91,8549,8550],{"class":93,"line":7429},[91,8551,97],{},[91,8553,8554],{"class":93,"line":7435},[91,8555,103],{},[91,8557,8559],{"class":93,"line":8558},15,[91,8560,110],{"emptyLinePlaceholder":109},[91,8562,8564],{"class":93,"line":8563},16,[91,8565,8566],{},"print(add(2, 3))\n",[10,8568,162],{},[82,8570,8573],{"className":8571,"code":8572,"language":168,"meta":87},[166],"开始： add\n结束： add\n5\n",[39,8574,8572],{"__ignoreMap":87},[10,8576,173],{},[14,8578,176],{"id":176},[178,8580,8581,8598],{},[54,8582,8583,8584,8587,8588,8591,8592,8595,8596,159],{},"解释器执行定义时，把原 ",[39,8585,8586],{},"add"," 函数交给 ",[39,8589,8590],{},"trace","，返回的 ",[39,8593,8594],{},"wrapper"," 重新绑定到名字 ",[39,8597,8586],{},[54,8599,8600],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[202,8602,204],{"id":204},[10,8604,8605],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8607,8608],{},[31,8609],{"alt":8610,"src":8611},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8613,8614,8616,8617,159],{},[39,8615,8467],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[39,8618,8471],{},[14,8620,222],{"id":222},[51,8622,8623,8628],{},[54,8624,8625,8626,159],{},"包装函数忘记返回原函数结果，调用方得到 ",[39,8627,5434],{},[54,8629,8630],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8632,241],{"id":241},[178,8634,8635,8638],{},[54,8636,8637],{},"编写只记录调用次数的简单装饰器。",[54,8639,8640,8641,8644],{},"删除包装函数的 ",[39,8642,8643],{},"return result","，观察调用方得到什么。",[10,8646,258],{},[14,8648,261],{"id":261},[10,8650,8651],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,8653,268],{},{"title":87,"searchDepth":100,"depth":100,"links":8655},[8656,8657,8658,8659,8660,8663,8664,8665],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":8661},[8662],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8437,"description":8442},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[281,8673,5385],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8676,"title":8677,"body":8678,"category":281,"cover":282,"description":8682,"extension":283,"meta":8869,"navigation":109,"path":8870,"pinned":286,"publishedAt":287,"seo":8871,"slug":8872,"stem":8873,"summary":8874,"tags":8875,"updatedAt":287,"visible":109,"__hash__":8878},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8679,"toc":8857},[8680,8683,8685,8688,8690,8696,8699,8701,8712,8714,8716,8791,8793,8799,8801,8803,8814,8816,8819,8825,8828,8830,8838,8840,8848,8850,8852,8855],[10,8681,8682],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8684,16],{"id":16},[10,8686,8687],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8689,27],{"id":27},[10,8691,8692],{},[31,8693],{"alt":8694,"src":8695},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8697,8698],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8700,49],{"id":49},[51,8702,8703,8706,8709],{},[54,8704,8705],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[54,8707,8708],{},"日志记录运行状态，测试判断结果是否符合约定。",[54,8710,8711],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8713,73],{"id":73},[10,8715,1490],{},[82,8717,8719],{"className":84,"code":8718,"language":86,"meta":87,"style":87},"import logging\nimport unittest\n\nlogging.basicConfig(level=logging.INFO)\n\ndef clamp_progress(value):\n    logging.info(\"检查进度：%s\", value)\n    return max(0, min(100, value))\n\nclass ProgressTest(unittest.TestCase):\n    def test_upper_limit(self):\n        self.assertEqual(clamp_progress(120), 100)\n\nif __name__ == \"__main__\":\n    unittest.main()\n",[39,8720,8721,8726,8731,8735,8740,8744,8749,8754,8759,8763,8768,8773,8778,8782,8786],{"__ignoreMap":87},[91,8722,8723],{"class":93,"line":94},[91,8724,8725],{},"import logging\n",[91,8727,8728],{"class":93,"line":100},[91,8729,8730],{},"import unittest\n",[91,8732,8733],{"class":93,"line":106},[91,8734,110],{"emptyLinePlaceholder":109},[91,8736,8737],{"class":93,"line":113},[91,8738,8739],{},"logging.basicConfig(level=logging.INFO)\n",[91,8741,8742],{"class":93,"line":119},[91,8743,110],{"emptyLinePlaceholder":109},[91,8745,8746],{"class":93,"line":1202},[91,8747,8748],{},"def clamp_progress(value):\n",[91,8750,8751],{"class":93,"line":2541},[91,8752,8753],{},"    logging.info(\"检查进度：%s\", value)\n",[91,8755,8756],{"class":93,"line":2547},[91,8757,8758],{},"    return max(0, min(100, value))\n",[91,8760,8761],{"class":93,"line":4006},[91,8762,110],{"emptyLinePlaceholder":109},[91,8764,8765],{"class":93,"line":4218},[91,8766,8767],{},"class ProgressTest(unittest.TestCase):\n",[91,8769,8770],{"class":93,"line":5883},[91,8771,8772],{},"    def test_upper_limit(self):\n",[91,8774,8775],{"class":93,"line":5888},[91,8776,8777],{},"        self.assertEqual(clamp_progress(120), 100)\n",[91,8779,8780],{"class":93,"line":7429},[91,8781,110],{"emptyLinePlaceholder":109},[91,8783,8784],{"class":93,"line":7435},[91,8785,116],{},[91,8787,8788],{"class":93,"line":8558},[91,8789,8790],{},"    unittest.main()\n",[10,8792,162],{},[82,8794,8797],{"className":8795,"code":8796,"language":168,"meta":87},[166],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[39,8798,8796],{"__ignoreMap":87},[10,8800,173],{},[14,8802,176],{"id":176},[178,8804,8805,8811],{},[54,8806,8807,8810],{},[39,8808,8809],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[54,8812,8813],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[202,8815,204],{"id":204},[10,8817,8818],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8820,8821],{},[31,8822],{"alt":8823,"src":8824},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8826,8827],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8829,222],{"id":222},[51,8831,8832,8835],{},[54,8833,8834],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[54,8836,8837],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8839,241],{"id":241},[178,8841,8842,8845],{},[54,8843,8844],{},"为负数进度增加测试。",[54,8846,8847],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8849,258],{},[14,8851,261],{"id":261},[10,8853,8854],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,8856,268],{},{"title":87,"searchDepth":100,"depth":100,"links":8858},[8859,8860,8861,8862,8863,8866,8867,8868],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":8864},[8865],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8677,"description":8682},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[281,8876,8877],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8880,"title":8881,"body":8882,"category":281,"cover":282,"description":8886,"extension":283,"meta":9186,"navigation":109,"path":9187,"pinned":286,"publishedAt":287,"seo":9188,"slug":9189,"stem":9190,"summary":9191,"tags":9192,"updatedAt":287,"visible":109,"__hash__":9195},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8883,"toc":9173},[8884,8887,8889,8892,8894,8900,8903,8905,8920,8922,8924,9071,9073,9079,9081,9083,9096,9098,9101,9107,9110,9112,9115,9121,9128,9130,9141,9143,9164,9166,9168,9171],[10,8885,8886],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8888,16],{"id":16},[10,8890,8891],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8893,27],{"id":27},[10,8895,8896],{},[31,8897],{"alt":8898,"src":8899},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8901,8902],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8904,49],{"id":49},[51,8906,8907,8910,8913],{},[54,8908,8909],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[54,8911,8912],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[54,8914,8915,8916,8919],{},"实际扩展前先为 ",[39,8917,8918],{},"add()"," 和存储边界补充测试。",[14,8921,73],{"id":73},[10,8923,1490],{},[82,8925,8927],{"className":84,"code":8926,"language":86,"meta":87,"style":87},"import json\nfrom pathlib import Path\n\nclass LearningRecords:\n    def __init__(self, file_path):\n        self.file_path = Path(file_path)\n        self.items = []\n\n    def add(self, title):\n        title = title.strip()\n        if not title:\n            raise ValueError(\"课程名称不能为空\")\n        self.items.append({\"title\": title, \"done\": False})\n\n    def save(self):\n        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n            json.dump(self.items, file, ensure_ascii=False, indent=2)\n\nrecords = LearningRecords(\"learning-records.json\")\n\ntry:\n    title = input(\"输入已学习课程：\")\n    records.add(title)\n    records.save()\nexcept ValueError as error:\n    print(\"无法保存：\", error)\nelse:\n    print(\"已保存 1 条学习记录\")\n",[39,8928,8929,8933,8937,8941,8946,8951,8956,8961,8965,8970,8975,8980,8985,8990,8994,8999,9004,9010,9015,9021,9026,9031,9037,9043,9049,9054,9060,9065],{"__ignoreMap":87},[91,8930,8931],{"class":93,"line":94},[91,8932,6984],{},[91,8934,8935],{"class":93,"line":100},[91,8936,6593],{},[91,8938,8939],{"class":93,"line":106},[91,8940,110],{"emptyLinePlaceholder":109},[91,8942,8943],{"class":93,"line":113},[91,8944,8945],{},"class LearningRecords:\n",[91,8947,8948],{"class":93,"line":119},[91,8949,8950],{},"    def __init__(self, file_path):\n",[91,8952,8953],{"class":93,"line":1202},[91,8954,8955],{},"        self.file_path = Path(file_path)\n",[91,8957,8958],{"class":93,"line":2541},[91,8959,8960],{},"        self.items = []\n",[91,8962,8963],{"class":93,"line":2547},[91,8964,110],{"emptyLinePlaceholder":109},[91,8966,8967],{"class":93,"line":4006},[91,8968,8969],{},"    def add(self, title):\n",[91,8971,8972],{"class":93,"line":4218},[91,8973,8974],{},"        title = title.strip()\n",[91,8976,8977],{"class":93,"line":5883},[91,8978,8979],{},"        if not title:\n",[91,8981,8982],{"class":93,"line":5888},[91,8983,8984],{},"            raise ValueError(\"课程名称不能为空\")\n",[91,8986,8987],{"class":93,"line":7429},[91,8988,8989],{},"        self.items.append({\"title\": title, \"done\": False})\n",[91,8991,8992],{"class":93,"line":7435},[91,8993,110],{"emptyLinePlaceholder":109},[91,8995,8996],{"class":93,"line":8558},[91,8997,8998],{},"    def save(self):\n",[91,9000,9001],{"class":93,"line":8563},[91,9002,9003],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[91,9005,9007],{"class":93,"line":9006},17,[91,9008,9009],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[91,9011,9013],{"class":93,"line":9012},18,[91,9014,110],{"emptyLinePlaceholder":109},[91,9016,9018],{"class":93,"line":9017},19,[91,9019,9020],{},"records = LearningRecords(\"learning-records.json\")\n",[91,9022,9024],{"class":93,"line":9023},20,[91,9025,110],{"emptyLinePlaceholder":109},[91,9027,9029],{"class":93,"line":9028},21,[91,9030,7402],{},[91,9032,9034],{"class":93,"line":9033},22,[91,9035,9036],{},"    title = input(\"输入已学习课程：\")\n",[91,9038,9040],{"class":93,"line":9039},23,[91,9041,9042],{},"    records.add(title)\n",[91,9044,9046],{"class":93,"line":9045},24,[91,9047,9048],{},"    records.save()\n",[91,9050,9052],{"class":93,"line":9051},25,[91,9053,7412],{},[91,9055,9057],{"class":93,"line":9056},26,[91,9058,9059],{},"    print(\"无法保存：\", error)\n",[91,9061,9063],{"class":93,"line":9062},27,[91,9064,1199],{},[91,9066,9068],{"class":93,"line":9067},28,[91,9069,9070],{},"    print(\"已保存 1 条学习记录\")\n",[10,9072,162],{},[82,9074,9077],{"className":9075,"code":9076,"language":168,"meta":87},[166],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[39,9078,9076],{"__ignoreMap":87},[10,9080,173],{},[14,9082,176],{"id":176},[178,9084,9085,9091],{},[54,9086,9087,9088,9090],{},"输入层取得课程名后，",[39,9089,8918],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[54,9092,9093,9095],{},[39,9094,8150],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[202,9097,204],{"id":204},[10,9099,9100],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9102,9103],{},[31,9104],{"alt":9105,"src":9106},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9108,9109],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[202,9111,204],{"id":4273},[10,9113,9114],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9116,9117],{},[31,9118],{"alt":9119,"src":9120},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9122,9123,9124,9127],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[39,9125,9126],{},"load()"," 把文件状态恢复到内存。",[14,9129,222],{"id":222},[51,9131,9132,9135],{},[54,9133,9134],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[54,9136,9137,9138,9140],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[39,9139,9126],{}," 是下一项必要扩展。",[14,9142,241],{"id":241},[178,9144,9145,9151,9154],{},[54,9146,9147,9148,9150],{},"增加 ",[39,9149,9126],{},"，文件不存在时从空列表开始。",[54,9152,9153],{},"增加按序号标记完成的功能，并校验序号范围。",[54,9155,9156,9157,9160,9161,9163],{},"把输入循环放进 ",[39,9158,9159],{},"main()","，通过 ",[39,9162,41],{}," 控制程序入口。",[10,9165,258],{},[14,9167,261],{"id":261},[10,9169,9170],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[266,9172,268],{},{"title":87,"searchDepth":100,"depth":100,"links":9174},[9175,9176,9177,9178,9179,9183,9184,9185],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":9180},[9181,9182],{"id":204,"depth":106,"text":204},{"id":4273,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8881,"description":8886},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[281,9193,9194],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9197,9300,9419,9550,9693,9818,9955,10092,10233,10402,10539,10672,10795,10924,11051,11214,11390,11531,11660,11809,11952,12073,12196,12345,12498,12663,12790,12971,13114,13271,13422,13569,13724,13942,14097,14272,14423,14590,14777,14940,15182,15422],{"id":1445,"title":1446,"body":9198,"category":281,"cover":282,"description":1451,"extension":283,"meta":9297,"navigation":109,"path":1571,"pinned":286,"publishedAt":287,"seo":9298,"slug":1573,"stem":1574,"summary":1575,"tags":9299,"updatedAt":287,"visible":109,"__hash__":1578},{"type":7,"value":9199,"toc":9287},[9200,9202,9204,9206,9208,9212,9216,9218,9228,9230,9232,9240,9242,9247,9249,9251,9261,9263,9271,9273,9279,9281,9283,9285],[10,9201,1451],{},[14,9203,16],{"id":16},[10,9205,1456],{},[14,9207,27],{"id":27},[10,9209,9210],{},[31,9211],{"alt":1463,"src":1464},[10,9213,9214,1469],{},[39,9215,59],{},[14,9217,49],{"id":49},[51,9219,9220,9224,9226],{},[54,9221,1476,9222,1479],{},[39,9223,59],{},[54,9225,1482],{},[54,9227,1485],{},[14,9229,73],{"id":73},[10,9231,1490],{},[82,9233,9234],{"className":84,"code":1493,"language":86,"meta":87,"style":87},[39,9235,9236],{"__ignoreMap":87},[91,9237,9238],{"class":93,"line":94},[91,9239,1493],{},[10,9241,162],{},[82,9243,9245],{"className":9244,"code":1505,"language":168,"meta":87},[166],[39,9246,1505],{"__ignoreMap":87},[10,9248,173],{},[14,9250,176],{"id":176},[178,9252,9253,9257],{},[54,9254,1516,9255,1520],{},[39,9256,1519],{},[54,9258,1523,9259,1527],{},[39,9260,1526],{},[14,9262,222],{"id":222},[51,9264,9265,9267],{},[54,9266,1534],{},[54,9268,1537,9269,1540],{},[39,9270,59],{},[14,9272,241],{"id":241},[178,9274,9275,9277],{},[54,9276,1547],{},[54,9278,1550],{},[10,9280,258],{},[14,9282,261],{"id":261},[10,9284,1557],{},[266,9286,268],{},{"title":87,"searchDepth":100,"depth":100,"links":9288},[9289,9290,9291,9292,9293,9294,9295,9296],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":1446,"description":1451},[281,1441,1577],{"id":1580,"title":1581,"body":9301,"category":281,"cover":282,"description":1586,"extension":283,"meta":9416,"navigation":109,"path":1723,"pinned":286,"publishedAt":287,"seo":9417,"slug":1725,"stem":1726,"summary":1727,"tags":9418,"updatedAt":287,"visible":109,"__hash__":1730},{"type":7,"value":9302,"toc":9406},[9303,9305,9307,9309,9311,9315,9319,9321,9331,9333,9335,9355,9357,9362,9364,9366,9376,9378,9388,9390,9398,9400,9402,9404],[10,9304,1586],{},[14,9306,16],{"id":16},[10,9308,1591],{},[14,9310,27],{"id":27},[10,9312,9313],{},[31,9314],{"alt":1598,"src":1599},[10,9316,1602,9317,1605],{},[39,9318,744],{},[14,9320,49],{"id":49},[51,9322,9323,9325,9327],{},[54,9324,1612],{},[54,9326,1615],{},[54,9328,1618,9329,1622],{},[39,9330,1621],{},[14,9332,73],{"id":73},[10,9334,1627],{},[82,9336,9337],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,9338,9339,9345],{"__ignoreMap":87},[91,9340,9341,9343],{"class":93,"line":94},[91,9342,744],{"class":653},[91,9344,657],{"class":656},[91,9346,9347,9349,9351,9353],{"class":93,"line":100},[91,9348,744],{"class":653},[91,9350,686],{"class":656},[91,9352,690],{"class":689},[91,9354,657],{"class":656},[10,9356,162],{},[82,9358,9360],{"className":9359,"code":1653,"language":168,"meta":87},[166],[39,9361,1653],{"__ignoreMap":87},[10,9363,173],{},[14,9365,176],{"id":176},[178,9367,9368,9372],{},[54,9369,9370,1667],{},[39,9371,1666],{},[54,9373,9374,1672],{},[39,9375,752],{},[14,9377,222],{"id":222},[51,9379,9380,9384],{},[54,9381,1679,9382,1682],{},[39,9383,744],{},[54,9385,1685,9386,1688],{},[39,9387,744],{},[14,9389,241],{"id":241},[178,9391,9392,9396],{},[54,9393,991,9394,1698],{},[39,9395,1697],{},[54,9397,1701],{},[10,9399,258],{},[14,9401,261],{"id":261},[10,9403,1708],{},[266,9405,1711],{},{"title":87,"searchDepth":100,"depth":100,"links":9407},[9408,9409,9410,9411,9412,9413,9414,9415],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":1581,"description":1586},[281,1729,1105],{"id":1732,"title":1733,"body":9420,"category":281,"cover":282,"description":1899,"extension":283,"meta":9547,"navigation":109,"path":1901,"pinned":286,"publishedAt":287,"seo":9548,"slug":1903,"stem":1904,"summary":1905,"tags":9549,"updatedAt":287,"visible":109,"__hash__":1909},{"type":7,"value":9421,"toc":9537},[9422,9426,9428,9430,9432,9436,9438,9440,9456,9458,9460,9480,9482,9487,9489,9491,9503,9505,9515,9517,9527,9529,9531,9535],[10,9423,1738,9424,1741],{},[39,9425,59],{},[14,9427,16],{"id":16},[10,9429,1746],{},[14,9431,27],{"id":27},[10,9433,9434],{},[31,9435],{"alt":1753,"src":1754},[10,9437,1757],{},[14,9439,49],{"id":49},[51,9441,9442,9448,9452],{},[54,9443,1764,9444,1767,9446,159],{},[39,9445,744],{},[39,9447,1770],{},[54,9449,1773,9450,1777],{},[39,9451,1776],{},[54,9453,1780,9454,1783],{},[39,9455,59],{},[14,9457,73],{"id":73},[10,9459,1490],{},[82,9461,9462],{"className":1790,"code":1791,"language":1792,"meta":87,"style":87},[39,9463,9464,9468,9472,9476],{"__ignoreMap":87},[91,9465,9466],{"class":93,"line":94},[91,9467,1799],{},[91,9469,9470],{"class":93,"line":100},[91,9471,1804],{},[91,9473,9474],{"class":93,"line":106},[91,9475,1809],{},[91,9477,9478],{"class":93,"line":113},[91,9479,1814],{},[10,9481,162],{},[82,9483,9485],{"className":9484,"code":1820,"language":168,"meta":87},[166],[39,9486,1820],{"__ignoreMap":87},[10,9488,173],{},[14,9490,176],{"id":176},[178,9492,9493,9499],{},[54,9494,1831,9495,1835,9497,159],{},[39,9496,1834],{},[39,9498,1838],{},[54,9500,1841,9501,1844],{},[39,9502,1526],{},[14,9504,222],{"id":222},[51,9506,9507,9513],{},[54,9508,1851,9509,1854,9511,1857],{},[39,9510,1770],{},[39,9512,59],{},[54,9514,1860],{},[14,9516,241],{"id":241},[178,9518,9519,9523],{},[54,9520,1867,9521,159],{},[39,9522,1870],{},[54,9524,1873,9525,1876],{},[39,9526,1526],{},[10,9528,258],{},[14,9530,261],{"id":261},[10,9532,1883,9533,1886],{},[39,9534,59],{},[266,9536,268],{},{"title":87,"searchDepth":100,"depth":100,"links":9538},[9539,9540,9541,9542,9543,9544,9545,9546],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":1733,"description":1899},[281,1907,1908],{"id":1911,"title":1912,"body":9551,"category":281,"cover":282,"description":1917,"extension":283,"meta":9690,"navigation":109,"path":2089,"pinned":286,"publishedAt":287,"seo":9691,"slug":2091,"stem":2092,"summary":2093,"tags":9692,"updatedAt":287,"visible":109,"__hash__":2097},{"type":7,"value":9552,"toc":9680},[9553,9555,9557,9559,9561,9565,9569,9571,9583,9585,9587,9623,9625,9630,9632,9634,9650,9652,9662,9664,9672,9674,9676,9678],[10,9554,1917],{},[14,9556,16],{"id":16},[10,9558,1922],{},[14,9560,27],{"id":27},[10,9562,9563],{},[31,9564],{"alt":1929,"src":1930},[10,9566,9567,1936],{},[39,9568,1935],{},[14,9570,49],{"id":49},[51,9572,9573,9575,9581],{},[54,9574,1943],{},[54,9576,9577,1949,9579,1953],{},[39,9578,1948],{},[39,9580,1952],{},[54,9582,1956],{},[14,9584,73],{"id":73},[10,9586,1627],{},[82,9588,9589],{"className":644,"code":1963,"language":646,"meta":87,"style":87},[39,9590,9591,9597,9603,9607,9617],{"__ignoreMap":87},[91,9592,9593,9595],{"class":93,"line":94},[91,9594,1970],{"class":653},[91,9596,1973],{"class":689},[91,9598,9599,9601],{"class":93,"line":100},[91,9600,1978],{"class":656},[91,9602,1973],{"class":689},[91,9604,9605],{"class":93,"line":106},[91,9606,1985],{"class":656},[91,9608,9609,9611,9613,9615],{"class":93,"line":113},[91,9610,1990],{"class":656},[91,9612,1993],{"class":689},[91,9614,1997],{"class":1996},[91,9616,1267],{"class":689},[91,9618,9619,9621],{"class":93,"line":119},[91,9620,744],{"class":653},[91,9622,1267],{"class":689},[10,9624,162],{},[82,9626,9628],{"className":9627,"code":2011,"language":168,"meta":87},[166],[39,9629,2011],{"__ignoreMap":87},[10,9631,173],{},[14,9633,176],{"id":176},[178,9635,9636,9644],{},[54,9637,9638,2024,9640,2027,9642,2030],{},[39,9639,1970],{},[39,9641,1978],{},[39,9643,1948],{},[54,9645,9646,2035,9648,2039],{},[39,9647,1935],{},[39,9649,2038],{},[14,9651,222],{"id":222},[51,9653,9654,9660],{},[54,9655,2046,9656,155,9658,159],{},[39,9657,1948],{},[39,9659,1952],{},[54,9661,2053],{},[14,9663,241],{"id":241},[178,9665,9666,9670],{},[54,9667,2060,9668,2064],{},[39,9669,2063],{},[54,9671,2067],{},[10,9673,258],{},[14,9675,261],{"id":261},[10,9677,2074],{},[266,9679,2077],{},{"title":87,"searchDepth":100,"depth":100,"links":9681},[9682,9683,9684,9685,9686,9687,9688,9689],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":1912,"description":1917},[281,2095,2096],{"id":2099,"title":2100,"body":9694,"category":281,"cover":282,"description":2105,"extension":283,"meta":9815,"navigation":109,"path":2254,"pinned":286,"publishedAt":287,"seo":9816,"slug":2256,"stem":2257,"summary":2258,"tags":9817,"updatedAt":287,"visible":109,"__hash__":2262},{"type":7,"value":9695,"toc":9805},[9696,9698,9700,9702,9704,9708,9716,9718,9732,9734,9736,9752,9754,9759,9761,9763,9777,9779,9785,9787,9797,9799,9801,9803],[10,9697,2105],{},[14,9699,16],{"id":16},[10,9701,2110],{},[14,9703,27],{"id":27},[10,9705,9706],{},[31,9707],{"alt":2117,"src":2118},[10,9709,2121,9710,159,9712,2127,9714,159],{},[39,9711,1526],{},[39,9713,2126],{},[39,9715,1834],{},[14,9717,49],{"id":49},[51,9719,9720,9724,9730],{},[54,9721,9722,2139],{},[39,9723,2138],{},[54,9725,9726,2145,9728,159],{},[39,9727,2144],{},[39,9729,2148],{},[54,9731,2151],{},[14,9733,73],{"id":73},[10,9735,1490],{},[82,9737,9738],{"className":84,"code":2158,"language":86,"meta":87,"style":87},[39,9739,9740,9744,9748],{"__ignoreMap":87},[91,9741,9742],{"class":93,"line":94},[91,9743,2165],{},[91,9745,9746],{"class":93,"line":100},[91,9747,2170],{},[91,9749,9750],{"class":93,"line":106},[91,9751,2175],{},[10,9753,162],{},[82,9755,9757],{"className":9756,"code":2181,"language":168,"meta":87},[166],[39,9758,2181],{"__ignoreMap":87},[10,9760,173],{},[14,9762,176],{"id":176},[178,9764,9765,9771],{},[54,9766,9767,2195,9769,159],{},[39,9768,2194],{},[39,9770,2148],{},[54,9772,9773,2202,9775,2206],{},[39,9774,1526],{},[39,9776,2205],{},[14,9778,222],{"id":222},[51,9780,9781,9783],{},[54,9782,2213],{},[54,9784,2216],{},[14,9786,241],{"id":241},[178,9788,9789,9791],{},[54,9790,2223],{},[54,9792,2226,9793,2229,9795,2233],{},[39,9794,2126],{},[39,9796,2232],{},[10,9798,258],{},[14,9800,261],{"id":261},[10,9802,2240],{},[266,9804,268],{},{"title":87,"searchDepth":100,"depth":100,"links":9806},[9807,9808,9809,9810,9811,9812,9813,9814],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":2100,"description":2105},[281,2260,2261],{"id":2264,"title":2265,"body":9819,"category":281,"cover":282,"description":2270,"extension":283,"meta":9952,"navigation":109,"path":2437,"pinned":286,"publishedAt":287,"seo":9953,"slug":2439,"stem":2440,"summary":2441,"tags":9954,"updatedAt":287,"visible":109,"__hash__":2445},{"type":7,"value":9820,"toc":9942},[9821,9823,9825,9827,9829,9833,9835,9837,9853,9855,9857,9881,9883,9888,9890,9892,9908,9910,9922,9924,9934,9936,9938,9940],[10,9822,2270],{},[14,9824,16],{"id":16},[10,9826,2275],{},[14,9828,27],{"id":27},[10,9830,9831],{},[31,9832],{"alt":2282,"src":2283},[10,9834,2286],{},[14,9836,49],{"id":49},[51,9838,9839,9841,9847],{},[54,9840,2293],{},[54,9842,2296,9843,2229,9845,2303],{},[39,9844,2299],{},[39,9846,2302],{},[54,9848,2306,9849,2310,9851,2314],{},[39,9850,2309],{},[39,9852,2313],{},[14,9854,73],{"id":73},[10,9856,1490],{},[82,9858,9859],{"className":84,"code":2321,"language":86,"meta":87,"style":87},[39,9860,9861,9865,9869,9873,9877],{"__ignoreMap":87},[91,9862,9863],{"class":93,"line":94},[91,9864,2328],{},[91,9866,9867],{"class":93,"line":100},[91,9868,2333],{},[91,9870,9871],{"class":93,"line":106},[91,9872,110],{"emptyLinePlaceholder":109},[91,9874,9875],{"class":93,"line":113},[91,9876,2342],{},[91,9878,9879],{"class":93,"line":119},[91,9880,2333],{},[10,9882,162],{},[82,9884,9886],{"className":9885,"code":2352,"language":168,"meta":87},[166],[39,9887,2352],{"__ignoreMap":87},[10,9889,173],{},[14,9891,176],{"id":176},[178,9893,9894,9900],{},[54,9895,991,9896,2366,9898,2369],{},[39,9897,2365],{},[39,9899,2299],{},[54,9901,991,9902,2375,9904,2379,9906,159],{},[39,9903,2374],{},[39,9905,2378],{},[39,9907,2382],{},[14,9909,222],{"id":222},[51,9911,9912,9914],{},[54,9913,2389],{},[54,9915,2392,9916,2310,9918,2310,9920,2400],{},[39,9917,2309],{},[39,9919,2313],{},[39,9921,2399],{},[14,9923,241],{"id":241},[178,9925,9926,9932],{},[54,9927,246,9928,155,9930,2413],{},[39,9929,2409],{},[39,9931,2412],{},[54,9933,2416],{},[10,9935,258],{},[14,9937,261],{"id":261},[10,9939,2423],{},[266,9941,268],{},{"title":87,"searchDepth":100,"depth":100,"links":9943},[9944,9945,9946,9947,9948,9949,9950,9951],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":2265,"description":2270},[281,2443,2444],{"id":2447,"title":2448,"body":9956,"category":281,"cover":282,"description":2453,"extension":283,"meta":10089,"navigation":109,"path":2620,"pinned":286,"publishedAt":287,"seo":10090,"slug":2622,"stem":2623,"summary":2624,"tags":10091,"updatedAt":287,"visible":109,"__hash__":2628},{"type":7,"value":9957,"toc":10079},[9958,9960,9962,9964,9966,9970,9972,9974,9992,9994,9996,10032,10034,10039,10041,10043,10053,10055,10063,10065,10071,10073,10075,10077],[10,9959,2453],{},[14,9961,16],{"id":16},[10,9963,2458],{},[14,9965,27],{"id":27},[10,9967,9968],{},[31,9969],{"alt":2465,"src":2466},[10,9971,2469],{},[14,9973,49],{"id":49},[51,9975,9976,9982,9990],{},[54,9977,9978,2479,9980,2483],{},[39,9979,2478],{},[39,9981,2482],{},[54,9983,9984,2489,9986,2493,9988,2497],{},[39,9985,2488],{},[39,9987,2492],{},[39,9989,2496],{},[54,9991,2500],{},[14,9993,73],{"id":73},[10,9995,1490],{},[82,9997,9998],{"className":84,"code":2507,"language":86,"meta":87,"style":87},[39,9999,10000,10004,10008,10012,10016,10020,10024,10028],{"__ignoreMap":87},[91,10001,10002],{"class":93,"line":94},[91,10003,2514],{},[91,10005,10006],{"class":93,"line":100},[91,10007,2519],{},[91,10009,10010],{"class":93,"line":106},[91,10011,2524],{},[91,10013,10014],{"class":93,"line":113},[91,10015,110],{"emptyLinePlaceholder":109},[91,10017,10018],{"class":93,"line":119},[91,10019,2533],{},[91,10021,10022],{"class":93,"line":1202},[91,10023,2538],{},[91,10025,10026],{"class":93,"line":2541},[91,10027,2544],{},[91,10029,10030],{"class":93,"line":2547},[91,10031,2550],{},[10,10033,162],{},[82,10035,10037],{"className":10036,"code":2556,"language":168,"meta":87},[166],[39,10038,2556],{"__ignoreMap":87},[10,10040,173],{},[14,10042,176],{"id":176},[178,10044,10045,10049],{},[54,10046,10047,2570],{},[39,10048,2569],{},[54,10050,10051,2576],{},[39,10052,2575],{},[14,10054,222],{"id":222},[51,10056,10057,10061],{},[54,10058,2583,10059,159],{},[39,10060,2586],{},[54,10062,2589],{},[14,10064,241],{"id":241},[178,10066,10067,10069],{},[54,10068,2596],{},[54,10070,2599],{},[10,10072,258],{},[14,10074,261],{"id":261},[10,10076,2606],{},[266,10078,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10080},[10081,10082,10083,10084,10085,10086,10087,10088],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":2448,"description":2453},[281,2626,2627],{"id":2630,"title":2631,"body":10093,"category":281,"cover":282,"description":2636,"extension":283,"meta":10230,"navigation":109,"path":2812,"pinned":286,"publishedAt":287,"seo":10231,"slug":2814,"stem":2815,"summary":2816,"tags":10232,"updatedAt":287,"visible":109,"__hash__":2820},{"type":7,"value":10094,"toc":10218},[10095,10097,10099,10101,10103,10107,10113,10115,10123,10125,10127,10151,10153,10158,10160,10162,10180,10182,10184,10188,10190,10192,10198,10200,10210,10212,10214,10216],[10,10096,2636],{},[14,10098,16],{"id":16},[10,10100,2641],{},[14,10102,27],{"id":27},[10,10104,10105],{},[31,10106],{"alt":2648,"src":2649},[10,10108,2652,10109,2656,10111,159],{},[39,10110,2655],{},[39,10112,2659],{},[14,10114,49],{"id":49},[51,10116,10117,10119,10121],{},[54,10118,2666],{},[54,10120,2669],{},[54,10122,2672],{},[14,10124,73],{"id":73},[10,10126,1490],{},[82,10128,10129],{"className":84,"code":2679,"language":86,"meta":87,"style":87},[39,10130,10131,10135,10139,10143,10147],{"__ignoreMap":87},[91,10132,10133],{"class":93,"line":94},[91,10134,2686],{},[91,10136,10137],{"class":93,"line":100},[91,10138,2691],{},[91,10140,10141],{"class":93,"line":106},[91,10142,2696],{},[91,10144,10145],{"class":93,"line":113},[91,10146,2701],{},[91,10148,10149],{"class":93,"line":119},[91,10150,2706],{},[10,10152,162],{},[82,10154,10156],{"className":10155,"code":2712,"language":168,"meta":87},[166],[39,10157,2712],{"__ignoreMap":87},[10,10159,173],{},[14,10161,176],{"id":176},[178,10163,10164,10172],{},[54,10165,2723,10166,2726,10168,2730,10170,2734],{},[39,10167,281],{},[39,10169,2729],{},[39,10171,2733],{},[54,10173,10174,2740,10176,2744,10178,2748],{},[39,10175,2739],{},[39,10177,2743],{},[39,10179,2747],{},[202,10181,204],{"id":204},[10,10183,2753],{},[10,10185,10186],{},[31,10187],{"alt":2758,"src":2759},[10,10189,2762],{},[14,10191,222],{"id":222},[51,10193,10194,10196],{},[54,10195,2769],{},[54,10197,2772],{},[14,10199,241],{"id":241},[178,10201,10202,10208],{},[54,10203,2779,10204,2783,10206,159],{},[39,10205,2782],{},[39,10207,2786],{},[54,10209,2789],{},[10,10211,258],{},[14,10213,261],{"id":261},[10,10215,2796],{},[266,10217,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10219},[10220,10221,10222,10223,10224,10227,10228,10229],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":10225},[10226],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":2631,"description":2636},[281,2818,2819],{"id":2822,"title":2823,"body":10234,"category":281,"cover":282,"description":2828,"extension":283,"meta":10399,"navigation":109,"path":3043,"pinned":286,"publishedAt":287,"seo":10400,"slug":3045,"stem":3046,"summary":3047,"tags":10401,"updatedAt":287,"visible":109,"__hash__":3051},{"type":7,"value":10235,"toc":10387},[10236,10238,10240,10242,10244,10248,10254,10256,10276,10278,10280,10316,10318,10323,10325,10327,10341,10343,10345,10349,10355,10357,10367,10369,10379,10381,10383,10385],[10,10237,2828],{},[14,10239,16],{"id":16},[10,10241,2833],{},[14,10243,27],{"id":27},[10,10245,10246],{},[31,10247],{"alt":2840,"src":2841},[10,10249,2844,10250,1062,10252,2851],{},[39,10251,2847],{},[39,10253,2850],{},[14,10255,49],{"id":49},[51,10257,10258,10266,10274],{},[54,10259,10260,2861,10262,2865,10264,2869],{},[39,10261,2860],{},[39,10263,2864],{},[39,10265,2868],{},[54,10267,10268,2875,10270,2879,10272,2883],{},[39,10269,2874],{},[39,10271,2878],{},[39,10273,2882],{},[54,10275,2886],{},[14,10277,73],{"id":73},[10,10279,1490],{},[82,10281,10282],{"className":84,"code":2893,"language":86,"meta":87,"style":87},[39,10283,10284,10288,10292,10296,10300,10304,10308,10312],{"__ignoreMap":87},[91,10285,10286],{"class":93,"line":94},[91,10287,2900],{},[91,10289,10290],{"class":93,"line":100},[91,10291,2905],{},[91,10293,10294],{"class":93,"line":106},[91,10295,110],{"emptyLinePlaceholder":109},[91,10297,10298],{"class":93,"line":113},[91,10299,2914],{},[91,10301,10302],{"class":93,"line":119},[91,10303,2919],{},[91,10305,10306],{"class":93,"line":1202},[91,10307,2924],{},[91,10309,10310],{"class":93,"line":2541},[91,10311,2929],{},[91,10313,10314],{"class":93,"line":2547},[91,10315,2934],{},[10,10317,162],{},[82,10319,10321],{"className":10320,"code":2940,"language":168,"meta":87},[166],[39,10322,2940],{"__ignoreMap":87},[10,10324,173],{},[14,10326,176],{"id":176},[178,10328,10329,10335],{},[54,10330,10331,2954,10333,2958],{},[39,10332,2953],{},[39,10334,2957],{},[54,10336,10337,2964,10339,2967],{},[39,10338,2963],{},[39,10340,2882],{},[202,10342,204],{"id":204},[10,10344,2972],{},[10,10346,10347],{},[31,10348],{"alt":2977,"src":2978},[10,10350,10351,2983,10353,2986],{},[39,10352,2874],{},[39,10354,2878],{},[14,10356,222],{"id":222},[51,10358,10359,10365],{},[54,10360,2993,10361,2996,10363,2999],{},[39,10362,2868],{},[39,10364,2860],{},[54,10366,3002],{},[14,10368,241],{"id":241},[178,10370,10371,10375],{},[54,10372,3009,10373,3013],{},[39,10374,3012],{},[54,10376,3016,10377,3020],{},[39,10378,3019],{},[10,10380,258],{},[14,10382,261],{"id":261},[10,10384,3027],{},[266,10386,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10388},[10389,10390,10391,10392,10393,10396,10397,10398],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":10394},[10395],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":2823,"description":2828},[281,3049,3050],{"id":3053,"title":3054,"body":10403,"category":281,"cover":282,"description":3059,"extension":283,"meta":10536,"navigation":109,"path":3228,"pinned":286,"publishedAt":287,"seo":10537,"slug":3230,"stem":3231,"summary":3232,"tags":10538,"updatedAt":287,"visible":109,"__hash__":3235},{"type":7,"value":10404,"toc":10526},[10405,10407,10409,10411,10413,10417,10427,10429,10439,10441,10443,10471,10473,10478,10480,10482,10496,10498,10506,10508,10518,10520,10522,10524],[10,10406,3059],{},[14,10408,16],{"id":16},[10,10410,3064],{},[14,10412,27],{"id":27},[10,10414,10415],{},[31,10416],{"alt":3071,"src":3072},[10,10418,10419,3078,10421,3082,10423,3086,10425,3090],{},[39,10420,3077],{},[39,10422,3081],{},[39,10424,3085],{},[39,10426,3089],{},[14,10428,49],{"id":49},[51,10430,10431,10433,10437],{},[54,10432,3097],{},[54,10434,10435,3102],{},[39,10436,3089],{},[54,10438,3105],{},[14,10440,73],{"id":73},[10,10442,1490],{},[82,10444,10445],{"className":84,"code":3112,"language":86,"meta":87,"style":87},[39,10446,10447,10451,10455,10459,10463,10467],{"__ignoreMap":87},[91,10448,10449],{"class":93,"line":94},[91,10450,3119],{},[91,10452,10453],{"class":93,"line":100},[91,10454,3124],{},[91,10456,10457],{"class":93,"line":106},[91,10458,3129],{},[91,10460,10461],{"class":93,"line":113},[91,10462,110],{"emptyLinePlaceholder":109},[91,10464,10465],{"class":93,"line":119},[91,10466,3138],{},[91,10468,10469],{"class":93,"line":1202},[91,10470,3143],{},[10,10472,162],{},[82,10474,10476],{"className":10475,"code":3149,"language":168,"meta":87},[166],[39,10477,3149],{"__ignoreMap":87},[10,10479,173],{},[14,10481,176],{"id":176},[178,10483,10484,10490],{},[54,10485,3160,10486,3163,10488,3167],{},[39,10487,3077],{},[39,10489,3166],{},[54,10491,10492,3173,10494,3177],{},[39,10493,3172],{},[39,10495,3176],{},[14,10497,222],{"id":222},[51,10499,10500,10504],{},[54,10501,3184,10502,3188],{},[39,10503,3187],{},[54,10505,3191],{},[14,10507,241],{"id":241},[178,10509,10510,10512],{},[54,10511,3198],{},[54,10513,1773,10514,3204,10516,3207],{},[39,10515,3203],{},[39,10517,3089],{},[10,10519,258],{},[14,10521,261],{"id":261},[10,10523,3214],{},[266,10525,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10527},[10528,10529,10530,10531,10532,10533,10534,10535],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":3054,"description":3059},[281,2399,3234],{"id":3237,"title":3238,"body":10540,"category":281,"cover":282,"description":3243,"extension":283,"meta":10669,"navigation":109,"path":3404,"pinned":286,"publishedAt":287,"seo":10670,"slug":3406,"stem":3407,"summary":3408,"tags":10671,"updatedAt":287,"visible":109,"__hash__":3412},{"type":7,"value":10541,"toc":10659},[10542,10544,10546,10548,10550,10554,10558,10560,10570,10572,10574,10606,10608,10613,10615,10617,10629,10631,10641,10643,10651,10653,10655,10657],[10,10543,3243],{},[14,10545,16],{"id":16},[10,10547,3248],{},[14,10549,27],{"id":27},[10,10551,10552],{},[31,10553],{"alt":3255,"src":3256},[10,10555,3259,10556,3263],{},[39,10557,3262],{},[14,10559,49],{"id":49},[51,10561,10562,10564,10566],{},[54,10563,3270],{},[54,10565,3273],{},[54,10567,3276,10568,159],{},[39,10569,3279],{},[14,10571,73],{"id":73},[10,10573,1490],{},[82,10575,10576],{"className":84,"code":3286,"language":86,"meta":87,"style":87},[39,10577,10578,10582,10586,10590,10594,10598,10602],{"__ignoreMap":87},[91,10579,10580],{"class":93,"line":94},[91,10581,3293],{},[91,10583,10584],{"class":93,"line":100},[91,10585,3298],{},[91,10587,10588],{"class":93,"line":106},[91,10589,110],{"emptyLinePlaceholder":109},[91,10591,10592],{"class":93,"line":113},[91,10593,3307],{},[91,10595,10596],{"class":93,"line":119},[91,10597,3312],{},[91,10599,10600],{"class":93,"line":1202},[91,10601,3317],{},[91,10603,10604],{"class":93,"line":2541},[91,10605,3322],{},[10,10607,162],{},[82,10609,10611],{"className":10610,"code":3328,"language":168,"meta":87},[166],[39,10612,3328],{"__ignoreMap":87},[10,10614,173],{},[14,10616,176],{"id":176},[178,10618,10619,10621],{},[54,10620,3339],{},[54,10622,10623,3345,10625,3349,10627,3353],{},[39,10624,3344],{},[39,10626,3348],{},[39,10628,3352],{},[14,10630,222],{"id":222},[51,10632,10633,10639],{},[54,10634,3360,10635,3364,10637,159],{},[39,10636,3363],{},[39,10638,3367],{},[54,10640,3370],{},[14,10642,241],{"id":241},[178,10644,10645,10647],{},[54,10646,3377],{},[54,10648,3380,10649,3383],{},[39,10650,3352],{},[10,10652,258],{},[14,10654,261],{"id":261},[10,10656,3390],{},[266,10658,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10660},[10661,10662,10663,10664,10665,10666,10667,10668],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":3238,"description":3243},[281,3410,3411],{"id":3414,"title":3415,"body":10673,"category":281,"cover":282,"description":3420,"extension":283,"meta":10792,"navigation":109,"path":3562,"pinned":286,"publishedAt":287,"seo":10793,"slug":3564,"stem":3565,"summary":3566,"tags":10794,"updatedAt":287,"visible":109,"__hash__":3569},{"type":7,"value":10674,"toc":10782},[10675,10677,10679,10681,10683,10687,10689,10691,10699,10701,10703,10731,10733,10738,10740,10742,10752,10754,10762,10764,10774,10776,10778,10780],[10,10676,3420],{},[14,10678,16],{"id":16},[10,10680,3425],{},[14,10682,27],{"id":27},[10,10684,10685],{},[31,10686],{"alt":3432,"src":3433},[10,10688,3436],{},[14,10690,49],{"id":49},[51,10692,10693,10695,10697],{},[54,10694,3443],{},[54,10696,3446],{},[54,10698,3449],{},[14,10700,73],{"id":73},[10,10702,1490],{},[82,10704,10705],{"className":84,"code":3456,"language":86,"meta":87,"style":87},[39,10706,10707,10711,10715,10719,10723,10727],{"__ignoreMap":87},[91,10708,10709],{"class":93,"line":94},[91,10710,3463],{},[91,10712,10713],{"class":93,"line":100},[91,10714,3468],{},[91,10716,10717],{"class":93,"line":106},[91,10718,3473],{},[91,10720,10721],{"class":93,"line":113},[91,10722,110],{"emptyLinePlaceholder":109},[91,10724,10725],{"class":93,"line":119},[91,10726,3482],{},[91,10728,10729],{"class":93,"line":1202},[91,10730,3487],{},[10,10732,162],{},[82,10734,10736],{"className":10735,"code":3493,"language":168,"meta":87},[166],[39,10737,3493],{"__ignoreMap":87},[10,10739,173],{},[14,10741,176],{"id":176},[178,10743,10744,10748],{},[54,10745,10746,3507],{},[39,10747,3506],{},[54,10749,10750,3513],{},[39,10751,3512],{},[14,10753,222],{"id":222},[51,10755,10756,10760],{},[54,10757,3520,10758,3524],{},[39,10759,3523],{},[54,10761,3527],{},[14,10763,241],{"id":241},[178,10765,10766,10768],{},[54,10767,3534],{},[54,10769,2226,10770,2229,10772,3541],{},[39,10771,3523],{},[39,10773,3512],{},[10,10775,258],{},[14,10777,261],{"id":261},[10,10779,3548],{},[266,10781,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10783},[10784,10785,10786,10787,10788,10789,10790,10791],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":3415,"description":3420},[281,3568,3411],{"id":3571,"title":3572,"body":10796,"category":281,"cover":282,"description":3577,"extension":283,"meta":10921,"navigation":109,"path":3733,"pinned":286,"publishedAt":287,"seo":10922,"slug":3735,"stem":3736,"summary":3737,"tags":10923,"updatedAt":287,"visible":109,"__hash__":3740},{"type":7,"value":10797,"toc":10911},[10798,10800,10802,10804,10806,10810,10816,10818,10828,10830,10832,10860,10862,10867,10869,10871,10881,10883,10895,10897,10903,10905,10907,10909],[10,10799,3577],{},[14,10801,16],{"id":16},[10,10803,3582],{},[14,10805,27],{"id":27},[10,10807,10808],{},[31,10809],{"alt":3589,"src":3590},[10,10811,3593,10812,3597,10814,3600],{},[39,10813,3596],{},[39,10815,2299],{},[14,10817,49],{"id":49},[51,10819,10820,10822,10826],{},[54,10821,3607],{},[54,10823,2392,10824,3613],{},[39,10825,3612],{},[54,10827,3616],{},[14,10829,73],{"id":73},[10,10831,1490],{},[82,10833,10834],{"className":84,"code":3623,"language":86,"meta":87,"style":87},[39,10835,10836,10840,10844,10848,10852,10856],{"__ignoreMap":87},[91,10837,10838],{"class":93,"line":94},[91,10839,3630],{},[91,10841,10842],{"class":93,"line":100},[91,10843,3635],{},[91,10845,10846],{"class":93,"line":106},[91,10847,110],{"emptyLinePlaceholder":109},[91,10849,10850],{"class":93,"line":113},[91,10851,3644],{},[91,10853,10854],{"class":93,"line":119},[91,10855,3649],{},[91,10857,10858],{"class":93,"line":1202},[91,10859,3654],{},[10,10861,162],{},[82,10863,10865],{"className":10864,"code":3660,"language":168,"meta":87},[166],[39,10866,3660],{"__ignoreMap":87},[10,10868,173],{},[14,10870,176],{"id":176},[178,10872,10873,10875],{},[54,10874,3671],{},[54,10876,3674,10877,3677,10879,3681],{},[39,10878,2299],{},[39,10880,3680],{},[14,10882,222],{"id":222},[51,10884,10885,10889],{},[54,10886,3688,10887,3692],{},[39,10888,3691],{},[54,10890,3695,10891,3699,10893,159],{},[39,10892,3698],{},[39,10894,3702],{},[14,10896,241],{"id":241},[178,10898,10899,10901],{},[54,10900,3709],{},[54,10902,3712],{},[10,10904,258],{},[14,10906,261],{"id":261},[10,10908,3719],{},[266,10910,268],{},{"title":87,"searchDepth":100,"depth":100,"links":10912},[10913,10914,10915,10916,10917,10918,10919,10920],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":3572,"description":3577},[281,3739,3411],{"id":3742,"title":3743,"body":10925,"category":281,"cover":282,"description":3748,"extension":283,"meta":11048,"navigation":109,"path":3898,"pinned":286,"publishedAt":287,"seo":11049,"slug":3900,"stem":3901,"summary":3902,"tags":11050,"updatedAt":287,"visible":109,"__hash__":3905},{"type":7,"value":10926,"toc":11038},[10927,10929,10931,10933,10935,10939,10941,10943,10955,10957,10959,10987,10989,10994,10996,10998,11008,11010,11020,11022,11030,11032,11034,11036],[10,10928,3748],{},[14,10930,16],{"id":16},[10,10932,3753],{},[14,10934,27],{"id":27},[10,10936,10937],{},[31,10938],{"alt":3760,"src":3761},[10,10940,3764],{},[14,10942,49],{"id":49},[51,10944,10945,10947,10949],{},[54,10946,3771],{},[54,10948,3774],{},[54,10950,3777,10951,3781,10953,3785],{},[39,10952,3780],{},[39,10954,3784],{},[14,10956,73],{"id":73},[10,10958,1490],{},[82,10960,10961],{"className":84,"code":3792,"language":86,"meta":87,"style":87},[39,10962,10963,10967,10971,10975,10979,10983],{"__ignoreMap":87},[91,10964,10965],{"class":93,"line":94},[91,10966,3799],{},[91,10968,10969],{"class":93,"line":100},[91,10970,3804],{},[91,10972,10973],{"class":93,"line":106},[91,10974,110],{"emptyLinePlaceholder":109},[91,10976,10977],{"class":93,"line":113},[91,10978,3813],{},[91,10980,10981],{"class":93,"line":119},[91,10982,3818],{},[91,10984,10985],{"class":93,"line":1202},[91,10986,3823],{},[10,10988,162],{},[82,10990,10992],{"className":10991,"code":3829,"language":168,"meta":87},[166],[39,10993,3829],{"__ignoreMap":87},[10,10995,173],{},[14,10997,176],{"id":176},[178,10999,11000,11002],{},[54,11001,3840],{},[54,11003,11004,3846,11006,3850],{},[39,11005,3845],{},[39,11007,3849],{},[14,11009,222],{"id":222},[51,11011,11012,11018],{},[54,11013,2392,11014,3859,11016,159],{},[39,11015,3784],{},[39,11017,3780],{},[54,11019,3864],{},[14,11021,241],{"id":241},[178,11023,11024,11028],{},[54,11025,3871,11026,3874],{},[39,11027,3780],{},[54,11029,3877],{},[10,11031,258],{},[14,11033,261],{"id":261},[10,11035,3884],{},[266,11037,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11039},[11040,11041,11042,11043,11044,11045,11046,11047],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":3743,"description":3748},[281,3904,3411],{"id":3907,"title":3908,"body":11052,"category":281,"cover":282,"description":3913,"extension":283,"meta":11211,"navigation":109,"path":4112,"pinned":286,"publishedAt":287,"seo":11212,"slug":4114,"stem":4115,"summary":4116,"tags":11213,"updatedAt":287,"visible":109,"__hash__":4120},{"type":7,"value":11053,"toc":11199},[11054,11056,11058,11060,11062,11066,11072,11074,11086,11088,11090,11130,11132,11137,11139,11141,11155,11157,11159,11163,11165,11167,11177,11179,11191,11193,11195,11197],[10,11055,3913],{},[14,11057,16],{"id":16},[10,11059,3918],{},[14,11061,27],{"id":27},[10,11063,11064],{},[31,11065],{"alt":3925,"src":3926},[10,11067,11068,3932,11070,3936],{},[39,11069,3931],{},[39,11071,3935],{},[14,11073,49],{"id":49},[51,11075,11076,11082,11084],{},[54,11077,11078,3945,11080,3949],{},[39,11079,2860],{},[39,11081,3948],{},[54,11083,3952],{},[54,11085,3955],{},[14,11087,73],{"id":73},[10,11089,1490],{},[82,11091,11092],{"className":84,"code":3962,"language":86,"meta":87,"style":87},[39,11093,11094,11098,11102,11106,11110,11114,11118,11122,11126],{"__ignoreMap":87},[91,11095,11096],{"class":93,"line":94},[91,11097,3969],{},[91,11099,11100],{"class":93,"line":100},[91,11101,3974],{},[91,11103,11104],{"class":93,"line":106},[91,11105,3979],{},[91,11107,11108],{"class":93,"line":113},[91,11109,110],{"emptyLinePlaceholder":109},[91,11111,11112],{"class":93,"line":119},[91,11113,3988],{},[91,11115,11116],{"class":93,"line":1202},[91,11117,3993],{},[91,11119,11120],{"class":93,"line":2541},[91,11121,3998],{},[91,11123,11124],{"class":93,"line":2547},[91,11125,4003],{},[91,11127,11128],{"class":93,"line":4006},[91,11129,4009],{},[10,11131,162],{},[82,11133,11135],{"className":11134,"code":4015,"language":168,"meta":87},[166],[39,11136,4015],{"__ignoreMap":87},[10,11138,173],{},[14,11140,176],{"id":176},[178,11142,11143,11147],{},[54,11144,11145,4029],{},[39,11146,4028],{},[54,11148,11149,4035,11151,4039,11153,4043],{},[39,11150,4034],{},[39,11152,4038],{},[39,11154,4042],{},[202,11156,204],{"id":204},[10,11158,4048],{},[10,11160,11161],{},[31,11162],{"alt":4053,"src":4054},[10,11164,4057],{},[14,11166,222],{"id":222},[51,11168,11169,11175],{},[54,11170,4064,11171,4067,11173,159],{},[39,11172,2860],{},[39,11174,3948],{},[54,11176,4072],{},[14,11178,241],{"id":241},[178,11180,11181,11183],{},[54,11182,4079],{},[54,11184,2392,11185,4085,11187,155,11189,159],{},[39,11186,4084],{},[39,11188,3948],{},[39,11190,2860],{},[10,11192,258],{},[14,11194,261],{"id":261},[10,11196,4096],{},[266,11198,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11200},[11201,11202,11203,11204,11205,11208,11209,11210],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":11206},[11207],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":3908,"description":3913},[281,4118,4119],{"id":4122,"title":4123,"body":11215,"category":281,"cover":282,"description":4128,"extension":283,"meta":11387,"navigation":109,"path":4342,"pinned":286,"publishedAt":287,"seo":11388,"slug":4344,"stem":4345,"summary":4346,"tags":11389,"updatedAt":287,"visible":109,"__hash__":4349},{"type":7,"value":11216,"toc":11374},[11217,11219,11221,11223,11225,11229,11237,11239,11247,11249,11251,11295,11297,11302,11304,11306,11318,11320,11322,11326,11332,11334,11336,11340,11344,11346,11358,11360,11366,11368,11370,11372],[10,11218,4128],{},[14,11220,16],{"id":16},[10,11222,4133],{},[14,11224,27],{"id":27},[10,11226,11227],{},[31,11228],{"alt":4140,"src":4141},[10,11230,11231,2310,11233,2310,11235,4151],{},[39,11232,1210],{},[39,11234,4148],{},[39,11236,1213],{},[14,11238,49],{"id":49},[51,11240,11241,11243,11245],{},[54,11242,4158],{},[54,11244,4161],{},[54,11246,4164],{},[14,11248,73],{"id":73},[10,11250,1490],{},[82,11252,11253],{"className":84,"code":4171,"language":86,"meta":87,"style":87},[39,11254,11255,11259,11263,11267,11271,11275,11279,11283,11287,11291],{"__ignoreMap":87},[91,11256,11257],{"class":93,"line":94},[91,11258,4178],{},[91,11260,11261],{"class":93,"line":100},[91,11262,110],{"emptyLinePlaceholder":109},[91,11264,11265],{"class":93,"line":106},[91,11266,4187],{},[91,11268,11269],{"class":93,"line":113},[91,11270,4192],{},[91,11272,11273],{"class":93,"line":119},[91,11274,4197],{},[91,11276,11277],{"class":93,"line":1202},[91,11278,4202],{},[91,11280,11281],{"class":93,"line":2541},[91,11282,1199],{},[91,11284,11285],{"class":93,"line":2547},[91,11286,4211],{},[91,11288,11289],{"class":93,"line":4006},[91,11290,110],{"emptyLinePlaceholder":109},[91,11292,11293],{"class":93,"line":4218},[91,11294,4221],{},[10,11296,162],{},[82,11298,11300],{"className":11299,"code":4227,"language":168,"meta":87},[166],[39,11301,4227],{"__ignoreMap":87},[10,11303,173],{},[14,11305,176],{"id":176},[178,11307,11308,11312],{},[54,11309,4238,11310,4242],{},[39,11311,4241],{},[54,11313,11314,4248,11316,4251],{},[39,11315,4247],{},[39,11317,1213],{},[202,11319,204],{"id":204},[10,11321,4256],{},[10,11323,11324],{},[31,11325],{"alt":4261,"src":4262},[10,11327,11328,4267,11330,4270],{},[39,11329,4241],{},[39,11331,4247],{},[202,11333,204],{"id":4273},[10,11335,4276],{},[10,11337,11338],{},[31,11339],{"alt":4281,"src":4282},[10,11341,4285,11342,4288],{},[39,11343,1210],{},[14,11345,222],{"id":222},[51,11347,11348,11352],{},[54,11349,4295,11350,4298],{},[39,11351,4247],{},[54,11353,4301,11354,4304,11356,4308],{},[39,11355,1210],{},[39,11357,4307],{},[14,11359,241],{"id":241},[178,11361,11362,11364],{},[54,11363,4315],{},[54,11365,4318],{},[10,11367,258],{},[14,11369,261],{"id":261},[10,11371,4325],{},[266,11373,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11375},[11376,11377,11378,11379,11380,11384,11385,11386],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":11381},[11382,11383],{"id":204,"depth":106,"text":204},{"id":4273,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":4123,"description":4128},[281,1210,4348],{"id":4351,"title":4352,"body":11391,"category":281,"cover":282,"description":4357,"extension":283,"meta":11528,"navigation":109,"path":4524,"pinned":286,"publishedAt":287,"seo":11529,"slug":4526,"stem":4527,"summary":4528,"tags":11530,"updatedAt":287,"visible":109,"__hash__":4531},{"type":7,"value":11392,"toc":11516},[11393,11395,11397,11399,11401,11405,11409,11411,11421,11423,11425,11457,11459,11464,11466,11468,11478,11480,11482,11486,11490,11492,11498,11500,11508,11510,11512,11514],[10,11394,4357],{},[14,11396,16],{"id":16},[10,11398,4362],{},[14,11400,27],{"id":27},[10,11402,11403],{},[31,11404],{"alt":4369,"src":4370},[10,11406,11407,4376],{},[39,11408,4375],{},[14,11410,49],{"id":49},[51,11412,11413,11415,11417],{},[54,11414,4383],{},[54,11416,4386],{},[54,11418,4389,11419,4393],{},[39,11420,4392],{},[14,11422,73],{"id":73},[10,11424,1490],{},[82,11426,11427],{"className":84,"code":4400,"language":86,"meta":87,"style":87},[39,11428,11429,11433,11437,11441,11445,11449,11453],{"__ignoreMap":87},[91,11430,11431],{"class":93,"line":94},[91,11432,4407],{},[91,11434,11435],{"class":93,"line":100},[91,11436,110],{"emptyLinePlaceholder":109},[91,11438,11439],{"class":93,"line":106},[91,11440,4416],{},[91,11442,11443],{"class":93,"line":113},[91,11444,4421],{},[91,11446,11447],{"class":93,"line":119},[91,11448,4426],{},[91,11450,11451],{"class":93,"line":1202},[91,11452,110],{"emptyLinePlaceholder":109},[91,11454,11455],{"class":93,"line":2541},[91,11456,4435],{},[10,11458,162],{},[82,11460,11462],{"className":11461,"code":4441,"language":168,"meta":87},[166],[39,11463,4441],{"__ignoreMap":87},[10,11465,173],{},[14,11467,176],{"id":176},[178,11469,11470,11474],{},[54,11471,4452,11472,4456],{},[39,11473,4455],{},[54,11475,4459,11476,4462],{},[39,11477,4455],{},[202,11479,204],{"id":204},[10,11481,4467],{},[10,11483,11484],{},[31,11485],{"alt":4472,"src":4473},[10,11487,4476,11488,4479],{},[39,11489,4455],{},[14,11491,222],{"id":222},[51,11493,11494,11496],{},[54,11495,4486],{},[54,11497,4489],{},[14,11499,241],{"id":241},[178,11501,11502,11506],{},[54,11503,2392,11504,4498],{},[39,11505,4375],{},[54,11507,4501],{},[10,11509,258],{},[14,11511,261],{"id":261},[10,11513,4508],{},[266,11515,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11517},[11518,11519,11520,11521,11522,11525,11526,11527],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":11523},[11524],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":4352,"description":4357},[281,4375,4530],{"id":4533,"title":4534,"body":11532,"category":281,"cover":282,"description":4539,"extension":283,"meta":11657,"navigation":109,"path":4688,"pinned":286,"publishedAt":287,"seo":11658,"slug":4690,"stem":4691,"summary":4692,"tags":11659,"updatedAt":287,"visible":109,"__hash__":4695},{"type":7,"value":11533,"toc":11647},[11534,11536,11538,11540,11542,11546,11550,11552,11562,11564,11566,11598,11600,11605,11607,11609,11621,11623,11629,11631,11639,11641,11643,11645],[10,11535,4539],{},[14,11537,16],{"id":16},[10,11539,4544],{},[14,11541,27],{"id":27},[10,11543,11544],{},[31,11545],{"alt":4551,"src":4552},[10,11547,11548,4557],{},[39,11549,4392],{},[14,11551,49],{"id":49},[51,11553,11554,11558,11560],{},[54,11555,11556,4567],{},[39,11557,4566],{},[54,11559,4570],{},[54,11561,4573],{},[14,11563,73],{"id":73},[10,11565,1490],{},[82,11567,11568],{"className":84,"code":4580,"language":86,"meta":87,"style":87},[39,11569,11570,11574,11578,11582,11586,11590,11594],{"__ignoreMap":87},[91,11571,11572],{"class":93,"line":94},[91,11573,4587],{},[91,11575,11576],{"class":93,"line":100},[91,11577,110],{"emptyLinePlaceholder":109},[91,11579,11580],{"class":93,"line":106},[91,11581,4596],{},[91,11583,11584],{"class":93,"line":113},[91,11585,4601],{},[91,11587,11588],{"class":93,"line":119},[91,11589,110],{"emptyLinePlaceholder":109},[91,11591,11592],{"class":93,"line":1202},[91,11593,4610],{},[91,11595,11596],{"class":93,"line":2541},[91,11597,4615],{},[10,11599,162],{},[82,11601,11603],{"className":11602,"code":4621,"language":168,"meta":87},[166],[39,11604,4621],{"__ignoreMap":87},[10,11606,173],{},[14,11608,176],{"id":176},[178,11610,11611,11617],{},[54,11612,4632,11613,4635,11615,4639],{},[39,11614,4392],{},[39,11616,4638],{},[54,11618,11619,4644],{},[39,11620,4566],{},[14,11622,222],{"id":222},[51,11624,11625,11627],{},[54,11626,4651],{},[54,11628,4654],{},[14,11630,241],{"id":241},[178,11632,11633,11635],{},[54,11634,4661],{},[54,11636,2392,11637,4667],{},[39,11638,4666],{},[10,11640,258],{},[14,11642,261],{"id":261},[10,11644,4674],{},[266,11646,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11648},[11649,11650,11651,11652,11653,11654,11655,11656],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":4534,"description":4539},[281,4392,4694],{"id":4697,"title":4698,"body":11661,"category":281,"cover":282,"description":4703,"extension":283,"meta":11806,"navigation":109,"path":4878,"pinned":286,"publishedAt":287,"seo":11807,"slug":4880,"stem":4881,"summary":4882,"tags":11808,"updatedAt":287,"visible":109,"__hash__":4884},{"type":7,"value":11662,"toc":11796},[11663,11665,11667,11669,11671,11675,11681,11683,11697,11699,11701,11745,11747,11752,11754,11756,11766,11768,11780,11782,11788,11790,11792,11794],[10,11664,4703],{},[14,11666,16],{"id":16},[10,11668,4708],{},[14,11670,27],{"id":27},[10,11672,11673],{},[31,11674],{"alt":4715,"src":4716},[10,11676,11677,4722,11679,4726],{},[39,11678,4721],{},[39,11680,4725],{},[14,11682,49],{"id":49},[51,11684,11685,11687,11693],{},[54,11686,4733],{},[54,11688,11689,4738,11691,4741],{},[39,11690,4721],{},[39,11692,4375],{},[54,11694,4744,11695,4747],{},[39,11696,4725],{},[14,11698,73],{"id":73},[10,11700,1490],{},[82,11702,11703],{"className":84,"code":4754,"language":86,"meta":87,"style":87},[39,11704,11705,11709,11713,11717,11721,11725,11729,11733,11737,11741],{"__ignoreMap":87},[91,11706,11707],{"class":93,"line":94},[91,11708,4761],{},[91,11710,11711],{"class":93,"line":100},[91,11712,110],{"emptyLinePlaceholder":109},[91,11714,11715],{"class":93,"line":106},[91,11716,4770],{},[91,11718,11719],{"class":93,"line":113},[91,11720,4775],{},[91,11722,11723],{"class":93,"line":119},[91,11724,4780],{},[91,11726,11727],{"class":93,"line":1202},[91,11728,4785],{},[91,11730,11731],{"class":93,"line":2541},[91,11732,4790],{},[91,11734,11735],{"class":93,"line":2547},[91,11736,4615],{},[91,11738,11739],{"class":93,"line":4006},[91,11740,110],{"emptyLinePlaceholder":109},[91,11742,11743],{"class":93,"line":4218},[91,11744,4803],{},[10,11746,162],{},[82,11748,11750],{"className":11749,"code":4809,"language":168,"meta":87},[166],[39,11751,4809],{"__ignoreMap":87},[10,11753,173],{},[14,11755,176],{"id":176},[178,11757,11758,11762],{},[54,11759,4820,11760,4823],{},[39,11761,4721],{},[54,11763,4826,11764,4829],{},[39,11765,4725],{},[14,11767,222],{"id":222},[51,11769,11770,11774],{},[54,11771,3520,11772,4838],{},[39,11773,4721],{},[54,11775,4841,11776,4844,11778,4847],{},[39,11777,4375],{},[39,11779,4721],{},[14,11781,241],{"id":241},[178,11783,11784,11786],{},[54,11785,4854],{},[54,11787,4857],{},[10,11789,258],{},[14,11791,261],{"id":261},[10,11793,4864],{},[266,11795,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11797},[11798,11799,11800,11801,11802,11803,11804,11805],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":4698,"description":4703},[281,4725,4721],{"id":4886,"title":4887,"body":11810,"category":281,"cover":282,"description":4892,"extension":283,"meta":11949,"navigation":109,"path":5064,"pinned":286,"publishedAt":287,"seo":11950,"slug":5066,"stem":5067,"summary":5068,"tags":11951,"updatedAt":287,"visible":109,"__hash__":5072},{"type":7,"value":11811,"toc":11937},[11812,11814,11816,11818,11820,11824,11826,11828,11844,11846,11848,11876,11878,11883,11885,11887,11899,11901,11903,11907,11909,11911,11921,11923,11929,11931,11933,11935],[10,11813,4892],{},[14,11815,16],{"id":16},[10,11817,4897],{},[14,11819,27],{"id":27},[10,11821,11822],{},[31,11823],{"alt":4904,"src":4905},[10,11825,4908],{},[14,11827,49],{"id":49},[51,11829,11830,11832,11834],{},[54,11831,4915],{},[54,11833,4918],{},[54,11835,4921,11836,2310,11838,4928,11840,2310,11842,159],{},[39,11837,4924],{},[39,11839,4927],{},[39,11841,4931],{},[39,11843,4934],{},[14,11845,73],{"id":73},[10,11847,1490],{},[82,11849,11850],{"className":84,"code":4941,"language":86,"meta":87,"style":87},[39,11851,11852,11856,11860,11864,11868,11872],{"__ignoreMap":87},[91,11853,11854],{"class":93,"line":94},[91,11855,4948],{},[91,11857,11858],{"class":93,"line":100},[91,11859,110],{"emptyLinePlaceholder":109},[91,11861,11862],{"class":93,"line":106},[91,11863,4957],{},[91,11865,11866],{"class":93,"line":113},[91,11867,4962],{},[91,11869,11870],{"class":93,"line":119},[91,11871,4967],{},[91,11873,11874],{"class":93,"line":1202},[91,11875,4972],{},[10,11877,162],{},[82,11879,11881],{"className":11880,"code":4978,"language":168,"meta":87},[166],[39,11882,4978],{"__ignoreMap":87},[10,11884,173],{},[14,11886,176],{"id":176},[178,11888,11889,11897],{},[54,11890,4989,11891,4992,11893,155,11895,159],{},[39,11892,4924],{},[39,11894,4995],{},[39,11896,4998],{},[54,11898,5001],{},[202,11900,204],{"id":204},[10,11902,5006],{},[10,11904,11905],{},[31,11906],{"alt":5011,"src":5012},[10,11908,5015],{},[14,11910,222],{"id":222},[51,11912,11913,11919],{},[54,11914,5022,11915,1062,11917,5028],{},[39,11916,5025],{},[39,11918,4931],{},[54,11920,5031],{},[14,11922,241],{"id":241},[178,11924,11925,11927],{},[54,11926,5038],{},[54,11928,5041],{},[10,11930,258],{},[14,11932,261],{"id":261},[10,11934,5048],{},[266,11936,268],{},{"title":87,"searchDepth":100,"depth":100,"links":11938},[11939,11940,11941,11942,11943,11946,11947,11948],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":11944},[11945],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":4887,"description":4892},[281,5070,5071],{"id":5074,"title":5075,"body":11953,"category":281,"cover":282,"description":5080,"extension":283,"meta":12070,"navigation":109,"path":5219,"pinned":286,"publishedAt":287,"seo":12071,"slug":5221,"stem":5222,"summary":5223,"tags":12072,"updatedAt":287,"visible":109,"__hash__":5227},{"type":7,"value":11954,"toc":12060},[11955,11957,11959,11961,11963,11967,11969,11971,11979,11981,11983,12015,12017,12022,12024,12026,12034,12036,12044,12046,12052,12054,12056,12058],[10,11956,5080],{},[14,11958,16],{"id":16},[10,11960,5085],{},[14,11962,27],{"id":27},[10,11964,11965],{},[31,11966],{"alt":5092,"src":5093},[10,11968,5096],{},[14,11970,49],{"id":49},[51,11972,11973,11975,11977],{},[54,11974,5103],{},[54,11976,5106],{},[54,11978,5109],{},[14,11980,73],{"id":73},[10,11982,1490],{},[82,11984,11985],{"className":84,"code":5116,"language":86,"meta":87,"style":87},[39,11986,11987,11991,11995,11999,12003,12007,12011],{"__ignoreMap":87},[91,11988,11989],{"class":93,"line":94},[91,11990,5123],{},[91,11992,11993],{"class":93,"line":100},[91,11994,110],{"emptyLinePlaceholder":109},[91,11996,11997],{"class":93,"line":106},[91,11998,5132],{},[91,12000,12001],{"class":93,"line":113},[91,12002,5137],{},[91,12004,12005],{"class":93,"line":119},[91,12006,110],{"emptyLinePlaceholder":109},[91,12008,12009],{"class":93,"line":1202},[91,12010,5146],{},[91,12012,12013],{"class":93,"line":2541},[91,12014,5151],{},[10,12016,162],{},[82,12018,12020],{"className":12019,"code":5157,"language":168,"meta":87},[166],[39,12021,5157],{"__ignoreMap":87},[10,12023,173],{},[14,12025,176],{"id":176},[178,12027,12028,12030],{},[54,12029,5168],{},[54,12031,5171,12032,5175],{},[39,12033,5174],{},[14,12035,222],{"id":222},[51,12037,12038,12042],{},[54,12039,5182,12040,5185],{},[39,12041,4392],{},[54,12043,5188],{},[14,12045,241],{"id":241},[178,12047,12048,12050],{},[54,12049,5195],{},[54,12051,5198],{},[10,12053,258],{},[14,12055,261],{"id":261},[10,12057,5205],{},[266,12059,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12061},[12062,12063,12064,12065,12066,12067,12068,12069],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5075,"description":5080},[281,5225,5226],{"id":5229,"title":5230,"body":12074,"category":281,"cover":282,"description":5235,"extension":283,"meta":12193,"navigation":109,"path":5379,"pinned":286,"publishedAt":287,"seo":12194,"slug":5381,"stem":5382,"summary":5383,"tags":12195,"updatedAt":287,"visible":109,"__hash__":5387},{"type":7,"value":12075,"toc":12183},[12076,12078,12080,12082,12084,12088,12090,12092,12100,12102,12104,12136,12138,12143,12145,12147,12157,12159,12165,12167,12175,12177,12179,12181],[10,12077,5235],{},[14,12079,16],{"id":16},[10,12081,5240],{},[14,12083,27],{"id":27},[10,12085,12086],{},[31,12087],{"alt":5247,"src":5248},[10,12089,5251],{},[14,12091,49],{"id":49},[51,12093,12094,12096,12098],{},[54,12095,5258],{},[54,12097,5261],{},[54,12099,5264],{},[14,12101,73],{"id":73},[10,12103,1490],{},[82,12105,12106],{"className":84,"code":5271,"language":86,"meta":87,"style":87},[39,12107,12108,12112,12116,12120,12124,12128,12132],{"__ignoreMap":87},[91,12109,12110],{"class":93,"line":94},[91,12111,5278],{},[91,12113,12114],{"class":93,"line":100},[91,12115,5283],{},[91,12117,12118],{"class":93,"line":106},[91,12119,5288],{},[91,12121,12122],{"class":93,"line":113},[91,12123,110],{"emptyLinePlaceholder":109},[91,12125,12126],{"class":93,"line":119},[91,12127,5297],{},[91,12129,12130],{"class":93,"line":1202},[91,12131,5302],{},[91,12133,12134],{"class":93,"line":2541},[91,12135,5307],{},[10,12137,162],{},[82,12139,12141],{"className":12140,"code":5313,"language":168,"meta":87},[166],[39,12142,5313],{"__ignoreMap":87},[10,12144,173],{},[14,12146,176],{"id":176},[178,12148,12149,12153],{},[54,12150,991,12151,5327],{},[39,12152,5326],{},[54,12154,5330,12155,5334],{},[39,12156,5333],{},[14,12158,222],{"id":222},[51,12160,12161,12163],{},[54,12162,5341],{},[54,12164,5344],{},[14,12166,241],{"id":241},[178,12168,12169,12173],{},[54,12170,5351,12171,5355],{},[39,12172,5354],{},[54,12174,5358],{},[10,12176,258],{},[14,12178,261],{"id":261},[10,12180,5365],{},[266,12182,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12184},[12185,12186,12187,12188,12189,12190,12191,12192],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5230,"description":5235},[281,5385,5386],{"id":5389,"title":5390,"body":12197,"category":281,"cover":282,"description":5395,"extension":283,"meta":12342,"navigation":109,"path":5576,"pinned":286,"publishedAt":287,"seo":12343,"slug":5578,"stem":5579,"summary":5580,"tags":12344,"updatedAt":287,"visible":109,"__hash__":5584},{"type":7,"value":12198,"toc":12330},[12199,12201,12203,12205,12207,12211,12215,12217,12229,12231,12233,12261,12263,12268,12270,12272,12286,12288,12290,12294,12302,12304,12314,12316,12322,12324,12326,12328],[10,12200,5395],{},[14,12202,16],{"id":16},[10,12204,5400],{},[14,12206,27],{"id":27},[10,12208,12209],{},[31,12210],{"alt":5407,"src":5408},[10,12212,5411,12213,5415],{},[39,12214,5414],{},[14,12216,49],{"id":49},[51,12218,12219,12221,12223],{},[54,12220,5422],{},[54,12222,5425],{},[54,12224,5428,12225,5431,12227,159],{},[39,12226,5414],{},[39,12228,5434],{},[14,12230,73],{"id":73},[10,12232,1490],{},[82,12234,12235],{"className":84,"code":5441,"language":86,"meta":87,"style":87},[39,12236,12237,12241,12245,12249,12253,12257],{"__ignoreMap":87},[91,12238,12239],{"class":93,"line":94},[91,12240,5448],{},[91,12242,12243],{"class":93,"line":100},[91,12244,5453],{},[91,12246,12247],{"class":93,"line":106},[91,12248,5458],{},[91,12250,12251],{"class":93,"line":113},[91,12252,110],{"emptyLinePlaceholder":109},[91,12254,12255],{"class":93,"line":119},[91,12256,5467],{},[91,12258,12259],{"class":93,"line":1202},[91,12260,5472],{},[10,12262,162],{},[82,12264,12266],{"className":12265,"code":5478,"language":168,"meta":87},[166],[39,12267,5478],{"__ignoreMap":87},[10,12269,173],{},[14,12271,176],{"id":176},[178,12273,12274,12280],{},[54,12275,5489,12276,2310,12278,5495],{},[39,12277,5492],{},[39,12279,4455],{},[54,12281,12282,5501,12284,5505],{},[39,12283,5500],{},[39,12285,5504],{},[202,12287,204],{"id":204},[10,12289,5510],{},[10,12291,12292],{},[31,12293],{"alt":5515,"src":5516},[10,12295,12296,2310,12298,155,12300,5526],{},[39,12297,5492],{},[39,12299,4455],{},[39,12301,5525],{},[14,12303,222],{"id":222},[51,12305,12306,12310],{},[54,12307,5533,12308,5537],{},[39,12309,5536],{},[54,12311,5540,12312,5543],{},[39,12313,5525],{},[14,12315,241],{"id":241},[178,12317,12318,12320],{},[54,12319,5550],{},[54,12321,5553],{},[10,12323,258],{},[14,12325,261],{"id":261},[10,12327,5560],{},[266,12329,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12331},[12332,12333,12334,12335,12336,12339,12340,12341],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":12337},[12338],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5390,"description":5395},[281,5582,5583],{"id":5586,"title":5587,"body":12346,"category":281,"cover":282,"description":5592,"extension":283,"meta":12495,"navigation":109,"path":5773,"pinned":286,"publishedAt":287,"seo":12496,"slug":5775,"stem":5776,"summary":5777,"tags":12497,"updatedAt":287,"visible":109,"__hash__":5781},{"type":7,"value":12347,"toc":12483},[12348,12350,12352,12354,12356,12360,12362,12364,12376,12378,12380,12424,12426,12431,12433,12435,12447,12449,12451,12455,12457,12459,12467,12469,12475,12477,12479,12481],[10,12349,5592],{},[14,12351,16],{"id":16},[10,12353,5597],{},[14,12355,27],{"id":27},[10,12357,12358],{},[31,12359],{"alt":5604,"src":5605},[10,12361,5608],{},[14,12363,49],{"id":49},[51,12365,12366,12368,12372],{},[54,12367,5615],{},[54,12369,12370,5621],{},[39,12371,5620],{},[54,12373,12374,5627],{},[39,12375,5626],{},[14,12377,73],{"id":73},[10,12379,1490],{},[82,12381,12382],{"className":84,"code":5634,"language":86,"meta":87,"style":87},[39,12383,12384,12388,12392,12396,12400,12404,12408,12412,12416,12420],{"__ignoreMap":87},[91,12385,12386],{"class":93,"line":94},[91,12387,5641],{},[91,12389,12390],{"class":93,"line":100},[91,12391,5646],{},[91,12393,12394],{"class":93,"line":106},[91,12395,110],{"emptyLinePlaceholder":109},[91,12397,12398],{"class":93,"line":113},[91,12399,5655],{},[91,12401,12402],{"class":93,"line":119},[91,12403,5660],{},[91,12405,12406],{"class":93,"line":1202},[91,12407,110],{"emptyLinePlaceholder":109},[91,12409,12410],{"class":93,"line":2541},[91,12411,5669],{},[91,12413,12414],{"class":93,"line":2547},[91,12415,5674],{},[91,12417,12418],{"class":93,"line":4006},[91,12419,110],{"emptyLinePlaceholder":109},[91,12421,12422],{"class":93,"line":4218},[91,12423,5683],{},[10,12425,162],{},[82,12427,12429],{"className":12428,"code":5689,"language":168,"meta":87},[166],[39,12430,5689],{"__ignoreMap":87},[10,12432,173],{},[14,12434,176],{"id":176},[178,12436,12437,12441],{},[54,12438,5700,12439,5704],{},[39,12440,5703],{},[54,12442,12443,5710,12445,159],{},[39,12444,5709],{},[39,12446,5713],{},[202,12448,204],{"id":204},[10,12450,5718],{},[10,12452,12453],{},[31,12454],{"alt":5723,"src":5724},[10,12456,5727],{},[14,12458,222],{"id":222},[51,12460,12461,12465],{},[54,12462,5734,12463,5737],{},[39,12464,5434],{},[54,12466,5740],{},[14,12468,241],{"id":241},[178,12470,12471,12473],{},[54,12472,5747],{},[54,12474,5750],{},[10,12476,258],{},[14,12478,261],{"id":261},[10,12480,5757],{},[266,12482,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12484},[12485,12486,12487,12488,12489,12492,12493,12494],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":12490},[12491],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5587,"description":5592},[281,5779,5780],{"id":5783,"title":5784,"body":12499,"category":281,"cover":282,"description":5789,"extension":283,"meta":12660,"navigation":109,"path":5987,"pinned":286,"publishedAt":287,"seo":12661,"slug":5989,"stem":5990,"summary":5991,"tags":12662,"updatedAt":287,"visible":109,"__hash__":5995},{"type":7,"value":12500,"toc":12648},[12501,12503,12505,12507,12509,12513,12515,12517,12529,12531,12533,12585,12587,12592,12594,12596,12614,12616,12618,12622,12624,12626,12632,12634,12640,12642,12644,12646],[10,12502,5789],{},[14,12504,16],{"id":16},[10,12506,5794],{},[14,12508,27],{"id":27},[10,12510,12511],{},[31,12512],{"alt":5801,"src":5802},[10,12514,5805],{},[14,12516,49],{"id":49},[51,12518,12519,12521,12523],{},[54,12520,5812],{},[54,12522,5815],{},[54,12524,12525,2229,12527,5824],{},[39,12526,5820],{},[39,12528,5823],{},[14,12530,73],{"id":73},[10,12532,1490],{},[82,12534,12535],{"className":84,"code":5831,"language":86,"meta":87,"style":87},[39,12536,12537,12541,12545,12549,12553,12557,12561,12565,12569,12573,12577,12581],{"__ignoreMap":87},[91,12538,12539],{"class":93,"line":94},[91,12540,5838],{},[91,12542,12543],{"class":93,"line":100},[91,12544,110],{"emptyLinePlaceholder":109},[91,12546,12547],{"class":93,"line":106},[91,12548,5847],{},[91,12550,12551],{"class":93,"line":113},[91,12552,5852],{},[91,12554,12555],{"class":93,"line":119},[91,12556,110],{"emptyLinePlaceholder":109},[91,12558,12559],{"class":93,"line":1202},[91,12560,5861],{},[91,12562,12563],{"class":93,"line":2541},[91,12564,5866],{},[91,12566,12567],{"class":93,"line":2547},[91,12568,5871],{},[91,12570,12571],{"class":93,"line":4006},[91,12572,110],{"emptyLinePlaceholder":109},[91,12574,12575],{"class":93,"line":4218},[91,12576,5880],{},[91,12578,12579],{"class":93,"line":5883},[91,12580,110],{"emptyLinePlaceholder":109},[91,12582,12583],{"class":93,"line":5888},[91,12584,5891],{},[10,12586,162],{},[82,12588,12590],{"className":12589,"code":5897,"language":168,"meta":87},[166],[39,12591,5897],{"__ignoreMap":87},[10,12593,173],{},[14,12595,176],{"id":176},[178,12597,12598,12608],{},[54,12599,12600,5911,12602,5915,12604,5918,12606,5922],{},[39,12601,5910],{},[39,12603,5914],{},[39,12605,5703],{},[39,12607,5921],{},[54,12609,12610,5927,12612,5930],{},[39,12611,4638],{},[39,12613,2261],{},[202,12615,204],{"id":204},[10,12617,5935],{},[10,12619,12620],{},[31,12621],{"alt":5940,"src":5941},[10,12623,5944],{},[14,12625,222],{"id":222},[51,12627,12628,12630],{},[54,12629,5951],{},[54,12631,5954],{},[14,12633,241],{"id":241},[178,12635,12636,12638],{},[54,12637,5961],{},[54,12639,5964],{},[10,12641,258],{},[14,12643,261],{"id":261},[10,12645,5971],{},[266,12647,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12649},[12650,12651,12652,12653,12654,12657,12658,12659],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":12655},[12656],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5784,"description":5789},[281,5993,5994],{"id":5997,"title":5998,"body":12664,"category":281,"cover":282,"description":6003,"extension":283,"meta":12787,"navigation":109,"path":6153,"pinned":286,"publishedAt":287,"seo":12788,"slug":6155,"stem":6156,"summary":6157,"tags":12789,"updatedAt":287,"visible":109,"__hash__":6161},{"type":7,"value":12665,"toc":12777},[12666,12668,12670,12672,12674,12678,12680,12682,12696,12698,12700,12728,12730,12735,12737,12739,12749,12751,12759,12761,12769,12771,12773,12775],[10,12667,6003],{},[14,12669,16],{"id":16},[10,12671,6008],{},[14,12673,27],{"id":27},[10,12675,12676],{},[31,12677],{"alt":6015,"src":6016},[10,12679,6019],{},[14,12681,49],{"id":49},[51,12683,12684,12686,12688],{},[54,12685,6026],{},[54,12687,6029],{},[54,12689,6032,12690,2310,12692,2310,12694,6040],{},[39,12691,2313],{},[39,12693,2478],{},[39,12695,6039],{},[14,12697,73],{"id":73},[10,12699,1490],{},[82,12701,12702],{"className":84,"code":6047,"language":86,"meta":87,"style":87},[39,12703,12704,12708,12712,12716,12720,12724],{"__ignoreMap":87},[91,12705,12706],{"class":93,"line":94},[91,12707,6054],{},[91,12709,12710],{"class":93,"line":100},[91,12711,6059],{},[91,12713,12714],{"class":93,"line":106},[91,12715,6064],{},[91,12717,12718],{"class":93,"line":113},[91,12719,110],{"emptyLinePlaceholder":109},[91,12721,12722],{"class":93,"line":119},[91,12723,6073],{},[91,12725,12726],{"class":93,"line":1202},[91,12727,6078],{},[10,12729,162],{},[82,12731,12733],{"className":12732,"code":6084,"language":168,"meta":87},[166],[39,12734,6084],{"__ignoreMap":87},[10,12736,173],{},[14,12738,176],{"id":176},[178,12740,12741,12747],{},[54,12742,6095,12743,6098,12745,6101],{},[39,12744,23],{},[39,12746,2299],{},[54,12748,6104],{},[14,12750,222],{"id":222},[51,12752,12753,12757],{},[54,12754,6111,12755,6115],{},[39,12756,6114],{},[54,12758,6118],{},[14,12760,241],{"id":241},[178,12762,12763,12765],{},[54,12764,6125],{},[54,12766,6128,12767,6132],{},[39,12768,6131],{},[10,12770,258],{},[14,12772,261],{"id":261},[10,12774,6139],{},[266,12776,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12778},[12779,12780,12781,12782,12783,12784,12785,12786],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5998,"description":6003},[281,6159,6160],{"id":4,"title":5,"body":12791,"category":281,"cover":282,"description":12,"extension":283,"meta":12968,"navigation":109,"path":285,"pinned":286,"publishedAt":287,"seo":12969,"slug":289,"stem":290,"summary":291,"tags":12970,"updatedAt":287,"visible":109,"__hash__":295},{"type":7,"value":12792,"toc":12956},[12793,12795,12797,12801,12803,12807,12813,12815,12827,12829,12833,12857,12861,12877,12883,12885,12890,12892,12894,12910,12912,12914,12918,12922,12924,12936,12938,12948,12950,12952,12954],[10,12794,12],{},[14,12796,16],{"id":16},[10,12798,19,12799,24],{},[21,12800,23],{},[14,12802,27],{"id":27},[10,12804,12805],{},[31,12806],{"alt":33,"src":34},[10,12808,37,12809,42,12811,46],{},[39,12810,41],{},[39,12812,45],{},[14,12814,49],{"id":49},[51,12816,12817,12821,12823],{},[54,12818,56,12819,60],{},[39,12820,59],{},[54,12822,63],{},[54,12824,66,12825,70],{},[39,12826,69],{},[14,12828,73],{"id":73},[10,12830,76,12831,80],{},[39,12832,79],{},[82,12834,12835],{"className":84,"code":85,"language":86,"meta":87,"style":87},[39,12836,12837,12841,12845,12849,12853],{"__ignoreMap":87},[91,12838,12839],{"class":93,"line":94},[91,12840,97],{},[91,12842,12843],{"class":93,"line":100},[91,12844,103],{},[91,12846,12847],{"class":93,"line":106},[91,12848,110],{"emptyLinePlaceholder":109},[91,12850,12851],{"class":93,"line":113},[91,12852,116],{},[91,12854,12855],{"class":93,"line":119},[91,12856,122],{},[10,12858,125,12859,129],{},[39,12860,128],{},[82,12862,12863],{"className":84,"code":132,"language":86,"meta":87,"style":87},[39,12864,12865,12869,12873],{"__ignoreMap":87},[91,12866,12867],{"class":93,"line":94},[91,12868,139],{},[91,12870,12871],{"class":93,"line":100},[91,12872,110],{"emptyLinePlaceholder":109},[91,12874,12875],{"class":93,"line":106},[91,12876,148],{},[10,12878,151,12879,155,12881,159],{},[39,12880,154],{},[39,12882,158],{},[10,12884,162],{},[82,12886,12888],{"className":12887,"code":167,"language":168,"meta":87},[166],[39,12889,167],{"__ignoreMap":87},[10,12891,173],{},[14,12893,176],{"id":176},[178,12895,12896,12902],{},[54,12897,182,12898,185,12900,189],{},[39,12899,79],{},[39,12901,188],{},[54,12903,12904,194,12906,197,12908,200],{},[39,12905,128],{},[39,12907,79],{},[39,12909,128],{},[202,12911,204],{"id":204},[10,12913,207],{},[10,12915,12916],{},[31,12917],{"alt":212,"src":213},[10,12919,216,12920,219],{},[39,12921,188],{},[14,12923,222],{"id":222},[51,12925,12926,12932],{},[54,12927,227,12928,155,12930,159],{},[39,12929,79],{},[39,12931,128],{},[54,12933,234,12934,238],{},[39,12935,237],{},[14,12937,241],{"id":241},[178,12939,12940,12944],{},[54,12941,246,12942,250],{},[39,12943,249],{},[54,12945,253,12946,159],{},[39,12947,41],{},[10,12949,258],{},[14,12951,261],{"id":261},[10,12953,264],{},[266,12955,268],{},{"title":87,"searchDepth":100,"depth":100,"links":12957},[12958,12959,12960,12961,12962,12965,12966,12967],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":12963},[12964],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":5,"description":12},[281,293,294],{"id":6344,"title":6345,"body":12972,"category":281,"cover":282,"description":6350,"extension":283,"meta":13111,"navigation":109,"path":6516,"pinned":286,"publishedAt":287,"seo":13112,"slug":6518,"stem":6519,"summary":6520,"tags":13113,"updatedAt":287,"visible":109,"__hash__":6523},{"type":7,"value":12973,"toc":13101},[12974,12976,12978,12980,12982,12986,12988,12990,13000,13002,13004,13044,13046,13051,13053,13055,13073,13075,13083,13085,13093,13095,13097,13099],[10,12975,6350],{},[14,12977,16],{"id":16},[10,12979,6355],{},[14,12981,27],{"id":27},[10,12983,12984],{},[31,12985],{"alt":6362,"src":6363},[10,12987,6366],{},[14,12989,49],{"id":49},[51,12991,12992,12996,12998],{},[54,12993,12994,6376],{},[39,12995,6375],{},[54,12997,6379],{},[54,12999,6382],{},[14,13001,73],{"id":73},[10,13003,1627],{},[82,13005,13006],{"className":644,"code":6389,"language":646,"meta":87,"style":87},[39,13007,13008,13018,13024,13030,13040],{"__ignoreMap":87},[91,13009,13010,13012,13014,13016],{"class":93,"line":94},[91,13011,744],{"class":653},[91,13013,686],{"class":656},[91,13015,6400],{"class":689},[91,13017,6403],{"class":689},[91,13019,13020,13022],{"class":93,"line":100},[91,13021,6408],{"class":656},[91,13023,6411],{"class":689},[91,13025,13026,13028],{"class":93,"line":106},[91,13027,86],{"class":653},[91,13029,657],{"class":656},[91,13031,13032,13034,13036,13038],{"class":93,"line":113},[91,13033,86],{"class":653},[91,13035,686],{"class":656},[91,13037,690],{"class":689},[91,13039,657],{"class":656},[91,13041,13042],{"class":93,"line":119},[91,13043,6432],{"class":653},[10,13045,162],{},[82,13047,13049],{"className":13048,"code":6438,"language":168,"meta":87},[166],[39,13050,6438],{"__ignoreMap":87},[10,13052,173],{},[14,13054,176],{"id":176},[178,13056,13057,13063],{},[54,13058,13059,6452,13061,6455],{},[39,13060,6451],{},[39,13062,744],{},[54,13064,6458,13065,2229,13067,6464,13069,3781,13071,6470],{},[39,13066,86],{},[39,13068,6463],{},[39,13070,6375],{},[39,13072,6469],{},[14,13074,222],{"id":222},[51,13076,13077,13079],{},[54,13078,6477],{},[54,13080,3520,13081,6482],{},[39,13082,6375],{},[14,13084,241],{"id":241},[178,13086,13087,13091],{},[54,13088,6489,13089,159],{},[39,13090,6492],{},[54,13092,6495],{},[10,13094,258],{},[14,13096,261],{"id":261},[10,13098,6502],{},[266,13100,1711],{},{"title":87,"searchDepth":100,"depth":100,"links":13102},[13103,13104,13105,13106,13107,13108,13109,13110],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":6345,"description":6350},[281,6522,316],{"id":6525,"title":6526,"body":13115,"category":281,"cover":282,"description":6531,"extension":283,"meta":13268,"navigation":109,"path":6720,"pinned":286,"publishedAt":287,"seo":13269,"slug":6722,"stem":6723,"summary":6724,"tags":13270,"updatedAt":287,"visible":109,"__hash__":6728},{"type":7,"value":13116,"toc":13258},[13117,13119,13121,13123,13125,13129,13135,13137,13153,13155,13157,13201,13203,13208,13210,13212,13224,13226,13240,13242,13250,13252,13254,13256],[10,13118,6531],{},[14,13120,16],{"id":16},[10,13122,6536],{},[14,13124,27],{"id":27},[10,13126,13127],{},[31,13128],{"alt":6543,"src":6544},[10,13130,13131,6550,13133,6553],{},[39,13132,6549],{},[39,13134,2488],{},[14,13136,49],{"id":49},[51,13138,13139,13141,13149],{},[54,13140,6560],{},[54,13142,13143,2310,13145,2310,13147,6572],{},[39,13144,6565],{},[39,13146,6568],{},[39,13148,6571],{},[54,13150,6575,13151,6579],{},[39,13152,6578],{},[14,13154,73],{"id":73},[10,13156,1490],{},[82,13158,13159],{"className":84,"code":6586,"language":86,"meta":87,"style":87},[39,13160,13161,13165,13169,13173,13177,13181,13185,13189,13193,13197],{"__ignoreMap":87},[91,13162,13163],{"class":93,"line":94},[91,13164,6593],{},[91,13166,13167],{"class":93,"line":100},[91,13168,110],{"emptyLinePlaceholder":109},[91,13170,13171],{"class":93,"line":106},[91,13172,6602],{},[91,13174,13175],{"class":93,"line":113},[91,13176,6607],{},[91,13178,13179],{"class":93,"line":119},[91,13180,6612],{},[91,13182,13183],{"class":93,"line":1202},[91,13184,110],{"emptyLinePlaceholder":109},[91,13186,13187],{"class":93,"line":2541},[91,13188,6621],{},[91,13190,13191],{"class":93,"line":2547},[91,13192,6626],{},[91,13194,13195],{"class":93,"line":4006},[91,13196,6631],{},[91,13198,13199],{"class":93,"line":4218},[91,13200,6636],{},[10,13202,162],{},[82,13204,13206],{"className":13205,"code":6642,"language":168,"meta":87},[166],[39,13207,6642],{"__ignoreMap":87},[10,13209,173],{},[14,13211,176],{"id":176},[178,13213,13214,13218],{},[54,13215,13216,6656],{},[39,13217,6655],{},[54,13219,2392,13220,6661,13222,6664],{},[39,13221,2488],{},[39,13223,6549],{},[14,13225,222],{"id":222},[51,13227,13228,13234],{},[54,13229,3520,13230,6673,13232,6676],{},[39,13231,6549],{},[39,13233,6565],{},[54,13235,6679,13236,1062,13238,6685],{},[39,13237,2488],{},[39,13239,6684],{},[14,13241,241],{"id":241},[178,13243,13244,13248],{},[54,13245,6692,13246,6696],{},[39,13247,6695],{},[54,13249,6699],{},[10,13251,258],{},[14,13253,261],{"id":261},[10,13255,6706],{},[266,13257,268],{},{"title":87,"searchDepth":100,"depth":100,"links":13259},[13260,13261,13262,13263,13264,13265,13266,13267],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":6526,"description":6531},[281,6726,6727],{"id":6730,"title":6731,"body":13272,"category":281,"cover":282,"description":6736,"extension":283,"meta":13419,"navigation":109,"path":6915,"pinned":286,"publishedAt":287,"seo":13420,"slug":6917,"stem":6918,"summary":6919,"tags":13421,"updatedAt":287,"visible":109,"__hash__":6923},{"type":7,"value":13273,"toc":13409},[13274,13276,13278,13280,13282,13286,13288,13290,13308,13310,13312,13360,13362,13367,13369,13371,13379,13381,13391,13393,13401,13403,13405,13407],[10,13275,6736],{},[14,13277,16],{"id":16},[10,13279,6741],{},[14,13281,27],{"id":27},[10,13283,13284],{},[31,13285],{"alt":6748,"src":6749},[10,13287,6752],{},[14,13289,49],{"id":49},[51,13291,13292,13296,13302],{},[54,13293,13294,6762],{},[39,13295,6761],{},[54,13297,13298,6768,13300,159],{},[39,13299,6767],{},[39,13301,6771],{},[54,13303,6774,13304,6778,13306,6782],{},[39,13305,6777],{},[39,13307,6781],{},[14,13309,73],{"id":73},[10,13311,1490],{},[82,13313,13314],{"className":84,"code":6789,"language":86,"meta":87,"style":87},[39,13315,13316,13320,13324,13328,13332,13336,13340,13344,13348,13352,13356],{"__ignoreMap":87},[91,13317,13318],{"class":93,"line":94},[91,13319,6593],{},[91,13321,13322],{"class":93,"line":100},[91,13323,110],{"emptyLinePlaceholder":109},[91,13325,13326],{"class":93,"line":106},[91,13327,6804],{},[91,13329,13330],{"class":93,"line":113},[91,13331,6809],{},[91,13333,13334],{"class":93,"line":119},[91,13335,6814],{},[91,13337,13338],{"class":93,"line":1202},[91,13339,6819],{},[91,13341,13342],{"class":93,"line":2541},[91,13343,110],{"emptyLinePlaceholder":109},[91,13345,13346],{"class":93,"line":2547},[91,13347,6828],{},[91,13349,13350],{"class":93,"line":4006},[91,13351,6833],{},[91,13353,13354],{"class":93,"line":4218},[91,13355,6838],{},[91,13357,13358],{"class":93,"line":5883},[91,13359,6843],{},[10,13361,162],{},[82,13363,13365],{"className":13364,"code":6849,"language":168,"meta":87},[166],[39,13366,6849],{"__ignoreMap":87},[10,13368,173],{},[14,13370,176],{"id":176},[178,13372,13373,13377],{},[54,13374,6860,13375,6863],{},[39,13376,6777],{},[54,13378,6866],{},[14,13380,222],{"id":222},[51,13382,13383,13387],{},[54,13384,2392,13385,6875],{},[39,13386,6761],{},[54,13388,6878,13389,159],{},[39,13390,6881],{},[14,13392,241],{"id":241},[178,13394,13395,13397],{},[54,13396,6888],{},[54,13398,6891,13399,6894],{},[39,13400,390],{},[10,13402,258],{},[14,13404,261],{"id":261},[10,13406,6901],{},[266,13408,268],{},{"title":87,"searchDepth":100,"depth":100,"links":13410},[13411,13412,13413,13414,13415,13416,13417,13418],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":6731,"description":6736},[281,6921,6922],{"id":6925,"title":6926,"body":13423,"category":281,"cover":282,"description":6931,"extension":283,"meta":13566,"navigation":109,"path":7099,"pinned":286,"publishedAt":287,"seo":13567,"slug":7101,"stem":7102,"summary":7103,"tags":13568,"updatedAt":287,"visible":109,"__hash__":7107},{"type":7,"value":13424,"toc":13556},[13425,13427,13429,13431,13433,13437,13443,13445,13455,13457,13459,13511,13513,13518,13520,13522,13532,13534,13540,13542,13548,13550,13552,13554],[10,13426,6931],{},[14,13428,16],{"id":16},[10,13430,6936],{},[14,13432,27],{"id":27},[10,13434,13435],{},[31,13436],{"alt":6943,"src":6944},[10,13438,13439,6950,13441,6954],{},[39,13440,6949],{},[39,13442,6953],{},[14,13444,49],{"id":49},[51,13446,13447,13449,13453],{},[54,13448,6961],{},[54,13450,13451,6967],{},[39,13452,6966],{},[54,13454,6970],{},[14,13456,73],{"id":73},[10,13458,1490],{},[82,13460,13461],{"className":84,"code":6977,"language":86,"meta":87,"style":87},[39,13462,13463,13467,13471,13475,13479,13483,13487,13491,13495,13499,13503,13507],{"__ignoreMap":87},[91,13464,13465],{"class":93,"line":94},[91,13466,6984],{},[91,13468,13469],{"class":93,"line":100},[91,13470,110],{"emptyLinePlaceholder":109},[91,13472,13473],{"class":93,"line":106},[91,13474,6993],{},[91,13476,13477],{"class":93,"line":113},[91,13478,110],{"emptyLinePlaceholder":109},[91,13480,13481],{"class":93,"line":119},[91,13482,7002],{},[91,13484,13485],{"class":93,"line":1202},[91,13486,7007],{},[91,13488,13489],{"class":93,"line":2541},[91,13490,6819],{},[91,13492,13493],{"class":93,"line":2547},[91,13494,110],{"emptyLinePlaceholder":109},[91,13496,13497],{"class":93,"line":4006},[91,13498,7020],{},[91,13500,13501],{"class":93,"line":4218},[91,13502,7025],{},[91,13504,13505],{"class":93,"line":5883},[91,13506,6838],{},[91,13508,13509],{"class":93,"line":5888},[91,13510,7034],{},[10,13512,162],{},[82,13514,13516],{"className":13515,"code":7040,"language":168,"meta":87},[166],[39,13517,7040],{"__ignoreMap":87},[10,13519,173],{},[14,13521,176],{"id":176},[178,13523,13524,13528],{},[54,13525,13526,7053],{},[39,13527,6949],{},[54,13529,13530,7058],{},[39,13531,6953],{},[14,13533,222],{"id":222},[51,13535,13536,13538],{},[54,13537,7065],{},[54,13539,7068],{},[14,13541,241],{"id":241},[178,13543,13544,13546],{},[54,13545,7075],{},[54,13547,7078],{},[10,13549,258],{},[14,13551,261],{"id":261},[10,13553,7085],{},[266,13555,268],{},{"title":87,"searchDepth":100,"depth":100,"links":13557},[13558,13559,13560,13561,13562,13563,13564,13565],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":6926,"description":6931},[281,7105,7106],{"id":7109,"title":7110,"body":13570,"category":281,"cover":282,"description":7115,"extension":283,"meta":13721,"navigation":109,"path":7300,"pinned":286,"publishedAt":287,"seo":13722,"slug":7302,"stem":7303,"summary":7304,"tags":13723,"updatedAt":287,"visible":109,"__hash__":7308},{"type":7,"value":13571,"toc":13711},[13572,13574,13576,13578,13580,13584,13588,13590,13604,13606,13608,13660,13662,13667,13669,13671,13683,13685,13695,13697,13703,13705,13707,13709],[10,13573,7115],{},[14,13575,16],{"id":16},[10,13577,7120],{},[14,13579,27],{"id":27},[10,13581,13582],{},[31,13583],{"alt":7127,"src":7128},[10,13585,13586,7134],{},[39,13587,7133],{},[14,13589,49],{"id":49},[51,13591,13592,13598,13602],{},[54,13593,2392,13594,7144,13596,7148],{},[39,13595,7143],{},[39,13597,7147],{},[54,13599,7151,13600,7155],{},[39,13601,7154],{},[54,13603,7158],{},[14,13605,73],{"id":73},[10,13607,1490],{},[82,13609,13610],{"className":84,"code":7165,"language":86,"meta":87,"style":87},[39,13611,13612,13616,13620,13624,13628,13632,13636,13640,13644,13648,13652,13656],{"__ignoreMap":87},[91,13613,13614],{"class":93,"line":94},[91,13615,7172],{},[91,13617,13618],{"class":93,"line":100},[91,13619,110],{"emptyLinePlaceholder":109},[91,13621,13622],{"class":93,"line":106},[91,13623,7181],{},[91,13625,13626],{"class":93,"line":113},[91,13627,7186],{},[91,13629,13630],{"class":93,"line":119},[91,13631,7191],{},[91,13633,13634],{"class":93,"line":1202},[91,13635,7196],{},[91,13637,13638],{"class":93,"line":2541},[91,13639,7201],{},[91,13641,13642],{"class":93,"line":2547},[91,13643,110],{"emptyLinePlaceholder":109},[91,13645,13646],{"class":93,"line":4006},[91,13647,7210],{},[91,13649,13650],{"class":93,"line":4218},[91,13651,7215],{},[91,13653,13654],{"class":93,"line":5883},[91,13655,7220],{},[91,13657,13658],{"class":93,"line":5888},[91,13659,7225],{},[10,13661,162],{},[82,13663,13665],{"className":13664,"code":7231,"language":168,"meta":87},[166],[39,13666,7231],{"__ignoreMap":87},[10,13668,173],{},[14,13670,176],{"id":176},[178,13672,13673,13679],{},[54,13674,13675,7245,13677,7248],{},[39,13676,7244],{},[39,13678,7154],{},[54,13680,13681,7253],{},[39,13682,7133],{},[14,13684,222],{"id":222},[51,13686,13687,13689],{},[54,13688,7260],{},[54,13690,7263,13691,7266,13693,7269],{},[39,13692,7143],{},[39,13694,7147],{},[14,13696,241],{"id":241},[178,13698,13699,13701],{},[54,13700,7276],{},[54,13702,7279],{},[10,13704,258],{},[14,13706,261],{"id":261},[10,13708,7286],{},[266,13710,268],{},{"title":87,"searchDepth":100,"depth":100,"links":13712},[13713,13714,13715,13716,13717,13718,13719,13720],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":7110,"description":7115},[281,7306,7307],{"id":7310,"title":7311,"body":13725,"category":281,"cover":282,"description":7316,"extension":283,"meta":13939,"navigation":109,"path":7590,"pinned":286,"publishedAt":287,"seo":13940,"slug":7592,"stem":7593,"summary":7594,"tags":13941,"updatedAt":287,"visible":109,"__hash__":7598},{"type":7,"value":13726,"toc":13926},[13727,13729,13731,13733,13735,13739,13745,13747,13759,13761,13763,13823,13825,13830,13832,13834,13852,13854,13862,13866,13874,13876,13880,13884,13890,13892,13902,13904,13918,13920,13922,13924],[10,13728,7316],{},[14,13730,16],{"id":16},[10,13732,7321],{},[14,13734,27],{"id":27},[10,13736,13737],{},[31,13738],{"alt":7328,"src":7329},[10,13740,7332,13741,7336,13743,7340],{},[39,13742,7335],{},[39,13744,7339],{},[14,13746,49],{"id":49},[51,13748,13749,13753,13757],{},[54,13750,7347,13751,7350],{},[39,13752,7335],{},[54,13754,13755,7356],{},[39,13756,7355],{},[54,13758,7359],{},[14,13760,73],{"id":73},[10,13762,1490],{},[82,13764,13765],{"className":84,"code":7366,"language":86,"meta":87,"style":87},[39,13766,13767,13771,13775,13779,13783,13787,13791,13795,13799,13803,13807,13811,13815,13819],{"__ignoreMap":87},[91,13768,13769],{"class":93,"line":94},[91,13770,7373],{},[91,13772,13773],{"class":93,"line":100},[91,13774,7378],{},[91,13776,13777],{"class":93,"line":106},[91,13778,7383],{},[91,13780,13781],{"class":93,"line":113},[91,13782,7388],{},[91,13784,13785],{"class":93,"line":119},[91,13786,7393],{},[91,13788,13789],{"class":93,"line":1202},[91,13790,110],{"emptyLinePlaceholder":109},[91,13792,13793],{"class":93,"line":2541},[91,13794,7402],{},[91,13796,13797],{"class":93,"line":2547},[91,13798,7407],{},[91,13800,13801],{"class":93,"line":4006},[91,13802,7412],{},[91,13804,13805],{"class":93,"line":4218},[91,13806,7417],{},[91,13808,13809],{"class":93,"line":5883},[91,13810,1199],{},[91,13812,13813],{"class":93,"line":5888},[91,13814,7426],{},[91,13816,13817],{"class":93,"line":7429},[91,13818,7432],{},[91,13820,13821],{"class":93,"line":7435},[91,13822,7438],{},[10,13824,162],{},[82,13826,13828],{"className":13827,"code":7444,"language":168,"meta":87},[166],[39,13829,7444],{"__ignoreMap":87},[10,13831,173],{},[14,13833,176],{"id":176},[178,13835,13836,13844],{},[54,13837,13838,7457,13840,7460,13842,7464],{},[39,13839,3089],{},[39,13841,7355],{},[39,13843,7463],{},[54,13845,7467,13846,7470,13848,7473,13850,159],{},[39,13847,7335],{},[39,13849,1213],{},[39,13851,7339],{},[202,13853,204],{"id":204},[10,13855,13856,2310,13858,155,13860,7486],{},[39,13857,7335],{},[39,13859,1213],{},[39,13861,7339],{},[10,13863,13864],{},[31,13865],{"alt":7491,"src":7492},[10,13867,13868,7497,13870,7500,13872,7503],{},[39,13869,7335],{},[39,13871,1213],{},[39,13873,7339],{},[202,13875,204],{"id":4273},[10,13877,13878,7511],{},[39,13879,7510],{},[10,13881,13882],{},[31,13883],{"alt":7516,"src":7517},[10,13885,7520,13886,7523,13888,7526],{},[39,13887,7510],{},[39,13889,1213],{},[14,13891,222],{"id":222},[51,13893,13894,13898],{},[54,13895,7533,13896,7537],{},[39,13897,7536],{},[54,13899,7540,13900,7543],{},[39,13901,7510],{},[14,13903,241],{"id":241},[178,13905,13906,13914],{},[54,13907,7550,13908,7554,13910,155,13912,159],{},[39,13909,7553],{},[39,13911,7557],{},[39,13913,7560],{},[54,13915,7563,13916,7566],{},[39,13917,6771],{},[10,13919,258],{},[14,13921,261],{"id":261},[10,13923,7573],{},[266,13925,268],{},{"title":87,"searchDepth":100,"depth":100,"links":13927},[13928,13929,13930,13931,13932,13936,13937,13938],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":13933},[13934,13935],{"id":204,"depth":106,"text":204},{"id":4273,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":7311,"description":7316},[281,7596,7597],{"id":7600,"title":7601,"body":13943,"category":281,"cover":282,"description":7606,"extension":283,"meta":14094,"navigation":109,"path":7783,"pinned":286,"publishedAt":287,"seo":14095,"slug":7785,"stem":7786,"summary":7787,"tags":14096,"updatedAt":287,"visible":109,"__hash__":7790},{"type":7,"value":13944,"toc":14084},[13945,13947,13949,13951,13953,13957,13961,13963,13975,13977,13979,14027,14029,14034,14036,14038,14048,14050,14060,14062,14076,14078,14080,14082],[10,13946,7606],{},[14,13948,16],{"id":16},[10,13950,7611],{},[14,13952,27],{"id":27},[10,13954,13955],{},[31,13956],{"alt":7618,"src":7619},[10,13958,7622,13959,7625],{},[39,13960,6781],{},[14,13962,49],{"id":49},[51,13964,13965,13969,13973],{},[54,13966,13967,7634],{},[39,13968,6781],{},[54,13970,13971,7640],{},[39,13972,7639],{},[54,13974,7643],{},[14,13976,73],{"id":73},[10,13978,1490],{},[82,13980,13981],{"className":84,"code":7650,"language":86,"meta":87,"style":87},[39,13982,13983,13987,13991,13995,13999,14003,14007,14011,14015,14019,14023],{"__ignoreMap":87},[91,13984,13985],{"class":93,"line":94},[91,13986,6593],{},[91,13988,13989],{"class":93,"line":100},[91,13990,110],{"emptyLinePlaceholder":109},[91,13992,13993],{"class":93,"line":106},[91,13994,6804],{},[91,13996,13997],{"class":93,"line":113},[91,13998,110],{"emptyLinePlaceholder":109},[91,14000,14001],{"class":93,"line":119},[91,14002,7673],{},[91,14004,14005],{"class":93,"line":1202},[91,14006,7678],{},[91,14008,14009],{"class":93,"line":2541},[91,14010,110],{"emptyLinePlaceholder":109},[91,14012,14013],{"class":93,"line":2547},[91,14014,7687],{},[91,14016,14017],{"class":93,"line":4006},[91,14018,7692],{},[91,14020,14021],{"class":93,"line":4218},[91,14022,110],{"emptyLinePlaceholder":109},[91,14024,14025],{"class":93,"line":5883},[91,14026,7701],{},[10,14028,162],{},[82,14030,14032],{"className":14031,"code":7707,"language":168,"meta":87},[166],[39,14033,7707],{"__ignoreMap":87},[10,14035,173],{},[14,14037,176],{"id":176},[178,14039,14040,14046],{},[54,14041,7622,14042,7720,14044,159],{},[39,14043,6781],{},[39,14045,7723],{},[54,14047,7726],{},[14,14049,222],{"id":222},[51,14051,14052,14056],{},[54,14053,4841,14054,7735],{},[39,14055,6781],{},[54,14057,7738,14058,7741],{},[39,14059,6781],{},[14,14061,241],{"id":241},[178,14063,14064,14070],{},[54,14065,7748,14066,7752,14068,159],{},[39,14067,7751],{},[39,14069,6781],{},[54,14071,4841,14072,7759,14074,159],{},[39,14073,6781],{},[39,14075,7762],{},[10,14077,258],{},[14,14079,261],{"id":261},[10,14081,7769],{},[266,14083,268],{},{"title":87,"searchDepth":100,"depth":100,"links":14085},[14086,14087,14088,14089,14090,14091,14092,14093],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":7601,"description":7606},[281,6781,7789],{"id":7792,"title":7793,"body":14098,"category":281,"cover":282,"description":7798,"extension":283,"meta":14269,"navigation":109,"path":8011,"pinned":286,"publishedAt":287,"seo":14270,"slug":8013,"stem":8014,"summary":8015,"tags":14271,"updatedAt":287,"visible":109,"__hash__":8019},{"type":7,"value":14099,"toc":14257},[14100,14102,14104,14106,14108,14112,14114,14116,14128,14130,14132,14188,14190,14195,14197,14199,14215,14217,14219,14223,14229,14231,14239,14241,14249,14251,14253,14255],[10,14101,7798],{},[14,14103,16],{"id":16},[10,14105,7803],{},[14,14107,27],{"id":27},[10,14109,14110],{},[31,14111],{"alt":7810,"src":7811},[10,14113,7814],{},[14,14115,49],{"id":49},[51,14117,14118,14122,14126],{},[54,14119,14120,7824],{},[39,14121,7823],{},[54,14123,14124,7830],{},[39,14125,7829],{},[54,14127,7833],{},[14,14129,73],{"id":73},[10,14131,1490],{},[82,14133,14134],{"className":84,"code":7840,"language":86,"meta":87,"style":87},[39,14135,14136,14140,14144,14148,14152,14156,14160,14164,14168,14172,14176,14180,14184],{"__ignoreMap":87},[91,14137,14138],{"class":93,"line":94},[91,14139,7847],{},[91,14141,14142],{"class":93,"line":100},[91,14143,7852],{},[91,14145,14146],{"class":93,"line":106},[91,14147,7857],{},[91,14149,14150],{"class":93,"line":113},[91,14151,7862],{},[91,14153,14154],{"class":93,"line":119},[91,14155,110],{"emptyLinePlaceholder":109},[91,14157,14158],{"class":93,"line":1202},[91,14159,7871],{},[91,14161,14162],{"class":93,"line":2541},[91,14163,7876],{},[91,14165,14166],{"class":93,"line":2547},[91,14167,7881],{},[91,14169,14170],{"class":93,"line":4006},[91,14171,7886],{},[91,14173,14174],{"class":93,"line":4218},[91,14175,110],{"emptyLinePlaceholder":109},[91,14177,14178],{"class":93,"line":5883},[91,14179,7895],{},[91,14181,14182],{"class":93,"line":5888},[91,14183,7900],{},[91,14185,14186],{"class":93,"line":7429},[91,14187,7905],{},[10,14189,162],{},[82,14191,14193],{"className":14192,"code":7911,"language":168,"meta":87},[166],[39,14194,7911],{"__ignoreMap":87},[10,14196,173],{},[14,14198,176],{"id":176},[178,14200,14201,14207],{},[54,14202,7922,14203,7926,14205,7929],{},[39,14204,7925],{},[39,14206,7829],{},[54,14208,14209,7935,14211,7939,14213,7942],{},[39,14210,7934],{},[39,14212,7938],{},[39,14214,7823],{},[202,14216,204],{"id":204},[10,14218,7947],{},[10,14220,14221],{},[31,14222],{"alt":7952,"src":7953},[10,14224,7956,14225,155,14227,7962],{},[39,14226,4638],{},[39,14228,7961],{},[14,14230,222],{"id":222},[51,14232,14233,14237],{},[54,14234,7969,14235,7972],{},[39,14236,7823],{},[54,14238,7975],{},[14,14240,241],{"id":241},[178,14242,14243,14247],{},[54,14244,5351,14245,7985],{},[39,14246,7984],{},[54,14248,7988],{},[10,14250,258],{},[14,14252,261],{"id":261},[10,14254,7995],{},[266,14256,268],{},{"title":87,"searchDepth":100,"depth":100,"links":14258},[14259,14260,14261,14262,14263,14266,14267,14268],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":14264},[14265],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":7793,"description":7798},[281,8017,8018],{"id":8021,"title":8022,"body":14273,"category":281,"cover":282,"description":8027,"extension":283,"meta":14420,"navigation":109,"path":8206,"pinned":286,"publishedAt":287,"seo":14421,"slug":8208,"stem":8209,"summary":8210,"tags":14422,"updatedAt":287,"visible":109,"__hash__":8214},{"type":7,"value":14274,"toc":14410},[14275,14277,14279,14281,14283,14287,14289,14291,14299,14301,14303,14359,14361,14366,14368,14370,14382,14384,14390,14392,14402,14404,14406,14408],[10,14276,8027],{},[14,14278,16],{"id":16},[10,14280,8032],{},[14,14282,27],{"id":27},[10,14284,14285],{},[31,14286],{"alt":8039,"src":8040},[10,14288,8043],{},[14,14290,49],{"id":49},[51,14292,14293,14295,14297],{},[54,14294,8050],{},[54,14296,8053],{},[54,14298,8056],{},[14,14300,73],{"id":73},[10,14302,1490],{},[82,14304,14305],{"className":84,"code":8063,"language":86,"meta":87,"style":87},[39,14306,14307,14311,14315,14319,14323,14327,14331,14335,14339,14343,14347,14351,14355],{"__ignoreMap":87},[91,14308,14309],{"class":93,"line":94},[91,14310,8070],{},[91,14312,14313],{"class":93,"line":100},[91,14314,8075],{},[91,14316,14317],{"class":93,"line":106},[91,14318,8080],{},[91,14320,14321],{"class":93,"line":113},[91,14322,110],{"emptyLinePlaceholder":109},[91,14324,14325],{"class":93,"line":119},[91,14326,8089],{},[91,14328,14329],{"class":93,"line":1202},[91,14330,8094],{},[91,14332,14333],{"class":93,"line":2541},[91,14334,8099],{},[91,14336,14337],{"class":93,"line":2547},[91,14338,110],{"emptyLinePlaceholder":109},[91,14340,14341],{"class":93,"line":4006},[91,14342,8108],{},[91,14344,14345],{"class":93,"line":4218},[91,14346,8113],{},[91,14348,14349],{"class":93,"line":5883},[91,14350,110],{"emptyLinePlaceholder":109},[91,14352,14353],{"class":93,"line":5888},[91,14354,8122],{},[91,14356,14357],{"class":93,"line":7429},[91,14358,8127],{},[10,14360,162],{},[82,14362,14364],{"className":14363,"code":8133,"language":168,"meta":87},[166],[39,14365,8133],{"__ignoreMap":87},[10,14367,173],{},[14,14369,176],{"id":176},[178,14371,14372,14378],{},[54,14373,14374,8147,14376,8151],{},[39,14375,8146],{},[39,14377,8150],{},[54,14379,8154,14380,8158],{},[39,14381,8157],{},[14,14383,222],{"id":222},[51,14385,14386,14388],{},[54,14387,8165],{},[54,14389,8168],{},[14,14391,241],{"id":241},[178,14393,14394,14400],{},[54,14395,8175,14396,8179,14398,159],{},[39,14397,8178],{},[39,14399,8182],{},[54,14401,8185],{},[10,14403,258],{},[14,14405,261],{"id":261},[10,14407,8192],{},[266,14409,268],{},{"title":87,"searchDepth":100,"depth":100,"links":14411},[14412,14413,14414,14415,14416,14417,14418,14419],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":8022,"description":8027},[281,8212,8213],{"id":8216,"title":8217,"body":14424,"category":281,"cover":282,"description":8222,"extension":283,"meta":14587,"navigation":109,"path":8426,"pinned":286,"publishedAt":287,"seo":14588,"slug":8428,"stem":8429,"summary":8430,"tags":14589,"updatedAt":287,"visible":109,"__hash__":8434},{"type":7,"value":14425,"toc":14575},[14426,14428,14430,14432,14434,14438,14442,14444,14460,14462,14464,14508,14510,14515,14517,14519,14533,14535,14539,14543,14547,14549,14555,14557,14567,14569,14571,14573],[10,14427,8222],{},[14,14429,16],{"id":16},[10,14431,8227],{},[14,14433,27],{"id":27},[10,14435,14436],{},[31,14437],{"alt":8234,"src":8235},[10,14439,8238,14440,8242],{},[39,14441,8241],{},[14,14443,49],{"id":49},[51,14445,14446,14452,14458],{},[54,14447,14448,8252,14450,8256],{},[39,14449,8251],{},[39,14451,8255],{},[54,14453,8259,14454,8263,14456,8266],{},[39,14455,8262],{},[39,14457,4392],{},[54,14459,8269],{},[14,14461,73],{"id":73},[10,14463,1490],{},[82,14465,14466],{"className":84,"code":8276,"language":86,"meta":87,"style":87},[39,14467,14468,14472,14476,14480,14484,14488,14492,14496,14500,14504],{"__ignoreMap":87},[91,14469,14470],{"class":93,"line":94},[91,14471,8283],{},[91,14473,14474],{"class":93,"line":100},[91,14475,8288],{},[91,14477,14478],{"class":93,"line":106},[91,14479,8293],{},[91,14481,14482],{"class":93,"line":113},[91,14483,8298],{},[91,14485,14486],{"class":93,"line":119},[91,14487,8303],{},[91,14489,14490],{"class":93,"line":1202},[91,14491,110],{"emptyLinePlaceholder":109},[91,14493,14494],{"class":93,"line":2541},[91,14495,8312],{},[91,14497,14498],{"class":93,"line":2547},[91,14499,8317],{},[91,14501,14502],{"class":93,"line":4006},[91,14503,8317],{},[91,14505,14506],{"class":93,"line":4218},[91,14507,8317],{},[10,14509,162],{},[82,14511,14513],{"className":14512,"code":8331,"language":168,"meta":87},[166],[39,14514,8331],{"__ignoreMap":87},[10,14516,173],{},[14,14518,176],{"id":176},[178,14520,14521,14525],{},[54,14522,7922,14523,8345],{},[39,14524,8344],{},[54,14526,8348,14527,8351,14529,8354,14531,8358],{},[39,14528,8255],{},[39,14530,8241],{},[39,14532,8357],{},[202,14534,204],{"id":204},[10,14536,8363,14537,8366],{},[39,14538,8255],{},[10,14540,14541],{},[31,14542],{"alt":8371,"src":8372},[10,14544,8375,14545,8378],{},[39,14546,8241],{},[14,14548,222],{"id":222},[51,14550,14551,14553],{},[54,14552,8385],{},[54,14554,8388],{},[14,14556,241],{"id":241},[178,14558,14559,14561],{},[54,14560,8395],{},[54,14562,4064,14563,8400,14565,8403],{},[39,14564,4392],{},[39,14566,8255],{},[10,14568,258],{},[14,14570,261],{"id":261},[10,14572,8410],{},[266,14574,268],{},{"title":87,"searchDepth":100,"depth":100,"links":14576},[14577,14578,14579,14580,14581,14584,14585,14586],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":14582},[14583],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":8217,"description":8222},[281,8432,8433],{"id":8436,"title":8437,"body":14591,"category":281,"cover":282,"description":8442,"extension":283,"meta":14774,"navigation":109,"path":8667,"pinned":286,"publishedAt":287,"seo":14775,"slug":8669,"stem":8670,"summary":8671,"tags":14776,"updatedAt":287,"visible":109,"__hash__":8674},{"type":7,"value":14592,"toc":14762},[14593,14595,14597,14599,14601,14605,14607,14609,14623,14625,14627,14695,14697,14702,14704,14706,14720,14722,14724,14728,14734,14736,14744,14746,14754,14756,14758,14760],[10,14594,8442],{},[14,14596,16],{"id":16},[10,14598,8447],{},[14,14600,27],{"id":27},[10,14602,14603],{},[31,14604],{"alt":8454,"src":8455},[10,14606,8458],{},[14,14608,49],{"id":49},[51,14610,14611,14617,14619],{},[54,14612,14613,8468,14615,159],{},[39,14614,8467],{},[39,14616,8471],{},[54,14618,8474],{},[54,14620,14621,8480],{},[39,14622,8479],{},[14,14624,73],{"id":73},[10,14626,1490],{},[82,14628,14629],{"className":84,"code":8487,"language":86,"meta":87,"style":87},[39,14630,14631,14635,14639,14643,14647,14651,14655,14659,14663,14667,14671,14675,14679,14683,14687,14691],{"__ignoreMap":87},[91,14632,14633],{"class":93,"line":94},[91,14634,8494],{},[91,14636,14637],{"class":93,"line":100},[91,14638,110],{"emptyLinePlaceholder":109},[91,14640,14641],{"class":93,"line":106},[91,14642,8503],{},[91,14644,14645],{"class":93,"line":113},[91,14646,8508],{},[91,14648,14649],{"class":93,"line":119},[91,14650,8513],{},[91,14652,14653],{"class":93,"line":1202},[91,14654,8518],{},[91,14656,14657],{"class":93,"line":2541},[91,14658,8523],{},[91,14660,14661],{"class":93,"line":2547},[91,14662,8528],{},[91,14664,14665],{"class":93,"line":4006},[91,14666,8533],{},[91,14668,14669],{"class":93,"line":4218},[91,14670,8538],{},[91,14672,14673],{"class":93,"line":5883},[91,14674,110],{"emptyLinePlaceholder":109},[91,14676,14677],{"class":93,"line":5888},[91,14678,8547],{},[91,14680,14681],{"class":93,"line":7429},[91,14682,97],{},[91,14684,14685],{"class":93,"line":7435},[91,14686,103],{},[91,14688,14689],{"class":93,"line":8558},[91,14690,110],{"emptyLinePlaceholder":109},[91,14692,14693],{"class":93,"line":8563},[91,14694,8566],{},[10,14696,162],{},[82,14698,14700],{"className":14699,"code":8572,"language":168,"meta":87},[166],[39,14701,8572],{"__ignoreMap":87},[10,14703,173],{},[14,14705,176],{"id":176},[178,14707,14708,14718],{},[54,14709,8583,14710,8587,14712,8591,14714,8595,14716,159],{},[39,14711,8586],{},[39,14713,8590],{},[39,14715,8594],{},[39,14717,8586],{},[54,14719,8600],{},[202,14721,204],{"id":204},[10,14723,8605],{},[10,14725,14726],{},[31,14727],{"alt":8610,"src":8611},[10,14729,14730,8616,14732,159],{},[39,14731,8467],{},[39,14733,8471],{},[14,14735,222],{"id":222},[51,14737,14738,14742],{},[54,14739,8625,14740,159],{},[39,14741,5434],{},[54,14743,8630],{},[14,14745,241],{"id":241},[178,14747,14748,14750],{},[54,14749,8637],{},[54,14751,8640,14752,8644],{},[39,14753,8643],{},[10,14755,258],{},[14,14757,261],{"id":261},[10,14759,8651],{},[266,14761,268],{},{"title":87,"searchDepth":100,"depth":100,"links":14763},[14764,14765,14766,14767,14768,14771,14772,14773],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":14769},[14770],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":8437,"description":8442},[281,8673,5385],{"id":8676,"title":8677,"body":14778,"category":281,"cover":282,"description":8682,"extension":283,"meta":14937,"navigation":109,"path":8870,"pinned":286,"publishedAt":287,"seo":14938,"slug":8872,"stem":8873,"summary":8874,"tags":14939,"updatedAt":287,"visible":109,"__hash__":8878},{"type":7,"value":14779,"toc":14925},[14780,14782,14784,14786,14788,14792,14794,14796,14804,14806,14808,14872,14874,14879,14881,14883,14891,14893,14895,14899,14901,14903,14909,14911,14917,14919,14921,14923],[10,14781,8682],{},[14,14783,16],{"id":16},[10,14785,8687],{},[14,14787,27],{"id":27},[10,14789,14790],{},[31,14791],{"alt":8694,"src":8695},[10,14793,8698],{},[14,14795,49],{"id":49},[51,14797,14798,14800,14802],{},[54,14799,8705],{},[54,14801,8708],{},[54,14803,8711],{},[14,14805,73],{"id":73},[10,14807,1490],{},[82,14809,14810],{"className":84,"code":8718,"language":86,"meta":87,"style":87},[39,14811,14812,14816,14820,14824,14828,14832,14836,14840,14844,14848,14852,14856,14860,14864,14868],{"__ignoreMap":87},[91,14813,14814],{"class":93,"line":94},[91,14815,8725],{},[91,14817,14818],{"class":93,"line":100},[91,14819,8730],{},[91,14821,14822],{"class":93,"line":106},[91,14823,110],{"emptyLinePlaceholder":109},[91,14825,14826],{"class":93,"line":113},[91,14827,8739],{},[91,14829,14830],{"class":93,"line":119},[91,14831,110],{"emptyLinePlaceholder":109},[91,14833,14834],{"class":93,"line":1202},[91,14835,8748],{},[91,14837,14838],{"class":93,"line":2541},[91,14839,8753],{},[91,14841,14842],{"class":93,"line":2547},[91,14843,8758],{},[91,14845,14846],{"class":93,"line":4006},[91,14847,110],{"emptyLinePlaceholder":109},[91,14849,14850],{"class":93,"line":4218},[91,14851,8767],{},[91,14853,14854],{"class":93,"line":5883},[91,14855,8772],{},[91,14857,14858],{"class":93,"line":5888},[91,14859,8777],{},[91,14861,14862],{"class":93,"line":7429},[91,14863,110],{"emptyLinePlaceholder":109},[91,14865,14866],{"class":93,"line":7435},[91,14867,116],{},[91,14869,14870],{"class":93,"line":8558},[91,14871,8790],{},[10,14873,162],{},[82,14875,14877],{"className":14876,"code":8796,"language":168,"meta":87},[166],[39,14878,8796],{"__ignoreMap":87},[10,14880,173],{},[14,14882,176],{"id":176},[178,14884,14885,14889],{},[54,14886,14887,8810],{},[39,14888,8809],{},[54,14890,8813],{},[202,14892,204],{"id":204},[10,14894,8818],{},[10,14896,14897],{},[31,14898],{"alt":8823,"src":8824},[10,14900,8827],{},[14,14902,222],{"id":222},[51,14904,14905,14907],{},[54,14906,8834],{},[54,14908,8837],{},[14,14910,241],{"id":241},[178,14912,14913,14915],{},[54,14914,8844],{},[54,14916,8847],{},[10,14918,258],{},[14,14920,261],{"id":261},[10,14922,8854],{},[266,14924,268],{},{"title":87,"searchDepth":100,"depth":100,"links":14926},[14927,14928,14929,14930,14931,14934,14935,14936],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":14932},[14933],{"id":204,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":8677,"description":8682},[281,8876,8877],{"id":8880,"title":8881,"body":14941,"category":281,"cover":282,"description":8886,"extension":283,"meta":15179,"navigation":109,"path":9187,"pinned":286,"publishedAt":287,"seo":15180,"slug":9189,"stem":9190,"summary":9191,"tags":15181,"updatedAt":287,"visible":109,"__hash__":9195},{"type":7,"value":14942,"toc":15166},[14943,14945,14947,14949,14951,14955,14957,14959,14969,14971,14973,15089,15091,15096,15098,15100,15110,15112,15114,15118,15120,15122,15124,15128,15132,15134,15142,15144,15158,15160,15162,15164],[10,14944,8886],{},[14,14946,16],{"id":16},[10,14948,8891],{},[14,14950,27],{"id":27},[10,14952,14953],{},[31,14954],{"alt":8898,"src":8899},[10,14956,8902],{},[14,14958,49],{"id":49},[51,14960,14961,14963,14965],{},[54,14962,8909],{},[54,14964,8912],{},[54,14966,8915,14967,8919],{},[39,14968,8918],{},[14,14970,73],{"id":73},[10,14972,1490],{},[82,14974,14975],{"className":84,"code":8926,"language":86,"meta":87,"style":87},[39,14976,14977,14981,14985,14989,14993,14997,15001,15005,15009,15013,15017,15021,15025,15029,15033,15037,15041,15045,15049,15053,15057,15061,15065,15069,15073,15077,15081,15085],{"__ignoreMap":87},[91,14978,14979],{"class":93,"line":94},[91,14980,6984],{},[91,14982,14983],{"class":93,"line":100},[91,14984,6593],{},[91,14986,14987],{"class":93,"line":106},[91,14988,110],{"emptyLinePlaceholder":109},[91,14990,14991],{"class":93,"line":113},[91,14992,8945],{},[91,14994,14995],{"class":93,"line":119},[91,14996,8950],{},[91,14998,14999],{"class":93,"line":1202},[91,15000,8955],{},[91,15002,15003],{"class":93,"line":2541},[91,15004,8960],{},[91,15006,15007],{"class":93,"line":2547},[91,15008,110],{"emptyLinePlaceholder":109},[91,15010,15011],{"class":93,"line":4006},[91,15012,8969],{},[91,15014,15015],{"class":93,"line":4218},[91,15016,8974],{},[91,15018,15019],{"class":93,"line":5883},[91,15020,8979],{},[91,15022,15023],{"class":93,"line":5888},[91,15024,8984],{},[91,15026,15027],{"class":93,"line":7429},[91,15028,8989],{},[91,15030,15031],{"class":93,"line":7435},[91,15032,110],{"emptyLinePlaceholder":109},[91,15034,15035],{"class":93,"line":8558},[91,15036,8998],{},[91,15038,15039],{"class":93,"line":8563},[91,15040,9003],{},[91,15042,15043],{"class":93,"line":9006},[91,15044,9009],{},[91,15046,15047],{"class":93,"line":9012},[91,15048,110],{"emptyLinePlaceholder":109},[91,15050,15051],{"class":93,"line":9017},[91,15052,9020],{},[91,15054,15055],{"class":93,"line":9023},[91,15056,110],{"emptyLinePlaceholder":109},[91,15058,15059],{"class":93,"line":9028},[91,15060,7402],{},[91,15062,15063],{"class":93,"line":9033},[91,15064,9036],{},[91,15066,15067],{"class":93,"line":9039},[91,15068,9042],{},[91,15070,15071],{"class":93,"line":9045},[91,15072,9048],{},[91,15074,15075],{"class":93,"line":9051},[91,15076,7412],{},[91,15078,15079],{"class":93,"line":9056},[91,15080,9059],{},[91,15082,15083],{"class":93,"line":9062},[91,15084,1199],{},[91,15086,15087],{"class":93,"line":9067},[91,15088,9070],{},[10,15090,162],{},[82,15092,15094],{"className":15093,"code":9076,"language":168,"meta":87},[166],[39,15095,9076],{"__ignoreMap":87},[10,15097,173],{},[14,15099,176],{"id":176},[178,15101,15102,15106],{},[54,15103,9087,15104,9090],{},[39,15105,8918],{},[54,15107,15108,9095],{},[39,15109,8150],{},[202,15111,204],{"id":204},[10,15113,9100],{},[10,15115,15116],{},[31,15117],{"alt":9105,"src":9106},[10,15119,9109],{},[202,15121,204],{"id":4273},[10,15123,9114],{},[10,15125,15126],{},[31,15127],{"alt":9119,"src":9120},[10,15129,9123,15130,9127],{},[39,15131,9126],{},[14,15133,222],{"id":222},[51,15135,15136,15138],{},[54,15137,9134],{},[54,15139,9137,15140,9140],{},[39,15141,9126],{},[14,15143,241],{"id":241},[178,15145,15146,15150,15152],{},[54,15147,9147,15148,9150],{},[39,15149,9126],{},[54,15151,9153],{},[54,15153,9156,15154,9160,15156,9163],{},[39,15155,9159],{},[39,15157,41],{},[10,15159,258],{},[14,15161,261],{"id":261},[10,15163,9170],{},[266,15165,268],{},{"title":87,"searchDepth":100,"depth":100,"links":15167},[15168,15169,15170,15171,15172,15176,15177,15178],{"id":16,"depth":100,"text":16},{"id":27,"depth":100,"text":27},{"id":49,"depth":100,"text":49},{"id":73,"depth":100,"text":73},{"id":176,"depth":100,"text":176,"children":15173},[15174,15175],{"id":204,"depth":106,"text":204},{"id":4273,"depth":106,"text":204},{"id":222,"depth":100,"text":222},{"id":241,"depth":100,"text":241},{"id":261,"depth":100,"text":261},{},{"title":8881,"description":8886},[281,9193,9194],{"id":1109,"title":1110,"body":15183,"category":281,"cover":1118,"description":87,"extension":283,"meta":15419,"navigation":109,"path":1434,"pinned":286,"publishedAt":1435,"seo":15420,"slug":1437,"stem":1438,"summary":1439,"tags":15421,"updatedAt":1435,"visible":109,"__hash__":1443},{"type":7,"value":15184,"toc":15404},[15185,15189,15191,15193,15195,15197,15217,15219,15224,15226,15228,15256,15262,15264,15268,15270,15290,15292,15302,15304,15306,15308,15310,15312,15314,15316,15318,15320,15340,15342,15344,15348,15350,15352,15354,15356,15360,15362,15380,15382,15384,15386,15388,15390,15392,15394,15396,15398,15400,15402],[10,15186,15187],{},[31,15188],{"alt":1117,"src":1118},[10,15190,1121],{},[10,15192,1124],{},[14,15194,1128],{"id":1127},[10,15196,1131],{},[82,15198,15199],{"className":84,"code":1134,"language":86,"meta":87,"style":87},[39,15200,15201,15205,15209,15213],{"__ignoreMap":87},[91,15202,15203],{"class":93,"line":94},[91,15204,1141],{},[91,15206,15207],{"class":93,"line":100},[91,15208,1146],{},[91,15210,15211],{"class":93,"line":106},[91,15212,110],{"emptyLinePlaceholder":109},[91,15214,15215],{"class":93,"line":113},[91,15216,1155],{},[10,15218,1158],{},[82,15220,15222],{"className":15221,"code":1162,"language":168,"meta":87},[166],[39,15223,1162],{"__ignoreMap":87},[10,15225,1167],{},[10,15227,1170],{},[82,15229,15230],{"className":84,"code":1173,"language":86,"meta":87,"style":87},[39,15231,15232,15236,15240,15244,15248,15252],{"__ignoreMap":87},[91,15233,15234],{"class":93,"line":94},[91,15235,1180],{},[91,15237,15238],{"class":93,"line":100},[91,15239,110],{"emptyLinePlaceholder":109},[91,15241,15242],{"class":93,"line":106},[91,15243,1189],{},[91,15245,15246],{"class":93,"line":113},[91,15247,1194],{},[91,15249,15250],{"class":93,"line":119},[91,15251,1199],{},[91,15253,15254],{"class":93,"line":1202},[91,15255,1205],{},[10,15257,15258,155,15260,1214],{},[39,15259,1210],{},[39,15261,1213],{},[14,15263,1218],{"id":1217},[10,15265,1221,15266,1224],{},[39,15267,59],{},[10,15269,1227],{},[82,15271,15272],{"className":84,"code":1230,"language":86,"meta":87,"style":87},[39,15273,15274,15278,15282,15286],{"__ignoreMap":87},[91,15275,15276],{"class":93,"line":94},[91,15277,1237],{},[91,15279,15280],{"class":93,"line":100},[91,15281,1242],{},[91,15283,15284],{"class":93,"line":106},[91,15285,1247],{},[91,15287,15288],{"class":93,"line":113},[91,15289,1252],{},[10,15291,1255],{},[82,15293,15294],{"className":644,"code":1258,"language":646,"meta":87,"style":87},[39,15295,15296],{"__ignoreMap":87},[91,15297,15298,15300],{"class":93,"line":94},[91,15299,744],{"class":653},[91,15301,1267],{"class":689},[10,15303,1270],{},[14,15305,1274],{"id":1273},[202,15307,1277],{"id":1277},[10,15309,1280],{},[202,15311,1283],{"id":1283},[10,15313,1286],{},[202,15315,1289],{"id":1289},[10,15317,1292],{},[10,15319,1295],{},[82,15321,15322],{"className":84,"code":1298,"language":86,"meta":87,"style":87},[39,15323,15324,15328,15332,15336],{"__ignoreMap":87},[91,15325,15326],{"class":93,"line":94},[91,15327,1305],{},[91,15329,15330],{"class":93,"line":100},[91,15331,110],{"emptyLinePlaceholder":109},[91,15333,15334],{"class":93,"line":106},[91,15335,1314],{},[91,15337,15338],{"class":93,"line":113},[91,15339,1319],{},[10,15341,1322],{},[202,15343,1325],{"id":1325},[10,15345,1328,15346,1331],{},[39,15347,316],{},[10,15349,1334],{},[202,15351,1337],{"id":1337},[10,15353,1340],{},[14,15355,1344],{"id":1343},[10,15357,15358],{},[31,15359],{"alt":1349,"src":1350},[10,15361,1353],{},[51,15363,15364,15366,15368,15370,15372,15374,15376,15378],{},[54,15365,1358],{},[54,15367,1361],{},[54,15369,1364],{},[54,15371,1367],{},[54,15373,1370],{},[54,15375,1373],{},[54,15377,1376],{},[54,15379,1379],{},[10,15381,1382],{},[14,15383,1386],{"id":1385},[10,15385,1389],{},[10,15387,1392],{},[14,15389,1396],{"id":1395},[10,15391,1399],{},[10,15393,1402],{},[10,15395,1405],{},[14,15397,1408],{"id":1408},[10,15399,1411],{},[10,15401,1414],{},[266,15403,1417],{},{"title":87,"searchDepth":100,"depth":100,"links":15405},[15406,15407,15408,15415,15416,15417,15418],{"id":1127,"depth":100,"text":1128},{"id":1217,"depth":100,"text":1218},{"id":1273,"depth":100,"text":1274,"children":15409},[15410,15411,15412,15413,15414],{"id":1277,"depth":106,"text":1277},{"id":1283,"depth":106,"text":1283},{"id":1289,"depth":106,"text":1289},{"id":1325,"depth":106,"text":1325},{"id":1337,"depth":106,"text":1337},{"id":1343,"depth":100,"text":1344},{"id":1385,"depth":100,"text":1386},{"id":1395,"depth":100,"text":1396},{"id":1408,"depth":100,"text":1408},{},{"title":1110,"description":87},[281,1441,1442],{"id":298,"title":299,"body":15423,"category":281,"cover":282,"description":87,"extension":283,"meta":16002,"navigation":109,"path":1098,"pinned":286,"publishedAt":1099,"seo":16003,"slug":1101,"stem":1102,"summary":1103,"tags":16004,"updatedAt":1099,"visible":109,"__hash__":1107},{"type":7,"value":15424,"toc":15978},[15425,15427,15429,15431,15435,15437,15439,15463,15475,15477,15479,15484,15488,15492,15504,15508,15512,15516,15518,15552,15554,15558,15562,15564,15586,15616,15628,15638,15646,15648,15654,15664,15666,15671,15675,15677,15691,15697,15717,15719,15721,15723,15733,15737,15739,15748,15752,15754,15756,15776,15780,15782,15784,15786,15788,15808,15810,15812,15814,15840,15842,15858,15860,15876,15880,15882,15884,15904,15906,15908,15910,15914,15924,15926,15928,15930,15940,15948,15950,15952,15966,15976],[14,15426,304],{"id":304},[10,15428,307],{},[10,15430,310],{},[10,15432,313,15433,317],{},[39,15434,316],{},[14,15436,320],{"id":320},[10,15438,323],{},[325,15440,15441,15443],{},[10,15442,329],{},[325,15444,15445,15451,15453,15457,15459],{},[10,15446,334,15447,338,15449,342],{},[39,15448,337],{},[39,15450,341],{},[10,15452,345],{},[10,15454,348,15455,352],{},[21,15456,351],{},[10,15458,355],{},[10,15460,15461],{},[31,15462],{"alt":360,"src":361},[325,15464,15465,15467],{},[10,15466,366],{},[325,15468,15469,15471],{},[10,15470,371],{},[10,15472,15473],{},[31,15474],{"alt":376,"src":377},[14,15476,381],{"id":380},[202,15478,385],{"id":384},[10,15480,388,15481,396],{},[390,15482,395],{"href":392,"rel":15483},[394],[325,15485,15486],{},[10,15487,401],{},[10,15489,15490],{},[31,15491],{"alt":406,"src":407},[51,15493,15494,15498,15502],{},[54,15495,412,15496,159],{},[21,15497,415],{},[54,15499,418,15500,159],{},[21,15501,421],{},[54,15503,424],{},[10,15505,15506],{},[31,15507],{"alt":429,"src":430},[325,15509,15510],{},[10,15511,435],{},[10,15513,15514],{},[31,15515],{"alt":440,"src":441},[202,15517,445],{"id":444},[325,15519,15520,15524,15528,15548],{},[325,15521,15522],{},[10,15523,452],{},[10,15525,455,15526,459],{},[21,15527,458],{},[82,15529,15530],{"className":84,"code":462,"language":86,"meta":87,"style":87},[39,15531,15532,15536,15540,15544],{"__ignoreMap":87},[91,15533,15534],{"class":93,"line":94},[91,15535,469],{},[91,15537,15538],{"class":93,"line":100},[91,15539,474],{},[91,15541,15542],{"class":93,"line":106},[91,15543,479],{},[91,15545,15546],{"class":93,"line":113},[91,15547,484],{},[10,15549,487,15550,491],{},[21,15551,490],{},[10,15553,494],{},[10,15555,497,15556,500],{},[39,15557,86],{},[10,15559,15560],{},[31,15561],{"alt":505,"src":506},[10,15563,509],{},[325,15565,15566,15568,15572],{},[10,15567,514],{},[10,15569,15570],{},[21,15571,519],{},[325,15573,15574,15578,15582],{},[10,15575,524,15576,527],{},[39,15577,86],{},[10,15579,530,15580,533],{},[39,15581,86],{},[10,15583,536,15584,540],{},[21,15585,539],{},[325,15587,15588,15590,15594],{},[10,15589,545],{},[10,15591,15592],{},[21,15593,550],{},[325,15595,15596,15602,15610,15612],{},[10,15597,15598,558,15600,562],{},[39,15599,557],{},[39,15601,561],{},[10,15603,565,15604,568,15606,572,15608,576],{},[39,15605,557],{},[21,15607,571],{},[21,15609,575],{},[10,15611,579],{},[10,15613,15614,585],{},[21,15615,584],{},[325,15617,15618,15620],{},[10,15619,590],{},[325,15621,15622,15626],{},[10,15623,595,15624,599],{},[21,15625,598],{},[10,15627,602],{},[325,15629,15630,15634],{},[10,15631,607,15632],{},[21,15633,610],{},[10,15635,15636],{},[31,15637],{"alt":615,"src":616},[325,15639,15640,15642],{},[10,15641,621],{},[10,15643,15644],{},[31,15645],{"alt":615,"src":626},[202,15647,630],{"id":629},[10,15649,633,15650,637,15652,641],{},[39,15651,636],{},[39,15653,640],{},[82,15655,15656],{"className":644,"code":645,"language":646,"meta":87,"style":87},[39,15657,15658],{"__ignoreMap":87},[91,15659,15660,15662],{"class":93,"line":94},[91,15661,86],{"class":653},[91,15663,657],{"class":656},[10,15665,660],{},[82,15667,15669],{"className":15668,"code":664,"language":168,"meta":87},[166],[39,15670,664],{"__ignoreMap":87},[10,15672,15673],{},[31,15674],{"alt":615,"src":671},[10,15676,674],{},[82,15678,15679],{"className":644,"code":677,"language":646,"meta":87,"style":87},[39,15680,15681],{"__ignoreMap":87},[91,15682,15683,15685,15687,15689],{"class":93,"line":94},[91,15684,86],{"class":653},[91,15686,686],{"class":656},[91,15688,690],{"class":689},[91,15690,657],{"class":656},[10,15692,695,15693,698,15695,702],{},[39,15694,86],{},[39,15696,701],{},[82,15698,15699],{"className":644,"code":705,"language":646,"meta":87,"style":87},[39,15700,15701,15707],{"__ignoreMap":87},[91,15702,15703,15705],{"class":93,"line":94},[91,15704,561],{"class":653},[91,15706,657],{"class":656},[91,15708,15709,15711,15713,15715],{"class":93,"line":100},[91,15710,561],{"class":653},[91,15712,686],{"class":656},[91,15714,690],{"class":689},[91,15716,657],{"class":656},[14,15718,727],{"id":726},[202,15720,731],{"id":730},[10,15722,734],{},[82,15724,15725],{"className":644,"code":737,"language":646,"meta":87,"style":87},[39,15726,15727],{"__ignoreMap":87},[91,15728,15729,15731],{"class":93,"line":94},[91,15730,744],{"class":653},[91,15732,657],{"class":656},[10,15734,749,15735,753],{},[39,15736,752],{},[202,15738,757],{"id":756},[10,15740,388,15741,765,15744,159,15746,772],{},[390,15742,764],{"href":762,"rel":15743},[394],[21,15745,768],{},[39,15747,771],{},[10,15749,775,15750,779],{},[39,15751,778],{},[202,15753,783],{"id":782},[10,15755,786],{},[82,15757,15758],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,15759,15760,15766],{"__ignoreMap":87},[91,15761,15762,15764],{"class":93,"line":94},[91,15763,744],{"class":653},[91,15765,657],{"class":656},[91,15767,15768,15770,15772,15774],{"class":93,"line":100},[91,15769,744],{"class":653},[91,15771,686],{"class":656},[91,15773,690],{"class":689},[91,15775,657],{"class":656},[10,15777,810,15778,813],{},[39,15779,744],{},[14,15781,817],{"id":816},[10,15783,820],{},[202,15785,824],{"id":823},[10,15787,827],{},[82,15789,15790],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,15791,15792,15798],{"__ignoreMap":87},[91,15793,15794,15796],{"class":93,"line":94},[91,15795,744],{"class":653},[91,15797,657],{"class":656},[91,15799,15800,15802,15804,15806],{"class":93,"line":100},[91,15801,744],{"class":653},[91,15803,686],{"class":656},[91,15805,690],{"class":689},[91,15807,657],{"class":656},[10,15809,850],{},[202,15811,854],{"id":853},[10,15813,857],{},[82,15815,15816],{"className":644,"code":860,"language":646,"meta":87,"style":87},[39,15817,15818,15826],{"__ignoreMap":87},[91,15819,15820,15822,15824],{"class":93,"line":94},[91,15821,867],{"class":653},[91,15823,870],{"class":689},[91,15825,873],{"class":689},[91,15827,15828,15830,15832,15834,15836,15838],{"class":93,"line":100},[91,15829,867],{"class":653},[91,15831,870],{"class":689},[91,15833,882],{"class":689},[91,15835,885],{"class":689},[91,15837,888],{"class":689},[91,15839,891],{"class":689},[10,15841,894],{},[82,15843,15844],{"className":644,"code":897,"language":646,"meta":87,"style":87},[39,15845,15846],{"__ignoreMap":87},[91,15847,15848,15850,15852,15854,15856],{"class":93,"line":94},[91,15849,867],{"class":653},[91,15851,906],{"class":689},[91,15853,882],{"class":689},[91,15855,885],{"class":689},[91,15857,913],{"class":689},[10,15859,916],{},[82,15861,15862],{"className":644,"code":919,"language":646,"meta":87,"style":87},[39,15863,15864],{"__ignoreMap":87},[91,15865,15866,15868,15870,15872,15874],{"class":93,"line":94},[91,15867,867],{"class":653},[91,15869,928],{"class":689},[91,15871,931],{"class":656},[91,15873,934],{"class":689},[91,15875,937],{"class":689},[10,15877,15878,942],{},[39,15879,867],{},[202,15881,946],{"id":945},[10,15883,949],{},[82,15885,15886],{"className":644,"code":789,"language":646,"meta":87,"style":87},[39,15887,15888,15894],{"__ignoreMap":87},[91,15889,15890,15892],{"class":93,"line":94},[91,15891,744],{"class":653},[91,15893,657],{"class":656},[91,15895,15896,15898,15900,15902],{"class":93,"line":100},[91,15897,744],{"class":653},[91,15899,686],{"class":656},[91,15901,690],{"class":689},[91,15903,657],{"class":656},[10,15905,972],{},[14,15907,975],{"id":975},[202,15909,979],{"id":978},[10,15911,982,15912,986],{},[39,15913,985],{},[178,15915,15916,15920,15922],{},[54,15917,991,15918,994],{},[39,15919,701],{},[54,15921,997],{},[54,15923,1000],{},[10,15925,1003],{},[202,15927,1007],{"id":1006},[10,15929,1010],{},[82,15931,15932],{"className":644,"code":737,"language":646,"meta":87,"style":87},[39,15933,15934],{"__ignoreMap":87},[91,15935,15936,15938],{"class":93,"line":94},[91,15937,744],{"class":653},[91,15939,657],{"class":656},[10,15941,1023,15942,1026,15944,1029,15946,159],{},[39,15943,744],{},[39,15945,86],{},[39,15947,744],{},[202,15949,1035],{"id":1034},[10,15951,1038],{},[82,15953,15954],{"className":644,"code":1041,"language":646,"meta":87,"style":87},[39,15955,15956],{"__ignoreMap":87},[91,15957,15958,15960,15962,15964],{"class":93,"line":94},[91,15959,744],{"class":653},[91,15961,686],{"class":656},[91,15963,690],{"class":689},[91,15965,657],{"class":656},[10,15967,1056,15968,1059,15970,1062,15972,1065,15974,1069],{},[39,15969,744],{},[39,15971,86],{},[39,15973,561],{},[39,15975,1068],{},[266,15977,1072],{},{"title":87,"searchDepth":100,"depth":100,"links":15979},[15980,15981,15982,15987,15992,15997],{"id":304,"depth":100,"text":304},{"id":320,"depth":100,"text":320},{"id":380,"depth":100,"text":381,"children":15983},[15984,15985,15986],{"id":384,"depth":106,"text":385},{"id":444,"depth":106,"text":445},{"id":629,"depth":106,"text":630},{"id":726,"depth":100,"text":727,"children":15988},[15989,15990,15991],{"id":730,"depth":106,"text":731},{"id":756,"depth":106,"text":757},{"id":782,"depth":106,"text":783},{"id":816,"depth":100,"text":817,"children":15993},[15994,15995,15996],{"id":823,"depth":106,"text":824},{"id":853,"depth":106,"text":854},{"id":945,"depth":106,"text":946},{"id":975,"depth":100,"text":975,"children":15998},[15999,16000,16001],{"id":978,"depth":106,"text":979},{"id":1006,"depth":106,"text":1007},{"id":1034,"depth":106,"text":1035},{},{"title":299,"description":87},[281,1105,1106],1786973365432]