[{"data":1,"prerenderedAt":16011},["ShallowReactive",2],{"post-python-decorator-basics":3,"sidebar-posts":301,"post-related-source":9202},{"id":4,"title":5,"body":6,"category":286,"cover":287,"description":12,"extension":288,"meta":289,"navigation":88,"path":290,"pinned":291,"publishedAt":292,"seo":293,"slug":294,"stem":295,"summary":296,"tags":297,"updatedAt":292,"visible":88,"__hash__":300},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8,"toc":274},"minimark",[9,13,17,20,23,30,33,36,60,63,66,172,175,183,186,189,212,216,219,225,232,235,246,249,261,264,267,270],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,15,16],"h2",{"id":16},"本篇要解决的问题",[10,18,19],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,21,22],{"id":22},"先看清一个容易误解的细节",[10,24,25],{},[26,27],"img",{"alt":28,"src":29},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,31,32],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,34,35],{"id":35},"核心概念",[37,38,39,51,54],"ul",{},[40,41,42,46,47,50],"li",{},[43,44,45],"code",{},"@trace"," 等价于 ",[43,48,49],{},"add = trace(add)","。",[40,52,53],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[40,55,56,59],{},[43,57,58],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,61,62],{"id":62},"跟着示例运行",[10,64,65],{},"把下面代码保存到本课脚本并运行：",[67,68,73],"pre",{"className":69,"code":70,"language":71,"meta":72,"style":72},"language-python shiki shiki-themes github-dark","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","python","",[43,74,75,83,90,96,102,108,114,120,126,132,138,143,149,155,161,166],{"__ignoreMap":72},[76,77,80],"span",{"class":78,"line":79},"line",1,[76,81,82],{},"from functools import wraps\n",[76,84,86],{"class":78,"line":85},2,[76,87,89],{"emptyLinePlaceholder":88},true,"\n",[76,91,93],{"class":78,"line":92},3,[76,94,95],{},"def trace(function):\n",[76,97,99],{"class":78,"line":98},4,[76,100,101],{},"    @wraps(function)\n",[76,103,105],{"class":78,"line":104},5,[76,106,107],{},"    def wrapper(*args, **kwargs):\n",[76,109,111],{"class":78,"line":110},6,[76,112,113],{},"        print(\"开始：\", function.__name__)\n",[76,115,117],{"class":78,"line":116},7,[76,118,119],{},"        result = function(*args, **kwargs)\n",[76,121,123],{"class":78,"line":122},8,[76,124,125],{},"        print(\"结束：\", function.__name__)\n",[76,127,129],{"class":78,"line":128},9,[76,130,131],{},"        return result\n",[76,133,135],{"class":78,"line":134},10,[76,136,137],{},"    return wrapper\n",[76,139,141],{"class":78,"line":140},11,[76,142,89],{"emptyLinePlaceholder":88},[76,144,146],{"class":78,"line":145},12,[76,147,148],{},"@trace\n",[76,150,152],{"class":78,"line":151},13,[76,153,154],{},"def add(left, right):\n",[76,156,158],{"class":78,"line":157},14,[76,159,160],{},"    return left + right\n",[76,162,164],{"class":78,"line":163},15,[76,165,89],{"emptyLinePlaceholder":88},[76,167,169],{"class":78,"line":168},16,[76,170,171],{},"print(add(2, 3))\n",[10,173,174],{},"预期结果：",[67,176,181],{"className":177,"code":179,"language":180,"meta":72},[178],"language-text","开始： add\n结束： add\n5\n","text",[43,182,179],{"__ignoreMap":72},[10,184,185],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,187,188],{"id":188},"按执行顺序拆开看",[190,191,192,209],"ol",{},[40,193,194,195,198,199,202,203,206,207,50],{},"解释器执行定义时，把原 ",[43,196,197],{},"add"," 函数交给 ",[43,200,201],{},"trace","，返回的 ",[43,204,205],{},"wrapper"," 重新绑定到名字 ",[43,208,197],{},[40,210,211],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[213,214,215],"h3",{"id":215},"再看一个具体细节",[10,217,218],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,220,221],{},[26,222],{"alt":223,"src":224},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,226,227,229,230,50],{},[43,228,45],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[43,231,49],{},[14,233,234],{"id":234},"初学者容易混淆的地方",[37,236,237,243],{},[40,238,239,240,50],{},"包装函数忘记返回原函数结果，调用方得到 ",[43,241,242],{},"None",[40,244,245],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,247,248],{"id":248},"练习",[190,250,251,254],{},[40,252,253],{},"编写只记录调用次数的简单装饰器。",[40,255,256,257,260],{},"删除包装函数的 ",[43,258,259],{},"return result","，观察调用方得到什么。",[10,262,263],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,265,266],{"id":266},"本篇边界",[10,268,269],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,272,273],"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":72,"searchDepth":85,"depth":85,"links":275},[276,277,278,279,280,283,284,285],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":281},[282],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",false,"2026-08-17",{"title":5,"description":12},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[286,298,299],"装饰器","函数","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",[302,1114,1451,1585,1737,1916,2104,2269,2453,2634,2826,3057,3241,3418,3575,3746,3911,4125,4353,4535,4699,4888,5076,5231,5390,5586,5783,5995,6162,6404,6585,6790,6985,7169,7370,7658,7850,8079,8274,8494,8681,8885],{"id":303,"title":304,"body":305,"category":286,"cover":287,"description":72,"extension":288,"meta":1103,"navigation":88,"path":1104,"pinned":291,"publishedAt":1105,"seo":1106,"slug":1107,"stem":1108,"summary":1109,"tags":1110,"updatedAt":1105,"visible":88,"__hash__":1113},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":306,"toc":1079},[307,310,313,316,323,326,329,368,384,388,392,403,408,414,431,437,442,448,452,498,501,507,513,516,547,592,609,623,633,637,648,664,667,673,678,681,699,709,730,734,738,741,753,760,764,779,786,790,793,814,820,824,827,831,834,854,857,861,864,898,901,920,923,944,949,953,956,976,979,982,986,993,1007,1010,1014,1017,1027,1038,1042,1045,1060,1076],[14,308,309],{"id":309},"引言",[10,311,312],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,314,315],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,317,318,319,322],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[43,320,321],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,324,325],{"id":325},"扫盲",[10,327,328],{},"那么这里有几个概念：",[330,331,332,335],"blockquote",{},[10,333,334],{},"为什么需要安装python解释器？",[330,336,337,348,351,359,362],{},[10,338,339,340,343,344,347],{},"我们写的代码，电脑其实看不懂，电脑只认识",[43,341,342],{},"0","和",[43,345,346],{},"1","组成的机器指令。",[10,349,350],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,352,353,354,358],{},"这样，我们就能用",[355,356,357],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,360,361],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,363,364],{},[26,365],{"alt":366,"src":367},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[330,369,370,373],{},[10,371,372],{},"pip又是什么？",[330,374,375,378],{},[10,376,377],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,379,380],{},[26,381],{"alt":382,"src":383},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,385,387],{"id":386},"windows-安装","Windows 安装",[213,389,391],{"id":390},"_1-下载官方安装程序","1. 下载官方安装程序",[10,393,394,395,402],{},"打开 ",[396,397,401],"a",{"href":398,"rel":399},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[400],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[330,404,405],{},[10,406,407],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,409,410],{},[26,411],{"alt":412,"src":413},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[37,415,416,422,428],{},[40,417,418,419,50],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[355,420,421],{},"Windows installer (64-bit)",[40,423,424,425,50],{},"搭载 ARM 处理器的 Windows 设备选择 ",[355,426,427],{},"Windows installer (ARM64)",[40,429,430],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,432,433],{},[26,434],{"alt":435,"src":436},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[330,438,439],{},[10,440,441],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,443,444],{},[26,445],{"alt":446,"src":447},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[213,449,451],{"id":450},"_2-安装并加入-path","2. 安装并加入 PATH",[330,453,454,459,466,491],{},[330,455,456],{},[10,457,458],{},"PATH 环境变量",[10,460,461,462,465],{},"Windows 有一个特殊的变量叫 ",[355,463,464],{},"PATH","，它里面存了一串文件夹路径，比如：",[67,467,469],{"className":69,"code":468,"language":71,"meta":72,"style":72},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[43,470,471,476,481,486],{"__ignoreMap":72},[76,472,473],{"class":78,"line":79},[76,474,475],{},"D:\\Python313\\\n",[76,477,478],{"class":78,"line":85},[76,479,480],{},"D:\\Python313\\Scripts\\\n",[76,482,483],{"class":78,"line":92},[76,484,485],{},"C:\\Windows\\System32\\\n",[76,487,488],{"class":78,"line":98},[76,489,490],{},"...\n",[10,492,493,494,497],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[355,495,496],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,499,500],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,502,503,504,506],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[43,505,71],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,508,509],{},[26,510],{"alt":511,"src":512},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,514,515],{},"对安装界面最底部的两个勾选项分别解释 :",[330,517,518,521,526],{},[10,519,520],{},"Add python.exe to PATH",[10,522,523],{},[355,524,525],{},"把 Python 添加到系统环境变量",[330,527,528,534,540],{},[10,529,530,531,533],{},"勾选后，你可以在命令行任意位置直接输入 ",[43,532,71],{}," 就能运行",[10,535,536,537,539],{},"不勾选的话，命令行输入 ",[43,538,71],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,541,542,543,546],{},"必须",[355,544,545],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[330,548,549,552,557],{},[10,550,551],{},"Use admin privileges when installing py.exe",[10,553,554],{},[355,555,556],{},"使用管理员权限安装 py.exe（Python 启动器）",[330,558,559,569,583,586],{},[10,560,561,564,565,568],{},[43,562,563],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[43,566,567],{},"py"," 来启动 Python。",[10,570,571,572,574,575,578,579,582],{},"勾选后，",[43,573,563],{}," 会安装到",[355,576,577],{},"系统级目录","，电脑上",[355,580,581],{},"所有用户账户","都能用",[10,584,585],{},"不勾选，只有当前用户能用",[10,587,588,591],{},[355,589,590],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[330,593,594,597],{},[10,595,596],{},"操作建议",[330,598,599,606],{},[10,600,601,602,605],{},"两个都勾上之后，再点 ",[355,603,604],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,607,608],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[330,610,611,617],{},[10,612,613,614],{},"Python 安装的",[355,615,616],{},"可选功能页",[10,618,619],{},[26,620],{"alt":621,"src":622},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[330,624,625,628],{},[10,626,627],{},"高级选项页",[10,629,630],{},[26,631],{"alt":621,"src":632},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[213,634,636],{"id":635},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,638,639,640,643,644,647],{},"按 ",[43,641,642],{},"Win + R","，输入 ",[43,645,646],{},"cmd"," 并回车，然后执行：",[67,649,653],{"className":650,"code":651,"language":652,"meta":72,"style":72},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[43,654,655],{"__ignoreMap":72},[76,656,657,660],{"class":78,"line":79},[76,658,71],{"class":659},"svObZ",[76,661,663],{"class":662},"sDLfK"," --version\n",[10,665,666],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[67,668,671],{"className":669,"code":670,"language":180,"meta":72},[178],"Python 3.x.x\n",[43,672,670],{"__ignoreMap":72},[10,674,675],{},[26,676],{"alt":621,"src":677},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,679,680],{},"继续检查 pip：",[67,682,684],{"className":650,"code":683,"language":652,"meta":72,"style":72},"python -m pip --version\n",[43,685,686],{"__ignoreMap":72},[76,687,688,690,693,697],{"class":78,"line":79},[76,689,71],{"class":659},[76,691,692],{"class":662}," -m",[76,694,696],{"class":695},"sU2Wk"," pip",[76,698,663],{"class":662},[10,700,701,702,704,705,708],{},"如果 ",[43,703,71],{}," 无法识别，但 ",[43,706,707],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[67,710,712],{"className":650,"code":711,"language":652,"meta":72,"style":72},"py --version\npy -m pip --version\n",[43,713,714,720],{"__ignoreMap":72},[76,715,716,718],{"class":78,"line":79},[76,717,567],{"class":659},[76,719,663],{"class":662},[76,721,722,724,726,728],{"class":78,"line":85},[76,723,567],{"class":659},[76,725,692],{"class":662},[76,727,696],{"class":695},[76,729,663],{"class":662},[14,731,733],{"id":732},"macos-安装","macOS 安装",[213,735,737],{"id":736},"_1-先检查现有环境","1. 先检查现有环境",[10,739,740],{},"打开“终端”应用，执行：",[67,742,744],{"className":650,"code":743,"language":652,"meta":72,"style":72},"python3 --version\n",[43,745,746],{"__ignoreMap":72},[76,747,748,751],{"class":78,"line":79},[76,749,750],{"class":659},"python3",[76,752,663],{"class":662},[10,754,755,756,759],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[43,757,758],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[213,761,763],{"id":762},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,765,394,766,771,772,50,775,778],{},[396,767,770],{"href":768,"rel":769},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[400],"Python macOS 下载页","，下载当前稳定版的 ",[355,773,774],{},"macOS 64-bit universal2 installer",[43,776,777],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,780,781,782,785],{},"下载完成后打开 ",[43,783,784],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[213,787,789],{"id":788},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,791,792],{},"安装完成后重新打开终端，执行：",[67,794,796],{"className":650,"code":795,"language":652,"meta":72,"style":72},"python3 --version\npython3 -m pip --version\n",[43,797,798,804],{"__ignoreMap":72},[76,799,800,802],{"class":78,"line":79},[76,801,750],{"class":659},[76,803,663],{"class":662},[76,805,806,808,810,812],{"class":78,"line":85},[76,807,750],{"class":659},[76,809,692],{"class":662},[76,811,696],{"class":695},[76,813,663],{"class":662},[10,815,816,817,819],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[43,818,750],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,821,823],{"id":822},"linux-安装","Linux 安装",[10,825,826],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[213,828,830],{"id":829},"_1-检查是否已经安装","1. 检查是否已经安装",[10,832,833],{},"打开终端，执行：",[67,835,836],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,837,838,844],{"__ignoreMap":72},[76,839,840,842],{"class":78,"line":79},[76,841,750],{"class":659},[76,843,663],{"class":662},[76,845,846,848,850,852],{"class":78,"line":85},[76,847,750],{"class":659},[76,849,692],{"class":662},[76,851,696],{"class":695},[76,853,663],{"class":662},[10,855,856],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[213,858,860],{"id":859},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,862,863],{},"Ubuntu 或 Debian：",[67,865,867],{"className":650,"code":866,"language":652,"meta":72,"style":72},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[43,868,869,880],{"__ignoreMap":72},[76,870,871,874,877],{"class":78,"line":79},[76,872,873],{"class":659},"sudo",[76,875,876],{"class":695}," apt",[76,878,879],{"class":695}," update\n",[76,881,882,884,886,889,892,895],{"class":78,"line":85},[76,883,873],{"class":659},[76,885,876],{"class":695},[76,887,888],{"class":695}," install",[76,890,891],{"class":695}," python3",[76,893,894],{"class":695}," python3-pip",[76,896,897],{"class":695}," python3-venv\n",[10,899,900],{},"Fedora：",[67,902,904],{"className":650,"code":903,"language":652,"meta":72,"style":72},"sudo dnf install python3 python3-pip\n",[43,905,906],{"__ignoreMap":72},[76,907,908,910,913,915,917],{"class":78,"line":79},[76,909,873],{"class":659},[76,911,912],{"class":695}," dnf",[76,914,888],{"class":695},[76,916,891],{"class":695},[76,918,919],{"class":695}," python3-pip\n",[10,921,922],{},"Arch Linux：",[67,924,926],{"className":650,"code":925,"language":652,"meta":72,"style":72},"sudo pacman -S python python-pip\n",[43,927,928],{"__ignoreMap":72},[76,929,930,932,935,938,941],{"class":78,"line":79},[76,931,873],{"class":659},[76,933,934],{"class":695}," pacman",[76,936,937],{"class":662}," -S",[76,939,940],{"class":695}," python",[76,942,943],{"class":695}," python-pip\n",[10,945,946,948],{},[43,947,873],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[213,950,952],{"id":951},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,954,955],{},"安装结束后执行：",[67,957,958],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,959,960,966],{"__ignoreMap":72},[76,961,962,964],{"class":78,"line":79},[76,963,750],{"class":659},[76,965,663],{"class":662},[76,967,968,970,972,974],{"class":78,"line":85},[76,969,750],{"class":659},[76,971,692],{"class":662},[76,973,696],{"class":695},[76,975,663],{"class":662},[10,977,978],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,980,981],{"id":981},"常见问题",[213,983,985],{"id":984},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,987,988,989,992],{},"先关闭当前命令提示符并重新打开，再执行 ",[43,990,991],{},"python --version","。如果仍然失败，按下面的顺序检查：",[190,994,995,1001,1004],{},[40,996,997,998,1000],{},"执行 ",[43,999,707],{},"，确认 Python Launcher 是否可用。",[40,1002,1003],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[40,1005,1006],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,1008,1009],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[213,1011,1013],{"id":1012},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,1015,1016],{},"先尝试：",[67,1018,1019],{"className":650,"code":743,"language":652,"meta":72,"style":72},[43,1020,1021],{"__ignoreMap":72},[76,1022,1023,1025],{"class":78,"line":79},[76,1024,750],{"class":659},[76,1026,663],{"class":662},[10,1028,1029,1030,1032,1033,1035,1036,50],{},"在这两个系统中，只有 ",[43,1031,750],{}," 命令而没有 ",[43,1034,71],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[43,1037,750],{},[213,1039,1041],{"id":1040},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,1043,1044],{},"先使用模块方式检查：",[67,1046,1048],{"className":650,"code":1047,"language":652,"meta":72,"style":72},"python3 -m pip --version\n",[43,1049,1050],{"__ignoreMap":72},[76,1051,1052,1054,1056,1058],{"class":78,"line":79},[76,1053,750],{"class":659},[76,1055,692],{"class":662},[76,1057,696],{"class":695},[76,1059,663],{"class":662},[10,1061,1062,1063,1065,1066,1068,1069,1071,1072,1075],{},"Windows 用户将命令中的 ",[43,1064,750],{}," 换成 ",[43,1067,71],{}," 或 ",[43,1070,567],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[43,1073,1074],{},"python3-pip","；不要直接使用其他系统的安装命令。",[271,1077,1078],{},"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":72,"searchDepth":85,"depth":85,"links":1080},[1081,1082,1083,1088,1093,1098],{"id":309,"depth":85,"text":309},{"id":325,"depth":85,"text":325},{"id":386,"depth":85,"text":387,"children":1084},[1085,1086,1087],{"id":390,"depth":92,"text":391},{"id":450,"depth":92,"text":451},{"id":635,"depth":92,"text":636},{"id":732,"depth":85,"text":733,"children":1089},[1090,1091,1092],{"id":736,"depth":92,"text":737},{"id":762,"depth":92,"text":763},{"id":788,"depth":92,"text":789},{"id":822,"depth":85,"text":823,"children":1094},[1095,1096,1097],{"id":829,"depth":92,"text":830},{"id":859,"depth":92,"text":860},{"id":951,"depth":92,"text":952},{"id":981,"depth":85,"text":981,"children":1099},[1100,1101,1102],{"id":984,"depth":92,"text":985},{"id":1012,"depth":92,"text":1013},{"id":1040,"depth":92,"text":1041},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":304,"description":72},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[286,1111,1112],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1115,"title":1116,"body":1117,"category":286,"cover":1124,"description":72,"extension":288,"meta":1440,"navigation":88,"path":1441,"pinned":291,"publishedAt":1442,"seo":1443,"slug":1444,"stem":1445,"summary":1446,"tags":1447,"updatedAt":1442,"visible":88,"__hash__":1450},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1118,"toc":1425},[1119,1125,1128,1131,1135,1138,1162,1165,1171,1174,1177,1211,1221,1225,1232,1235,1260,1263,1275,1278,1282,1285,1288,1291,1294,1297,1300,1303,1327,1330,1333,1339,1342,1345,1348,1352,1358,1361,1387,1390,1394,1397,1400,1404,1407,1410,1413,1416,1419,1422],[10,1120,1121],{},[26,1122],{"alt":1123,"src":1124},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1126,1127],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1129,1130],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1132,1134],{"id":1133},"python-代码是什么样的","Python 代码是什么样的",[10,1136,1137],{},"下面是一段简单的 Python 代码：",[67,1139,1141],{"className":69,"code":1140,"language":71,"meta":72,"style":72},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[43,1142,1143,1148,1153,1157],{"__ignoreMap":72},[76,1144,1145],{"class":78,"line":79},[76,1146,1147],{},"name = \"Python\"\n",[76,1149,1150],{"class":78,"line":85},[76,1151,1152],{},"year = 2026\n",[76,1154,1155],{"class":78,"line":92},[76,1156,89],{"emptyLinePlaceholder":88},[76,1158,1159],{"class":78,"line":98},[76,1160,1161],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1163,1164],{},"运行结果：",[67,1166,1169],{"className":1167,"code":1168,"language":180,"meta":72},[178],"正在学习 Python，当前年份是 2026\n",[43,1170,1168],{"__ignoreMap":72},[10,1172,1173],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1175,1176],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[67,1178,1180],{"className":69,"code":1179,"language":71,"meta":72,"style":72},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[43,1181,1182,1187,1191,1196,1201,1206],{"__ignoreMap":72},[76,1183,1184],{"class":78,"line":79},[76,1185,1186],{},"score = 85\n",[76,1188,1189],{"class":78,"line":85},[76,1190,89],{"emptyLinePlaceholder":88},[76,1192,1193],{"class":78,"line":92},[76,1194,1195],{},"if score >= 60:\n",[76,1197,1198],{"class":78,"line":98},[76,1199,1200],{},"    print(\"成绩合格\")\n",[76,1202,1203],{"class":78,"line":104},[76,1204,1205],{},"else:\n",[76,1207,1208],{"class":78,"line":110},[76,1209,1210],{},"    print(\"需要继续学习\")\n",[10,1212,1213,1216,1217,1220],{},[43,1214,1215],{},"if"," 和 ",[43,1218,1219],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1222,1224],{"id":1223},"python-如何运行代码","Python 如何运行代码",[10,1226,1227,1228,1231],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[43,1229,1230],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1233,1234],{},"交互式环境适合快速验证一个表达式：",[67,1236,1238],{"className":69,"code":1237,"language":71,"meta":72,"style":72},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[43,1239,1240,1245,1250,1255],{"__ignoreMap":72},[76,1241,1242],{"class":78,"line":79},[76,1243,1244],{},">>> 10 + 20\n",[76,1246,1247],{"class":78,"line":85},[76,1248,1249],{},"30\n",[76,1251,1252],{"class":78,"line":92},[76,1253,1254],{},">>> \"Python\".lower()\n",[76,1256,1257],{"class":78,"line":98},[76,1258,1259],{},"'python'\n",[10,1261,1262],{},"需要保存和重复运行的程序，则可以写入文件：",[67,1264,1266],{"className":650,"code":1265,"language":652,"meta":72,"style":72},"python3 hello.py\n",[43,1267,1268],{"__ignoreMap":72},[76,1269,1270,1272],{"class":78,"line":79},[76,1271,750],{"class":659},[76,1273,1274],{"class":695}," hello.py\n",[10,1276,1277],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1279,1281],{"id":1280},"python-的特点","Python 的特点",[213,1283,1284],{"id":1284},"语法相对简洁",[10,1286,1287],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[213,1289,1290],{"id":1290},"支持多种编程方式",[10,1292,1293],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[213,1295,1296],{"id":1296},"标准库比较完整",[10,1298,1299],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1301,1302],{},"例如，获取当前时间：",[67,1304,1306],{"className":69,"code":1305,"language":71,"meta":72,"style":72},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[43,1307,1308,1313,1317,1322],{"__ignoreMap":72},[76,1309,1310],{"class":78,"line":79},[76,1311,1312],{},"from datetime import datetime\n",[76,1314,1315],{"class":78,"line":85},[76,1316,89],{"emptyLinePlaceholder":88},[76,1318,1319],{"class":78,"line":92},[76,1320,1321],{},"now = datetime.now()\n",[76,1323,1324],{"class":78,"line":98},[76,1325,1326],{},"print(now)\n",[10,1328,1329],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[213,1331,1332],{"id":1332},"第三方工具丰富",[10,1334,1335,1336,1338],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[43,1337,321],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1340,1341],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[213,1343,1344],{"id":1344},"支持多个操作系统",[10,1346,1347],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1349,1351],{"id":1350},"python-可以做什么","Python 可以做什么",[10,1353,1354],{},[26,1355],{"alt":1356,"src":1357},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1359,1360],{},"Python 的应用范围比较广，常见方向包括：",[37,1362,1363,1366,1369,1372,1375,1378,1381,1384],{},[40,1364,1365],{},"编写自动化脚本，批量处理文件和重复任务；",[40,1367,1368],{},"开发网站后端和 API 服务；",[40,1370,1371],{},"进行数据清洗、统计分析和图表展示；",[40,1373,1374],{},"编写网络爬虫和信息采集工具；",[40,1376,1377],{},"开发自动化测试程序；",[40,1379,1380],{},"进行机器学习和人工智能开发；",[40,1382,1383],{},"编写运维、监控和辅助开发工具；",[40,1385,1386],{},"开发部分桌面应用和插件。",[10,1388,1389],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1391,1393],{"id":1392},"python-的发展","Python 的发展",[10,1395,1396],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1398,1399],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1401,1403],{"id":1402},"python-也有局限","Python 也有局限",[10,1405,1406],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1408,1409],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1411,1412],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1414,1415],{"id":1415},"写在最后",[10,1417,1418],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1420,1421],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[271,1423,1424],{},"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":72,"searchDepth":85,"depth":85,"links":1426},[1427,1428,1429,1436,1437,1438,1439],{"id":1133,"depth":85,"text":1134},{"id":1223,"depth":85,"text":1224},{"id":1280,"depth":85,"text":1281,"children":1430},[1431,1432,1433,1434,1435],{"id":1284,"depth":92,"text":1284},{"id":1290,"depth":92,"text":1290},{"id":1296,"depth":92,"text":1296},{"id":1332,"depth":92,"text":1332},{"id":1344,"depth":92,"text":1344},{"id":1350,"depth":85,"text":1351},{"id":1392,"depth":85,"text":1393},{"id":1402,"depth":85,"text":1403},{"id":1415,"depth":85,"text":1415},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1116,"description":72},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[286,1448,1449],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1452,"title":1453,"body":1454,"category":286,"cover":287,"description":1458,"extension":288,"meta":1576,"navigation":88,"path":1577,"pinned":291,"publishedAt":292,"seo":1578,"slug":1579,"stem":1580,"summary":1581,"tags":1582,"updatedAt":292,"visible":88,"__hash__":1584},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1455,"toc":1566},[1456,1459,1461,1464,1466,1472,1477,1479,1493,1495,1497,1506,1508,1514,1516,1518,1534,1536,1547,1549,1557,1559,1561,1564],[10,1457,1458],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1460,16],{"id":16},[10,1462,1463],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1465,22],{"id":22},[10,1467,1468],{},[26,1469],{"alt":1470,"src":1471},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1473,1474,1476],{},[43,1475,1230],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1478,35],{"id":35},[37,1480,1481,1487,1490],{},[40,1482,1483,1484,1486],{},"源代码是人编写的文本，通常保存在 ",[43,1485,1230],{}," 文件中。",[40,1488,1489],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[40,1491,1492],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1494,62],{"id":62},[10,1496,65],{},[67,1498,1500],{"className":69,"code":1499,"language":71,"meta":72,"style":72},"print(\"你好，Python\")\n",[43,1501,1502],{"__ignoreMap":72},[76,1503,1504],{"class":78,"line":79},[76,1505,1499],{},[10,1507,174],{},[67,1509,1512],{"className":1510,"code":1511,"language":180,"meta":72},[178],"你好，Python\n",[43,1513,1511],{"__ignoreMap":72},[10,1515,185],{},[14,1517,188],{"id":188},[190,1519,1520,1527],{},[40,1521,1522,1523,1526],{},"终端启动解释器后，解释器读取 ",[43,1524,1525],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[40,1528,1529,1530,1533],{},"字符串对象先准备好，再交给 ",[43,1531,1532],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1535,234],{"id":234},[37,1537,1538,1541],{},[40,1539,1540],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[40,1542,1543,1544,1546],{},"认为 ",[43,1545,1230],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1548,248],{"id":248},[190,1550,1551,1554],{},[40,1552,1553],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[40,1555,1556],{},"把示例文字改成自己的学习目标并重新运行。",[10,1558,263],{},[14,1560,266],{"id":266},[10,1562,1563],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,1565,273],{},{"title":72,"searchDepth":85,"depth":85,"links":1567},[1568,1569,1570,1571,1572,1573,1574,1575],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1453,"description":1458},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[286,1448,1583],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1586,"title":1587,"body":1588,"category":286,"cover":287,"description":1592,"extension":288,"meta":1728,"navigation":88,"path":1729,"pinned":291,"publishedAt":292,"seo":1730,"slug":1731,"stem":1732,"summary":1733,"tags":1734,"updatedAt":292,"visible":88,"__hash__":1736},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1589,"toc":1718},[1590,1593,1595,1598,1600,1606,1612,1614,1629,1631,1634,1654,1656,1662,1664,1666,1679,1681,1695,1697,1708,1710,1712,1715],[10,1591,1592],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1594,16],{"id":16},[10,1596,1597],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1599,22],{"id":22},[10,1601,1602],{},[26,1603],{"alt":1604,"src":1605},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1607,1608,1609,1611],{},"终端收到 ",[43,1610,750],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1613,35],{"id":35},[37,1615,1616,1619,1622],{},[40,1617,1618],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[40,1620,1621],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[40,1623,1624,1625,1628],{},"检查 pip 时使用 ",[43,1626,1627],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1630,62],{"id":62},[10,1632,1633],{},"在 macOS 终端执行：",[67,1635,1636],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,1637,1638,1644],{"__ignoreMap":72},[76,1639,1640,1642],{"class":78,"line":79},[76,1641,750],{"class":659},[76,1643,663],{"class":662},[76,1645,1646,1648,1650,1652],{"class":78,"line":85},[76,1647,750],{"class":659},[76,1649,692],{"class":662},[76,1651,696],{"class":695},[76,1653,663],{"class":662},[10,1655,174],{},[67,1657,1660],{"className":1658,"code":1659,"language":180,"meta":72},[178],"Python 3.14.x\npip 版本信息与安装路径\n",[43,1661,1659],{"__ignoreMap":72},[10,1663,185],{},[14,1665,188],{"id":188},[190,1667,1668,1674],{},[40,1669,1670,1673],{},[43,1671,1672],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[40,1675,1676,1678],{},[43,1677,758],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1680,234],{"id":234},[37,1682,1683,1689],{},[40,1684,1685,1686,1688],{},"看到系统已有 ",[43,1687,750],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[40,1690,1691,1692,1694],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[43,1693,750],{},"，不修改系统自带工具。",[14,1696,248],{"id":248},[190,1698,1699,1705],{},[40,1700,997,1701,1704],{},[43,1702,1703],{},"which python3","，记录当前解释器路径。",[40,1706,1707],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1709,263],{},[14,1711,266],{"id":266},[10,1713,1714],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,1716,1717],{},"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":72,"searchDepth":85,"depth":85,"links":1719},[1720,1721,1722,1723,1724,1725,1726,1727],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1587,"description":1592},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[286,1735,1111],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1738,"title":1739,"body":1740,"category":286,"cover":287,"description":1905,"extension":288,"meta":1906,"navigation":88,"path":1907,"pinned":291,"publishedAt":292,"seo":1908,"slug":1909,"stem":1910,"summary":1911,"tags":1912,"updatedAt":292,"visible":88,"__hash__":1915},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1741,"toc":1895},[1742,1748,1750,1753,1755,1761,1764,1766,1790,1792,1794,1821,1823,1829,1831,1833,1851,1853,1867,1869,1883,1885,1887,1893],[10,1743,1744,1745,1747],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[43,1746,1230],{}," 脚本。",[14,1749,16],{"id":16},[10,1751,1752],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1754,22],{"id":22},[10,1756,1757],{},[26,1758],{"alt":1759,"src":1760},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1762,1763],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1765,35],{"id":35},[37,1767,1768,1777,1784],{},[40,1769,1770,1771,1773,1774,50],{},"在终端输入 ",[43,1772,750],{}," 进入 REPL，提示符通常是 ",[43,1775,1776],{},">>>",[40,1778,1779,1780,1783],{},"输入 ",[43,1781,1782],{},"exit()"," 或按 Control-D 退出 REPL。",[40,1785,1786,1787,1789],{},"需要保存、复查或多次运行的代码应写入 ",[43,1788,1230],{}," 文件。",[14,1791,62],{"id":62},[10,1793,65],{},[67,1795,1799],{"className":1796,"code":1797,"language":1798,"meta":72,"style":72},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[43,1800,1801,1806,1811,1816],{"__ignoreMap":72},[76,1802,1803],{"class":78,"line":79},[76,1804,1805],{},">>> 2 + 3\n",[76,1807,1808],{"class":78,"line":85},[76,1809,1810],{},"5\n",[76,1812,1813],{"class":78,"line":92},[76,1814,1815],{},">>> \"python\".upper()\n",[76,1817,1818],{"class":78,"line":98},[76,1819,1820],{},"'PYTHON'\n",[10,1822,174],{},[67,1824,1827],{"className":1825,"code":1826,"language":180,"meta":72},[178],"REPL 会直接显示表达式结果\n",[43,1828,1826],{"__ignoreMap":72},[10,1830,185],{},[14,1832,188],{"id":188},[190,1834,1835,1845],{},[40,1836,1837,1838,1841,1842,50],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[43,1839,1840],{},"2 + 3"," 能直接看到 ",[43,1843,1844],{},"5",[40,1846,1847,1848,1850],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[43,1849,1532],{}," 才会写到标准输出。",[14,1852,234],{"id":234},[37,1854,1855,1864],{},[40,1856,1857,1858,1860,1861,1863],{},"把提示符 ",[43,1859,1776],{}," 复制进 ",[43,1862,1230],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[40,1865,1866],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1868,248],{"id":248},[190,1870,1871,1877],{},[40,1872,1873,1874,50],{},"在 REPL 计算 ",[43,1875,1876],{},"12 * 8",[40,1878,1879,1880,1882],{},"把同一表达式写入脚本；观察脚本中不调用 ",[43,1881,1532],{}," 时是否显示结果。",[10,1884,263],{},[14,1886,266],{"id":266},[10,1888,1889,1890,1892],{},"本篇目标是根据任务选择 REPL 或 ",[43,1891,1230],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,1894,273],{},{"title":72,"searchDepth":85,"depth":85,"links":1896},[1897,1898,1899,1900,1901,1902,1903,1904],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1739,"description":1905},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[286,1913,1914],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1917,"title":1918,"body":1919,"category":286,"cover":287,"description":1923,"extension":288,"meta":2094,"navigation":88,"path":2095,"pinned":291,"publishedAt":292,"seo":2096,"slug":2097,"stem":2098,"summary":2099,"tags":2100,"updatedAt":292,"visible":88,"__hash__":2103},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1920,"toc":2084},[1921,1924,1926,1929,1931,1937,1943,1945,1963,1965,1967,2012,2014,2020,2022,2024,2046,2048,2060,2062,2074,2076,2078,2081],[10,1922,1923],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1925,16],{"id":16},[10,1927,1928],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1930,22],{"id":22},[10,1932,1933],{},[26,1934],{"alt":1935,"src":1936},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1938,1939,1942],{},[43,1940,1941],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1944,35],{"id":35},[37,1946,1947,1950,1960],{},[40,1948,1949],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[40,1951,1952,1955,1956,1959],{},[43,1953,1954],{},"pwd"," 显示当前目录，",[43,1957,1958],{},"ls"," 显示目录里的文件。",[40,1961,1962],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1964,62],{"id":62},[10,1966,1633],{},[67,1968,1970],{"className":650,"code":1969,"language":652,"meta":72,"style":72},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[43,1971,1972,1980,1987,1992,2006],{"__ignoreMap":72},[76,1973,1974,1977],{"class":78,"line":79},[76,1975,1976],{"class":659},"mkdir",[76,1978,1979],{"class":695}," python-study\n",[76,1981,1982,1985],{"class":78,"line":85},[76,1983,1984],{"class":662},"cd",[76,1986,1979],{"class":695},[76,1988,1989],{"class":78,"line":92},[76,1990,1991],{"class":662},"pwd\n",[76,1993,1994,1997,2000,2004],{"class":78,"line":98},[76,1995,1996],{"class":662},"printf",[76,1998,1999],{"class":695}," 'print(\"项目已经运行\")\\n'",[76,2001,2003],{"class":2002},"snl16"," >",[76,2005,1274],{"class":695},[76,2007,2008,2010],{"class":78,"line":104},[76,2009,750],{"class":659},[76,2011,1274],{"class":695},[10,2013,174],{},[67,2015,2018],{"className":2016,"code":2017,"language":180,"meta":72},[178],"项目已经运行\n",[43,2019,2017],{"__ignoreMap":72},[10,2021,185],{},[14,2023,188],{"id":188},[190,2025,2026,2037],{},[40,2027,2028,2030,2031,2033,2034,2036],{},[43,2029,1976],{}," 创建目录，",[43,2032,1984],{}," 改变终端当前目录，",[43,2035,1954],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[40,2038,2039,2041,2042,2045],{},[43,2040,1941],{}," 会在当前目录寻找 ",[43,2043,2044],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,2047,234],{"id":234},[37,2049,2050,2057],{},[40,2051,2052,2053,1216,2055,50],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[43,2054,1954],{},[43,2056,1958],{},[40,2058,2059],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2061,248],{"id":248},[190,2063,2064,2071],{},[40,2065,2066,2067,2070],{},"新建 ",[43,2068,2069],{},"lesson01.py"," 并输出课程编号。",[40,2072,2073],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2075,263],{},[14,2077,266],{"id":266},[10,2079,2080],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,2082,2083],{},"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":72,"searchDepth":85,"depth":85,"links":2085},[2086,2087,2088,2089,2090,2091,2092,2093],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1918,"description":1923},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[286,2101,2102],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2105,"title":2106,"body":2107,"category":286,"cover":287,"description":2111,"extension":288,"meta":2259,"navigation":88,"path":2260,"pinned":291,"publishedAt":292,"seo":2261,"slug":2262,"stem":2263,"summary":2264,"tags":2265,"updatedAt":292,"visible":88,"__hash__":2268},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2108,"toc":2249},[2109,2112,2114,2117,2119,2125,2136,2138,2158,2160,2162,2182,2184,2190,2192,2194,2213,2215,2223,2225,2240,2242,2244,2247],[10,2110,2111],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2113,16],{"id":16},[10,2115,2116],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2118,22],{"id":22},[10,2120,2121],{},[26,2122],{"alt":2123,"src":2124},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2126,2127,2128,50,2130,2133,2134,50],{},"Python 先计算表达式，再把得到的对象交给 ",[43,2129,1532],{},[43,2131,2132],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[43,2135,1840],{},[14,2137,35],{"id":35},[37,2139,2140,2146,2155],{},[40,2141,2142,2145],{},[43,2143,2144],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[40,2147,2148,2151,2152,50],{},[43,2149,2150],{},"7 + 5"," 是表达式，运行时先求值得到 ",[43,2153,2154],{},"12",[40,2156,2157],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2159,62],{"id":62},[10,2161,65],{},[67,2163,2165],{"className":69,"code":2164,"language":71,"meta":72,"style":72},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[43,2166,2167,2172,2177],{"__ignoreMap":72},[76,2168,2169],{"class":78,"line":79},[76,2170,2171],{},"print(42)\n",[76,2173,2174],{"class":78,"line":85},[76,2175,2176],{},"print(7 + 5)\n",[76,2178,2179],{"class":78,"line":92},[76,2180,2181],{},"print(\"Python 基础课\")\n",[10,2183,174],{},[67,2185,2188],{"className":2186,"code":2187,"language":180,"meta":72},[178],"42\n12\nPython 基础课\n",[43,2189,2187],{"__ignoreMap":72},[10,2191,185],{},[14,2193,188],{"id":188},[190,2195,2196,2204],{},[40,2197,2198,2201,2202,50],{},[43,2199,2200],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[43,2203,2154],{},[40,2205,2206,2208,2209,2212],{},[43,2207,1532],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[43,2210,2211],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2214,234],{"id":234},[37,2216,2217,2220],{},[40,2218,2219],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[40,2221,2222],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2224,248],{"id":248},[190,2226,2227,2230],{},[40,2228,2229],{},"分别输出一个整数、一个小数和一段文本。",[40,2231,2232,2233,2235,2236,2239],{},"比较 ",[43,2234,2132],{}," 与 ",[43,2237,2238],{},"print(\"2 + 3\")"," 的结果。",[10,2241,263],{},[14,2243,266],{"id":266},[10,2245,2246],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,2248,273],{},{"title":72,"searchDepth":85,"depth":85,"links":2250},[2251,2252,2253,2254,2255,2256,2257,2258],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2106,"description":2111},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[286,2266,2267],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2270,"title":2271,"body":2272,"category":286,"cover":287,"description":2276,"extension":288,"meta":2443,"navigation":88,"path":2444,"pinned":291,"publishedAt":292,"seo":2445,"slug":2446,"stem":2447,"summary":2448,"tags":2449,"updatedAt":292,"visible":88,"__hash__":2452},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2273,"toc":2433},[2274,2277,2279,2282,2284,2290,2293,2295,2321,2323,2325,2353,2355,2361,2363,2365,2389,2391,2407,2409,2424,2426,2428,2431],[10,2275,2276],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2278,16],{"id":16},[10,2280,2281],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2283,22],{"id":22},[10,2285,2286],{},[26,2287],{"alt":2288,"src":2289},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2291,2292],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2294,35],{"id":35},[37,2296,2297,2300,2310],{},[40,2298,2299],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[40,2301,2302,2303,2235,2306,2309],{},"变量名区分大小写，",[43,2304,2305],{},"score",[43,2307,2308],{},"Score"," 是两个名字。",[40,2311,2312,2313,2316,2317,2320],{},"使用能表达含义的名称；不要用 ",[43,2314,2315],{},"list","、",[43,2318,2319],{},"str"," 等内置名称作为普通变量名。",[14,2322,62],{"id":62},[10,2324,65],{},[67,2326,2328],{"className":69,"code":2327,"language":71,"meta":72,"style":72},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[43,2329,2330,2335,2340,2344,2349],{"__ignoreMap":72},[76,2331,2332],{"class":78,"line":79},[76,2333,2334],{},"score = 90\n",[76,2336,2337],{"class":78,"line":85},[76,2338,2339],{},"print(score)\n",[76,2341,2342],{"class":78,"line":92},[76,2343,89],{"emptyLinePlaceholder":88},[76,2345,2346],{"class":78,"line":98},[76,2347,2348],{},"score = 95\n",[76,2350,2351],{"class":78,"line":104},[76,2352,2339],{},[10,2354,174],{},[67,2356,2359],{"className":2357,"code":2358,"language":180,"meta":72},[178],"90\n95\n",[43,2360,2358],{"__ignoreMap":72},[10,2362,185],{},[14,2364,188],{"id":188},[190,2366,2367,2376],{},[40,2368,997,2369,2372,2373,2375],{},[43,2370,2371],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[43,2374,2305],{}," 再绑定到它。",[40,2377,997,2378,2381,2382,2385,2386,50],{},[43,2379,2380],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[43,2383,2384],{},"90"," 没有被改造成 ",[43,2387,2388],{},"95",[14,2390,234],{"id":234},[37,2392,2393,2396],{},[40,2394,2395],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[40,2397,2398,2399,2316,2401,2316,2403,2406],{},"使用 ",[43,2400,2315],{},[43,2402,2319],{},[43,2404,2405],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2408,248],{"id":248},[190,2410,2411,2421],{},[40,2412,2413,2414,1216,2417,2420],{},"创建 ",[43,2415,2416],{},"course_name",[43,2418,2419],{},"lesson_count"," 两个变量并输出。",[40,2422,2423],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2425,263],{},[14,2427,266],{"id":266},[10,2429,2430],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,2432,273],{},{"title":72,"searchDepth":85,"depth":85,"links":2434},[2435,2436,2437,2438,2439,2440,2441,2442],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2271,"description":2276},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[286,2450,2451],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2454,"title":2455,"body":2456,"category":286,"cover":287,"description":2460,"extension":288,"meta":2624,"navigation":88,"path":2625,"pinned":291,"publishedAt":292,"seo":2626,"slug":2627,"stem":2628,"summary":2629,"tags":2630,"updatedAt":292,"visible":88,"__hash__":2633},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2457,"toc":2614},[2458,2461,2463,2466,2468,2474,2477,2479,2508,2510,2512,2556,2558,2564,2566,2568,2582,2584,2595,2597,2605,2607,2609,2612],[10,2459,2460],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2462,16],{"id":16},[10,2464,2465],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2467,22],{"id":22},[10,2469,2470],{},[26,2471],{"alt":2472,"src":2473},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2475,2476],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2478,35],{"id":35},[37,2480,2481,2491,2505],{},[40,2482,2483,2486,2487,2490],{},[43,2484,2485],{},"int"," 表示整数，",[43,2488,2489],{},"float"," 表示浮点数。",[40,2492,2493,2496,2497,2500,2501,2504],{},[43,2494,2495],{},"\u002F"," 总是进行真除法；",[43,2498,2499],{},"\u002F\u002F"," 是向下取整除法，",[43,2502,2503],{},"%"," 得到余数。",[40,2506,2507],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2509,62],{"id":62},[10,2511,65],{},[67,2513,2515],{"className":69,"code":2514,"language":71,"meta":72,"style":72},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[43,2516,2517,2522,2527,2532,2536,2541,2546,2551],{"__ignoreMap":72},[76,2518,2519],{"class":78,"line":79},[76,2520,2521],{},"price = 25\n",[76,2523,2524],{"class":78,"line":85},[76,2525,2526],{},"count = 4\n",[76,2528,2529],{"class":78,"line":92},[76,2530,2531],{},"discount = 0.9\n",[76,2533,2534],{"class":78,"line":98},[76,2535,89],{"emptyLinePlaceholder":88},[76,2537,2538],{"class":78,"line":104},[76,2539,2540],{},"total = price * count * discount\n",[76,2542,2543],{"class":78,"line":110},[76,2544,2545],{},"average = total \u002F count\n",[76,2547,2548],{"class":78,"line":116},[76,2549,2550],{},"print(total)\n",[76,2552,2553],{"class":78,"line":122},[76,2554,2555],{},"print(average)\n",[10,2557,174],{},[67,2559,2562],{"className":2560,"code":2561,"language":180,"meta":72},[178],"90.0\n22.5\n",[43,2563,2561],{"__ignoreMap":72},[10,2565,185],{},[14,2567,188],{"id":188},[190,2569,2570,2576],{},[40,2571,2572,2575],{},[43,2573,2574],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[40,2577,2578,2581],{},[43,2579,2580],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2583,234],{"id":234},[37,2585,2586,2592],{},[40,2587,2588,2589,50],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[43,2590,2591],{},"decimal.Decimal",[40,2593,2594],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2596,248],{"id":248},[190,2598,2599,2602],{},[40,2600,2601],{},"计算 137 除以 10 的商和余数。",[40,2603,2604],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2606,263],{},[14,2608,266],{"id":266},[10,2610,2611],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,2613,273],{},{"title":72,"searchDepth":85,"depth":85,"links":2615},[2616,2617,2618,2619,2620,2621,2622,2623],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2455,"description":2460},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[286,2631,2632],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2635,"title":2636,"body":2637,"category":286,"cover":287,"description":2641,"extension":288,"meta":2816,"navigation":88,"path":2817,"pinned":291,"publishedAt":292,"seo":2818,"slug":2819,"stem":2820,"summary":2821,"tags":2822,"updatedAt":292,"visible":88,"__hash__":2825},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2638,"toc":2804},[2639,2642,2644,2647,2649,2655,2665,2667,2678,2680,2682,2712,2714,2720,2722,2724,2754,2756,2759,2765,2768,2770,2778,2780,2795,2797,2799,2802],[10,2640,2641],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2643,16],{"id":16},[10,2645,2646],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2648,22],{"id":22},[10,2650,2651],{},[26,2652],{"alt":2653,"src":2654},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2656,2657,2658,2661,2662,50],{},"切片 ",[43,2659,2660],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[43,2663,2664],{},"stop - start",[14,2666,35],{"id":35},[37,2668,2669,2672,2675],{},[40,2670,2671],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[40,2673,2674],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[40,2676,2677],{},"切片会创建新的字符串，不会修改原字符串。",[14,2679,62],{"id":62},[10,2681,65],{},[67,2683,2685],{"className":69,"code":2684,"language":71,"meta":72,"style":72},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[43,2686,2687,2692,2697,2702,2707],{"__ignoreMap":72},[76,2688,2689],{"class":78,"line":79},[76,2690,2691],{},"language = \"Python\"\n",[76,2693,2694],{"class":78,"line":85},[76,2695,2696],{},"print(language[0])\n",[76,2698,2699],{"class":78,"line":92},[76,2700,2701],{},"print(language[-1])\n",[76,2703,2704],{"class":78,"line":98},[76,2705,2706],{},"print(language[0:3])\n",[76,2708,2709],{"class":78,"line":104},[76,2710,2711],{},"print(language + \" 3.14\")\n",[10,2713,174],{},[67,2715,2718],{"className":2716,"code":2717,"language":180,"meta":72},[178],"P\nn\nPyt\nPython 3.14\n",[43,2719,2717],{"__ignoreMap":72},[10,2721,185],{},[14,2723,188],{"id":188},[190,2725,2726,2740],{},[40,2727,2728,2729,2731,2732,2735,2736,2739],{},"字符串 ",[43,2730,286],{}," 的正索引从 ",[43,2733,2734],{},"P"," 的 0 开始，负索引从末尾 ",[43,2737,2738],{},"n"," 的 -1 开始。",[40,2741,2742,2745,2746,2749,2750,2753],{},[43,2743,2744],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[43,2747,2748],{},"Pyt","；索引 3 的 ",[43,2751,2752],{},"h"," 不在结果中。",[213,2755,215],{"id":215},[10,2757,2758],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2760,2761],{},[26,2762],{"alt":2763,"src":2764},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2766,2767],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2769,234],{"id":234},[37,2771,2772,2775],{},[40,2773,2774],{},"把第一个字符写成索引 1，造成整体偏移一位。",[40,2776,2777],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2779,248],{"id":248},[190,2781,2782,2792],{},[40,2783,2784,2785,2788,2789,50],{},"从 ",[43,2786,2787],{},"\"programming\""," 中切出 ",[43,2790,2791],{},"\"gram\"",[40,2793,2794],{},"使用负索引取得字符串倒数第二个字符。",[10,2796,263],{},[14,2798,266],{"id":266},[10,2800,2801],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,2803,273],{},{"title":72,"searchDepth":85,"depth":85,"links":2805},[2806,2807,2808,2809,2810,2813,2814,2815],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":2811},[2812],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2636,"description":2641},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[286,2823,2824],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2827,"title":2828,"body":2829,"category":286,"cover":287,"description":2833,"extension":288,"meta":3047,"navigation":88,"path":3048,"pinned":291,"publishedAt":292,"seo":3049,"slug":3050,"stem":3051,"summary":3052,"tags":3053,"updatedAt":292,"visible":88,"__hash__":3056},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2830,"toc":3035},[2831,2834,2836,2839,2841,2847,2857,2859,2892,2894,2896,2940,2942,2948,2950,2952,2973,2975,2978,2984,2992,2994,3008,3010,3026,3028,3030,3033],[10,2832,2833],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2835,16],{"id":16},[10,2837,2838],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2840,22],{"id":22},[10,2842,2843],{},[26,2844],{"alt":2845,"src":2846},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2848,2849,2850,1068,2853,2856],{},"比较表达式先产生 ",[43,2851,2852],{},"True",[43,2854,2855],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2858,35],{"id":35},[37,2860,2861,2875,2889],{},[40,2862,2863,2866,2867,2870,2871,2874],{},[43,2864,2865],{},"=="," 判断是否相等，",[43,2868,2869],{},"!="," 判断是否不等；单个 ",[43,2872,2873],{},"="," 是赋值。",[40,2876,2877,2880,2881,2884,2885,2888],{},[43,2878,2879],{},"and"," 要求两侧都为真，",[43,2882,2883],{},"or"," 只需一侧为真，",[43,2886,2887],{},"not"," 取反。",[40,2890,2891],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2893,62],{"id":62},[10,2895,65],{},[67,2897,2899],{"className":69,"code":2898,"language":71,"meta":72,"style":72},"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",[43,2900,2901,2906,2911,2915,2920,2925,2930,2935],{"__ignoreMap":72},[76,2902,2903],{"class":78,"line":79},[76,2904,2905],{},"age = 20\n",[76,2907,2908],{"class":78,"line":85},[76,2909,2910],{},"has_ticket = True\n",[76,2912,2913],{"class":78,"line":92},[76,2914,89],{"emptyLinePlaceholder":88},[76,2916,2917],{"class":78,"line":98},[76,2918,2919],{},"is_adult = age >= 18\n",[76,2921,2922],{"class":78,"line":104},[76,2923,2924],{},"can_enter = is_adult and has_ticket\n",[76,2926,2927],{"class":78,"line":110},[76,2928,2929],{},"print(is_adult)\n",[76,2931,2932],{"class":78,"line":116},[76,2933,2934],{},"print(can_enter)\n",[76,2936,2937],{"class":78,"line":122},[76,2938,2939],{},"print(not has_ticket)\n",[10,2941,174],{},[67,2943,2946],{"className":2944,"code":2945,"language":180,"meta":72},[178],"True\nTrue\nFalse\n",[43,2947,2945],{"__ignoreMap":72},[10,2949,185],{},[14,2951,188],{"id":188},[190,2953,2954,2964],{},[40,2955,2956,2959,2960,2963],{},[43,2957,2958],{},"age >= 18"," 先产生布尔值并绑定给 ",[43,2961,2962],{},"is_adult","，这一步没有任何分支跳转。",[40,2965,2966,2969,2970,2972],{},[43,2967,2968],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[43,2971,2887],{}," 只对紧随其后的值取反。",[213,2974,215],{"id":215},[10,2976,2977],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2979,2980],{},[26,2981],{"alt":2982,"src":2983},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2985,2986,2988,2989,2991],{},[43,2987,2879],{}," 只有“真、真”得到真；",[43,2990,2883],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2993,234],{"id":234},[37,2995,2996,3005],{},[40,2997,2998,2999,3001,3002,3004],{},"用单个等号判断相等。",[43,3000,2873],{}," 是赋值，",[43,3003,2865],{}," 才是相等比较。",[40,3006,3007],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,3009,248],{"id":248},[190,3011,3012,3019],{},[40,3013,3014,3015,3018],{},"判断数字 ",[43,3016,3017],{},"15"," 是否同时大于 10 且小于 20。",[40,3020,3021,3022,3025],{},"分别修改年龄和票据状态，记录 ",[43,3023,3024],{},"can_enter"," 的四种组合结果。",[10,3027,263],{},[14,3029,266],{"id":266},[10,3031,3032],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,3034,273],{},{"title":72,"searchDepth":85,"depth":85,"links":3036},[3037,3038,3039,3040,3041,3044,3045,3046],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":3042},[3043],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2828,"description":2833},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[286,3054,3055],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3058,"title":3059,"body":3060,"category":286,"cover":287,"description":3064,"extension":288,"meta":3232,"navigation":88,"path":3233,"pinned":291,"publishedAt":292,"seo":3234,"slug":3235,"stem":3236,"summary":3237,"tags":3238,"updatedAt":292,"visible":88,"__hash__":3240},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3061,"toc":3222},[3062,3065,3067,3070,3072,3078,3096,3098,3111,3113,3115,3149,3151,3157,3159,3161,3183,3185,3197,3199,3213,3215,3217,3220],[10,3063,3064],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3066,16],{"id":16},[10,3068,3069],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3071,22],{"id":22},[10,3073,3074],{},[26,3075],{"alt":3076,"src":3077},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3079,3080,3083,3084,3087,3088,3091,3092,3095],{},[43,3081,3082],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[43,3085,3086],{},"18","，程序首先得到的也是 ",[43,3089,3090],{},"\"18\"","，需要 ",[43,3093,3094],{},"int()"," 后才能按整数参与计算。",[14,3097,35],{"id":35},[37,3099,3100,3103,3108],{},[40,3101,3102],{},"提示文字应告诉用户需要输入什么。",[40,3104,3105,3107],{},[43,3106,3094],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[40,3109,3110],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3112,62],{"id":62},[10,3114,65],{},[67,3116,3118],{"className":69,"code":3117,"language":71,"meta":72,"style":72},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[43,3119,3120,3125,3130,3135,3139,3144],{"__ignoreMap":72},[76,3121,3122],{"class":78,"line":79},[76,3123,3124],{},"name = input(\"请输入姓名：\")\n",[76,3126,3127],{"class":78,"line":85},[76,3128,3129],{},"age_text = input(\"请输入年龄：\")\n",[76,3131,3132],{"class":78,"line":92},[76,3133,3134],{},"age = int(age_text)\n",[76,3136,3137],{"class":78,"line":98},[76,3138,89],{"emptyLinePlaceholder":88},[76,3140,3141],{"class":78,"line":104},[76,3142,3143],{},"print(\"你好，\" + name)\n",[76,3145,3146],{"class":78,"line":110},[76,3147,3148],{},"print(age + 1)\n",[10,3150,174],{},[67,3152,3155],{"className":3153,"code":3154,"language":180,"meta":72},[178],"根据输入显示姓名，并输出下一年的年龄\n",[43,3156,3154],{"__ignoreMap":72},[10,3158,185],{},[14,3160,188],{"id":188},[190,3162,3163,3173],{},[40,3164,3165,3166,3168,3169,3172],{},"两次 ",[43,3167,3082],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[43,3170,3171],{},"age_text"," 用来提醒这仍是文本。",[40,3174,3175,3178,3179,3182],{},[43,3176,3177],{},"int(age_text)"," 创建整数对象，后面的 ",[43,3180,3181],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3184,234],{"id":234},[37,3186,3187,3194],{},[40,3188,3189,3190,3193],{},"直接计算 ",[43,3191,3192],{},"input(...) + 1","，忽略输入结果是字符串。",[40,3195,3196],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3198,248],{"id":248},[190,3200,3201,3204],{},[40,3202,3203],{},"接收两个整数并输出它们的和。",[40,3205,1779,3206,3209,3210,3212],{},[43,3207,3208],{},"18.5"," 给 ",[43,3211,3094],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3214,263],{},[14,3216,266],{"id":266},[10,3218,3219],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,3221,273],{},{"title":72,"searchDepth":85,"depth":85,"links":3223},[3224,3225,3226,3227,3228,3229,3230,3231],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3059,"description":3064},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[286,2405,3239],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3242,"title":3243,"body":3244,"category":286,"cover":287,"description":3248,"extension":288,"meta":3408,"navigation":88,"path":3409,"pinned":291,"publishedAt":292,"seo":3410,"slug":3411,"stem":3412,"summary":3413,"tags":3414,"updatedAt":292,"visible":88,"__hash__":3417},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3245,"toc":3398},[3246,3249,3251,3254,3256,3262,3269,3271,3285,3287,3289,3328,3330,3336,3338,3340,3359,3361,3376,3378,3389,3391,3393,3396],[10,3247,3248],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3250,16],{"id":16},[10,3252,3253],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3255,22],{"id":22},[10,3257,3258],{},[26,3259],{"alt":3260,"src":3261},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3263,3264,3265,3268],{},"列表为元素维护从 0 开始的位置索引。修改 ",[43,3266,3267],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3270,35],{"id":35},[37,3272,3273,3276,3279],{},[40,3274,3275],{},"列表使用方括号，元素之间用逗号分隔。",[40,3277,3278],{},"列表可变，可以替换、追加和删除元素。",[40,3280,3281,3282,50],{},"访问不存在的索引会产生 ",[43,3283,3284],{},"IndexError",[14,3286,62],{"id":62},[10,3288,65],{},[67,3290,3292],{"className":69,"code":3291,"language":71,"meta":72,"style":72},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[43,3293,3294,3299,3304,3308,3313,3318,3323],{"__ignoreMap":72},[76,3295,3296],{"class":78,"line":79},[76,3297,3298],{},"scores = [82, 90, 76]\n",[76,3300,3301],{"class":78,"line":85},[76,3302,3303],{},"print(scores[0])\n",[76,3305,3306],{"class":78,"line":92},[76,3307,89],{"emptyLinePlaceholder":88},[76,3309,3310],{"class":78,"line":98},[76,3311,3312],{},"scores[1] = 95\n",[76,3314,3315],{"class":78,"line":104},[76,3316,3317],{},"scores.append(88)\n",[76,3319,3320],{"class":78,"line":110},[76,3321,3322],{},"print(scores)\n",[76,3324,3325],{"class":78,"line":116},[76,3326,3327],{},"print(len(scores))\n",[10,3329,174],{},[67,3331,3334],{"className":3332,"code":3333,"language":180,"meta":72},[178],"82\n[82, 95, 76, 88]\n4\n",[43,3335,3333],{"__ignoreMap":72},[10,3337,185],{},[14,3339,188],{"id":188},[190,3341,3342,3345],{},[40,3343,3344],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[40,3346,3347,3350,3351,3354,3355,3358],{},[43,3348,3349],{},"scores[1] = 95"," 替换第二个位置，",[43,3352,3353],{},"append(88)"," 在末尾增加新位置，",[43,3356,3357],{},"len()"," 因而从 3 变为 4。",[14,3360,234],{"id":234},[37,3362,3363,3373],{},[40,3364,3365,3366,3369,3370,50],{},"访问 ",[43,3367,3368],{},"scores[len(scores)]","。最后一个合法正索引是 ",[43,3371,3372],{},"len(scores) - 1",[40,3374,3375],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3377,248],{"id":248},[190,3379,3380,3383],{},[40,3381,3382],{},"建立三项学习任务列表，再追加第四项。",[40,3384,3385,3386,3388],{},"修改第二项，并用 ",[43,3387,3357],{}," 检查元素数量。",[10,3390,263],{},[14,3392,266],{"id":266},[10,3394,3395],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,3397,273],{},{"title":72,"searchDepth":85,"depth":85,"links":3399},[3400,3401,3402,3403,3404,3405,3406,3407],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3243,"description":3248},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[286,3415,3416],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3419,"title":3420,"body":3421,"category":286,"cover":287,"description":3425,"extension":288,"meta":3566,"navigation":88,"path":3567,"pinned":291,"publishedAt":292,"seo":3568,"slug":3569,"stem":3570,"summary":3571,"tags":3572,"updatedAt":292,"visible":88,"__hash__":3574},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3422,"toc":3556},[3423,3426,3428,3431,3433,3439,3442,3444,3455,3457,3459,3493,3495,3501,3503,3505,3519,3521,3533,3535,3547,3549,3551,3554],[10,3424,3425],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3427,16],{"id":16},[10,3429,3430],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3432,22],{"id":22},[10,3434,3435],{},[26,3436],{"alt":3437,"src":3438},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3440,3441],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3443,35],{"id":35},[37,3445,3446,3449,3452],{},[40,3447,3448],{},"元组常用来表达固定数量、固定含义的一组值。",[40,3450,3451],{},"只有一个元素的元组必须保留尾随逗号。",[40,3453,3454],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3456,62],{"id":62},[10,3458,65],{},[67,3460,3462],{"className":69,"code":3461,"language":71,"meta":72,"style":72},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[43,3463,3464,3469,3474,3479,3483,3488],{"__ignoreMap":72},[76,3465,3466],{"class":78,"line":79},[76,3467,3468],{},"point = (120, 80)\n",[76,3470,3471],{"class":78,"line":85},[76,3472,3473],{},"print(point[0])\n",[76,3475,3476],{"class":78,"line":92},[76,3477,3478],{},"print(point[1])\n",[76,3480,3481],{"class":78,"line":98},[76,3482,89],{"emptyLinePlaceholder":88},[76,3484,3485],{"class":78,"line":104},[76,3486,3487],{},"single = (5,)\n",[76,3489,3490],{"class":78,"line":110},[76,3491,3492],{},"print(single)\n",[10,3494,174],{},[67,3496,3499],{"className":3497,"code":3498,"language":180,"meta":72},[178],"120\n80\n(5,)\n",[43,3500,3498],{"__ignoreMap":72},[10,3502,185],{},[14,3504,188],{"id":188},[190,3506,3507,3513],{},[40,3508,3509,3512],{},[43,3510,3511],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[40,3514,3515,3518],{},[43,3516,3517],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3520,234],{"id":234},[37,3522,3523,3530],{},[40,3524,3525,3526,3529],{},"把 ",[43,3527,3528],{},"(5)"," 当作元组，实际它仍是整数。",[40,3531,3532],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3534,248],{"id":248},[190,3536,3537,3540],{},[40,3538,3539],{},"用元组表示宽度和高度。",[40,3541,2232,3542,2235,3544,3546],{},[43,3543,3528],{},[43,3545,3517],{}," 的类型。",[10,3548,263],{},[14,3550,266],{"id":266},[10,3552,3553],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,3555,273],{},{"title":72,"searchDepth":85,"depth":85,"links":3557},[3558,3559,3560,3561,3562,3563,3564,3565],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3420,"description":3425},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[286,3573,3416],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3576,"title":3577,"body":3578,"category":286,"cover":287,"description":3582,"extension":288,"meta":3737,"navigation":88,"path":3738,"pinned":291,"publishedAt":292,"seo":3739,"slug":3740,"stem":3741,"summary":3742,"tags":3743,"updatedAt":292,"visible":88,"__hash__":3745},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3579,"toc":3727},[3580,3583,3585,3588,3590,3596,3606,3608,3622,3624,3626,3660,3662,3668,3670,3672,3687,3689,3708,3710,3718,3720,3722,3725],[10,3581,3582],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3584,16],{"id":16},[10,3586,3587],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3589,22],{"id":22},[10,3591,3592],{},[26,3593],{"alt":3594,"src":3595},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3597,3598,3599,3602,3603,3605],{},"字典通过键定位值，不使用连续位置表达含义。",[43,3600,3601],{},"student[\"score\"]"," 读取的是键 ",[43,3604,2305],{}," 对应的值，而不是“第几个元素”。",[14,3607,35],{"id":35},[37,3609,3610,3613,3619],{},[40,3611,3612],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[40,3614,2398,3615,3618],{},[43,3616,3617],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[40,3620,3621],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3623,62],{"id":62},[10,3625,65],{},[67,3627,3629],{"className":69,"code":3628,"language":71,"meta":72,"style":72},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[43,3630,3631,3636,3641,3645,3650,3655],{"__ignoreMap":72},[76,3632,3633],{"class":78,"line":79},[76,3634,3635],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[76,3637,3638],{"class":78,"line":85},[76,3639,3640],{},"print(student[\"name\"])\n",[76,3642,3643],{"class":78,"line":92},[76,3644,89],{"emptyLinePlaceholder":88},[76,3646,3647],{"class":78,"line":98},[76,3648,3649],{},"student[\"score\"] = 95\n",[76,3651,3652],{"class":78,"line":104},[76,3653,3654],{},"student[\"city\"] = \"郑州\"\n",[76,3656,3657],{"class":78,"line":110},[76,3658,3659],{},"print(student)\n",[10,3661,174],{},[67,3663,3666],{"className":3664,"code":3665,"language":180,"meta":72},[178],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[43,3667,3665],{"__ignoreMap":72},[10,3669,185],{},[14,3671,188],{"id":188},[190,3673,3674,3677],{},[40,3675,3676],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[40,3678,3679,3680,3682,3683,3686],{},"给已有键 ",[43,3681,2305],{}," 赋值会更新映射，给新键 ",[43,3684,3685],{},"city"," 赋值会增加映射。",[14,3688,234],{"id":234},[37,3690,3691,3698],{},[40,3692,3693,3694,3697],{},"按位置理解字典并尝试 ",[43,3695,3696],{},"student[0]","，而实际键是字符串。",[40,3699,3700,3701,3704,3705,50],{},"直接读取不确定存在的键并忽略 ",[43,3702,3703],{},"KeyError","；后续可根据场景使用成员检查或 ",[43,3706,3707],{},"get()",[14,3709,248],{"id":248},[190,3711,3712,3715],{},[40,3713,3714],{},"建立一本书的标题、作者和页数字典。",[40,3716,3717],{},"添加分类键，再修改页数。",[10,3719,263],{},[14,3721,266],{"id":266},[10,3723,3724],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,3726,273],{},{"title":72,"searchDepth":85,"depth":85,"links":3728},[3729,3730,3731,3732,3733,3734,3735,3736],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3577,"description":3582},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[286,3744,3416],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3747,"title":3748,"body":3749,"category":286,"cover":287,"description":3753,"extension":288,"meta":3902,"navigation":88,"path":3903,"pinned":291,"publishedAt":292,"seo":3904,"slug":3905,"stem":3906,"summary":3907,"tags":3908,"updatedAt":292,"visible":88,"__hash__":3910},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3750,"toc":3892},[3751,3754,3756,3759,3761,3767,3770,3772,3791,3793,3795,3829,3831,3837,3839,3841,3856,3858,3870,3872,3883,3885,3887,3890],[10,3752,3753],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3755,16],{"id":16},[10,3757,3758],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3760,22],{"id":22},[10,3762,3763],{},[26,3764],{"alt":3765,"src":3766},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3768,3769],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3771,35],{"id":35},[37,3773,3774,3777,3780],{},[40,3775,3776],{},"集合中的元素不重复。",[40,3778,3779],{},"集合是无序容器，不要依赖打印顺序或索引。",[40,3781,3782,3783,3786,3787,3790],{},"创建空集合必须写 ",[43,3784,3785],{},"set()","；",[43,3788,3789],{},"{}"," 创建的是空字典。",[14,3792,62],{"id":62},[10,3794,65],{},[67,3796,3798],{"className":69,"code":3797,"language":71,"meta":72,"style":72},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[43,3799,3800,3805,3810,3814,3819,3824],{"__ignoreMap":72},[76,3801,3802],{"class":78,"line":79},[76,3803,3804],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[76,3806,3807],{"class":78,"line":85},[76,3808,3809],{},"right = {\"Python\", \"Docker\"}\n",[76,3811,3812],{"class":78,"line":92},[76,3813,89],{"emptyLinePlaceholder":88},[76,3815,3816],{"class":78,"line":98},[76,3817,3818],{},"print(left & right)\n",[76,3820,3821],{"class":78,"line":104},[76,3822,3823],{},"print(left | right)\n",[76,3825,3826],{"class":78,"line":110},[76,3827,3828],{},"print(\"Git\" in left)\n",[10,3830,174],{},[67,3832,3835],{"className":3833,"code":3834,"language":180,"meta":72},[178],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[43,3836,3834],{"__ignoreMap":72},[10,3838,185],{},[14,3840,188],{"id":188},[190,3842,3843,3846],{},[40,3844,3845],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[40,3847,3848,3851,3852,3855],{},[43,3849,3850],{},"&"," 计算交集，",[43,3853,3854],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3857,234],{"id":234},[37,3859,3860,3867],{},[40,3861,2398,3862,3864,3865,50],{},[43,3863,3789],{}," 创建空集合，实际得到空字典；空集合应写 ",[43,3866,3785],{},[40,3868,3869],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3871,248],{"id":248},[190,3873,3874,3880],{},[40,3875,3876,3877,3879],{},"把包含重复标签的列表交给 ",[43,3878,3785],{}," 去重。",[40,3881,3882],{},"计算两组课程标签的交集和差集。",[10,3884,263],{},[14,3886,266],{"id":266},[10,3888,3889],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,3891,273],{},{"title":72,"searchDepth":85,"depth":85,"links":3893},[3894,3895,3896,3897,3898,3899,3900,3901],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3748,"description":3753},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[286,3909,3416],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3912,"title":3913,"body":3914,"category":286,"cover":287,"description":3918,"extension":288,"meta":4115,"navigation":88,"path":4116,"pinned":291,"publishedAt":292,"seo":4117,"slug":4118,"stem":4119,"summary":4120,"tags":4121,"updatedAt":292,"visible":88,"__hash__":4124},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3915,"toc":4103},[3916,3919,3921,3924,3926,3932,3942,3944,3961,3963,3965,4014,4016,4022,4024,4026,4048,4050,4053,4059,4062,4064,4077,4079,4094,4096,4098,4101],[10,3917,3918],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3920,16],{"id":16},[10,3922,3923],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3925,22],{"id":22},[10,3927,3928],{},[26,3929],{"alt":3930,"src":3931},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3933,3934,3937,3938,3941],{},[43,3935,3936],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[43,3939,3940],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3943,35],{"id":35},[37,3945,3946,3955,3958],{},[40,3947,3948,3950,3951,3954],{},[43,3949,2865],{}," 比较内容是否相等，",[43,3952,3953],{},"is"," 比较是否为同一个对象。",[40,3956,3957],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[40,3959,3960],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3962,62],{"id":62},[10,3964,65],{},[67,3966,3968],{"className":69,"code":3967,"language":71,"meta":72,"style":72},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[43,3969,3970,3975,3980,3985,3989,3994,3999,4004,4009],{"__ignoreMap":72},[76,3971,3972],{"class":78,"line":79},[76,3973,3974],{},"tasks = [\"变量\", \"字符串\"]\n",[76,3976,3977],{"class":78,"line":85},[76,3978,3979],{},"shared = tasks\n",[76,3981,3982],{"class":78,"line":92},[76,3983,3984],{},"backup = tasks.copy()\n",[76,3986,3987],{"class":78,"line":98},[76,3988,89],{"emptyLinePlaceholder":88},[76,3990,3991],{"class":78,"line":104},[76,3992,3993],{},"tasks.append(\"列表\")\n",[76,3995,3996],{"class":78,"line":110},[76,3997,3998],{},"print(shared)\n",[76,4000,4001],{"class":78,"line":116},[76,4002,4003],{},"print(backup)\n",[76,4005,4006],{"class":78,"line":122},[76,4007,4008],{},"print(tasks is shared)\n",[76,4010,4011],{"class":78,"line":128},[76,4012,4013],{},"print(tasks is backup)\n",[10,4015,174],{},[67,4017,4020],{"className":4018,"code":4019,"language":180,"meta":72},[178],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[43,4021,4019],{"__ignoreMap":72},[10,4023,185],{},[14,4025,188],{"id":188},[190,4027,4028,4034],{},[40,4029,4030,4033],{},[43,4031,4032],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[40,4035,4036,4039,4040,4043,4044,4047],{},[43,4037,4038],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[43,4041,4042],{},"shared"," 能观察到变化，",[43,4045,4046],{},"backup"," 不会。",[213,4049,215],{"id":215},[10,4051,4052],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4054,4055],{},[26,4056],{"alt":4057,"src":4058},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4060,4061],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4063,234],{"id":234},[37,4065,4066,4074],{},[40,4067,4068,4069,4071,4072,50],{},"用 ",[43,4070,2865],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[43,4073,3953],{},[40,4075,4076],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4078,248],{"id":248},[190,4080,4081,4084],{},[40,4082,4083],{},"让两个变量引用同一个字典并修改其中一个。",[40,4085,2398,4086,4089,4090,1216,4092,50],{},[43,4087,4088],{},"copy()"," 创建外层副本，再比较 ",[43,4091,3953],{},[43,4093,2865],{},[10,4095,263],{},[14,4097,266],{"id":266},[10,4099,4100],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,4102,273],{},{"title":72,"searchDepth":85,"depth":85,"links":4104},[4105,4106,4107,4108,4109,4112,4113,4114],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":4110},[4111],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3913,"description":3918},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[286,4122,4123],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4126,"title":4127,"body":4128,"category":286,"cover":287,"description":4132,"extension":288,"meta":4344,"navigation":88,"path":4345,"pinned":291,"publishedAt":292,"seo":4346,"slug":4347,"stem":4348,"summary":4349,"tags":4350,"updatedAt":292,"visible":88,"__hash__":4352},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4129,"toc":4331},[4130,4133,4135,4138,4140,4146,4156,4158,4169,4171,4173,4225,4227,4233,4235,4237,4255,4257,4260,4266,4274,4277,4280,4286,4292,4294,4312,4314,4322,4324,4326,4329],[10,4131,4132],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4134,16],{"id":16},[10,4136,4137],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4139,22],{"id":22},[10,4141,4142],{},[26,4143],{"alt":4144,"src":4145},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4147,4148,2316,4150,2316,4153,4155],{},[43,4149,1215],{},[43,4151,4152],{},"elif",[43,4154,1219],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4157,35],{"id":35},[37,4159,4160,4163,4166],{},[40,4161,4162],{},"冒号表示接下来开始一个代码块。",[40,4164,4165],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[40,4167,4168],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4170,62],{"id":62},[10,4172,65],{},[67,4174,4176],{"className":69,"code":4175,"language":71,"meta":72,"style":72},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[43,4177,4178,4183,4187,4192,4197,4202,4207,4211,4216,4220],{"__ignoreMap":72},[76,4179,4180],{"class":78,"line":79},[76,4181,4182],{},"score = int(input(\"请输入分数：\"))\n",[76,4184,4185],{"class":78,"line":85},[76,4186,89],{"emptyLinePlaceholder":88},[76,4188,4189],{"class":78,"line":92},[76,4190,4191],{},"if score >= 90:\n",[76,4193,4194],{"class":78,"line":98},[76,4195,4196],{},"    level = \"优秀\"\n",[76,4198,4199],{"class":78,"line":104},[76,4200,4201],{},"elif score >= 60:\n",[76,4203,4204],{"class":78,"line":110},[76,4205,4206],{},"    level = \"合格\"\n",[76,4208,4209],{"class":78,"line":116},[76,4210,1205],{},[76,4212,4213],{"class":78,"line":122},[76,4214,4215],{},"    level = \"需要继续学习\"\n",[76,4217,4218],{"class":78,"line":128},[76,4219,89],{"emptyLinePlaceholder":88},[76,4221,4222],{"class":78,"line":134},[76,4223,4224],{},"print(level)\n",[10,4226,174],{},[67,4228,4231],{"className":4229,"code":4230,"language":180,"meta":72},[178],"输入 85 时输出：合格\n",[43,4232,4230],{"__ignoreMap":72},[10,4234,185],{},[14,4236,188],{"id":188},[190,4238,4239,4246],{},[40,4240,4241,4242,4245],{},"输入先转换为整数，程序从 ",[43,4243,4244],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[40,4247,4248,4251,4252,4254],{},[43,4249,4250],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[43,4253,1219],{}," 被跳过；最终三个分支只会选择一个。",[213,4256,215],{"id":215},[10,4258,4259],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4261,4262],{},[26,4263],{"alt":4264,"src":4265},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4267,4268,4270,4271,4273],{},[43,4269,4244],{}," 必须放在 ",[43,4272,4250],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[213,4275,215],{"id":4276},"再看一个具体细节-1",[10,4278,4279],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4281,4282],{},[26,4283],{"alt":4284,"src":4285},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4287,4288,4289,4291],{},"同一缩进层级属于同一个代码块；回到 ",[43,4290,1215],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4293,234],{"id":234},[37,4295,4296,4302],{},[40,4297,4298,4299,4301],{},"先写 ",[43,4300,4250],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[40,4303,4304,4305,4307,4308,4311],{},"混用多个独立 ",[43,4306,1215],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[43,4309,4310],{},"if\u002Felif\u002Felse"," 链。",[14,4313,248],{"id":248},[190,4315,4316,4319],{},[40,4317,4318],{},"根据温度输出“冷、适中、热”三个等级。",[40,4320,4321],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4323,263],{},[14,4325,266],{"id":266},[10,4327,4328],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,4330,273],{},{"title":72,"searchDepth":85,"depth":85,"links":4332},[4333,4334,4335,4336,4337,4341,4342,4343],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":4338},[4339,4340],{"id":215,"depth":92,"text":215},{"id":4276,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4127,"description":4132},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[286,1215,4351],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4354,"title":4355,"body":4356,"category":286,"cover":287,"description":4360,"extension":288,"meta":4526,"navigation":88,"path":4527,"pinned":291,"publishedAt":292,"seo":4528,"slug":4529,"stem":4530,"summary":4531,"tags":4532,"updatedAt":292,"visible":88,"__hash__":4534},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4357,"toc":4514},[4358,4361,4363,4366,4368,4374,4380,4382,4397,4399,4401,4439,4441,4447,4449,4451,4466,4468,4471,4477,4483,4485,4493,4495,4505,4507,4509,4512],[10,4359,4360],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4362,16],{"id":16},[10,4364,4365],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4367,22],{"id":22},[10,4369,4370],{},[26,4371],{"alt":4372,"src":4373},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4375,4376,4379],{},[43,4377,4378],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4381,35],{"id":35},[37,4383,4384,4387,4390],{},[40,4385,4386],{},"进入循环前先准备参与条件判断的状态。",[40,4388,4389],{},"循环体中必须有机会让条件变为假。",[40,4391,4392,4393,4396],{},"能够预先确定遍历对象时，后续介绍的 ",[43,4394,4395],{},"for"," 通常更直接。",[14,4398,62],{"id":62},[10,4400,65],{},[67,4402,4404],{"className":69,"code":4403,"language":71,"meta":72,"style":72},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[43,4405,4406,4411,4415,4420,4425,4430,4434],{"__ignoreMap":72},[76,4407,4408],{"class":78,"line":79},[76,4409,4410],{},"count = 1\n",[76,4412,4413],{"class":78,"line":85},[76,4414,89],{"emptyLinePlaceholder":88},[76,4416,4417],{"class":78,"line":92},[76,4418,4419],{},"while count \u003C= 3:\n",[76,4421,4422],{"class":78,"line":98},[76,4423,4424],{},"    print(\"第\", count, \"次练习\")\n",[76,4426,4427],{"class":78,"line":104},[76,4428,4429],{},"    count = count + 1\n",[76,4431,4432],{"class":78,"line":110},[76,4433,89],{"emptyLinePlaceholder":88},[76,4435,4436],{"class":78,"line":116},[76,4437,4438],{},"print(\"练习结束\")\n",[10,4440,174],{},[67,4442,4445],{"className":4443,"code":4444,"language":180,"meta":72},[178],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[43,4446,4444],{"__ignoreMap":72},[10,4448,185],{},[14,4450,188],{"id":188},[190,4452,4453,4460],{},[40,4454,4455,4456,4459],{},"进入循环前 ",[43,4457,4458],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[40,4461,4462,4463,4465],{},"循环体末尾把 ",[43,4464,4458],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[213,4467,215],{"id":215},[10,4469,4470],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4472,4473],{},[26,4474],{"alt":4475,"src":4476},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4478,4479,4480,4482],{},"第4次检查时 ",[43,4481,4458],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4484,234],{"id":234},[37,4486,4487,4490],{},[40,4488,4489],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[40,4491,4492],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4494,248],{"id":248},[190,4496,4497,4502],{},[40,4498,2398,4499,4501],{},[43,4500,4378],{}," 输出 1 到 5。",[40,4503,4504],{},"计算 1 到 10 的累加和。",[10,4506,263],{},[14,4508,266],{"id":266},[10,4510,4511],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,4513,273],{},{"title":72,"searchDepth":85,"depth":85,"links":4515},[4516,4517,4518,4519,4520,4523,4524,4525],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":4521},[4522],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4355,"description":4360},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[286,4378,4533],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4536,"title":4537,"body":4538,"category":286,"cover":287,"description":4542,"extension":288,"meta":4690,"navigation":88,"path":4691,"pinned":291,"publishedAt":292,"seo":4692,"slug":4693,"stem":4694,"summary":4695,"tags":4696,"updatedAt":292,"visible":88,"__hash__":4698},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4539,"toc":4680},[4540,4543,4545,4548,4550,4556,4561,4563,4577,4579,4581,4619,4621,4627,4629,4631,4648,4650,4658,4660,4671,4673,4675,4678],[10,4541,4542],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4544,16],{"id":16},[10,4546,4547],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4549,22],{"id":22},[10,4551,4552],{},[26,4553],{"alt":4554,"src":4555},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4557,4558,4560],{},[43,4559,4395],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4562,35],{"id":35},[37,4564,4565,4571,4574],{},[40,4566,4567,4570],{},[43,4568,4569],{},"range(1, 4)"," 包含 1，不包含 4。",[40,4572,4573],{},"只需要元素时直接遍历元素，不必手工维护索引。",[40,4575,4576],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4578,62],{"id":62},[10,4580,65],{},[67,4582,4584],{"className":69,"code":4583,"language":71,"meta":72,"style":72},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[43,4585,4586,4591,4595,4600,4605,4609,4614],{"__ignoreMap":72},[76,4587,4588],{"class":78,"line":79},[76,4589,4590],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[76,4592,4593],{"class":78,"line":85},[76,4594,89],{"emptyLinePlaceholder":88},[76,4596,4597],{"class":78,"line":92},[76,4598,4599],{},"for course in courses:\n",[76,4601,4602],{"class":78,"line":98},[76,4603,4604],{},"    print(course)\n",[76,4606,4607],{"class":78,"line":104},[76,4608,89],{"emptyLinePlaceholder":88},[76,4610,4611],{"class":78,"line":110},[76,4612,4613],{},"for number in range(1, 4):\n",[76,4615,4616],{"class":78,"line":116},[76,4617,4618],{},"    print(number)\n",[10,4620,174],{},[67,4622,4625],{"className":4623,"code":4624,"language":180,"meta":72},[178],"变量\n字符串\n列表\n1\n2\n3\n",[43,4626,4624],{"__ignoreMap":72},[10,4628,185],{},[14,4630,188],{"id":188},[190,4632,4633,4643],{},[40,4634,4635,4636,4638,4639,4642],{},"第一个 ",[43,4637,4395],{}," 依次从列表取得字符串，循环变量 ",[43,4640,4641],{},"course"," 每轮重新绑定。",[40,4644,4645,4647],{},[43,4646,4569],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4649,234],{"id":234},[37,4651,4652,4655],{},[40,4653,4654],{},"只需要元素却手工维护索引，增加越界风险。",[40,4656,4657],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4659,248],{"id":248},[190,4661,4662,4665],{},[40,4663,4664],{},"逐项输出一个字符串中的字符。",[40,4666,2398,4667,4670],{},[43,4668,4669],{},"range()"," 输出 2、4、6、8。",[10,4672,263],{},[14,4674,266],{"id":266},[10,4676,4677],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,4679,273],{},{"title":72,"searchDepth":85,"depth":85,"links":4681},[4682,4683,4684,4685,4686,4687,4688,4689],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4537,"description":4542},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[286,4395,4697],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4700,"title":4701,"body":4702,"category":286,"cover":287,"description":4706,"extension":288,"meta":4880,"navigation":88,"path":4881,"pinned":291,"publishedAt":292,"seo":4882,"slug":4883,"stem":4884,"summary":4885,"tags":4886,"updatedAt":292,"visible":88,"__hash__":4887},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4703,"toc":4870},[4704,4707,4709,4712,4714,4720,4730,4732,4751,4753,4755,4807,4809,4815,4817,4819,4833,4835,4851,4853,4861,4863,4865,4868],[10,4705,4706],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4708,16],{"id":16},[10,4710,4711],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4713,22],{"id":22},[10,4715,4716],{},[26,4717],{"alt":4718,"src":4719},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4721,4722,4725,4726,4729],{},[43,4723,4724],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[43,4727,4728],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4731,35],{"id":35},[37,4733,4734,4737,4745],{},[40,4735,4736],{},"先写普通循环，再在确有需要时加入流程控制语句。",[40,4738,4739,4741,4742,4744],{},[43,4740,4724],{}," 前要确认不会跳过 ",[43,4743,4378],{}," 循环中的状态更新。",[40,4746,4747,4748,4750],{},"多层嵌套中 ",[43,4749,4728],{}," 只结束它所在的最内层循环。",[14,4752,62],{"id":62},[10,4754,65],{},[67,4756,4758],{"className":69,"code":4757,"language":71,"meta":72,"style":72},"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",[43,4759,4760,4765,4769,4774,4779,4784,4789,4794,4798,4802],{"__ignoreMap":72},[76,4761,4762],{"class":78,"line":79},[76,4763,4764],{},"numbers = [3, -1, 0, 8, 12]\n",[76,4766,4767],{"class":78,"line":85},[76,4768,89],{"emptyLinePlaceholder":88},[76,4770,4771],{"class":78,"line":92},[76,4772,4773],{},"for number in numbers:\n",[76,4775,4776],{"class":78,"line":98},[76,4777,4778],{},"    if number \u003C 0:\n",[76,4780,4781],{"class":78,"line":104},[76,4782,4783],{},"        continue\n",[76,4785,4786],{"class":78,"line":110},[76,4787,4788],{},"    if number == 0:\n",[76,4790,4791],{"class":78,"line":116},[76,4792,4793],{},"        break\n",[76,4795,4796],{"class":78,"line":122},[76,4797,4618],{},[76,4799,4800],{"class":78,"line":128},[76,4801,89],{"emptyLinePlaceholder":88},[76,4803,4804],{"class":78,"line":134},[76,4805,4806],{},"print(\"循环结束\")\n",[10,4808,174],{},[67,4810,4813],{"className":4811,"code":4812,"language":180,"meta":72},[178],"3\n循环结束\n",[43,4814,4812],{"__ignoreMap":72},[10,4816,185],{},[14,4818,188],{"id":188},[190,4820,4821,4827],{},[40,4822,4823,4824,4826],{},"遇到 -1 时 ",[43,4825,4724],{}," 立即结束本轮，后面的判断和输出都不执行。",[40,4828,4829,4830,4832],{},"遇到 0 时 ",[43,4831,4728],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4834,234],{"id":234},[37,4836,4837,4842],{},[40,4838,3525,4839,4841],{},[43,4840,4724],{}," 当作结束循环，实际它只跳到下一轮。",[40,4843,4844,4845,4847,4848,4850],{},"在 ",[43,4846,4378],{}," 中把状态更新放在可能被 ",[43,4849,4724],{}," 跳过的位置，造成无限循环。",[14,4852,248],{"id":248},[190,4854,4855,4858],{},[40,4856,4857],{},"跳过列表中的空字符串并输出其他内容。",[40,4859,4860],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4862,263],{},[14,4864,266],{"id":266},[10,4866,4867],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,4869,273],{},{"title":72,"searchDepth":85,"depth":85,"links":4871},[4872,4873,4874,4875,4876,4877,4878,4879],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4701,"description":4706},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[286,4728,4724],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4889,"title":4890,"body":4891,"category":286,"cover":287,"description":4895,"extension":288,"meta":5066,"navigation":88,"path":5067,"pinned":291,"publishedAt":292,"seo":5068,"slug":5069,"stem":5070,"summary":5071,"tags":5072,"updatedAt":292,"visible":88,"__hash__":5075},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4892,"toc":5054},[4893,4896,4898,4901,4903,4909,4912,4914,4938,4940,4942,4976,4978,4984,4986,4988,5005,5007,5010,5016,5019,5021,5035,5037,5045,5047,5049,5052],[10,4894,4895],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4897,16],{"id":16},[10,4899,4900],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4902,22],{"id":22},[10,4904,4905],{},[26,4906],{"alt":4907,"src":4908},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4910,4911],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4913,35],{"id":35},[37,4915,4916,4919,4922],{},[40,4917,4918],{},"每增加一层嵌套，阅读成本都会上升。",[40,4920,4921],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[40,4923,4924,4925,2316,4928,4931,4932,2316,4935,50],{},"变量名使用 ",[43,4926,4927],{},"row",[43,4929,4930],{},"cell"," 等层级含义，避免全部写成 ",[43,4933,4934],{},"i",[43,4936,4937],{},"j",[14,4939,62],{"id":62},[10,4941,65],{},[67,4943,4945],{"className":69,"code":4944,"language":71,"meta":72,"style":72},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[43,4946,4947,4952,4956,4961,4966,4971],{"__ignoreMap":72},[76,4948,4949],{"class":78,"line":79},[76,4950,4951],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[76,4953,4954],{"class":78,"line":85},[76,4955,89],{"emptyLinePlaceholder":88},[76,4957,4958],{"class":78,"line":92},[76,4959,4960],{},"for row in table:\n",[76,4962,4963],{"class":78,"line":98},[76,4964,4965],{},"    for cell in row:\n",[76,4967,4968],{"class":78,"line":104},[76,4969,4970],{},"        print(cell)\n",[76,4972,4973],{"class":78,"line":110},[76,4974,4975],{},"    print(\"一行结束\")\n",[10,4977,174],{},[67,4979,4982],{"className":4980,"code":4981,"language":180,"meta":72},[178],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[43,4983,4981],{"__ignoreMap":72},[10,4985,185],{},[14,4987,188],{"id":188},[190,4989,4990,5002],{},[40,4991,4992,4993,4995,4996,1216,4999,50],{},"外层变量 ",[43,4994,4927],{}," 先引用第一行列表，内层才依次处理 ",[43,4997,4998],{},"A1",[43,5000,5001],{},"A2",[40,5003,5004],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[213,5006,215],{"id":215},[10,5008,5009],{},"二维列表的输出顺序可以展开成一条时间线。",[10,5011,5012],{},[26,5013],{"alt":5014,"src":5015},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,5017,5018],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,5020,234],{"id":234},[37,5022,5023,5032],{},[40,5024,5025,5026,1068,5029,5031],{},"把两层循环变量都叫 ",[43,5027,5028],{},"item",[43,5030,4934],{},"，难以确认当前层级。",[40,5033,5034],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,5036,248],{"id":248},[190,5038,5039,5042],{},[40,5040,5041],{},"打印一个 2×3 数字表。",[40,5043,5044],{},"在内层增加条件，只输出大于 3 的元素。",[10,5046,263],{},[14,5048,266],{"id":266},[10,5050,5051],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,5053,273],{},{"title":72,"searchDepth":85,"depth":85,"links":5055},[5056,5057,5058,5059,5060,5063,5064,5065],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":5061},[5062],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4890,"description":4895},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[286,5073,5074],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5077,"title":5078,"body":5079,"category":286,"cover":287,"description":5083,"extension":288,"meta":5221,"navigation":88,"path":5222,"pinned":291,"publishedAt":292,"seo":5223,"slug":5224,"stem":5225,"summary":5226,"tags":5227,"updatedAt":292,"visible":88,"__hash__":5230},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5080,"toc":5211},[5081,5084,5086,5089,5091,5097,5100,5102,5113,5115,5117,5155,5157,5163,5165,5167,5179,5181,5192,5194,5202,5204,5206,5209],[10,5082,5083],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5085,16],{"id":16},[10,5087,5088],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5090,22],{"id":22},[10,5092,5093],{},[26,5094],{"alt":5095,"src":5096},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5098,5099],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5101,35],{"id":35},[37,5103,5104,5107,5110],{},[40,5105,5106],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[40,5108,5109],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[40,5111,5112],{},"推导式创建新列表，不修改输入列表。",[14,5114,62],{"id":62},[10,5116,65],{},[67,5118,5120],{"className":69,"code":5119,"language":71,"meta":72,"style":72},"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",[43,5121,5122,5127,5131,5136,5141,5145,5150],{"__ignoreMap":72},[76,5123,5124],{"class":78,"line":79},[76,5125,5126],{},"numbers = [1, 2, 3, 4, 5]\n",[76,5128,5129],{"class":78,"line":85},[76,5130,89],{"emptyLinePlaceholder":88},[76,5132,5133],{"class":78,"line":92},[76,5134,5135],{},"squares = [number * number for number in numbers]\n",[76,5137,5138],{"class":78,"line":98},[76,5139,5140],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[76,5142,5143],{"class":78,"line":104},[76,5144,89],{"emptyLinePlaceholder":88},[76,5146,5147],{"class":78,"line":110},[76,5148,5149],{},"print(squares)\n",[76,5151,5152],{"class":78,"line":116},[76,5153,5154],{},"print(even_squares)\n",[10,5156,174],{},[67,5158,5161],{"className":5159,"code":5160,"language":180,"meta":72},[178],"[1, 4, 9, 16, 25]\n[4, 16]\n",[43,5162,5160],{"__ignoreMap":72},[10,5164,185],{},[14,5166,188],{"id":188},[190,5168,5169,5172],{},[40,5170,5171],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[40,5173,5174,5175,5178],{},"第二条先用 ",[43,5176,5177],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5180,234],{"id":234},[37,5182,5183,5189],{},[40,5184,5185,5186,5188],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[43,5187,4395],{}," 开始找输入。",[40,5190,5191],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5193,248],{"id":248},[190,5195,5196,5199],{},[40,5197,5198],{},"把字符串列表转换为长度列表。",[40,5200,5201],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5203,263],{},[14,5205,266],{"id":266},[10,5207,5208],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,5210,273],{},{"title":72,"searchDepth":85,"depth":85,"links":5212},[5213,5214,5215,5216,5217,5218,5219,5220],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5078,"description":5083},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[286,5228,5229],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5232,"title":5233,"body":5234,"category":286,"cover":287,"description":5238,"extension":288,"meta":5381,"navigation":88,"path":5382,"pinned":291,"publishedAt":292,"seo":5383,"slug":5384,"stem":5385,"summary":5386,"tags":5387,"updatedAt":292,"visible":88,"__hash__":5389},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5235,"toc":5371},[5236,5239,5241,5244,5246,5252,5255,5257,5268,5270,5272,5311,5313,5319,5321,5323,5338,5340,5348,5350,5362,5364,5366,5369],[10,5237,5238],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5240,16],{"id":16},[10,5242,5243],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5245,22],{"id":22},[10,5247,5248],{},[26,5249],{"alt":5250,"src":5251},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5253,5254],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5256,35],{"id":35},[37,5258,5259,5262,5265],{},[40,5260,5261],{},"函数名描述动作，使用小写字母和下划线。",[40,5263,5264],{},"函数定义要先执行，之后才能调用。",[40,5266,5267],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5269,62],{"id":62},[10,5271,65],{},[67,5273,5275],{"className":69,"code":5274,"language":71,"meta":72,"style":72},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[43,5276,5277,5282,5287,5292,5296,5301,5306],{"__ignoreMap":72},[76,5278,5279],{"class":78,"line":79},[76,5280,5281],{},"def show_progress():\n",[76,5283,5284],{"class":78,"line":85},[76,5285,5286],{},"    print(\"正在学习函数\")\n",[76,5288,5289],{"class":78,"line":92},[76,5290,5291],{},"    print(\"本节完成 50%\")\n",[76,5293,5294],{"class":78,"line":98},[76,5295,89],{"emptyLinePlaceholder":88},[76,5297,5298],{"class":78,"line":104},[76,5299,5300],{},"print(\"调用前\")\n",[76,5302,5303],{"class":78,"line":110},[76,5304,5305],{},"show_progress()\n",[76,5307,5308],{"class":78,"line":116},[76,5309,5310],{},"print(\"调用后\")\n",[10,5312,174],{},[67,5314,5317],{"className":5315,"code":5316,"language":180,"meta":72},[178],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[43,5318,5316],{"__ignoreMap":72},[10,5320,185],{},[14,5322,188],{"id":188},[190,5324,5325,5331],{},[40,5326,997,5327,5330],{},[43,5328,5329],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[40,5332,5333,5334,5337],{},"运行到 ",[43,5335,5336],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5339,234],{"id":234},[37,5341,5342,5345],{},[40,5343,5344],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[40,5346,5347],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5349,248],{"id":248},[190,5351,5352,5359],{},[40,5353,5354,5355,5358],{},"定义 ",[43,5356,5357],{},"show_plan()"," 输出两行学习计划。",[40,5360,5361],{},"连续调用同一个函数两次，观察执行顺序。",[10,5363,263],{},[14,5365,266],{"id":266},[10,5367,5368],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,5370,273],{},{"title":72,"searchDepth":85,"depth":85,"links":5372},[5373,5374,5375,5376,5377,5378,5379,5380],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5233,"description":5238},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[286,299,5388],"代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5391,"title":5392,"body":5393,"category":286,"cover":287,"description":5397,"extension":288,"meta":5576,"navigation":88,"path":5577,"pinned":291,"publishedAt":292,"seo":5578,"slug":5579,"stem":5580,"summary":5581,"tags":5582,"updatedAt":292,"visible":88,"__hash__":5585},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5394,"toc":5564},[5395,5398,5400,5403,5405,5411,5418,5420,5436,5438,5440,5474,5476,5482,5484,5486,5507,5509,5512,5518,5528,5530,5545,5547,5555,5557,5559,5562],[10,5396,5397],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5399,16],{"id":16},[10,5401,5402],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5404,22],{"id":22},[10,5406,5407],{},[26,5408],{"alt":5409,"src":5410},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5412,5413,5414,5417],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[43,5415,5416],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5419,35],{"id":35},[37,5421,5422,5425,5428],{},[40,5423,5424],{},"形参出现在函数定义中，实参出现在函数调用中。",[40,5426,5427],{},"局部变量默认只在函数内部可见。",[40,5429,5430,5431,5433,5434,50],{},"没有显式 ",[43,5432,5416],{}," 的函数会返回 ",[43,5435,242],{},[14,5437,62],{"id":62},[10,5439,65],{},[67,5441,5443],{"className":69,"code":5442,"language":71,"meta":72,"style":72},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[43,5444,5445,5450,5455,5460,5464,5469],{"__ignoreMap":72},[76,5446,5447],{"class":78,"line":79},[76,5448,5449],{},"def calculate_total(price, count):\n",[76,5451,5452],{"class":78,"line":85},[76,5453,5454],{},"    total = price * count\n",[76,5456,5457],{"class":78,"line":92},[76,5458,5459],{},"    return total\n",[76,5461,5462],{"class":78,"line":98},[76,5463,89],{"emptyLinePlaceholder":88},[76,5465,5466],{"class":78,"line":104},[76,5467,5468],{},"result = calculate_total(25, 4)\n",[76,5470,5471],{"class":78,"line":110},[76,5472,5473],{},"print(result)\n",[10,5475,174],{},[67,5477,5480],{"className":5478,"code":5479,"language":180,"meta":72},[178],"100\n",[43,5481,5479],{"__ignoreMap":72},[10,5483,185],{},[14,5485,188],{"id":188},[190,5487,5488,5497],{},[40,5489,5490,5491,2316,5494,5496],{},"调用时 25 和 4 分别绑定到 ",[43,5492,5493],{},"price",[43,5495,4458],{},"，它们只在本次函数调用的局部范围中使用。",[40,5498,5499,5502,5503,5506],{},[43,5500,5501],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[43,5504,5505],{},"result"," 并输出。",[213,5508,215],{"id":215},[10,5510,5511],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5513,5514],{},[26,5515],{"alt":5516,"src":5517},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5519,5520,2316,5522,1216,5524,5527],{},[43,5521,5493],{},[43,5523,4458],{},[43,5525,5526],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5529,234],{"id":234},[37,5531,5532,5539],{},[40,5533,5534,5535,5538],{},"在函数内部只 ",[43,5536,5537],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[40,5540,5541,5542,5544],{},"试图在函数外直接访问局部变量 ",[43,5543,5526],{},"，它的名字只在调用期间的局部作用域存在。",[14,5546,248],{"id":248},[190,5548,5549,5552],{},[40,5550,5551],{},"编写计算长方形面积的函数。",[40,5553,5554],{},"让函数返回结果后在调用方加上单位再输出。",[10,5556,263],{},[14,5558,266],{"id":266},[10,5560,5561],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,5563,273],{},{"title":72,"searchDepth":85,"depth":85,"links":5565},[5566,5567,5568,5569,5570,5573,5574,5575],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":5571},[5572],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5392,"description":5397},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[286,5583,5584],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5587,"title":5588,"body":5589,"category":286,"cover":287,"description":5593,"extension":288,"meta":5773,"navigation":88,"path":5774,"pinned":291,"publishedAt":292,"seo":5775,"slug":5776,"stem":5777,"summary":5778,"tags":5779,"updatedAt":292,"visible":88,"__hash__":5782},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5590,"toc":5761},[5591,5594,5596,5599,5601,5607,5610,5612,5629,5631,5633,5685,5687,5693,5695,5697,5715,5717,5720,5726,5729,5731,5742,5744,5752,5754,5756,5759],[10,5592,5593],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5595,16],{"id":16},[10,5597,5598],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5600,22],{"id":22},[10,5602,5603],{},[26,5604],{"alt":5605,"src":5606},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5608,5609],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5611,35],{"id":35},[37,5613,5614,5617,5623],{},[40,5615,5616],{},"必需参数应放在有默认值的参数之前。",[40,5618,5619,5622],{},[43,5620,5621],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[40,5624,5625,5628],{},[43,5626,5627],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5630,62],{"id":62},[10,5632,65],{},[67,5634,5636],{"className":69,"code":5635,"language":71,"meta":72,"style":72},"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",[43,5637,5638,5643,5648,5652,5657,5662,5666,5671,5676,5680],{"__ignoreMap":72},[76,5639,5640],{"class":78,"line":79},[76,5641,5642],{},"def build_title(name, level=\"基础\"):\n",[76,5644,5645],{"class":78,"line":85},[76,5646,5647],{},"    return name + \"｜\" + level\n",[76,5649,5650],{"class":78,"line":92},[76,5651,89],{"emptyLinePlaceholder":88},[76,5653,5654],{"class":78,"line":98},[76,5655,5656],{},"print(build_title(\"Python\"))\n",[76,5658,5659],{"class":78,"line":104},[76,5660,5661],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[76,5663,5664],{"class":78,"line":110},[76,5665,89],{"emptyLinePlaceholder":88},[76,5667,5668],{"class":78,"line":116},[76,5669,5670],{},"def total(*numbers):\n",[76,5672,5673],{"class":78,"line":122},[76,5674,5675],{},"    return sum(numbers)\n",[76,5677,5678],{"class":78,"line":128},[76,5679,89],{"emptyLinePlaceholder":88},[76,5681,5682],{"class":78,"line":134},[76,5683,5684],{},"print(total(10, 20, 30))\n",[10,5686,174],{},[67,5688,5691],{"className":5689,"code":5690,"language":180,"meta":72},[178],"Python｜基础\n异常处理｜进阶\n60\n",[43,5692,5690],{"__ignoreMap":72},[10,5694,185],{},[14,5696,188],{"id":188},[190,5698,5699,5706],{},[40,5700,5701,5702,5705],{},"第一次调用只提供必需参数，",[43,5703,5704],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[40,5707,5708,5711,5712,50],{},[43,5709,5710],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[43,5713,5714],{},"sum()",[213,5716,215],{"id":215},[10,5718,5719],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5721,5722],{},[26,5723],{"alt":5724,"src":5725},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5727,5728],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5730,234],{"id":234},[37,5732,5733,5739],{},[40,5734,5735,5736,5738],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[43,5737,242],{}," 再在函数内创建。",[40,5740,5741],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5743,248],{"id":248},[190,5745,5746,5749],{},[40,5747,5748],{},"给问候函数增加默认称呼。",[40,5750,5751],{},"编写接收任意数量分数并返回总分的函数。",[10,5753,263],{},[14,5755,266],{"id":266},[10,5757,5758],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,5760,273],{},{"title":72,"searchDepth":85,"depth":85,"links":5762},[5763,5764,5765,5766,5767,5770,5771,5772],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":5768},[5769],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5588,"description":5593},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[286,5780,5781],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5784,"title":5785,"body":5786,"category":286,"cover":287,"description":5790,"extension":288,"meta":5985,"navigation":88,"path":5986,"pinned":291,"publishedAt":292,"seo":5987,"slug":5988,"stem":5989,"summary":5990,"tags":5991,"updatedAt":292,"visible":88,"__hash__":5994},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5787,"toc":5973},[5788,5791,5793,5796,5798,5804,5807,5809,5826,5828,5830,5891,5893,5899,5901,5903,5930,5932,5935,5941,5944,5946,5954,5956,5964,5966,5968,5971],[10,5789,5790],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5792,16],{"id":16},[10,5794,5795],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5797,22],{"id":22},[10,5799,5800],{},[26,5801],{"alt":5802,"src":5803},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5805,5806],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5808,35],{"id":35},[37,5810,5811,5814,5817],{},[40,5812,5813],{},"函数内部赋值默认创建局部变量。",[40,5815,5816],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[40,5818,5819,2235,5822,5825],{},[43,5820,5821],{},"global",[43,5823,5824],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5827,62],{"id":62},[10,5829,65],{},[67,5831,5833],{"className":69,"code":5832,"language":71,"meta":72,"style":72},"course = \"Python\"\n\ndef outer():\n    level = \"基础\"\n\n    def show():\n        lesson = \"作用域\"\n        print(course, level, lesson)\n\n    show()\n\nouter()\n",[43,5834,5835,5840,5844,5849,5854,5858,5863,5868,5873,5877,5882,5886],{"__ignoreMap":72},[76,5836,5837],{"class":78,"line":79},[76,5838,5839],{},"course = \"Python\"\n",[76,5841,5842],{"class":78,"line":85},[76,5843,89],{"emptyLinePlaceholder":88},[76,5845,5846],{"class":78,"line":92},[76,5847,5848],{},"def outer():\n",[76,5850,5851],{"class":78,"line":98},[76,5852,5853],{},"    level = \"基础\"\n",[76,5855,5856],{"class":78,"line":104},[76,5857,89],{"emptyLinePlaceholder":88},[76,5859,5860],{"class":78,"line":110},[76,5861,5862],{},"    def show():\n",[76,5864,5865],{"class":78,"line":116},[76,5866,5867],{},"        lesson = \"作用域\"\n",[76,5869,5870],{"class":78,"line":122},[76,5871,5872],{},"        print(course, level, lesson)\n",[76,5874,5875],{"class":78,"line":128},[76,5876,89],{"emptyLinePlaceholder":88},[76,5878,5879],{"class":78,"line":134},[76,5880,5881],{},"    show()\n",[76,5883,5884],{"class":78,"line":140},[76,5885,89],{"emptyLinePlaceholder":88},[76,5887,5888],{"class":78,"line":145},[76,5889,5890],{},"outer()\n",[10,5892,174],{},[67,5894,5897],{"className":5895,"code":5896,"language":180,"meta":72},[178],"Python 基础 作用域\n",[43,5898,5896],{"__ignoreMap":72},[10,5900,185],{},[14,5902,188],{"id":188},[190,5904,5905,5922],{},[40,5906,5907,5910,5911,5914,5915,5917,5918,5921],{},[43,5908,5909],{},"show()"," 中查找 ",[43,5912,5913],{},"lesson"," 时先在局部找到，查找 ",[43,5916,5704],{}," 时到外层 ",[43,5919,5920],{},"outer()"," 找到。",[40,5923,5924,5926,5927,5929],{},[43,5925,4641],{}," 在局部和外层都不存在，继续到模块全局找到；",[43,5928,2267],{}," 最后在内置作用域找到。",[213,5931,215],{"id":215},[10,5933,5934],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5936,5937],{},[26,5938],{"alt":5939,"src":5940},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5942,5943],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5945,234],{"id":234},[37,5947,5948,5951],{},[40,5949,5950],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[40,5952,5953],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5955,248],{"id":248},[190,5957,5958,5961],{},[40,5959,5960],{},"在内外层定义同名变量，观察最近作用域优先。",[40,5962,5963],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5965,263],{},[14,5967,266],{"id":266},[10,5969,5970],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,5972,273],{},{"title":72,"searchDepth":85,"depth":85,"links":5974},[5975,5976,5977,5978,5979,5982,5983,5984],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":5980},[5981],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5785,"description":5790},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[286,5992,5993],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5996,"title":5997,"body":5998,"category":286,"cover":287,"description":6002,"extension":288,"meta":6152,"navigation":88,"path":6153,"pinned":291,"publishedAt":292,"seo":6154,"slug":6155,"stem":6156,"summary":6157,"tags":6158,"updatedAt":292,"visible":88,"__hash__":6161},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5999,"toc":6142},[6000,6003,6005,6008,6010,6016,6019,6021,6040,6042,6044,6078,6080,6086,6088,6090,6105,6107,6119,6121,6133,6135,6137,6140],[10,6001,6002],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,6004,16],{"id":16},[10,6006,6007],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6009,22],{"id":22},[10,6011,6012],{},[26,6013],{"alt":6014,"src":6015},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,6017,6018],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,6020,35],{"id":35},[37,6022,6023,6026,6029],{},[40,6024,6025],{},"文档字符串紧跟在函数定义后的第一条语句。",[40,6027,6028],{},"注解表达接口意图，不代替输入校验和测试。",[40,6030,6031,6032,2316,6034,2316,6036,6039],{},"基础注解优先使用 ",[43,6033,2319],{},[43,6035,2485],{},[43,6037,6038],{},"list[str]"," 等直接写法。",[14,6041,62],{"id":62},[10,6043,65],{},[67,6045,6047],{"className":69,"code":6046,"language":71,"meta":72,"style":72},"def format_score(name: str, score: int) -> str:\n    \"\"\"返回带姓名的分数文本。\"\"\"\n    return name + \"：\" + str(score)\n\nprint(format_score(\"小郑\", 95))\nprint(format_score.__doc__)\n",[43,6048,6049,6054,6059,6064,6068,6073],{"__ignoreMap":72},[76,6050,6051],{"class":78,"line":79},[76,6052,6053],{},"def format_score(name: str, score: int) -> str:\n",[76,6055,6056],{"class":78,"line":85},[76,6057,6058],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[76,6060,6061],{"class":78,"line":92},[76,6062,6063],{},"    return name + \"：\" + str(score)\n",[76,6065,6066],{"class":78,"line":98},[76,6067,89],{"emptyLinePlaceholder":88},[76,6069,6070],{"class":78,"line":104},[76,6071,6072],{},"print(format_score(\"小郑\", 95))\n",[76,6074,6075],{"class":78,"line":110},[76,6076,6077],{},"print(format_score.__doc__)\n",[10,6079,174],{},[67,6081,6084],{"className":6082,"code":6083,"language":180,"meta":72},[178],"小郑：95\n返回带姓名的分数文本。\n",[43,6085,6083],{"__ignoreMap":72},[10,6087,185],{},[14,6089,188],{"id":188},[190,6091,6092,6102],{},[40,6093,6094,6095,6098,6099,6101],{},"函数签名说明 ",[43,6096,6097],{},"name"," 预期为字符串、",[43,6100,2305],{}," 预期为整数，返回值预期为字符串。",[40,6103,6104],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6106,234],{"id":234},[37,6108,6109,6116],{},[40,6110,6111,6112,6115],{},"认为加了 ",[43,6113,6114],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[40,6117,6118],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6120,248],{"id":248},[190,6122,6123,6126],{},[40,6124,6125],{},"为面积函数补充参数和返回值注解。",[40,6127,6128,6129,6132],{},"通过 ",[43,6130,6131],{},"函数名.__doc__"," 查看文档字符串。",[10,6134,263],{},[14,6136,266],{"id":266},[10,6138,6139],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,6141,273],{},{"title":72,"searchDepth":85,"depth":85,"links":6143},[6144,6145,6146,6147,6148,6149,6150,6151],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5997,"description":6002},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[286,6159,6160],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6163,"title":6164,"body":6165,"category":286,"cover":287,"description":6169,"extension":288,"meta":6394,"navigation":88,"path":6395,"pinned":291,"publishedAt":292,"seo":6396,"slug":6397,"stem":6398,"summary":6399,"tags":6400,"updatedAt":292,"visible":88,"__hash__":6403},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6166,"toc":6382},[6167,6170,6172,6178,6180,6186,6197,6199,6217,6219,6226,6253,6260,6279,6288,6290,6296,6298,6300,6323,6325,6328,6334,6340,6342,6358,6360,6373,6375,6377,6380],[10,6168,6169],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6171,16],{"id":16},[10,6173,6174,6175,6177],{},"本篇只处理“模块、import 与 ",[355,6176,6097],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6179,22],{"id":22},[10,6181,6182],{},[26,6183],{"alt":6184,"src":6185},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6187,6188,6189,6192,6193,6196],{},"同一个文件直接运行时 ",[43,6190,6191],{},"__name__"," 等于 ",[43,6194,6195],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6198,35],{"id":35},[37,6200,6201,6207,6210],{},[40,6202,6203,6204,6206],{},"一个 ",[43,6205,1230],{}," 文件就是一个模块。",[40,6208,6209],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[40,6211,6212,6213,6216],{},"避免使用 ",[43,6214,6215],{},"from module import *","，它会让名字来源不清楚。",[14,6218,62],{"id":62},[10,6220,6221,6222,6225],{},"先在同一个目录中创建两个文件。把函数放进 ",[43,6223,6224],{},"calculator.py","：",[67,6227,6229],{"className":69,"code":6228,"language":71,"meta":72,"style":72},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[43,6230,6231,6235,6239,6243,6248],{"__ignoreMap":72},[76,6232,6233],{"class":78,"line":79},[76,6234,154],{},[76,6236,6237],{"class":78,"line":85},[76,6238,160],{},[76,6240,6241],{"class":78,"line":92},[76,6242,89],{"emptyLinePlaceholder":88},[76,6244,6245],{"class":78,"line":98},[76,6246,6247],{},"if __name__ == \"__main__\":\n",[76,6249,6250],{"class":78,"line":104},[76,6251,6252],{},"    print(add(2, 3))\n",[10,6254,6255,6256,6259],{},"再创建 ",[43,6257,6258],{},"app.py","，从模块中导入函数：",[67,6261,6263],{"className":69,"code":6262,"language":71,"meta":72,"style":72},"from calculator import add\n\nprint(add(10, 20))\n",[43,6264,6265,6270,6274],{"__ignoreMap":72},[76,6266,6267],{"class":78,"line":79},[76,6268,6269],{},"from calculator import add\n",[76,6271,6272],{"class":78,"line":85},[76,6273,89],{"emptyLinePlaceholder":88},[76,6275,6276],{"class":78,"line":92},[76,6277,6278],{},"print(add(10, 20))\n",[10,6280,6281,6282,1216,6285,50],{},"分别执行 ",[43,6283,6284],{},"python3 calculator.py",[43,6286,6287],{},"python3 app.py",[10,6289,174],{},[67,6291,6294],{"className":6292,"code":6293,"language":180,"meta":72},[178],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[43,6295,6293],{"__ignoreMap":72},[10,6297,185],{},[14,6299,188],{"id":188},[190,6301,6302,6312],{},[40,6303,6304,6305,6307,6308,6311],{},"直接运行 ",[43,6306,6224],{}," 时，模块名是 ",[43,6309,6310],{},"__main__","，入口代码输出 5。",[40,6313,6314,6316,6317,6319,6320,6322],{},[43,6315,6258],{}," 导入模块时，",[43,6318,6224],{}," 的函数定义会执行，但入口判断为假；随后 ",[43,6321,6258],{}," 调用函数输出 30。",[213,6324,215],{"id":215},[10,6326,6327],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6329,6330],{},[26,6331],{"alt":6332,"src":6333},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6335,6336,6337,6339],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[43,6338,6310],{}," 保护下的演示代码。",[14,6341,234],{"id":234},[37,6343,6344,6351],{},[40,6345,6346,6347,1216,6349,50],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[43,6348,6224],{},[43,6350,6258],{},[40,6352,6353,6354,6357],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[43,6355,6356],{},"json.py","，导致导入目标被遮蔽。",[14,6359,248],{"id":248},[190,6361,6362,6368],{},[40,6363,2413,6364,6367],{},[43,6365,6366],{},"text_tools.py"," 并导出一个格式化函数。",[40,6369,6370,6371,50],{},"分别直接运行模块和从另一个脚本导入，输出 ",[43,6372,6191],{},[10,6374,263],{},[14,6376,266],{"id":266},[10,6378,6379],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,6381,273],{},{"title":72,"searchDepth":85,"depth":85,"links":6383},[6384,6385,6386,6387,6388,6391,6392,6393],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":6389},[6390],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6164,"description":6169},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[286,6401,6402],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6405,"title":6406,"body":6407,"category":286,"cover":287,"description":6411,"extension":288,"meta":6576,"navigation":88,"path":6577,"pinned":291,"publishedAt":292,"seo":6578,"slug":6579,"stem":6580,"summary":6581,"tags":6582,"updatedAt":292,"visible":88,"__hash__":6584},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6408,"toc":6566},[6409,6412,6414,6417,6419,6425,6428,6430,6444,6446,6448,6494,6496,6502,6504,6506,6532,6534,6544,6546,6557,6559,6561,6564],[10,6410,6411],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6413,16],{"id":16},[10,6415,6416],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6418,22],{"id":22},[10,6420,6421],{},[26,6422],{"alt":6423,"src":6424},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6426,6427],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6429,35],{"id":35},[37,6431,6432,6438,6441],{},[40,6433,6434,6437],{},[43,6435,6436],{},".venv"," 是常见目录名，不应提交到 Git。",[40,6439,6440],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[40,6442,6443],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6445,62],{"id":62},[10,6447,1633],{},[67,6449,6451],{"className":650,"code":6450,"language":652,"meta":72,"style":72},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[43,6452,6453,6465,6473,6479,6489],{"__ignoreMap":72},[76,6454,6455,6457,6459,6462],{"class":78,"line":79},[76,6456,750],{"class":659},[76,6458,692],{"class":662},[76,6460,6461],{"class":695}," venv",[76,6463,6464],{"class":695}," .venv\n",[76,6466,6467,6470],{"class":78,"line":85},[76,6468,6469],{"class":662},"source",[76,6471,6472],{"class":695}," .venv\u002Fbin\u002Factivate\n",[76,6474,6475,6477],{"class":78,"line":92},[76,6476,71],{"class":659},[76,6478,663],{"class":662},[76,6480,6481,6483,6485,6487],{"class":78,"line":98},[76,6482,71],{"class":659},[76,6484,692],{"class":662},[76,6486,696],{"class":695},[76,6488,663],{"class":662},[76,6490,6491],{"class":78,"line":104},[76,6492,6493],{"class":659},"deactivate\n",[10,6495,174],{},[67,6497,6500],{"className":6498,"code":6499,"language":180,"meta":72},[178],"Python 和 pip 的路径应指向当前项目的 .venv\n",[43,6501,6499],{"__ignoreMap":72},[10,6503,185],{},[14,6505,188],{"id":188},[190,6507,6508,6517],{},[40,6509,6510,6513,6514,6516],{},[43,6511,6512],{},"venv"," 根据当前 ",[43,6515,750],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[40,6518,6519,6520,2235,6522,6525,6526,3786,6528,6531],{},"激活后 ",[43,6521,71],{},[43,6523,6524],{},"python -m pip"," 优先指向 ",[43,6527,6436],{},[43,6529,6530],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6533,234],{"id":234},[37,6535,6536,6539],{},[40,6537,6538],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[40,6540,3525,6541,6543],{},[43,6542,6436],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6545,248],{"id":248},[190,6547,6548,6554],{},[40,6549,6550,6551,50],{},"创建虚拟环境并记录激活前后的 ",[43,6552,6553],{},"which python",[40,6555,6556],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6558,263],{},[14,6560,266],{"id":266},[10,6562,6563],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,6565,1717],{},{"title":72,"searchDepth":85,"depth":85,"links":6567},[6568,6569,6570,6571,6572,6573,6574,6575],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6406,"description":6411},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[286,6583,321],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6586,"title":6587,"body":6588,"category":286,"cover":287,"description":6592,"extension":288,"meta":6780,"navigation":88,"path":6781,"pinned":291,"publishedAt":292,"seo":6782,"slug":6783,"stem":6784,"summary":6785,"tags":6786,"updatedAt":292,"visible":88,"__hash__":6789},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6589,"toc":6770},[6590,6593,6595,6598,6600,6606,6615,6617,6641,6643,6645,6698,6700,6706,6708,6710,6726,6728,6747,6749,6761,6763,6765,6768],[10,6591,6592],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6594,16],{"id":16},[10,6596,6597],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6599,22],{"id":22},[10,6601,6602],{},[26,6603],{"alt":6604,"src":6605},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6607,6608,6611,6612,6614],{},[43,6609,6610],{},"Path"," 使用 ",[43,6613,2495],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6616,35],{"id":35},[37,6618,6619,6622,6634],{},[40,6620,6621],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[40,6623,6624,2316,6627,2316,6630,6633],{},[43,6625,6626],{},"exists()",[43,6628,6629],{},"is_file()",[43,6631,6632],{},"is_dir()"," 检查真实文件系统状态。",[40,6635,6636,6637,6640],{},"创建目录前明确目标；",[43,6638,6639],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6642,62],{"id":62},[10,6644,65],{},[67,6646,6648],{"className":69,"code":6647,"language":71,"meta":72,"style":72},"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",[43,6649,6650,6655,6659,6664,6669,6674,6678,6683,6688,6693],{"__ignoreMap":72},[76,6651,6652],{"class":78,"line":79},[76,6653,6654],{},"from pathlib import Path\n",[76,6656,6657],{"class":78,"line":85},[76,6658,89],{"emptyLinePlaceholder":88},[76,6660,6661],{"class":78,"line":92},[76,6662,6663],{},"project = Path.cwd()\n",[76,6665,6666],{"class":78,"line":98},[76,6667,6668],{},"data_dir = project \u002F \"data\"\n",[76,6670,6671],{"class":78,"line":104},[76,6672,6673],{},"file_path = data_dir \u002F \"records.json\"\n",[76,6675,6676],{"class":78,"line":110},[76,6677,89],{"emptyLinePlaceholder":88},[76,6679,6680],{"class":78,"line":116},[76,6681,6682],{},"print(project)\n",[76,6684,6685],{"class":78,"line":122},[76,6686,6687],{},"print(file_path.name)\n",[76,6689,6690],{"class":78,"line":128},[76,6691,6692],{},"print(file_path.suffix)\n",[76,6694,6695],{"class":78,"line":134},[76,6696,6697],{},"print(file_path.exists())\n",[10,6699,174],{},[67,6701,6704],{"className":6702,"code":6703,"language":180,"meta":72},[178],"显示当前项目路径、records.json、.json 和存在状态\n",[43,6705,6703],{"__ignoreMap":72},[10,6707,185],{},[14,6709,188],{"id":188},[190,6711,6712,6718],{},[40,6713,6714,6717],{},[43,6715,6716],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[40,6719,2398,6720,6722,6723,6725],{},[43,6721,2495],{}," 组合路径片段只创建新的 ",[43,6724,6610],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6727,234],{"id":234},[37,6729,6730,6738],{},[40,6731,3525,6732,6734,6735,6737],{},[43,6733,6610],{}," 对象存在当成真实文件存在，仍需调用 ",[43,6736,6626],{}," 等方法确认。",[40,6739,6740,6741,1068,6743,6746],{},"手工拼接 ",[43,6742,2495],{},[43,6744,6745],{},"\\"," 分隔符，降低跨平台可读性。",[14,6748,248],{"id":248},[190,6750,6751,6758],{},[40,6752,6753,6754,6757],{},"组合 ",[43,6755,6756],{},"output\u002Freport.txt"," 路径但先不创建文件。",[40,6759,6760],{},"输出路径的父目录、文件名和扩展名。",[10,6762,263],{},[14,6764,266],{"id":266},[10,6766,6767],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,6769,273],{},{"title":72,"searchDepth":85,"depth":85,"links":6771},[6772,6773,6774,6775,6776,6777,6778,6779],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6587,"description":6592},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[286,6787,6788],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6791,"title":6792,"body":6793,"category":286,"cover":287,"description":6797,"extension":288,"meta":6975,"navigation":88,"path":6976,"pinned":291,"publishedAt":292,"seo":6977,"slug":6978,"stem":6979,"summary":6980,"tags":6981,"updatedAt":292,"visible":88,"__hash__":6984},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6794,"toc":6965},[6795,6798,6800,6803,6805,6811,6814,6816,6844,6846,6848,6905,6907,6913,6915,6917,6928,6930,6943,6945,6956,6958,6960,6963],[10,6796,6797],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6799,16],{"id":16},[10,6801,6802],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6804,22],{"id":22},[10,6806,6807],{},[26,6808],{"alt":6809,"src":6810},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6812,6813],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6815,35],{"id":35},[37,6817,6818,6824,6833],{},[40,6819,6820,6823],{},[43,6821,6822],{},"w"," 模式会截断原文件，写入前必须确认目标。",[40,6825,6826,6829,6830,50],{},[43,6827,6828],{},"r"," 模式读取不存在文件会产生 ",[43,6831,6832],{},"FileNotFoundError",[40,6834,6835,6836,6839,6840,6843],{},"本篇显式调用 ",[43,6837,6838],{},"close()","；第 34 篇会用 ",[43,6841,6842],{},"with"," 更可靠地管理关闭动作。",[14,6845,62],{"id":62},[10,6847,65],{},[67,6849,6851],{"className":69,"code":6850,"language":71,"meta":72,"style":72},"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",[43,6852,6853,6857,6861,6866,6871,6876,6881,6885,6890,6895,6900],{"__ignoreMap":72},[76,6854,6855],{"class":78,"line":79},[76,6856,6654],{},[76,6858,6859],{"class":78,"line":85},[76,6860,89],{"emptyLinePlaceholder":88},[76,6862,6863],{"class":78,"line":92},[76,6864,6865],{},"file_path = Path(\"notes.txt\")\n",[76,6867,6868],{"class":78,"line":98},[76,6869,6870],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[76,6872,6873],{"class":78,"line":104},[76,6874,6875],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[76,6877,6878],{"class":78,"line":110},[76,6879,6880],{},"writer.close()\n",[76,6882,6883],{"class":78,"line":116},[76,6884,89],{"emptyLinePlaceholder":88},[76,6886,6887],{"class":78,"line":122},[76,6888,6889],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[76,6891,6892],{"class":78,"line":128},[76,6893,6894],{},"content = reader.read()\n",[76,6896,6897],{"class":78,"line":134},[76,6898,6899],{},"reader.close()\n",[76,6901,6902],{"class":78,"line":140},[76,6903,6904],{},"print(content)\n",[10,6906,174],{},[67,6908,6911],{"className":6909,"code":6910,"language":180,"meta":72},[178],"变量\n循环\n函数\n",[43,6912,6910],{"__ignoreMap":72},[10,6914,185],{},[14,6916,188],{"id":188},[190,6918,6919,6925],{},[40,6920,6921,6922,6924],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[43,6923,6838],{}," 确保缓冲内容交给文件系统。",[40,6926,6927],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6929,234],{"id":234},[37,6931,6932,6937],{},[40,6933,2398,6934,6936],{},[43,6935,6822],{}," 模式打开重要文件却未确认覆盖风险。",[40,6938,6939,6940,50],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[43,6941,6942],{},"encoding=\"utf-8\"",[14,6944,248],{"id":248},[190,6946,6947,6950],{},[40,6948,6949],{},"写入三行学习记录并读取。",[40,6951,6952,6953,6955],{},"改用 ",[43,6954,396],{}," 模式追加一行，确认原内容仍保留。",[10,6957,263],{},[14,6959,266],{"id":266},[10,6961,6962],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,6964,273],{},{"title":72,"searchDepth":85,"depth":85,"links":6966},[6967,6968,6969,6970,6971,6972,6973,6974],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6792,"description":6797},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[286,6982,6983],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6986,"title":6987,"body":6988,"category":286,"cover":287,"description":6992,"extension":288,"meta":7159,"navigation":88,"path":7160,"pinned":291,"publishedAt":292,"seo":7161,"slug":7162,"stem":7163,"summary":7164,"tags":7165,"updatedAt":292,"visible":88,"__hash__":7168},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6989,"toc":7149},[6990,6993,6995,6998,7000,7006,7016,7018,7032,7034,7036,7096,7098,7104,7106,7108,7120,7122,7130,7132,7140,7142,7144,7147],[10,6991,6992],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6994,16],{"id":16},[10,6996,6997],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6999,22],{"id":22},[10,7001,7002],{},[26,7003],{"alt":7004,"src":7005},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,7007,7008,7011,7012,7015],{},[43,7009,7010],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[43,7013,7014],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,7017,35],{"id":35},[37,7019,7020,7023,7029],{},[40,7021,7022],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[40,7024,7025,7028],{},[43,7026,7027],{},"ensure_ascii=False"," 让中文以可读字符写入。",[40,7030,7031],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,7033,62],{"id":62},[10,7035,65],{},[67,7037,7039],{"className":69,"code":7038,"language":71,"meta":72,"style":72},"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",[43,7040,7041,7046,7050,7055,7059,7064,7069,7073,7077,7082,7087,7091],{"__ignoreMap":72},[76,7042,7043],{"class":78,"line":79},[76,7044,7045],{},"import json\n",[76,7047,7048],{"class":78,"line":85},[76,7049,89],{"emptyLinePlaceholder":88},[76,7051,7052],{"class":78,"line":92},[76,7053,7054],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[76,7056,7057],{"class":78,"line":98},[76,7058,89],{"emptyLinePlaceholder":88},[76,7060,7061],{"class":78,"line":104},[76,7062,7063],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[76,7065,7066],{"class":78,"line":110},[76,7067,7068],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[76,7070,7071],{"class":78,"line":116},[76,7072,6880],{},[76,7074,7075],{"class":78,"line":122},[76,7076,89],{"emptyLinePlaceholder":88},[76,7078,7079],{"class":78,"line":128},[76,7080,7081],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[76,7083,7084],{"class":78,"line":134},[76,7085,7086],{},"loaded = json.load(reader)\n",[76,7088,7089],{"class":78,"line":140},[76,7090,6899],{},[76,7092,7093],{"class":78,"line":145},[76,7094,7095],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7097,174],{},[67,7099,7102],{"className":7100,"code":7101,"language":180,"meta":72},[178],"Python 60\n",[43,7103,7101],{"__ignoreMap":72},[10,7105,185],{},[14,7107,188],{"id":188},[190,7109,7110,7115],{},[40,7111,7112,7114],{},[43,7113,7010],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[40,7116,7117,7119],{},[43,7118,7014],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7121,234],{"id":234},[37,7123,7124,7127],{},[40,7125,7126],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[40,7128,7129],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7131,248],{"id":248},[190,7133,7134,7137],{},[40,7135,7136],{},"保存包含两条学习记录的列表。",[40,7138,7139],{},"读取后修改进度，再重新写回文件。",[10,7141,263],{},[14,7143,266],{"id":266},[10,7145,7146],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,7148,273],{},{"title":72,"searchDepth":85,"depth":85,"links":7150},[7151,7152,7153,7154,7155,7156,7157,7158],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6987,"description":6992},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[286,7166,7167],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7170,"title":7171,"body":7172,"category":286,"cover":287,"description":7176,"extension":288,"meta":7360,"navigation":88,"path":7361,"pinned":291,"publishedAt":292,"seo":7362,"slug":7363,"stem":7364,"summary":7365,"tags":7366,"updatedAt":292,"visible":88,"__hash__":7369},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7173,"toc":7350},[7174,7177,7179,7182,7184,7190,7196,7198,7220,7222,7224,7287,7289,7295,7297,7299,7315,7317,7331,7333,7341,7343,7345,7348],[10,7175,7176],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7178,16],{"id":16},[10,7180,7181],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7183,22],{"id":22},[10,7185,7186],{},[26,7187],{"alt":7188,"src":7189},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7191,7192,7195],{},[43,7193,7194],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7197,35],{"id":35},[37,7199,7200,7210,7217],{},[40,7201,2398,7202,7205,7206,7209],{},[43,7203,7204],{},"newline=\"\""," 让 ",[43,7207,7208],{},"csv"," 模块正确处理换行。",[40,7211,7212,7213,7216],{},"字段顺序由 ",[43,7214,7215],{},"fieldnames"," 决定，字典键需要与字段名一致。",[40,7218,7219],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7221,62],{"id":62},[10,7223,65],{},[67,7225,7227],{"className":69,"code":7226,"language":71,"meta":72,"style":72},"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",[43,7228,7229,7234,7238,7243,7248,7253,7258,7263,7267,7272,7277,7282],{"__ignoreMap":72},[76,7230,7231],{"class":78,"line":79},[76,7232,7233],{},"import csv\n",[76,7235,7236],{"class":78,"line":85},[76,7237,89],{"emptyLinePlaceholder":88},[76,7239,7240],{"class":78,"line":92},[76,7241,7242],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[76,7244,7245],{"class":78,"line":98},[76,7246,7247],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[76,7249,7250],{"class":78,"line":104},[76,7251,7252],{},"writer.writeheader()\n",[76,7254,7255],{"class":78,"line":110},[76,7256,7257],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[76,7259,7260],{"class":78,"line":116},[76,7261,7262],{},"writer_file.close()\n",[76,7264,7265],{"class":78,"line":122},[76,7266,89],{"emptyLinePlaceholder":88},[76,7268,7269],{"class":78,"line":128},[76,7270,7271],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[76,7273,7274],{"class":78,"line":134},[76,7275,7276],{},"for row in csv.DictReader(reader_file):\n",[76,7278,7279],{"class":78,"line":140},[76,7280,7281],{},"    print(row[\"name\"], row[\"score\"])\n",[76,7283,7284],{"class":78,"line":145},[76,7285,7286],{},"reader_file.close()\n",[10,7288,174],{},[67,7290,7293],{"className":7291,"code":7292,"language":180,"meta":72},[178],"小郑 95\n",[43,7294,7292],{"__ignoreMap":72},[10,7296,185],{},[14,7298,188],{"id":188},[190,7300,7301,7310],{},[40,7302,7303,7306,7307,7309],{},[43,7304,7305],{},"DictWriter"," 按 ",[43,7308,7215],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[40,7311,7312,7314],{},[43,7313,7194],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7316,234],{"id":234},[37,7318,7319,7322],{},[40,7320,7321],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[40,7323,7324,7325,7327,7328,7330],{},"在 macOS 以外环境忽略 ",[43,7326,7204],{}," 可能出现额外空行；统一交给 ",[43,7329,7208],{}," 模块管理换行。",[14,7332,248],{"id":248},[190,7334,7335,7338],{},[40,7336,7337],{},"写入三名学习者的课程和分数。",[40,7339,7340],{},"读取 CSV 后把分数字符串转换为整数。",[10,7342,263],{},[14,7344,266],{"id":266},[10,7346,7347],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,7349,273],{},{"title":72,"searchDepth":85,"depth":85,"links":7351},[7352,7353,7354,7355,7356,7357,7358,7359],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7171,"description":7176},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[286,7367,7368],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7371,"title":7372,"body":7373,"category":286,"cover":287,"description":7377,"extension":288,"meta":7648,"navigation":88,"path":7649,"pinned":291,"publishedAt":292,"seo":7650,"slug":7651,"stem":7652,"summary":7653,"tags":7654,"updatedAt":292,"visible":88,"__hash__":7657},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7374,"toc":7635},[7375,7378,7380,7383,7385,7391,7402,7404,7421,7423,7425,7498,7500,7506,7508,7510,7535,7537,7546,7552,7563,7565,7571,7577,7586,7588,7603,7605,7626,7628,7630,7633],[10,7376,7377],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7379,16],{"id":16},[10,7381,7382],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7384,22],{"id":22},[10,7386,7387],{},[26,7388],{"alt":7389,"src":7390},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7392,7393,7394,7397,7398,7401],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[43,7395,7396],{},"except","；无论是否异常，",[43,7399,7400],{},"finally"," 都会在离开结构前执行。",[14,7403,35],{"id":35},[37,7405,7406,7412,7418],{},[40,7407,7408,7409,7411],{},"只捕获能够处理的具体异常，不使用空的 ",[43,7410,7396],{}," 吞掉全部错误。",[40,7413,7414,7417],{},[43,7415,7416],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[40,7419,7420],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7422,62],{"id":62},[10,7424,65],{},[67,7426,7428],{"className":69,"code":7427,"language":71,"meta":72,"style":72},"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",[43,7429,7430,7435,7440,7445,7450,7455,7459,7464,7469,7474,7479,7483,7488,7493],{"__ignoreMap":72},[76,7431,7432],{"class":78,"line":79},[76,7433,7434],{},"def parse_age(text):\n",[76,7436,7437],{"class":78,"line":85},[76,7438,7439],{},"    age = int(text)\n",[76,7441,7442],{"class":78,"line":92},[76,7443,7444],{},"    if age \u003C 0:\n",[76,7446,7447],{"class":78,"line":98},[76,7448,7449],{},"        raise ValueError(\"年龄不能为负数\")\n",[76,7451,7452],{"class":78,"line":104},[76,7453,7454],{},"    return age\n",[76,7456,7457],{"class":78,"line":110},[76,7458,89],{"emptyLinePlaceholder":88},[76,7460,7461],{"class":78,"line":116},[76,7462,7463],{},"try:\n",[76,7465,7466],{"class":78,"line":122},[76,7467,7468],{},"    age = parse_age(\"18\")\n",[76,7470,7471],{"class":78,"line":128},[76,7472,7473],{},"except ValueError as error:\n",[76,7475,7476],{"class":78,"line":134},[76,7477,7478],{},"    print(\"输入错误：\", error)\n",[76,7480,7481],{"class":78,"line":140},[76,7482,1205],{},[76,7484,7485],{"class":78,"line":145},[76,7486,7487],{},"    print(\"年龄：\", age)\n",[76,7489,7490],{"class":78,"line":151},[76,7491,7492],{},"finally:\n",[76,7494,7495],{"class":78,"line":157},[76,7496,7497],{},"    print(\"处理结束\")\n",[10,7499,174],{},[67,7501,7504],{"className":7502,"code":7503,"language":180,"meta":72},[178],"年龄： 18\n处理结束\n",[43,7505,7503],{"__ignoreMap":72},[10,7507,185],{},[14,7509,188],{"id":188},[190,7511,7512,7524],{},[40,7513,7514,7516,7517,7519,7520,7523],{},[43,7515,3094],{}," 或主动 ",[43,7518,7416],{}," 都可能产生 ",[43,7521,7522],{},"ValueError","，控制流立即离开当前正常路径。",[40,7525,7526,7527,7529,7530,7532,7533,50],{},"有异常时进入匹配的 ",[43,7528,7396],{},"；没有异常时执行 ",[43,7531,1219],{},"；两种情况最后都会执行 ",[43,7534,7400],{},[213,7536,215],{"id":215},[10,7538,7539,2316,7541,1216,7543,7545],{},[43,7540,7396],{},[43,7542,1219],{},[43,7544,7400],{}," 的职责不同，不能只看它们出现的顺序。",[10,7547,7548],{},[26,7549],{"alt":7550,"src":7551},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7553,7554,7556,7557,7559,7560,7562],{},[43,7555,7396],{}," 处理匹配异常，",[43,7558,1219],{}," 只在无异常时运行，",[43,7561,7400],{}," 负责两条路径都需要的清理动作。",[213,7564,215],{"id":4276},[10,7566,7567,7570],{},[43,7568,7569],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7572,7573],{},[26,7574],{"alt":7575,"src":7576},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7578,7579,7580,7582,7583,7585],{},"只把可能产生预期异常的操作放进 ",[43,7581,7569],{},"，后续正常业务放进 ",[43,7584,1219],{},"，错误边界会更清楚。",[14,7587,234],{"id":234},[37,7589,7590,7597],{},[40,7591,7592,7593,7596],{},"使用裸 ",[43,7594,7595],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[40,7598,7599,7600,7602],{},"把整个程序包在一个巨大 ",[43,7601,7569],{}," 中，无法判断究竟哪一步允许失败。",[14,7604,248],{"id":248},[190,7606,7607,7620],{},[40,7608,7609,7610,7613,7614,1216,7617,50],{},"让 ",[43,7611,7612],{},"parse_age"," 分别处理 ",[43,7615,7616],{},"\"abc\"",[43,7618,7619],{},"\"-1\"",[40,7621,7622,7623,7625],{},"为文件读取捕获 ",[43,7624,6832],{}," 并给出清晰提示。",[10,7627,263],{},[14,7629,266],{"id":266},[10,7631,7632],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,7634,273],{},{"title":72,"searchDepth":85,"depth":85,"links":7636},[7637,7638,7639,7640,7641,7645,7646,7647],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":7642},[7643,7644],{"id":215,"depth":92,"text":215},{"id":4276,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7372,"description":7377},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[286,7655,7656],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7659,"title":7660,"body":7661,"category":286,"cover":287,"description":7665,"extension":288,"meta":7841,"navigation":88,"path":7842,"pinned":291,"publishedAt":292,"seo":7843,"slug":7844,"stem":7845,"summary":7846,"tags":7847,"updatedAt":292,"visible":88,"__hash__":7849},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7662,"toc":7831},[7663,7666,7668,7671,7673,7679,7685,7687,7703,7705,7707,7761,7763,7769,7771,7773,7786,7788,7801,7803,7822,7824,7826,7829],[10,7664,7665],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7667,16],{"id":16},[10,7669,7670],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7672,22],{"id":22},[10,7674,7675],{},[26,7676],{"alt":7677,"src":7678},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7680,7681,7682,7684],{},"进入 ",[43,7683,6842],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7686,35],{"id":35},[37,7688,7689,7694,7700],{},[40,7690,7691,7693],{},[43,7692,6842],{}," 把资源获取和释放配成一个清晰边界。",[40,7695,7696,7699],{},[43,7697,7698],{},"as file"," 得到的是上下文返回的资源对象。",[40,7701,7702],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7704,62],{"id":62},[10,7706,65],{},[67,7708,7710],{"className":69,"code":7709,"language":71,"meta":72,"style":72},"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",[43,7711,7712,7716,7720,7724,7728,7733,7738,7742,7747,7752,7756],{"__ignoreMap":72},[76,7713,7714],{"class":78,"line":79},[76,7715,6654],{},[76,7717,7718],{"class":78,"line":85},[76,7719,89],{"emptyLinePlaceholder":88},[76,7721,7722],{"class":78,"line":92},[76,7723,6865],{},[76,7725,7726],{"class":78,"line":98},[76,7727,89],{"emptyLinePlaceholder":88},[76,7729,7730],{"class":78,"line":104},[76,7731,7732],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[76,7734,7735],{"class":78,"line":110},[76,7736,7737],{},"    file.write(\"上下文管理器\\n\")\n",[76,7739,7740],{"class":78,"line":116},[76,7741,89],{"emptyLinePlaceholder":88},[76,7743,7744],{"class":78,"line":122},[76,7745,7746],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[76,7748,7749],{"class":78,"line":128},[76,7750,7751],{},"    print(file.read())\n",[76,7753,7754],{"class":78,"line":134},[76,7755,89],{"emptyLinePlaceholder":88},[76,7757,7758],{"class":78,"line":140},[76,7759,7760],{},"print(file.closed)\n",[10,7762,174],{},[67,7764,7767],{"className":7765,"code":7766,"language":180,"meta":72},[178],"上下文管理器\n\nTrue\n",[43,7768,7766],{"__ignoreMap":72},[10,7770,185],{},[14,7772,188],{"id":188},[190,7774,7775,7783],{},[40,7776,7681,7777,7779,7780,50],{},[43,7778,6842],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[43,7781,7782],{},"file",[40,7784,7785],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7787,234],{"id":234},[37,7789,7790,7795],{},[40,7791,4844,7792,7794],{},[43,7793,6842],{}," 代码块外继续读写已经关闭的文件对象。",[40,7796,7797,7798,7800],{},"误以为 ",[43,7799,6842],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7802,248],{"id":248},[190,7804,7805,7814],{},[40,7806,7807,7808,7811,7812,50],{},"把第 30 篇的手动 ",[43,7809,7810],{},"open\u002Fclose"," 改写为 ",[43,7813,6842],{},[40,7815,4844,7816,7818,7819,50],{},[43,7817,6842],{}," 块后检查 ",[43,7820,7821],{},"file.closed",[10,7823,263],{},[14,7825,266],{"id":266},[10,7827,7828],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,7830,273],{},{"title":72,"searchDepth":85,"depth":85,"links":7832},[7833,7834,7835,7836,7837,7838,7839,7840],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7660,"description":7665},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[286,6842,7848],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7851,"title":7852,"body":7853,"category":286,"cover":287,"description":7857,"extension":288,"meta":8069,"navigation":88,"path":8070,"pinned":291,"publishedAt":292,"seo":8071,"slug":8072,"stem":8073,"summary":8074,"tags":8075,"updatedAt":292,"visible":88,"__hash__":8078},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7854,"toc":8057},[7855,7858,7860,7863,7865,7871,7874,7876,7893,7895,7897,7965,7967,7973,7975,7977,8002,8004,8007,8013,8022,8024,8035,8037,8048,8050,8052,8055],[10,7856,7857],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7859,16],{"id":16},[10,7861,7862],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7864,22],{"id":22},[10,7866,7867],{},[26,7868],{"alt":7869,"src":7870},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7872,7873],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7875,35],{"id":35},[37,7877,7878,7884,7890],{},[40,7879,7880,7883],{},[43,7881,7882],{},"self"," 表示当前实例，由方法调用自动传入。",[40,7885,7886,7889],{},[43,7887,7888],{},"__init__"," 在实例创建过程中初始化属性。",[40,7891,7892],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7894,62],{"id":62},[10,7896,65],{},[67,7898,7900],{"className":69,"code":7899,"language":71,"meta":72,"style":72},"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",[43,7901,7902,7907,7912,7917,7922,7926,7931,7936,7941,7946,7950,7955,7960],{"__ignoreMap":72},[76,7903,7904],{"class":78,"line":79},[76,7905,7906],{},"class LearningRecord:\n",[76,7908,7909],{"class":78,"line":85},[76,7910,7911],{},"    def __init__(self, course, progress=0):\n",[76,7913,7914],{"class":78,"line":92},[76,7915,7916],{},"        self.course = course\n",[76,7918,7919],{"class":78,"line":98},[76,7920,7921],{},"        self.progress = progress\n",[76,7923,7924],{"class":78,"line":104},[76,7925,89],{"emptyLinePlaceholder":88},[76,7927,7928],{"class":78,"line":110},[76,7929,7930],{},"    def advance(self, amount):\n",[76,7932,7933],{"class":78,"line":116},[76,7934,7935],{},"        self.progress = self.progress + amount\n",[76,7937,7938],{"class":78,"line":122},[76,7939,7940],{},"        if self.progress > 100:\n",[76,7942,7943],{"class":78,"line":128},[76,7944,7945],{},"            self.progress = 100\n",[76,7947,7948],{"class":78,"line":134},[76,7949,89],{"emptyLinePlaceholder":88},[76,7951,7952],{"class":78,"line":140},[76,7953,7954],{},"record = LearningRecord(\"Python\", 40)\n",[76,7956,7957],{"class":78,"line":145},[76,7958,7959],{},"record.advance(15)\n",[76,7961,7962],{"class":78,"line":151},[76,7963,7964],{},"print(record.course, record.progress)\n",[10,7966,174],{},[67,7968,7971],{"className":7969,"code":7970,"language":180,"meta":72},[178],"Python 55\n",[43,7972,7970],{"__ignoreMap":72},[10,7974,185],{},[14,7976,188],{"id":188},[190,7978,7979,7989],{},[40,7980,7981,7982,7985,7986,7988],{},"调用 ",[43,7983,7984],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[43,7987,7888],{}," 把课程和进度保存在该实例属性中。",[40,7990,7991,7994,7995,7998,7999,8001],{},[43,7992,7993],{},"record.advance(15)"," 自动把 ",[43,7996,7997],{},"record"," 作为 ",[43,8000,7882],{},"，方法更新同一实例的进度并限制上限。",[213,8003,215],{"id":215},[10,8005,8006],{},"类是共同定义，实例则各自保存状态。",[10,8008,8009],{},[26,8010],{"alt":8011,"src":8012},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,8014,8015,8016,1216,8018,8021],{},"两个实例共享同一套方法定义，但 ",[43,8017,4641],{},[43,8019,8020],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,8023,234],{"id":234},[37,8025,8026,8032],{},[40,8027,8028,8029,8031],{},"调用实例方法时手工再传一次 ",[43,8030,7882],{},"。通过实例调用时 Python 会自动绑定。",[40,8033,8034],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,8036,248],{"id":248},[190,8038,8039,8045],{},[40,8040,5354,8041,8044],{},[43,8042,8043],{},"Book"," 类，保存标题和阅读页数。",[40,8046,8047],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,8049,263],{},[14,8051,266],{"id":266},[10,8053,8054],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,8056,273],{},{"title":72,"searchDepth":85,"depth":85,"links":8058},[8059,8060,8061,8062,8063,8066,8067,8068],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":8064},[8065],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7852,"description":7857},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[286,8076,8077],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":8080,"title":8081,"body":8082,"category":286,"cover":287,"description":8086,"extension":288,"meta":8264,"navigation":88,"path":8265,"pinned":291,"publishedAt":292,"seo":8266,"slug":8267,"stem":8268,"summary":8269,"tags":8270,"updatedAt":292,"visible":88,"__hash__":8273},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8083,"toc":8254},[8084,8087,8089,8092,8094,8100,8103,8105,8116,8118,8120,8187,8189,8195,8197,8199,8218,8220,8228,8230,8245,8247,8249,8252],[10,8085,8086],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,8088,16],{"id":16},[10,8090,8091],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8093,22],{"id":22},[10,8095,8096],{},[26,8097],{"alt":8098,"src":8099},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8101,8102],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8104,35],{"id":35},[37,8106,8107,8110,8113],{},[40,8108,8109],{},"封装让对象通过方法维护自己的有效状态。",[40,8111,8112],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[40,8114,8115],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8117,62],{"id":62},[10,8119,65],{},[67,8121,8123],{"className":69,"code":8122,"language":71,"meta":72,"style":72},"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",[43,8124,8125,8130,8135,8140,8144,8149,8154,8159,8163,8168,8173,8177,8182],{"__ignoreMap":72},[76,8126,8127],{"class":78,"line":79},[76,8128,8129],{},"class Storage:\n",[76,8131,8132],{"class":78,"line":85},[76,8133,8134],{},"    def save(self, text):\n",[76,8136,8137],{"class":78,"line":92},[76,8138,8139],{},"        print(\"保存：\", text)\n",[76,8141,8142],{"class":78,"line":98},[76,8143,89],{"emptyLinePlaceholder":88},[76,8145,8146],{"class":78,"line":104},[76,8147,8148],{},"class LearningService:\n",[76,8150,8151],{"class":78,"line":110},[76,8152,8153],{},"    def __init__(self, storage):\n",[76,8155,8156],{"class":78,"line":116},[76,8157,8158],{},"        self.storage = storage\n",[76,8160,8161],{"class":78,"line":122},[76,8162,89],{"emptyLinePlaceholder":88},[76,8164,8165],{"class":78,"line":128},[76,8166,8167],{},"    def finish_lesson(self, title):\n",[76,8169,8170],{"class":78,"line":134},[76,8171,8172],{},"        self.storage.save(title)\n",[76,8174,8175],{"class":78,"line":140},[76,8176,89],{"emptyLinePlaceholder":88},[76,8178,8179],{"class":78,"line":145},[76,8180,8181],{},"service = LearningService(Storage())\n",[76,8183,8184],{"class":78,"line":151},[76,8185,8186],{},"service.finish_lesson(\"异常处理\")\n",[10,8188,174],{},[67,8190,8193],{"className":8191,"code":8192,"language":180,"meta":72},[178],"保存： 异常处理\n",[43,8194,8192],{"__ignoreMap":72},[10,8196,185],{},[14,8198,188],{"id":188},[190,8200,8201,8211],{},[40,8202,8203,8206,8207,8210],{},[43,8204,8205],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[43,8208,8209],{},"save()"," 的协作对象。",[40,8212,8213,8214,8217],{},"调用业务方法时，服务把保存动作委托给 ",[43,8215,8216],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8219,234],{"id":234},[37,8221,8222,8225],{},[40,8223,8224],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[40,8226,8227],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8229,248],{"id":248},[190,8231,8232,8242],{},[40,8233,8234,8235,8238,8239,50],{},"用组合让 ",[43,8236,8237],{},"OrderService"," 使用一个 ",[43,8240,8241],{},"Notifier",[40,8243,8244],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8246,263],{},[14,8248,266],{"id":266},[10,8250,8251],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,8253,273],{},{"title":72,"searchDepth":85,"depth":85,"links":8255},[8256,8257,8258,8259,8260,8261,8262,8263],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":8081,"description":8086},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[286,8271,8272],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8275,"title":8276,"body":8277,"category":286,"cover":287,"description":8281,"extension":288,"meta":8484,"navigation":88,"path":8485,"pinned":291,"publishedAt":292,"seo":8486,"slug":8487,"stem":8488,"summary":8489,"tags":8490,"updatedAt":292,"visible":88,"__hash__":8493},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8278,"toc":8472},[8279,8282,8284,8287,8289,8295,8302,8304,8329,8331,8333,8385,8387,8393,8395,8397,8418,8420,8426,8432,8438,8440,8448,8450,8463,8465,8467,8470],[10,8280,8281],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8283,16],{"id":16},[10,8285,8286],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8288,22],{"id":22},[10,8290,8291],{},[26,8292],{"alt":8293,"src":8294},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8296,8297,8298,8301],{},"生成器运行到 ",[43,8299,8300],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8303,35],{"id":35},[37,8305,8306,8316,8326],{},[40,8307,8308,8311,8312,8315],{},[43,8309,8310],{},"iter()"," 从可迭代对象取得迭代器，",[43,8313,8314],{},"next()"," 请求下一个值。",[40,8317,8318,8319,8322,8323,8325],{},"没有更多值时迭代器抛出 ",[43,8320,8321],{},"StopIteration","，",[43,8324,4395],{}," 会自动处理。",[40,8327,8328],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8330,62],{"id":62},[10,8332,65],{},[67,8334,8336],{"className":69,"code":8335,"language":71,"meta":72,"style":72},"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",[43,8337,8338,8343,8348,8353,8358,8363,8367,8372,8377,8381],{"__ignoreMap":72},[76,8339,8340],{"class":78,"line":79},[76,8341,8342],{},"def countdown(start):\n",[76,8344,8345],{"class":78,"line":85},[76,8346,8347],{},"    current = start\n",[76,8349,8350],{"class":78,"line":92},[76,8351,8352],{},"    while current > 0:\n",[76,8354,8355],{"class":78,"line":98},[76,8356,8357],{},"        yield current\n",[76,8359,8360],{"class":78,"line":104},[76,8361,8362],{},"        current = current - 1\n",[76,8364,8365],{"class":78,"line":110},[76,8366,89],{"emptyLinePlaceholder":88},[76,8368,8369],{"class":78,"line":116},[76,8370,8371],{},"iterator = countdown(3)\n",[76,8373,8374],{"class":78,"line":122},[76,8375,8376],{},"print(next(iterator))\n",[76,8378,8379],{"class":78,"line":128},[76,8380,8376],{},[76,8382,8383],{"class":78,"line":134},[76,8384,8376],{},[10,8386,174],{},[67,8388,8391],{"className":8389,"code":8390,"language":180,"meta":72},[178],"3\n2\n1\n",[43,8392,8390],{"__ignoreMap":72},[10,8394,185],{},[14,8396,188],{"id":188},[190,8398,8399,8405],{},[40,8400,7981,8401,8404],{},[43,8402,8403],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[40,8406,8407,8408,8410,8411,8413,8414,8417],{},"每次 ",[43,8409,8314],{}," 运行到下一个 ",[43,8412,8300],{}," 并暂停，局部变量 ",[43,8415,8416],{},"current"," 和执行位置被保留。",[213,8419,215],{"id":215},[10,8421,8422,8423,8425],{},"生成器的暂停位置可以展开成多次 ",[43,8424,8314],{}," 的时间线。",[10,8427,8428],{},[26,8429],{"alt":8430,"src":8431},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8433,8434,8435,8437],{},"每次请求只推进到下一个 ",[43,8436,8300],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8439,234],{"id":234},[37,8441,8442,8445],{},[40,8443,8444],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[40,8446,8447],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8449,248],{"id":248},[190,8451,8452,8455],{},[40,8453,8454],{},"编写产生 1 到指定上限偶数的生成器。",[40,8456,4068,8457,8459,8460,8462],{},[43,8458,4395],{}," 遍历生成器，比较手动 ",[43,8461,8314],{}," 的差异。",[10,8464,263],{},[14,8466,266],{"id":266},[10,8468,8469],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,8471,273],{},{"title":72,"searchDepth":85,"depth":85,"links":8473},[8474,8475,8476,8477,8478,8481,8482,8483],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":8479},[8480],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8276,"description":8281},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[286,8491,8492],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":4,"title":5,"body":8495,"category":286,"cover":287,"description":12,"extension":288,"meta":8678,"navigation":88,"path":290,"pinned":291,"publishedAt":292,"seo":8679,"slug":294,"stem":295,"summary":296,"tags":8680,"updatedAt":292,"visible":88,"__hash__":300},{"type":7,"value":8496,"toc":8666},[8497,8499,8501,8503,8505,8509,8511,8513,8527,8529,8531,8599,8601,8606,8608,8610,8624,8626,8628,8632,8638,8640,8648,8650,8658,8660,8662,8664],[10,8498,12],{},[14,8500,16],{"id":16},[10,8502,19],{},[14,8504,22],{"id":22},[10,8506,8507],{},[26,8508],{"alt":28,"src":29},[10,8510,32],{},[14,8512,35],{"id":35},[37,8514,8515,8521,8523],{},[40,8516,8517,46,8519,50],{},[43,8518,45],{},[43,8520,49],{},[40,8522,53],{},[40,8524,8525,59],{},[43,8526,58],{},[14,8528,62],{"id":62},[10,8530,65],{},[67,8532,8533],{"className":69,"code":70,"language":71,"meta":72,"style":72},[43,8534,8535,8539,8543,8547,8551,8555,8559,8563,8567,8571,8575,8579,8583,8587,8591,8595],{"__ignoreMap":72},[76,8536,8537],{"class":78,"line":79},[76,8538,82],{},[76,8540,8541],{"class":78,"line":85},[76,8542,89],{"emptyLinePlaceholder":88},[76,8544,8545],{"class":78,"line":92},[76,8546,95],{},[76,8548,8549],{"class":78,"line":98},[76,8550,101],{},[76,8552,8553],{"class":78,"line":104},[76,8554,107],{},[76,8556,8557],{"class":78,"line":110},[76,8558,113],{},[76,8560,8561],{"class":78,"line":116},[76,8562,119],{},[76,8564,8565],{"class":78,"line":122},[76,8566,125],{},[76,8568,8569],{"class":78,"line":128},[76,8570,131],{},[76,8572,8573],{"class":78,"line":134},[76,8574,137],{},[76,8576,8577],{"class":78,"line":140},[76,8578,89],{"emptyLinePlaceholder":88},[76,8580,8581],{"class":78,"line":145},[76,8582,148],{},[76,8584,8585],{"class":78,"line":151},[76,8586,154],{},[76,8588,8589],{"class":78,"line":157},[76,8590,160],{},[76,8592,8593],{"class":78,"line":163},[76,8594,89],{"emptyLinePlaceholder":88},[76,8596,8597],{"class":78,"line":168},[76,8598,171],{},[10,8600,174],{},[67,8602,8604],{"className":8603,"code":179,"language":180,"meta":72},[178],[43,8605,179],{"__ignoreMap":72},[10,8607,185],{},[14,8609,188],{"id":188},[190,8611,8612,8622],{},[40,8613,194,8614,198,8616,202,8618,206,8620,50],{},[43,8615,197],{},[43,8617,201],{},[43,8619,205],{},[43,8621,197],{},[40,8623,211],{},[213,8625,215],{"id":215},[10,8627,218],{},[10,8629,8630],{},[26,8631],{"alt":223,"src":224},[10,8633,8634,229,8636,50],{},[43,8635,45],{},[43,8637,49],{},[14,8639,234],{"id":234},[37,8641,8642,8646],{},[40,8643,239,8644,50],{},[43,8645,242],{},[40,8647,245],{},[14,8649,248],{"id":248},[190,8651,8652,8654],{},[40,8653,253],{},[40,8655,256,8656,260],{},[43,8657,259],{},[10,8659,263],{},[14,8661,266],{"id":266},[10,8663,269],{},[271,8665,273],{},{"title":72,"searchDepth":85,"depth":85,"links":8667},[8668,8669,8670,8671,8672,8675,8676,8677],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":8673},[8674],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5,"description":12},[286,298,299],{"id":8682,"title":8683,"body":8684,"category":286,"cover":287,"description":8688,"extension":288,"meta":8875,"navigation":88,"path":8876,"pinned":291,"publishedAt":292,"seo":8877,"slug":8878,"stem":8879,"summary":8880,"tags":8881,"updatedAt":292,"visible":88,"__hash__":8884},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8685,"toc":8863},[8686,8689,8691,8694,8696,8702,8705,8707,8718,8720,8722,8797,8799,8805,8807,8809,8820,8822,8825,8831,8834,8836,8844,8846,8854,8856,8858,8861],[10,8687,8688],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8690,16],{"id":16},[10,8692,8693],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8695,22],{"id":22},[10,8697,8698],{},[26,8699],{"alt":8700,"src":8701},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8703,8704],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8706,35],{"id":35},[37,8708,8709,8712,8715],{},[40,8710,8711],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[40,8713,8714],{},"日志记录运行状态，测试判断结果是否符合约定。",[40,8716,8717],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8719,62],{"id":62},[10,8721,65],{},[67,8723,8725],{"className":69,"code":8724,"language":71,"meta":72,"style":72},"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",[43,8726,8727,8732,8737,8741,8746,8750,8755,8760,8765,8769,8774,8779,8784,8788,8792],{"__ignoreMap":72},[76,8728,8729],{"class":78,"line":79},[76,8730,8731],{},"import logging\n",[76,8733,8734],{"class":78,"line":85},[76,8735,8736],{},"import unittest\n",[76,8738,8739],{"class":78,"line":92},[76,8740,89],{"emptyLinePlaceholder":88},[76,8742,8743],{"class":78,"line":98},[76,8744,8745],{},"logging.basicConfig(level=logging.INFO)\n",[76,8747,8748],{"class":78,"line":104},[76,8749,89],{"emptyLinePlaceholder":88},[76,8751,8752],{"class":78,"line":110},[76,8753,8754],{},"def clamp_progress(value):\n",[76,8756,8757],{"class":78,"line":116},[76,8758,8759],{},"    logging.info(\"检查进度：%s\", value)\n",[76,8761,8762],{"class":78,"line":122},[76,8763,8764],{},"    return max(0, min(100, value))\n",[76,8766,8767],{"class":78,"line":128},[76,8768,89],{"emptyLinePlaceholder":88},[76,8770,8771],{"class":78,"line":134},[76,8772,8773],{},"class ProgressTest(unittest.TestCase):\n",[76,8775,8776],{"class":78,"line":140},[76,8777,8778],{},"    def test_upper_limit(self):\n",[76,8780,8781],{"class":78,"line":145},[76,8782,8783],{},"        self.assertEqual(clamp_progress(120), 100)\n",[76,8785,8786],{"class":78,"line":151},[76,8787,89],{"emptyLinePlaceholder":88},[76,8789,8790],{"class":78,"line":157},[76,8791,6247],{},[76,8793,8794],{"class":78,"line":163},[76,8795,8796],{},"    unittest.main()\n",[10,8798,174],{},[67,8800,8803],{"className":8801,"code":8802,"language":180,"meta":72},[178],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[43,8804,8802],{"__ignoreMap":72},[10,8806,185],{},[14,8808,188],{"id":188},[190,8810,8811,8817],{},[40,8812,8813,8816],{},[43,8814,8815],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[40,8818,8819],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[213,8821,215],{"id":215},[10,8823,8824],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8826,8827],{},[26,8828],{"alt":8829,"src":8830},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8832,8833],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8835,234],{"id":234},[37,8837,8838,8841],{},[40,8839,8840],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[40,8842,8843],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8845,248],{"id":248},[190,8847,8848,8851],{},[40,8849,8850],{},"为负数进度增加测试。",[40,8852,8853],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8855,263],{},[14,8857,266],{"id":266},[10,8859,8860],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,8862,273],{},{"title":72,"searchDepth":85,"depth":85,"links":8864},[8865,8866,8867,8868,8869,8872,8873,8874],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":8870},[8871],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8683,"description":8688},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[286,8882,8883],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8886,"title":8887,"body":8888,"category":286,"cover":287,"description":8892,"extension":288,"meta":9192,"navigation":88,"path":9193,"pinned":291,"publishedAt":292,"seo":9194,"slug":9195,"stem":9196,"summary":9197,"tags":9198,"updatedAt":292,"visible":88,"__hash__":9201},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8889,"toc":9179},[8890,8893,8895,8898,8900,8906,8909,8911,8926,8928,8930,9077,9079,9085,9087,9089,9102,9104,9107,9113,9116,9118,9121,9127,9134,9136,9147,9149,9170,9172,9174,9177],[10,8891,8892],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8894,16],{"id":16},[10,8896,8897],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8899,22],{"id":22},[10,8901,8902],{},[26,8903],{"alt":8904,"src":8905},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8907,8908],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8910,35],{"id":35},[37,8912,8913,8916,8919],{},[40,8914,8915],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[40,8917,8918],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[40,8920,8921,8922,8925],{},"实际扩展前先为 ",[43,8923,8924],{},"add()"," 和存储边界补充测试。",[14,8927,62],{"id":62},[10,8929,65],{},[67,8931,8933],{"className":69,"code":8932,"language":71,"meta":72,"style":72},"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",[43,8934,8935,8939,8943,8947,8952,8957,8962,8967,8971,8976,8981,8986,8991,8996,9000,9005,9010,9016,9021,9027,9032,9037,9043,9049,9055,9060,9066,9071],{"__ignoreMap":72},[76,8936,8937],{"class":78,"line":79},[76,8938,7045],{},[76,8940,8941],{"class":78,"line":85},[76,8942,6654],{},[76,8944,8945],{"class":78,"line":92},[76,8946,89],{"emptyLinePlaceholder":88},[76,8948,8949],{"class":78,"line":98},[76,8950,8951],{},"class LearningRecords:\n",[76,8953,8954],{"class":78,"line":104},[76,8955,8956],{},"    def __init__(self, file_path):\n",[76,8958,8959],{"class":78,"line":110},[76,8960,8961],{},"        self.file_path = Path(file_path)\n",[76,8963,8964],{"class":78,"line":116},[76,8965,8966],{},"        self.items = []\n",[76,8968,8969],{"class":78,"line":122},[76,8970,89],{"emptyLinePlaceholder":88},[76,8972,8973],{"class":78,"line":128},[76,8974,8975],{},"    def add(self, title):\n",[76,8977,8978],{"class":78,"line":134},[76,8979,8980],{},"        title = title.strip()\n",[76,8982,8983],{"class":78,"line":140},[76,8984,8985],{},"        if not title:\n",[76,8987,8988],{"class":78,"line":145},[76,8989,8990],{},"            raise ValueError(\"课程名称不能为空\")\n",[76,8992,8993],{"class":78,"line":151},[76,8994,8995],{},"        self.items.append({\"title\": title, \"done\": False})\n",[76,8997,8998],{"class":78,"line":157},[76,8999,89],{"emptyLinePlaceholder":88},[76,9001,9002],{"class":78,"line":163},[76,9003,9004],{},"    def save(self):\n",[76,9006,9007],{"class":78,"line":168},[76,9008,9009],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[76,9011,9013],{"class":78,"line":9012},17,[76,9014,9015],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[76,9017,9019],{"class":78,"line":9018},18,[76,9020,89],{"emptyLinePlaceholder":88},[76,9022,9024],{"class":78,"line":9023},19,[76,9025,9026],{},"records = LearningRecords(\"learning-records.json\")\n",[76,9028,9030],{"class":78,"line":9029},20,[76,9031,89],{"emptyLinePlaceholder":88},[76,9033,9035],{"class":78,"line":9034},21,[76,9036,7463],{},[76,9038,9040],{"class":78,"line":9039},22,[76,9041,9042],{},"    title = input(\"输入已学习课程：\")\n",[76,9044,9046],{"class":78,"line":9045},23,[76,9047,9048],{},"    records.add(title)\n",[76,9050,9052],{"class":78,"line":9051},24,[76,9053,9054],{},"    records.save()\n",[76,9056,9058],{"class":78,"line":9057},25,[76,9059,7473],{},[76,9061,9063],{"class":78,"line":9062},26,[76,9064,9065],{},"    print(\"无法保存：\", error)\n",[76,9067,9069],{"class":78,"line":9068},27,[76,9070,1205],{},[76,9072,9074],{"class":78,"line":9073},28,[76,9075,9076],{},"    print(\"已保存 1 条学习记录\")\n",[10,9078,174],{},[67,9080,9083],{"className":9081,"code":9082,"language":180,"meta":72},[178],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[43,9084,9082],{"__ignoreMap":72},[10,9086,185],{},[14,9088,188],{"id":188},[190,9090,9091,9097],{},[40,9092,9093,9094,9096],{},"输入层取得课程名后，",[43,9095,8924],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[40,9098,9099,9101],{},[43,9100,8209],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[213,9103,215],{"id":215},[10,9105,9106],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9108,9109],{},[26,9110],{"alt":9111,"src":9112},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9114,9115],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[213,9117,215],{"id":4276},[10,9119,9120],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9122,9123],{},[26,9124],{"alt":9125,"src":9126},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9128,9129,9130,9133],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[43,9131,9132],{},"load()"," 把文件状态恢复到内存。",[14,9135,234],{"id":234},[37,9137,9138,9141],{},[40,9139,9140],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[40,9142,9143,9144,9146],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[43,9145,9132],{}," 是下一项必要扩展。",[14,9148,248],{"id":248},[190,9150,9151,9157,9160],{},[40,9152,9153,9154,9156],{},"增加 ",[43,9155,9132],{},"，文件不存在时从空列表开始。",[40,9158,9159],{},"增加按序号标记完成的功能，并校验序号范围。",[40,9161,9162,9163,9166,9167,9169],{},"把输入循环放进 ",[43,9164,9165],{},"main()","，通过 ",[43,9168,6191],{}," 控制程序入口。",[10,9171,263],{},[14,9173,266],{"id":266},[10,9175,9176],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[271,9178,273],{},{"title":72,"searchDepth":85,"depth":85,"links":9180},[9181,9182,9183,9184,9185,9189,9190,9191],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":9186},[9187,9188],{"id":215,"depth":92,"text":215},{"id":4276,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8887,"description":8892},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[286,9199,9200],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9203,9306,9425,9556,9699,9824,9961,10098,10239,10408,10545,10678,10801,10930,11057,11220,11396,11537,11666,11815,11958,12079,12202,12351,12504,12669,12796,12977,13120,13277,13428,13575,13730,13948,14103,14278,14429,14596,14783,14946,15188,15428],{"id":1452,"title":1453,"body":9204,"category":286,"cover":287,"description":1458,"extension":288,"meta":9303,"navigation":88,"path":1577,"pinned":291,"publishedAt":292,"seo":9304,"slug":1579,"stem":1580,"summary":1581,"tags":9305,"updatedAt":292,"visible":88,"__hash__":1584},{"type":7,"value":9205,"toc":9293},[9206,9208,9210,9212,9214,9218,9222,9224,9234,9236,9238,9246,9248,9253,9255,9257,9267,9269,9277,9279,9285,9287,9289,9291],[10,9207,1458],{},[14,9209,16],{"id":16},[10,9211,1463],{},[14,9213,22],{"id":22},[10,9215,9216],{},[26,9217],{"alt":1470,"src":1471},[10,9219,9220,1476],{},[43,9221,1230],{},[14,9223,35],{"id":35},[37,9225,9226,9230,9232],{},[40,9227,1483,9228,1486],{},[43,9229,1230],{},[40,9231,1489],{},[40,9233,1492],{},[14,9235,62],{"id":62},[10,9237,65],{},[67,9239,9240],{"className":69,"code":1499,"language":71,"meta":72,"style":72},[43,9241,9242],{"__ignoreMap":72},[76,9243,9244],{"class":78,"line":79},[76,9245,1499],{},[10,9247,174],{},[67,9249,9251],{"className":9250,"code":1511,"language":180,"meta":72},[178],[43,9252,1511],{"__ignoreMap":72},[10,9254,185],{},[14,9256,188],{"id":188},[190,9258,9259,9263],{},[40,9260,1522,9261,1526],{},[43,9262,1525],{},[40,9264,1529,9265,1533],{},[43,9266,1532],{},[14,9268,234],{"id":234},[37,9270,9271,9273],{},[40,9272,1540],{},[40,9274,1543,9275,1546],{},[43,9276,1230],{},[14,9278,248],{"id":248},[190,9280,9281,9283],{},[40,9282,1553],{},[40,9284,1556],{},[10,9286,263],{},[14,9288,266],{"id":266},[10,9290,1563],{},[271,9292,273],{},{"title":72,"searchDepth":85,"depth":85,"links":9294},[9295,9296,9297,9298,9299,9300,9301,9302],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":1453,"description":1458},[286,1448,1583],{"id":1586,"title":1587,"body":9307,"category":286,"cover":287,"description":1592,"extension":288,"meta":9422,"navigation":88,"path":1729,"pinned":291,"publishedAt":292,"seo":9423,"slug":1731,"stem":1732,"summary":1733,"tags":9424,"updatedAt":292,"visible":88,"__hash__":1736},{"type":7,"value":9308,"toc":9412},[9309,9311,9313,9315,9317,9321,9325,9327,9337,9339,9341,9361,9363,9368,9370,9372,9382,9384,9394,9396,9404,9406,9408,9410],[10,9310,1592],{},[14,9312,16],{"id":16},[10,9314,1597],{},[14,9316,22],{"id":22},[10,9318,9319],{},[26,9320],{"alt":1604,"src":1605},[10,9322,1608,9323,1611],{},[43,9324,750],{},[14,9326,35],{"id":35},[37,9328,9329,9331,9333],{},[40,9330,1618],{},[40,9332,1621],{},[40,9334,1624,9335,1628],{},[43,9336,1627],{},[14,9338,62],{"id":62},[10,9340,1633],{},[67,9342,9343],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,9344,9345,9351],{"__ignoreMap":72},[76,9346,9347,9349],{"class":78,"line":79},[76,9348,750],{"class":659},[76,9350,663],{"class":662},[76,9352,9353,9355,9357,9359],{"class":78,"line":85},[76,9354,750],{"class":659},[76,9356,692],{"class":662},[76,9358,696],{"class":695},[76,9360,663],{"class":662},[10,9362,174],{},[67,9364,9366],{"className":9365,"code":1659,"language":180,"meta":72},[178],[43,9367,1659],{"__ignoreMap":72},[10,9369,185],{},[14,9371,188],{"id":188},[190,9373,9374,9378],{},[40,9375,9376,1673],{},[43,9377,1672],{},[40,9379,9380,1678],{},[43,9381,758],{},[14,9383,234],{"id":234},[37,9385,9386,9390],{},[40,9387,1685,9388,1688],{},[43,9389,750],{},[40,9391,1691,9392,1694],{},[43,9393,750],{},[14,9395,248],{"id":248},[190,9397,9398,9402],{},[40,9399,997,9400,1704],{},[43,9401,1703],{},[40,9403,1707],{},[10,9405,263],{},[14,9407,266],{"id":266},[10,9409,1714],{},[271,9411,1717],{},{"title":72,"searchDepth":85,"depth":85,"links":9413},[9414,9415,9416,9417,9418,9419,9420,9421],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":1587,"description":1592},[286,1735,1111],{"id":1738,"title":1739,"body":9426,"category":286,"cover":287,"description":1905,"extension":288,"meta":9553,"navigation":88,"path":1907,"pinned":291,"publishedAt":292,"seo":9554,"slug":1909,"stem":1910,"summary":1911,"tags":9555,"updatedAt":292,"visible":88,"__hash__":1915},{"type":7,"value":9427,"toc":9543},[9428,9432,9434,9436,9438,9442,9444,9446,9462,9464,9466,9486,9488,9493,9495,9497,9509,9511,9521,9523,9533,9535,9537,9541],[10,9429,1744,9430,1747],{},[43,9431,1230],{},[14,9433,16],{"id":16},[10,9435,1752],{},[14,9437,22],{"id":22},[10,9439,9440],{},[26,9441],{"alt":1759,"src":1760},[10,9443,1763],{},[14,9445,35],{"id":35},[37,9447,9448,9454,9458],{},[40,9449,1770,9450,1773,9452,50],{},[43,9451,750],{},[43,9453,1776],{},[40,9455,1779,9456,1783],{},[43,9457,1782],{},[40,9459,1786,9460,1789],{},[43,9461,1230],{},[14,9463,62],{"id":62},[10,9465,65],{},[67,9467,9468],{"className":1796,"code":1797,"language":1798,"meta":72,"style":72},[43,9469,9470,9474,9478,9482],{"__ignoreMap":72},[76,9471,9472],{"class":78,"line":79},[76,9473,1805],{},[76,9475,9476],{"class":78,"line":85},[76,9477,1810],{},[76,9479,9480],{"class":78,"line":92},[76,9481,1815],{},[76,9483,9484],{"class":78,"line":98},[76,9485,1820],{},[10,9487,174],{},[67,9489,9491],{"className":9490,"code":1826,"language":180,"meta":72},[178],[43,9492,1826],{"__ignoreMap":72},[10,9494,185],{},[14,9496,188],{"id":188},[190,9498,9499,9505],{},[40,9500,1837,9501,1841,9503,50],{},[43,9502,1840],{},[43,9504,1844],{},[40,9506,1847,9507,1850],{},[43,9508,1532],{},[14,9510,234],{"id":234},[37,9512,9513,9519],{},[40,9514,1857,9515,1860,9517,1863],{},[43,9516,1776],{},[43,9518,1230],{},[40,9520,1866],{},[14,9522,248],{"id":248},[190,9524,9525,9529],{},[40,9526,1873,9527,50],{},[43,9528,1876],{},[40,9530,1879,9531,1882],{},[43,9532,1532],{},[10,9534,263],{},[14,9536,266],{"id":266},[10,9538,1889,9539,1892],{},[43,9540,1230],{},[271,9542,273],{},{"title":72,"searchDepth":85,"depth":85,"links":9544},[9545,9546,9547,9548,9549,9550,9551,9552],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":1739,"description":1905},[286,1913,1914],{"id":1917,"title":1918,"body":9557,"category":286,"cover":287,"description":1923,"extension":288,"meta":9696,"navigation":88,"path":2095,"pinned":291,"publishedAt":292,"seo":9697,"slug":2097,"stem":2098,"summary":2099,"tags":9698,"updatedAt":292,"visible":88,"__hash__":2103},{"type":7,"value":9558,"toc":9686},[9559,9561,9563,9565,9567,9571,9575,9577,9589,9591,9593,9629,9631,9636,9638,9640,9656,9658,9668,9670,9678,9680,9682,9684],[10,9560,1923],{},[14,9562,16],{"id":16},[10,9564,1928],{},[14,9566,22],{"id":22},[10,9568,9569],{},[26,9570],{"alt":1935,"src":1936},[10,9572,9573,1942],{},[43,9574,1941],{},[14,9576,35],{"id":35},[37,9578,9579,9581,9587],{},[40,9580,1949],{},[40,9582,9583,1955,9585,1959],{},[43,9584,1954],{},[43,9586,1958],{},[40,9588,1962],{},[14,9590,62],{"id":62},[10,9592,1633],{},[67,9594,9595],{"className":650,"code":1969,"language":652,"meta":72,"style":72},[43,9596,9597,9603,9609,9613,9623],{"__ignoreMap":72},[76,9598,9599,9601],{"class":78,"line":79},[76,9600,1976],{"class":659},[76,9602,1979],{"class":695},[76,9604,9605,9607],{"class":78,"line":85},[76,9606,1984],{"class":662},[76,9608,1979],{"class":695},[76,9610,9611],{"class":78,"line":92},[76,9612,1991],{"class":662},[76,9614,9615,9617,9619,9621],{"class":78,"line":98},[76,9616,1996],{"class":662},[76,9618,1999],{"class":695},[76,9620,2003],{"class":2002},[76,9622,1274],{"class":695},[76,9624,9625,9627],{"class":78,"line":104},[76,9626,750],{"class":659},[76,9628,1274],{"class":695},[10,9630,174],{},[67,9632,9634],{"className":9633,"code":2017,"language":180,"meta":72},[178],[43,9635,2017],{"__ignoreMap":72},[10,9637,185],{},[14,9639,188],{"id":188},[190,9641,9642,9650],{},[40,9643,9644,2030,9646,2033,9648,2036],{},[43,9645,1976],{},[43,9647,1984],{},[43,9649,1954],{},[40,9651,9652,2041,9654,2045],{},[43,9653,1941],{},[43,9655,2044],{},[14,9657,234],{"id":234},[37,9659,9660,9666],{},[40,9661,2052,9662,1216,9664,50],{},[43,9663,1954],{},[43,9665,1958],{},[40,9667,2059],{},[14,9669,248],{"id":248},[190,9671,9672,9676],{},[40,9673,2066,9674,2070],{},[43,9675,2069],{},[40,9677,2073],{},[10,9679,263],{},[14,9681,266],{"id":266},[10,9683,2080],{},[271,9685,2083],{},{"title":72,"searchDepth":85,"depth":85,"links":9687},[9688,9689,9690,9691,9692,9693,9694,9695],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":1918,"description":1923},[286,2101,2102],{"id":2105,"title":2106,"body":9700,"category":286,"cover":287,"description":2111,"extension":288,"meta":9821,"navigation":88,"path":2260,"pinned":291,"publishedAt":292,"seo":9822,"slug":2262,"stem":2263,"summary":2264,"tags":9823,"updatedAt":292,"visible":88,"__hash__":2268},{"type":7,"value":9701,"toc":9811},[9702,9704,9706,9708,9710,9714,9722,9724,9738,9740,9742,9758,9760,9765,9767,9769,9783,9785,9791,9793,9803,9805,9807,9809],[10,9703,2111],{},[14,9705,16],{"id":16},[10,9707,2116],{},[14,9709,22],{"id":22},[10,9711,9712],{},[26,9713],{"alt":2123,"src":2124},[10,9715,2127,9716,50,9718,2133,9720,50],{},[43,9717,1532],{},[43,9719,2132],{},[43,9721,1840],{},[14,9723,35],{"id":35},[37,9725,9726,9730,9736],{},[40,9727,9728,2145],{},[43,9729,2144],{},[40,9731,9732,2151,9734,50],{},[43,9733,2150],{},[43,9735,2154],{},[40,9737,2157],{},[14,9739,62],{"id":62},[10,9741,65],{},[67,9743,9744],{"className":69,"code":2164,"language":71,"meta":72,"style":72},[43,9745,9746,9750,9754],{"__ignoreMap":72},[76,9747,9748],{"class":78,"line":79},[76,9749,2171],{},[76,9751,9752],{"class":78,"line":85},[76,9753,2176],{},[76,9755,9756],{"class":78,"line":92},[76,9757,2181],{},[10,9759,174],{},[67,9761,9763],{"className":9762,"code":2187,"language":180,"meta":72},[178],[43,9764,2187],{"__ignoreMap":72},[10,9766,185],{},[14,9768,188],{"id":188},[190,9770,9771,9777],{},[40,9772,9773,2201,9775,50],{},[43,9774,2200],{},[43,9776,2154],{},[40,9778,9779,2208,9781,2212],{},[43,9780,1532],{},[43,9782,2211],{},[14,9784,234],{"id":234},[37,9786,9787,9789],{},[40,9788,2219],{},[40,9790,2222],{},[14,9792,248],{"id":248},[190,9794,9795,9797],{},[40,9796,2229],{},[40,9798,2232,9799,2235,9801,2239],{},[43,9800,2132],{},[43,9802,2238],{},[10,9804,263],{},[14,9806,266],{"id":266},[10,9808,2246],{},[271,9810,273],{},{"title":72,"searchDepth":85,"depth":85,"links":9812},[9813,9814,9815,9816,9817,9818,9819,9820],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":2106,"description":2111},[286,2266,2267],{"id":2270,"title":2271,"body":9825,"category":286,"cover":287,"description":2276,"extension":288,"meta":9958,"navigation":88,"path":2444,"pinned":291,"publishedAt":292,"seo":9959,"slug":2446,"stem":2447,"summary":2448,"tags":9960,"updatedAt":292,"visible":88,"__hash__":2452},{"type":7,"value":9826,"toc":9948},[9827,9829,9831,9833,9835,9839,9841,9843,9859,9861,9863,9887,9889,9894,9896,9898,9914,9916,9928,9930,9940,9942,9944,9946],[10,9828,2276],{},[14,9830,16],{"id":16},[10,9832,2281],{},[14,9834,22],{"id":22},[10,9836,9837],{},[26,9838],{"alt":2288,"src":2289},[10,9840,2292],{},[14,9842,35],{"id":35},[37,9844,9845,9847,9853],{},[40,9846,2299],{},[40,9848,2302,9849,2235,9851,2309],{},[43,9850,2305],{},[43,9852,2308],{},[40,9854,2312,9855,2316,9857,2320],{},[43,9856,2315],{},[43,9858,2319],{},[14,9860,62],{"id":62},[10,9862,65],{},[67,9864,9865],{"className":69,"code":2327,"language":71,"meta":72,"style":72},[43,9866,9867,9871,9875,9879,9883],{"__ignoreMap":72},[76,9868,9869],{"class":78,"line":79},[76,9870,2334],{},[76,9872,9873],{"class":78,"line":85},[76,9874,2339],{},[76,9876,9877],{"class":78,"line":92},[76,9878,89],{"emptyLinePlaceholder":88},[76,9880,9881],{"class":78,"line":98},[76,9882,2348],{},[76,9884,9885],{"class":78,"line":104},[76,9886,2339],{},[10,9888,174],{},[67,9890,9892],{"className":9891,"code":2358,"language":180,"meta":72},[178],[43,9893,2358],{"__ignoreMap":72},[10,9895,185],{},[14,9897,188],{"id":188},[190,9899,9900,9906],{},[40,9901,997,9902,2372,9904,2375],{},[43,9903,2371],{},[43,9905,2305],{},[40,9907,997,9908,2381,9910,2385,9912,50],{},[43,9909,2380],{},[43,9911,2384],{},[43,9913,2388],{},[14,9915,234],{"id":234},[37,9917,9918,9920],{},[40,9919,2395],{},[40,9921,2398,9922,2316,9924,2316,9926,2406],{},[43,9923,2315],{},[43,9925,2319],{},[43,9927,2405],{},[14,9929,248],{"id":248},[190,9931,9932,9938],{},[40,9933,2413,9934,1216,9936,2420],{},[43,9935,2416],{},[43,9937,2419],{},[40,9939,2423],{},[10,9941,263],{},[14,9943,266],{"id":266},[10,9945,2430],{},[271,9947,273],{},{"title":72,"searchDepth":85,"depth":85,"links":9949},[9950,9951,9952,9953,9954,9955,9956,9957],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":2271,"description":2276},[286,2450,2451],{"id":2454,"title":2455,"body":9962,"category":286,"cover":287,"description":2460,"extension":288,"meta":10095,"navigation":88,"path":2625,"pinned":291,"publishedAt":292,"seo":10096,"slug":2627,"stem":2628,"summary":2629,"tags":10097,"updatedAt":292,"visible":88,"__hash__":2633},{"type":7,"value":9963,"toc":10085},[9964,9966,9968,9970,9972,9976,9978,9980,9998,10000,10002,10038,10040,10045,10047,10049,10059,10061,10069,10071,10077,10079,10081,10083],[10,9965,2460],{},[14,9967,16],{"id":16},[10,9969,2465],{},[14,9971,22],{"id":22},[10,9973,9974],{},[26,9975],{"alt":2472,"src":2473},[10,9977,2476],{},[14,9979,35],{"id":35},[37,9981,9982,9988,9996],{},[40,9983,9984,2486,9986,2490],{},[43,9985,2485],{},[43,9987,2489],{},[40,9989,9990,2496,9992,2500,9994,2504],{},[43,9991,2495],{},[43,9993,2499],{},[43,9995,2503],{},[40,9997,2507],{},[14,9999,62],{"id":62},[10,10001,65],{},[67,10003,10004],{"className":69,"code":2514,"language":71,"meta":72,"style":72},[43,10005,10006,10010,10014,10018,10022,10026,10030,10034],{"__ignoreMap":72},[76,10007,10008],{"class":78,"line":79},[76,10009,2521],{},[76,10011,10012],{"class":78,"line":85},[76,10013,2526],{},[76,10015,10016],{"class":78,"line":92},[76,10017,2531],{},[76,10019,10020],{"class":78,"line":98},[76,10021,89],{"emptyLinePlaceholder":88},[76,10023,10024],{"class":78,"line":104},[76,10025,2540],{},[76,10027,10028],{"class":78,"line":110},[76,10029,2545],{},[76,10031,10032],{"class":78,"line":116},[76,10033,2550],{},[76,10035,10036],{"class":78,"line":122},[76,10037,2555],{},[10,10039,174],{},[67,10041,10043],{"className":10042,"code":2561,"language":180,"meta":72},[178],[43,10044,2561],{"__ignoreMap":72},[10,10046,185],{},[14,10048,188],{"id":188},[190,10050,10051,10055],{},[40,10052,10053,2575],{},[43,10054,2574],{},[40,10056,10057,2581],{},[43,10058,2580],{},[14,10060,234],{"id":234},[37,10062,10063,10067],{},[40,10064,2588,10065,50],{},[43,10066,2591],{},[40,10068,2594],{},[14,10070,248],{"id":248},[190,10072,10073,10075],{},[40,10074,2601],{},[40,10076,2604],{},[10,10078,263],{},[14,10080,266],{"id":266},[10,10082,2611],{},[271,10084,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10086},[10087,10088,10089,10090,10091,10092,10093,10094],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":2455,"description":2460},[286,2631,2632],{"id":2635,"title":2636,"body":10099,"category":286,"cover":287,"description":2641,"extension":288,"meta":10236,"navigation":88,"path":2817,"pinned":291,"publishedAt":292,"seo":10237,"slug":2819,"stem":2820,"summary":2821,"tags":10238,"updatedAt":292,"visible":88,"__hash__":2825},{"type":7,"value":10100,"toc":10224},[10101,10103,10105,10107,10109,10113,10119,10121,10129,10131,10133,10157,10159,10164,10166,10168,10186,10188,10190,10194,10196,10198,10204,10206,10216,10218,10220,10222],[10,10102,2641],{},[14,10104,16],{"id":16},[10,10106,2646],{},[14,10108,22],{"id":22},[10,10110,10111],{},[26,10112],{"alt":2653,"src":2654},[10,10114,2657,10115,2661,10117,50],{},[43,10116,2660],{},[43,10118,2664],{},[14,10120,35],{"id":35},[37,10122,10123,10125,10127],{},[40,10124,2671],{},[40,10126,2674],{},[40,10128,2677],{},[14,10130,62],{"id":62},[10,10132,65],{},[67,10134,10135],{"className":69,"code":2684,"language":71,"meta":72,"style":72},[43,10136,10137,10141,10145,10149,10153],{"__ignoreMap":72},[76,10138,10139],{"class":78,"line":79},[76,10140,2691],{},[76,10142,10143],{"class":78,"line":85},[76,10144,2696],{},[76,10146,10147],{"class":78,"line":92},[76,10148,2701],{},[76,10150,10151],{"class":78,"line":98},[76,10152,2706],{},[76,10154,10155],{"class":78,"line":104},[76,10156,2711],{},[10,10158,174],{},[67,10160,10162],{"className":10161,"code":2717,"language":180,"meta":72},[178],[43,10163,2717],{"__ignoreMap":72},[10,10165,185],{},[14,10167,188],{"id":188},[190,10169,10170,10178],{},[40,10171,2728,10172,2731,10174,2735,10176,2739],{},[43,10173,286],{},[43,10175,2734],{},[43,10177,2738],{},[40,10179,10180,2745,10182,2749,10184,2753],{},[43,10181,2744],{},[43,10183,2748],{},[43,10185,2752],{},[213,10187,215],{"id":215},[10,10189,2758],{},[10,10191,10192],{},[26,10193],{"alt":2763,"src":2764},[10,10195,2767],{},[14,10197,234],{"id":234},[37,10199,10200,10202],{},[40,10201,2774],{},[40,10203,2777],{},[14,10205,248],{"id":248},[190,10207,10208,10214],{},[40,10209,2784,10210,2788,10212,50],{},[43,10211,2787],{},[43,10213,2791],{},[40,10215,2794],{},[10,10217,263],{},[14,10219,266],{"id":266},[10,10221,2801],{},[271,10223,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10225},[10226,10227,10228,10229,10230,10233,10234,10235],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":10231},[10232],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":2636,"description":2641},[286,2823,2824],{"id":2827,"title":2828,"body":10240,"category":286,"cover":287,"description":2833,"extension":288,"meta":10405,"navigation":88,"path":3048,"pinned":291,"publishedAt":292,"seo":10406,"slug":3050,"stem":3051,"summary":3052,"tags":10407,"updatedAt":292,"visible":88,"__hash__":3056},{"type":7,"value":10241,"toc":10393},[10242,10244,10246,10248,10250,10254,10260,10262,10282,10284,10286,10322,10324,10329,10331,10333,10347,10349,10351,10355,10361,10363,10373,10375,10385,10387,10389,10391],[10,10243,2833],{},[14,10245,16],{"id":16},[10,10247,2838],{},[14,10249,22],{"id":22},[10,10251,10252],{},[26,10253],{"alt":2845,"src":2846},[10,10255,2849,10256,1068,10258,2856],{},[43,10257,2852],{},[43,10259,2855],{},[14,10261,35],{"id":35},[37,10263,10264,10272,10280],{},[40,10265,10266,2866,10268,2870,10270,2874],{},[43,10267,2865],{},[43,10269,2869],{},[43,10271,2873],{},[40,10273,10274,2880,10276,2884,10278,2888],{},[43,10275,2879],{},[43,10277,2883],{},[43,10279,2887],{},[40,10281,2891],{},[14,10283,62],{"id":62},[10,10285,65],{},[67,10287,10288],{"className":69,"code":2898,"language":71,"meta":72,"style":72},[43,10289,10290,10294,10298,10302,10306,10310,10314,10318],{"__ignoreMap":72},[76,10291,10292],{"class":78,"line":79},[76,10293,2905],{},[76,10295,10296],{"class":78,"line":85},[76,10297,2910],{},[76,10299,10300],{"class":78,"line":92},[76,10301,89],{"emptyLinePlaceholder":88},[76,10303,10304],{"class":78,"line":98},[76,10305,2919],{},[76,10307,10308],{"class":78,"line":104},[76,10309,2924],{},[76,10311,10312],{"class":78,"line":110},[76,10313,2929],{},[76,10315,10316],{"class":78,"line":116},[76,10317,2934],{},[76,10319,10320],{"class":78,"line":122},[76,10321,2939],{},[10,10323,174],{},[67,10325,10327],{"className":10326,"code":2945,"language":180,"meta":72},[178],[43,10328,2945],{"__ignoreMap":72},[10,10330,185],{},[14,10332,188],{"id":188},[190,10334,10335,10341],{},[40,10336,10337,2959,10339,2963],{},[43,10338,2958],{},[43,10340,2962],{},[40,10342,10343,2969,10345,2972],{},[43,10344,2968],{},[43,10346,2887],{},[213,10348,215],{"id":215},[10,10350,2977],{},[10,10352,10353],{},[26,10354],{"alt":2982,"src":2983},[10,10356,10357,2988,10359,2991],{},[43,10358,2879],{},[43,10360,2883],{},[14,10362,234],{"id":234},[37,10364,10365,10371],{},[40,10366,2998,10367,3001,10369,3004],{},[43,10368,2873],{},[43,10370,2865],{},[40,10372,3007],{},[14,10374,248],{"id":248},[190,10376,10377,10381],{},[40,10378,3014,10379,3018],{},[43,10380,3017],{},[40,10382,3021,10383,3025],{},[43,10384,3024],{},[10,10386,263],{},[14,10388,266],{"id":266},[10,10390,3032],{},[271,10392,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10394},[10395,10396,10397,10398,10399,10402,10403,10404],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":10400},[10401],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":2828,"description":2833},[286,3054,3055],{"id":3058,"title":3059,"body":10409,"category":286,"cover":287,"description":3064,"extension":288,"meta":10542,"navigation":88,"path":3233,"pinned":291,"publishedAt":292,"seo":10543,"slug":3235,"stem":3236,"summary":3237,"tags":10544,"updatedAt":292,"visible":88,"__hash__":3240},{"type":7,"value":10410,"toc":10532},[10411,10413,10415,10417,10419,10423,10433,10435,10445,10447,10449,10477,10479,10484,10486,10488,10502,10504,10512,10514,10524,10526,10528,10530],[10,10412,3064],{},[14,10414,16],{"id":16},[10,10416,3069],{},[14,10418,22],{"id":22},[10,10420,10421],{},[26,10422],{"alt":3076,"src":3077},[10,10424,10425,3083,10427,3087,10429,3091,10431,3095],{},[43,10426,3082],{},[43,10428,3086],{},[43,10430,3090],{},[43,10432,3094],{},[14,10434,35],{"id":35},[37,10436,10437,10439,10443],{},[40,10438,3102],{},[40,10440,10441,3107],{},[43,10442,3094],{},[40,10444,3110],{},[14,10446,62],{"id":62},[10,10448,65],{},[67,10450,10451],{"className":69,"code":3117,"language":71,"meta":72,"style":72},[43,10452,10453,10457,10461,10465,10469,10473],{"__ignoreMap":72},[76,10454,10455],{"class":78,"line":79},[76,10456,3124],{},[76,10458,10459],{"class":78,"line":85},[76,10460,3129],{},[76,10462,10463],{"class":78,"line":92},[76,10464,3134],{},[76,10466,10467],{"class":78,"line":98},[76,10468,89],{"emptyLinePlaceholder":88},[76,10470,10471],{"class":78,"line":104},[76,10472,3143],{},[76,10474,10475],{"class":78,"line":110},[76,10476,3148],{},[10,10478,174],{},[67,10480,10482],{"className":10481,"code":3154,"language":180,"meta":72},[178],[43,10483,3154],{"__ignoreMap":72},[10,10485,185],{},[14,10487,188],{"id":188},[190,10489,10490,10496],{},[40,10491,3165,10492,3168,10494,3172],{},[43,10493,3082],{},[43,10495,3171],{},[40,10497,10498,3178,10500,3182],{},[43,10499,3177],{},[43,10501,3181],{},[14,10503,234],{"id":234},[37,10505,10506,10510],{},[40,10507,3189,10508,3193],{},[43,10509,3192],{},[40,10511,3196],{},[14,10513,248],{"id":248},[190,10515,10516,10518],{},[40,10517,3203],{},[40,10519,1779,10520,3209,10522,3212],{},[43,10521,3208],{},[43,10523,3094],{},[10,10525,263],{},[14,10527,266],{"id":266},[10,10529,3219],{},[271,10531,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10533},[10534,10535,10536,10537,10538,10539,10540,10541],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":3059,"description":3064},[286,2405,3239],{"id":3242,"title":3243,"body":10546,"category":286,"cover":287,"description":3248,"extension":288,"meta":10675,"navigation":88,"path":3409,"pinned":291,"publishedAt":292,"seo":10676,"slug":3411,"stem":3412,"summary":3413,"tags":10677,"updatedAt":292,"visible":88,"__hash__":3417},{"type":7,"value":10547,"toc":10665},[10548,10550,10552,10554,10556,10560,10564,10566,10576,10578,10580,10612,10614,10619,10621,10623,10635,10637,10647,10649,10657,10659,10661,10663],[10,10549,3248],{},[14,10551,16],{"id":16},[10,10553,3253],{},[14,10555,22],{"id":22},[10,10557,10558],{},[26,10559],{"alt":3260,"src":3261},[10,10561,3264,10562,3268],{},[43,10563,3267],{},[14,10565,35],{"id":35},[37,10567,10568,10570,10572],{},[40,10569,3275],{},[40,10571,3278],{},[40,10573,3281,10574,50],{},[43,10575,3284],{},[14,10577,62],{"id":62},[10,10579,65],{},[67,10581,10582],{"className":69,"code":3291,"language":71,"meta":72,"style":72},[43,10583,10584,10588,10592,10596,10600,10604,10608],{"__ignoreMap":72},[76,10585,10586],{"class":78,"line":79},[76,10587,3298],{},[76,10589,10590],{"class":78,"line":85},[76,10591,3303],{},[76,10593,10594],{"class":78,"line":92},[76,10595,89],{"emptyLinePlaceholder":88},[76,10597,10598],{"class":78,"line":98},[76,10599,3312],{},[76,10601,10602],{"class":78,"line":104},[76,10603,3317],{},[76,10605,10606],{"class":78,"line":110},[76,10607,3322],{},[76,10609,10610],{"class":78,"line":116},[76,10611,3327],{},[10,10613,174],{},[67,10615,10617],{"className":10616,"code":3333,"language":180,"meta":72},[178],[43,10618,3333],{"__ignoreMap":72},[10,10620,185],{},[14,10622,188],{"id":188},[190,10624,10625,10627],{},[40,10626,3344],{},[40,10628,10629,3350,10631,3354,10633,3358],{},[43,10630,3349],{},[43,10632,3353],{},[43,10634,3357],{},[14,10636,234],{"id":234},[37,10638,10639,10645],{},[40,10640,3365,10641,3369,10643,50],{},[43,10642,3368],{},[43,10644,3372],{},[40,10646,3375],{},[14,10648,248],{"id":248},[190,10650,10651,10653],{},[40,10652,3382],{},[40,10654,3385,10655,3388],{},[43,10656,3357],{},[10,10658,263],{},[14,10660,266],{"id":266},[10,10662,3395],{},[271,10664,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10666},[10667,10668,10669,10670,10671,10672,10673,10674],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":3243,"description":3248},[286,3415,3416],{"id":3419,"title":3420,"body":10679,"category":286,"cover":287,"description":3425,"extension":288,"meta":10798,"navigation":88,"path":3567,"pinned":291,"publishedAt":292,"seo":10799,"slug":3569,"stem":3570,"summary":3571,"tags":10800,"updatedAt":292,"visible":88,"__hash__":3574},{"type":7,"value":10680,"toc":10788},[10681,10683,10685,10687,10689,10693,10695,10697,10705,10707,10709,10737,10739,10744,10746,10748,10758,10760,10768,10770,10780,10782,10784,10786],[10,10682,3425],{},[14,10684,16],{"id":16},[10,10686,3430],{},[14,10688,22],{"id":22},[10,10690,10691],{},[26,10692],{"alt":3437,"src":3438},[10,10694,3441],{},[14,10696,35],{"id":35},[37,10698,10699,10701,10703],{},[40,10700,3448],{},[40,10702,3451],{},[40,10704,3454],{},[14,10706,62],{"id":62},[10,10708,65],{},[67,10710,10711],{"className":69,"code":3461,"language":71,"meta":72,"style":72},[43,10712,10713,10717,10721,10725,10729,10733],{"__ignoreMap":72},[76,10714,10715],{"class":78,"line":79},[76,10716,3468],{},[76,10718,10719],{"class":78,"line":85},[76,10720,3473],{},[76,10722,10723],{"class":78,"line":92},[76,10724,3478],{},[76,10726,10727],{"class":78,"line":98},[76,10728,89],{"emptyLinePlaceholder":88},[76,10730,10731],{"class":78,"line":104},[76,10732,3487],{},[76,10734,10735],{"class":78,"line":110},[76,10736,3492],{},[10,10738,174],{},[67,10740,10742],{"className":10741,"code":3498,"language":180,"meta":72},[178],[43,10743,3498],{"__ignoreMap":72},[10,10745,185],{},[14,10747,188],{"id":188},[190,10749,10750,10754],{},[40,10751,10752,3512],{},[43,10753,3511],{},[40,10755,10756,3518],{},[43,10757,3517],{},[14,10759,234],{"id":234},[37,10761,10762,10766],{},[40,10763,3525,10764,3529],{},[43,10765,3528],{},[40,10767,3532],{},[14,10769,248],{"id":248},[190,10771,10772,10774],{},[40,10773,3539],{},[40,10775,2232,10776,2235,10778,3546],{},[43,10777,3528],{},[43,10779,3517],{},[10,10781,263],{},[14,10783,266],{"id":266},[10,10785,3553],{},[271,10787,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10789},[10790,10791,10792,10793,10794,10795,10796,10797],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":3420,"description":3425},[286,3573,3416],{"id":3576,"title":3577,"body":10802,"category":286,"cover":287,"description":3582,"extension":288,"meta":10927,"navigation":88,"path":3738,"pinned":291,"publishedAt":292,"seo":10928,"slug":3740,"stem":3741,"summary":3742,"tags":10929,"updatedAt":292,"visible":88,"__hash__":3745},{"type":7,"value":10803,"toc":10917},[10804,10806,10808,10810,10812,10816,10822,10824,10834,10836,10838,10866,10868,10873,10875,10877,10887,10889,10901,10903,10909,10911,10913,10915],[10,10805,3582],{},[14,10807,16],{"id":16},[10,10809,3587],{},[14,10811,22],{"id":22},[10,10813,10814],{},[26,10815],{"alt":3594,"src":3595},[10,10817,3598,10818,3602,10820,3605],{},[43,10819,3601],{},[43,10821,2305],{},[14,10823,35],{"id":35},[37,10825,10826,10828,10832],{},[40,10827,3612],{},[40,10829,2398,10830,3618],{},[43,10831,3617],{},[40,10833,3621],{},[14,10835,62],{"id":62},[10,10837,65],{},[67,10839,10840],{"className":69,"code":3628,"language":71,"meta":72,"style":72},[43,10841,10842,10846,10850,10854,10858,10862],{"__ignoreMap":72},[76,10843,10844],{"class":78,"line":79},[76,10845,3635],{},[76,10847,10848],{"class":78,"line":85},[76,10849,3640],{},[76,10851,10852],{"class":78,"line":92},[76,10853,89],{"emptyLinePlaceholder":88},[76,10855,10856],{"class":78,"line":98},[76,10857,3649],{},[76,10859,10860],{"class":78,"line":104},[76,10861,3654],{},[76,10863,10864],{"class":78,"line":110},[76,10865,3659],{},[10,10867,174],{},[67,10869,10871],{"className":10870,"code":3665,"language":180,"meta":72},[178],[43,10872,3665],{"__ignoreMap":72},[10,10874,185],{},[14,10876,188],{"id":188},[190,10878,10879,10881],{},[40,10880,3676],{},[40,10882,3679,10883,3682,10885,3686],{},[43,10884,2305],{},[43,10886,3685],{},[14,10888,234],{"id":234},[37,10890,10891,10895],{},[40,10892,3693,10893,3697],{},[43,10894,3696],{},[40,10896,3700,10897,3704,10899,50],{},[43,10898,3703],{},[43,10900,3707],{},[14,10902,248],{"id":248},[190,10904,10905,10907],{},[40,10906,3714],{},[40,10908,3717],{},[10,10910,263],{},[14,10912,266],{"id":266},[10,10914,3724],{},[271,10916,273],{},{"title":72,"searchDepth":85,"depth":85,"links":10918},[10919,10920,10921,10922,10923,10924,10925,10926],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":3577,"description":3582},[286,3744,3416],{"id":3747,"title":3748,"body":10931,"category":286,"cover":287,"description":3753,"extension":288,"meta":11054,"navigation":88,"path":3903,"pinned":291,"publishedAt":292,"seo":11055,"slug":3905,"stem":3906,"summary":3907,"tags":11056,"updatedAt":292,"visible":88,"__hash__":3910},{"type":7,"value":10932,"toc":11044},[10933,10935,10937,10939,10941,10945,10947,10949,10961,10963,10965,10993,10995,11000,11002,11004,11014,11016,11026,11028,11036,11038,11040,11042],[10,10934,3753],{},[14,10936,16],{"id":16},[10,10938,3758],{},[14,10940,22],{"id":22},[10,10942,10943],{},[26,10944],{"alt":3765,"src":3766},[10,10946,3769],{},[14,10948,35],{"id":35},[37,10950,10951,10953,10955],{},[40,10952,3776],{},[40,10954,3779],{},[40,10956,3782,10957,3786,10959,3790],{},[43,10958,3785],{},[43,10960,3789],{},[14,10962,62],{"id":62},[10,10964,65],{},[67,10966,10967],{"className":69,"code":3797,"language":71,"meta":72,"style":72},[43,10968,10969,10973,10977,10981,10985,10989],{"__ignoreMap":72},[76,10970,10971],{"class":78,"line":79},[76,10972,3804],{},[76,10974,10975],{"class":78,"line":85},[76,10976,3809],{},[76,10978,10979],{"class":78,"line":92},[76,10980,89],{"emptyLinePlaceholder":88},[76,10982,10983],{"class":78,"line":98},[76,10984,3818],{},[76,10986,10987],{"class":78,"line":104},[76,10988,3823],{},[76,10990,10991],{"class":78,"line":110},[76,10992,3828],{},[10,10994,174],{},[67,10996,10998],{"className":10997,"code":3834,"language":180,"meta":72},[178],[43,10999,3834],{"__ignoreMap":72},[10,11001,185],{},[14,11003,188],{"id":188},[190,11005,11006,11008],{},[40,11007,3845],{},[40,11009,11010,3851,11012,3855],{},[43,11011,3850],{},[43,11013,3854],{},[14,11015,234],{"id":234},[37,11017,11018,11024],{},[40,11019,2398,11020,3864,11022,50],{},[43,11021,3789],{},[43,11023,3785],{},[40,11025,3869],{},[14,11027,248],{"id":248},[190,11029,11030,11034],{},[40,11031,3876,11032,3879],{},[43,11033,3785],{},[40,11035,3882],{},[10,11037,263],{},[14,11039,266],{"id":266},[10,11041,3889],{},[271,11043,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11045},[11046,11047,11048,11049,11050,11051,11052,11053],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":3748,"description":3753},[286,3909,3416],{"id":3912,"title":3913,"body":11058,"category":286,"cover":287,"description":3918,"extension":288,"meta":11217,"navigation":88,"path":4116,"pinned":291,"publishedAt":292,"seo":11218,"slug":4118,"stem":4119,"summary":4120,"tags":11219,"updatedAt":292,"visible":88,"__hash__":4124},{"type":7,"value":11059,"toc":11205},[11060,11062,11064,11066,11068,11072,11078,11080,11092,11094,11096,11136,11138,11143,11145,11147,11161,11163,11165,11169,11171,11173,11183,11185,11197,11199,11201,11203],[10,11061,3918],{},[14,11063,16],{"id":16},[10,11065,3923],{},[14,11067,22],{"id":22},[10,11069,11070],{},[26,11071],{"alt":3930,"src":3931},[10,11073,11074,3937,11076,3941],{},[43,11075,3936],{},[43,11077,3940],{},[14,11079,35],{"id":35},[37,11081,11082,11088,11090],{},[40,11083,11084,3950,11086,3954],{},[43,11085,2865],{},[43,11087,3953],{},[40,11089,3957],{},[40,11091,3960],{},[14,11093,62],{"id":62},[10,11095,65],{},[67,11097,11098],{"className":69,"code":3967,"language":71,"meta":72,"style":72},[43,11099,11100,11104,11108,11112,11116,11120,11124,11128,11132],{"__ignoreMap":72},[76,11101,11102],{"class":78,"line":79},[76,11103,3974],{},[76,11105,11106],{"class":78,"line":85},[76,11107,3979],{},[76,11109,11110],{"class":78,"line":92},[76,11111,3984],{},[76,11113,11114],{"class":78,"line":98},[76,11115,89],{"emptyLinePlaceholder":88},[76,11117,11118],{"class":78,"line":104},[76,11119,3993],{},[76,11121,11122],{"class":78,"line":110},[76,11123,3998],{},[76,11125,11126],{"class":78,"line":116},[76,11127,4003],{},[76,11129,11130],{"class":78,"line":122},[76,11131,4008],{},[76,11133,11134],{"class":78,"line":128},[76,11135,4013],{},[10,11137,174],{},[67,11139,11141],{"className":11140,"code":4019,"language":180,"meta":72},[178],[43,11142,4019],{"__ignoreMap":72},[10,11144,185],{},[14,11146,188],{"id":188},[190,11148,11149,11153],{},[40,11150,11151,4033],{},[43,11152,4032],{},[40,11154,11155,4039,11157,4043,11159,4047],{},[43,11156,4038],{},[43,11158,4042],{},[43,11160,4046],{},[213,11162,215],{"id":215},[10,11164,4052],{},[10,11166,11167],{},[26,11168],{"alt":4057,"src":4058},[10,11170,4061],{},[14,11172,234],{"id":234},[37,11174,11175,11181],{},[40,11176,4068,11177,4071,11179,50],{},[43,11178,2865],{},[43,11180,3953],{},[40,11182,4076],{},[14,11184,248],{"id":248},[190,11186,11187,11189],{},[40,11188,4083],{},[40,11190,2398,11191,4089,11193,1216,11195,50],{},[43,11192,4088],{},[43,11194,3953],{},[43,11196,2865],{},[10,11198,263],{},[14,11200,266],{"id":266},[10,11202,4100],{},[271,11204,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11206},[11207,11208,11209,11210,11211,11214,11215,11216],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":11212},[11213],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":3913,"description":3918},[286,4122,4123],{"id":4126,"title":4127,"body":11221,"category":286,"cover":287,"description":4132,"extension":288,"meta":11393,"navigation":88,"path":4345,"pinned":291,"publishedAt":292,"seo":11394,"slug":4347,"stem":4348,"summary":4349,"tags":11395,"updatedAt":292,"visible":88,"__hash__":4352},{"type":7,"value":11222,"toc":11380},[11223,11225,11227,11229,11231,11235,11243,11245,11253,11255,11257,11301,11303,11308,11310,11312,11324,11326,11328,11332,11338,11340,11342,11346,11350,11352,11364,11366,11372,11374,11376,11378],[10,11224,4132],{},[14,11226,16],{"id":16},[10,11228,4137],{},[14,11230,22],{"id":22},[10,11232,11233],{},[26,11234],{"alt":4144,"src":4145},[10,11236,11237,2316,11239,2316,11241,4155],{},[43,11238,1215],{},[43,11240,4152],{},[43,11242,1219],{},[14,11244,35],{"id":35},[37,11246,11247,11249,11251],{},[40,11248,4162],{},[40,11250,4165],{},[40,11252,4168],{},[14,11254,62],{"id":62},[10,11256,65],{},[67,11258,11259],{"className":69,"code":4175,"language":71,"meta":72,"style":72},[43,11260,11261,11265,11269,11273,11277,11281,11285,11289,11293,11297],{"__ignoreMap":72},[76,11262,11263],{"class":78,"line":79},[76,11264,4182],{},[76,11266,11267],{"class":78,"line":85},[76,11268,89],{"emptyLinePlaceholder":88},[76,11270,11271],{"class":78,"line":92},[76,11272,4191],{},[76,11274,11275],{"class":78,"line":98},[76,11276,4196],{},[76,11278,11279],{"class":78,"line":104},[76,11280,4201],{},[76,11282,11283],{"class":78,"line":110},[76,11284,4206],{},[76,11286,11287],{"class":78,"line":116},[76,11288,1205],{},[76,11290,11291],{"class":78,"line":122},[76,11292,4215],{},[76,11294,11295],{"class":78,"line":128},[76,11296,89],{"emptyLinePlaceholder":88},[76,11298,11299],{"class":78,"line":134},[76,11300,4224],{},[10,11302,174],{},[67,11304,11306],{"className":11305,"code":4230,"language":180,"meta":72},[178],[43,11307,4230],{"__ignoreMap":72},[10,11309,185],{},[14,11311,188],{"id":188},[190,11313,11314,11318],{},[40,11315,4241,11316,4245],{},[43,11317,4244],{},[40,11319,11320,4251,11322,4254],{},[43,11321,4250],{},[43,11323,1219],{},[213,11325,215],{"id":215},[10,11327,4259],{},[10,11329,11330],{},[26,11331],{"alt":4264,"src":4265},[10,11333,11334,4270,11336,4273],{},[43,11335,4244],{},[43,11337,4250],{},[213,11339,215],{"id":4276},[10,11341,4279],{},[10,11343,11344],{},[26,11345],{"alt":4284,"src":4285},[10,11347,4288,11348,4291],{},[43,11349,1215],{},[14,11351,234],{"id":234},[37,11353,11354,11358],{},[40,11355,4298,11356,4301],{},[43,11357,4250],{},[40,11359,4304,11360,4307,11362,4311],{},[43,11361,1215],{},[43,11363,4310],{},[14,11365,248],{"id":248},[190,11367,11368,11370],{},[40,11369,4318],{},[40,11371,4321],{},[10,11373,263],{},[14,11375,266],{"id":266},[10,11377,4328],{},[271,11379,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11381},[11382,11383,11384,11385,11386,11390,11391,11392],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":11387},[11388,11389],{"id":215,"depth":92,"text":215},{"id":4276,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":4127,"description":4132},[286,1215,4351],{"id":4354,"title":4355,"body":11397,"category":286,"cover":287,"description":4360,"extension":288,"meta":11534,"navigation":88,"path":4527,"pinned":291,"publishedAt":292,"seo":11535,"slug":4529,"stem":4530,"summary":4531,"tags":11536,"updatedAt":292,"visible":88,"__hash__":4534},{"type":7,"value":11398,"toc":11522},[11399,11401,11403,11405,11407,11411,11415,11417,11427,11429,11431,11463,11465,11470,11472,11474,11484,11486,11488,11492,11496,11498,11504,11506,11514,11516,11518,11520],[10,11400,4360],{},[14,11402,16],{"id":16},[10,11404,4365],{},[14,11406,22],{"id":22},[10,11408,11409],{},[26,11410],{"alt":4372,"src":4373},[10,11412,11413,4379],{},[43,11414,4378],{},[14,11416,35],{"id":35},[37,11418,11419,11421,11423],{},[40,11420,4386],{},[40,11422,4389],{},[40,11424,4392,11425,4396],{},[43,11426,4395],{},[14,11428,62],{"id":62},[10,11430,65],{},[67,11432,11433],{"className":69,"code":4403,"language":71,"meta":72,"style":72},[43,11434,11435,11439,11443,11447,11451,11455,11459],{"__ignoreMap":72},[76,11436,11437],{"class":78,"line":79},[76,11438,4410],{},[76,11440,11441],{"class":78,"line":85},[76,11442,89],{"emptyLinePlaceholder":88},[76,11444,11445],{"class":78,"line":92},[76,11446,4419],{},[76,11448,11449],{"class":78,"line":98},[76,11450,4424],{},[76,11452,11453],{"class":78,"line":104},[76,11454,4429],{},[76,11456,11457],{"class":78,"line":110},[76,11458,89],{"emptyLinePlaceholder":88},[76,11460,11461],{"class":78,"line":116},[76,11462,4438],{},[10,11464,174],{},[67,11466,11468],{"className":11467,"code":4444,"language":180,"meta":72},[178],[43,11469,4444],{"__ignoreMap":72},[10,11471,185],{},[14,11473,188],{"id":188},[190,11475,11476,11480],{},[40,11477,4455,11478,4459],{},[43,11479,4458],{},[40,11481,4462,11482,4465],{},[43,11483,4458],{},[213,11485,215],{"id":215},[10,11487,4470],{},[10,11489,11490],{},[26,11491],{"alt":4475,"src":4476},[10,11493,4479,11494,4482],{},[43,11495,4458],{},[14,11497,234],{"id":234},[37,11499,11500,11502],{},[40,11501,4489],{},[40,11503,4492],{},[14,11505,248],{"id":248},[190,11507,11508,11512],{},[40,11509,2398,11510,4501],{},[43,11511,4378],{},[40,11513,4504],{},[10,11515,263],{},[14,11517,266],{"id":266},[10,11519,4511],{},[271,11521,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11523},[11524,11525,11526,11527,11528,11531,11532,11533],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":11529},[11530],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":4355,"description":4360},[286,4378,4533],{"id":4536,"title":4537,"body":11538,"category":286,"cover":287,"description":4542,"extension":288,"meta":11663,"navigation":88,"path":4691,"pinned":291,"publishedAt":292,"seo":11664,"slug":4693,"stem":4694,"summary":4695,"tags":11665,"updatedAt":292,"visible":88,"__hash__":4698},{"type":7,"value":11539,"toc":11653},[11540,11542,11544,11546,11548,11552,11556,11558,11568,11570,11572,11604,11606,11611,11613,11615,11627,11629,11635,11637,11645,11647,11649,11651],[10,11541,4542],{},[14,11543,16],{"id":16},[10,11545,4547],{},[14,11547,22],{"id":22},[10,11549,11550],{},[26,11551],{"alt":4554,"src":4555},[10,11553,11554,4560],{},[43,11555,4395],{},[14,11557,35],{"id":35},[37,11559,11560,11564,11566],{},[40,11561,11562,4570],{},[43,11563,4569],{},[40,11565,4573],{},[40,11567,4576],{},[14,11569,62],{"id":62},[10,11571,65],{},[67,11573,11574],{"className":69,"code":4583,"language":71,"meta":72,"style":72},[43,11575,11576,11580,11584,11588,11592,11596,11600],{"__ignoreMap":72},[76,11577,11578],{"class":78,"line":79},[76,11579,4590],{},[76,11581,11582],{"class":78,"line":85},[76,11583,89],{"emptyLinePlaceholder":88},[76,11585,11586],{"class":78,"line":92},[76,11587,4599],{},[76,11589,11590],{"class":78,"line":98},[76,11591,4604],{},[76,11593,11594],{"class":78,"line":104},[76,11595,89],{"emptyLinePlaceholder":88},[76,11597,11598],{"class":78,"line":110},[76,11599,4613],{},[76,11601,11602],{"class":78,"line":116},[76,11603,4618],{},[10,11605,174],{},[67,11607,11609],{"className":11608,"code":4624,"language":180,"meta":72},[178],[43,11610,4624],{"__ignoreMap":72},[10,11612,185],{},[14,11614,188],{"id":188},[190,11616,11617,11623],{},[40,11618,4635,11619,4638,11621,4642],{},[43,11620,4395],{},[43,11622,4641],{},[40,11624,11625,4647],{},[43,11626,4569],{},[14,11628,234],{"id":234},[37,11630,11631,11633],{},[40,11632,4654],{},[40,11634,4657],{},[14,11636,248],{"id":248},[190,11638,11639,11641],{},[40,11640,4664],{},[40,11642,2398,11643,4670],{},[43,11644,4669],{},[10,11646,263],{},[14,11648,266],{"id":266},[10,11650,4677],{},[271,11652,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11654},[11655,11656,11657,11658,11659,11660,11661,11662],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":4537,"description":4542},[286,4395,4697],{"id":4700,"title":4701,"body":11667,"category":286,"cover":287,"description":4706,"extension":288,"meta":11812,"navigation":88,"path":4881,"pinned":291,"publishedAt":292,"seo":11813,"slug":4883,"stem":4884,"summary":4885,"tags":11814,"updatedAt":292,"visible":88,"__hash__":4887},{"type":7,"value":11668,"toc":11802},[11669,11671,11673,11675,11677,11681,11687,11689,11703,11705,11707,11751,11753,11758,11760,11762,11772,11774,11786,11788,11794,11796,11798,11800],[10,11670,4706],{},[14,11672,16],{"id":16},[10,11674,4711],{},[14,11676,22],{"id":22},[10,11678,11679],{},[26,11680],{"alt":4718,"src":4719},[10,11682,11683,4725,11685,4729],{},[43,11684,4724],{},[43,11686,4728],{},[14,11688,35],{"id":35},[37,11690,11691,11693,11699],{},[40,11692,4736],{},[40,11694,11695,4741,11697,4744],{},[43,11696,4724],{},[43,11698,4378],{},[40,11700,4747,11701,4750],{},[43,11702,4728],{},[14,11704,62],{"id":62},[10,11706,65],{},[67,11708,11709],{"className":69,"code":4757,"language":71,"meta":72,"style":72},[43,11710,11711,11715,11719,11723,11727,11731,11735,11739,11743,11747],{"__ignoreMap":72},[76,11712,11713],{"class":78,"line":79},[76,11714,4764],{},[76,11716,11717],{"class":78,"line":85},[76,11718,89],{"emptyLinePlaceholder":88},[76,11720,11721],{"class":78,"line":92},[76,11722,4773],{},[76,11724,11725],{"class":78,"line":98},[76,11726,4778],{},[76,11728,11729],{"class":78,"line":104},[76,11730,4783],{},[76,11732,11733],{"class":78,"line":110},[76,11734,4788],{},[76,11736,11737],{"class":78,"line":116},[76,11738,4793],{},[76,11740,11741],{"class":78,"line":122},[76,11742,4618],{},[76,11744,11745],{"class":78,"line":128},[76,11746,89],{"emptyLinePlaceholder":88},[76,11748,11749],{"class":78,"line":134},[76,11750,4806],{},[10,11752,174],{},[67,11754,11756],{"className":11755,"code":4812,"language":180,"meta":72},[178],[43,11757,4812],{"__ignoreMap":72},[10,11759,185],{},[14,11761,188],{"id":188},[190,11763,11764,11768],{},[40,11765,4823,11766,4826],{},[43,11767,4724],{},[40,11769,4829,11770,4832],{},[43,11771,4728],{},[14,11773,234],{"id":234},[37,11775,11776,11780],{},[40,11777,3525,11778,4841],{},[43,11779,4724],{},[40,11781,4844,11782,4847,11784,4850],{},[43,11783,4378],{},[43,11785,4724],{},[14,11787,248],{"id":248},[190,11789,11790,11792],{},[40,11791,4857],{},[40,11793,4860],{},[10,11795,263],{},[14,11797,266],{"id":266},[10,11799,4867],{},[271,11801,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11803},[11804,11805,11806,11807,11808,11809,11810,11811],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":4701,"description":4706},[286,4728,4724],{"id":4889,"title":4890,"body":11816,"category":286,"cover":287,"description":4895,"extension":288,"meta":11955,"navigation":88,"path":5067,"pinned":291,"publishedAt":292,"seo":11956,"slug":5069,"stem":5070,"summary":5071,"tags":11957,"updatedAt":292,"visible":88,"__hash__":5075},{"type":7,"value":11817,"toc":11943},[11818,11820,11822,11824,11826,11830,11832,11834,11850,11852,11854,11882,11884,11889,11891,11893,11905,11907,11909,11913,11915,11917,11927,11929,11935,11937,11939,11941],[10,11819,4895],{},[14,11821,16],{"id":16},[10,11823,4900],{},[14,11825,22],{"id":22},[10,11827,11828],{},[26,11829],{"alt":4907,"src":4908},[10,11831,4911],{},[14,11833,35],{"id":35},[37,11835,11836,11838,11840],{},[40,11837,4918],{},[40,11839,4921],{},[40,11841,4924,11842,2316,11844,4931,11846,2316,11848,50],{},[43,11843,4927],{},[43,11845,4930],{},[43,11847,4934],{},[43,11849,4937],{},[14,11851,62],{"id":62},[10,11853,65],{},[67,11855,11856],{"className":69,"code":4944,"language":71,"meta":72,"style":72},[43,11857,11858,11862,11866,11870,11874,11878],{"__ignoreMap":72},[76,11859,11860],{"class":78,"line":79},[76,11861,4951],{},[76,11863,11864],{"class":78,"line":85},[76,11865,89],{"emptyLinePlaceholder":88},[76,11867,11868],{"class":78,"line":92},[76,11869,4960],{},[76,11871,11872],{"class":78,"line":98},[76,11873,4965],{},[76,11875,11876],{"class":78,"line":104},[76,11877,4970],{},[76,11879,11880],{"class":78,"line":110},[76,11881,4975],{},[10,11883,174],{},[67,11885,11887],{"className":11886,"code":4981,"language":180,"meta":72},[178],[43,11888,4981],{"__ignoreMap":72},[10,11890,185],{},[14,11892,188],{"id":188},[190,11894,11895,11903],{},[40,11896,4992,11897,4995,11899,1216,11901,50],{},[43,11898,4927],{},[43,11900,4998],{},[43,11902,5001],{},[40,11904,5004],{},[213,11906,215],{"id":215},[10,11908,5009],{},[10,11910,11911],{},[26,11912],{"alt":5014,"src":5015},[10,11914,5018],{},[14,11916,234],{"id":234},[37,11918,11919,11925],{},[40,11920,5025,11921,1068,11923,5031],{},[43,11922,5028],{},[43,11924,4934],{},[40,11926,5034],{},[14,11928,248],{"id":248},[190,11930,11931,11933],{},[40,11932,5041],{},[40,11934,5044],{},[10,11936,263],{},[14,11938,266],{"id":266},[10,11940,5051],{},[271,11942,273],{},{"title":72,"searchDepth":85,"depth":85,"links":11944},[11945,11946,11947,11948,11949,11952,11953,11954],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":11950},[11951],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":4890,"description":4895},[286,5073,5074],{"id":5077,"title":5078,"body":11959,"category":286,"cover":287,"description":5083,"extension":288,"meta":12076,"navigation":88,"path":5222,"pinned":291,"publishedAt":292,"seo":12077,"slug":5224,"stem":5225,"summary":5226,"tags":12078,"updatedAt":292,"visible":88,"__hash__":5230},{"type":7,"value":11960,"toc":12066},[11961,11963,11965,11967,11969,11973,11975,11977,11985,11987,11989,12021,12023,12028,12030,12032,12040,12042,12050,12052,12058,12060,12062,12064],[10,11962,5083],{},[14,11964,16],{"id":16},[10,11966,5088],{},[14,11968,22],{"id":22},[10,11970,11971],{},[26,11972],{"alt":5095,"src":5096},[10,11974,5099],{},[14,11976,35],{"id":35},[37,11978,11979,11981,11983],{},[40,11980,5106],{},[40,11982,5109],{},[40,11984,5112],{},[14,11986,62],{"id":62},[10,11988,65],{},[67,11990,11991],{"className":69,"code":5119,"language":71,"meta":72,"style":72},[43,11992,11993,11997,12001,12005,12009,12013,12017],{"__ignoreMap":72},[76,11994,11995],{"class":78,"line":79},[76,11996,5126],{},[76,11998,11999],{"class":78,"line":85},[76,12000,89],{"emptyLinePlaceholder":88},[76,12002,12003],{"class":78,"line":92},[76,12004,5135],{},[76,12006,12007],{"class":78,"line":98},[76,12008,5140],{},[76,12010,12011],{"class":78,"line":104},[76,12012,89],{"emptyLinePlaceholder":88},[76,12014,12015],{"class":78,"line":110},[76,12016,5149],{},[76,12018,12019],{"class":78,"line":116},[76,12020,5154],{},[10,12022,174],{},[67,12024,12026],{"className":12025,"code":5160,"language":180,"meta":72},[178],[43,12027,5160],{"__ignoreMap":72},[10,12029,185],{},[14,12031,188],{"id":188},[190,12033,12034,12036],{},[40,12035,5171],{},[40,12037,5174,12038,5178],{},[43,12039,5177],{},[14,12041,234],{"id":234},[37,12043,12044,12048],{},[40,12045,5185,12046,5188],{},[43,12047,4395],{},[40,12049,5191],{},[14,12051,248],{"id":248},[190,12053,12054,12056],{},[40,12055,5198],{},[40,12057,5201],{},[10,12059,263],{},[14,12061,266],{"id":266},[10,12063,5208],{},[271,12065,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12067},[12068,12069,12070,12071,12072,12073,12074,12075],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5078,"description":5083},[286,5228,5229],{"id":5232,"title":5233,"body":12080,"category":286,"cover":287,"description":5238,"extension":288,"meta":12199,"navigation":88,"path":5382,"pinned":291,"publishedAt":292,"seo":12200,"slug":5384,"stem":5385,"summary":5386,"tags":12201,"updatedAt":292,"visible":88,"__hash__":5389},{"type":7,"value":12081,"toc":12189},[12082,12084,12086,12088,12090,12094,12096,12098,12106,12108,12110,12142,12144,12149,12151,12153,12163,12165,12171,12173,12181,12183,12185,12187],[10,12083,5238],{},[14,12085,16],{"id":16},[10,12087,5243],{},[14,12089,22],{"id":22},[10,12091,12092],{},[26,12093],{"alt":5250,"src":5251},[10,12095,5254],{},[14,12097,35],{"id":35},[37,12099,12100,12102,12104],{},[40,12101,5261],{},[40,12103,5264],{},[40,12105,5267],{},[14,12107,62],{"id":62},[10,12109,65],{},[67,12111,12112],{"className":69,"code":5274,"language":71,"meta":72,"style":72},[43,12113,12114,12118,12122,12126,12130,12134,12138],{"__ignoreMap":72},[76,12115,12116],{"class":78,"line":79},[76,12117,5281],{},[76,12119,12120],{"class":78,"line":85},[76,12121,5286],{},[76,12123,12124],{"class":78,"line":92},[76,12125,5291],{},[76,12127,12128],{"class":78,"line":98},[76,12129,89],{"emptyLinePlaceholder":88},[76,12131,12132],{"class":78,"line":104},[76,12133,5300],{},[76,12135,12136],{"class":78,"line":110},[76,12137,5305],{},[76,12139,12140],{"class":78,"line":116},[76,12141,5310],{},[10,12143,174],{},[67,12145,12147],{"className":12146,"code":5316,"language":180,"meta":72},[178],[43,12148,5316],{"__ignoreMap":72},[10,12150,185],{},[14,12152,188],{"id":188},[190,12154,12155,12159],{},[40,12156,997,12157,5330],{},[43,12158,5329],{},[40,12160,5333,12161,5337],{},[43,12162,5336],{},[14,12164,234],{"id":234},[37,12166,12167,12169],{},[40,12168,5344],{},[40,12170,5347],{},[14,12172,248],{"id":248},[190,12174,12175,12179],{},[40,12176,5354,12177,5358],{},[43,12178,5357],{},[40,12180,5361],{},[10,12182,263],{},[14,12184,266],{"id":266},[10,12186,5368],{},[271,12188,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12190},[12191,12192,12193,12194,12195,12196,12197,12198],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5233,"description":5238},[286,299,5388],{"id":5391,"title":5392,"body":12203,"category":286,"cover":287,"description":5397,"extension":288,"meta":12348,"navigation":88,"path":5577,"pinned":291,"publishedAt":292,"seo":12349,"slug":5579,"stem":5580,"summary":5581,"tags":12350,"updatedAt":292,"visible":88,"__hash__":5585},{"type":7,"value":12204,"toc":12336},[12205,12207,12209,12211,12213,12217,12221,12223,12235,12237,12239,12267,12269,12274,12276,12278,12292,12294,12296,12300,12308,12310,12320,12322,12328,12330,12332,12334],[10,12206,5397],{},[14,12208,16],{"id":16},[10,12210,5402],{},[14,12212,22],{"id":22},[10,12214,12215],{},[26,12216],{"alt":5409,"src":5410},[10,12218,5413,12219,5417],{},[43,12220,5416],{},[14,12222,35],{"id":35},[37,12224,12225,12227,12229],{},[40,12226,5424],{},[40,12228,5427],{},[40,12230,5430,12231,5433,12233,50],{},[43,12232,5416],{},[43,12234,242],{},[14,12236,62],{"id":62},[10,12238,65],{},[67,12240,12241],{"className":69,"code":5442,"language":71,"meta":72,"style":72},[43,12242,12243,12247,12251,12255,12259,12263],{"__ignoreMap":72},[76,12244,12245],{"class":78,"line":79},[76,12246,5449],{},[76,12248,12249],{"class":78,"line":85},[76,12250,5454],{},[76,12252,12253],{"class":78,"line":92},[76,12254,5459],{},[76,12256,12257],{"class":78,"line":98},[76,12258,89],{"emptyLinePlaceholder":88},[76,12260,12261],{"class":78,"line":104},[76,12262,5468],{},[76,12264,12265],{"class":78,"line":110},[76,12266,5473],{},[10,12268,174],{},[67,12270,12272],{"className":12271,"code":5479,"language":180,"meta":72},[178],[43,12273,5479],{"__ignoreMap":72},[10,12275,185],{},[14,12277,188],{"id":188},[190,12279,12280,12286],{},[40,12281,5490,12282,2316,12284,5496],{},[43,12283,5493],{},[43,12285,4458],{},[40,12287,12288,5502,12290,5506],{},[43,12289,5501],{},[43,12291,5505],{},[213,12293,215],{"id":215},[10,12295,5511],{},[10,12297,12298],{},[26,12299],{"alt":5516,"src":5517},[10,12301,12302,2316,12304,1216,12306,5527],{},[43,12303,5493],{},[43,12305,4458],{},[43,12307,5526],{},[14,12309,234],{"id":234},[37,12311,12312,12316],{},[40,12313,5534,12314,5538],{},[43,12315,5537],{},[40,12317,5541,12318,5544],{},[43,12319,5526],{},[14,12321,248],{"id":248},[190,12323,12324,12326],{},[40,12325,5551],{},[40,12327,5554],{},[10,12329,263],{},[14,12331,266],{"id":266},[10,12333,5561],{},[271,12335,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12337},[12338,12339,12340,12341,12342,12345,12346,12347],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":12343},[12344],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5392,"description":5397},[286,5583,5584],{"id":5587,"title":5588,"body":12352,"category":286,"cover":287,"description":5593,"extension":288,"meta":12501,"navigation":88,"path":5774,"pinned":291,"publishedAt":292,"seo":12502,"slug":5776,"stem":5777,"summary":5778,"tags":12503,"updatedAt":292,"visible":88,"__hash__":5782},{"type":7,"value":12353,"toc":12489},[12354,12356,12358,12360,12362,12366,12368,12370,12382,12384,12386,12430,12432,12437,12439,12441,12453,12455,12457,12461,12463,12465,12473,12475,12481,12483,12485,12487],[10,12355,5593],{},[14,12357,16],{"id":16},[10,12359,5598],{},[14,12361,22],{"id":22},[10,12363,12364],{},[26,12365],{"alt":5605,"src":5606},[10,12367,5609],{},[14,12369,35],{"id":35},[37,12371,12372,12374,12378],{},[40,12373,5616],{},[40,12375,12376,5622],{},[43,12377,5621],{},[40,12379,12380,5628],{},[43,12381,5627],{},[14,12383,62],{"id":62},[10,12385,65],{},[67,12387,12388],{"className":69,"code":5635,"language":71,"meta":72,"style":72},[43,12389,12390,12394,12398,12402,12406,12410,12414,12418,12422,12426],{"__ignoreMap":72},[76,12391,12392],{"class":78,"line":79},[76,12393,5642],{},[76,12395,12396],{"class":78,"line":85},[76,12397,5647],{},[76,12399,12400],{"class":78,"line":92},[76,12401,89],{"emptyLinePlaceholder":88},[76,12403,12404],{"class":78,"line":98},[76,12405,5656],{},[76,12407,12408],{"class":78,"line":104},[76,12409,5661],{},[76,12411,12412],{"class":78,"line":110},[76,12413,89],{"emptyLinePlaceholder":88},[76,12415,12416],{"class":78,"line":116},[76,12417,5670],{},[76,12419,12420],{"class":78,"line":122},[76,12421,5675],{},[76,12423,12424],{"class":78,"line":128},[76,12425,89],{"emptyLinePlaceholder":88},[76,12427,12428],{"class":78,"line":134},[76,12429,5684],{},[10,12431,174],{},[67,12433,12435],{"className":12434,"code":5690,"language":180,"meta":72},[178],[43,12436,5690],{"__ignoreMap":72},[10,12438,185],{},[14,12440,188],{"id":188},[190,12442,12443,12447],{},[40,12444,5701,12445,5705],{},[43,12446,5704],{},[40,12448,12449,5711,12451,50],{},[43,12450,5710],{},[43,12452,5714],{},[213,12454,215],{"id":215},[10,12456,5719],{},[10,12458,12459],{},[26,12460],{"alt":5724,"src":5725},[10,12462,5728],{},[14,12464,234],{"id":234},[37,12466,12467,12471],{},[40,12468,5735,12469,5738],{},[43,12470,242],{},[40,12472,5741],{},[14,12474,248],{"id":248},[190,12476,12477,12479],{},[40,12478,5748],{},[40,12480,5751],{},[10,12482,263],{},[14,12484,266],{"id":266},[10,12486,5758],{},[271,12488,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12490},[12491,12492,12493,12494,12495,12498,12499,12500],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":12496},[12497],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5588,"description":5593},[286,5780,5781],{"id":5784,"title":5785,"body":12505,"category":286,"cover":287,"description":5790,"extension":288,"meta":12666,"navigation":88,"path":5986,"pinned":291,"publishedAt":292,"seo":12667,"slug":5988,"stem":5989,"summary":5990,"tags":12668,"updatedAt":292,"visible":88,"__hash__":5994},{"type":7,"value":12506,"toc":12654},[12507,12509,12511,12513,12515,12519,12521,12523,12535,12537,12539,12591,12593,12598,12600,12602,12620,12622,12624,12628,12630,12632,12638,12640,12646,12648,12650,12652],[10,12508,5790],{},[14,12510,16],{"id":16},[10,12512,5795],{},[14,12514,22],{"id":22},[10,12516,12517],{},[26,12518],{"alt":5802,"src":5803},[10,12520,5806],{},[14,12522,35],{"id":35},[37,12524,12525,12527,12529],{},[40,12526,5813],{},[40,12528,5816],{},[40,12530,12531,2235,12533,5825],{},[43,12532,5821],{},[43,12534,5824],{},[14,12536,62],{"id":62},[10,12538,65],{},[67,12540,12541],{"className":69,"code":5832,"language":71,"meta":72,"style":72},[43,12542,12543,12547,12551,12555,12559,12563,12567,12571,12575,12579,12583,12587],{"__ignoreMap":72},[76,12544,12545],{"class":78,"line":79},[76,12546,5839],{},[76,12548,12549],{"class":78,"line":85},[76,12550,89],{"emptyLinePlaceholder":88},[76,12552,12553],{"class":78,"line":92},[76,12554,5848],{},[76,12556,12557],{"class":78,"line":98},[76,12558,5853],{},[76,12560,12561],{"class":78,"line":104},[76,12562,89],{"emptyLinePlaceholder":88},[76,12564,12565],{"class":78,"line":110},[76,12566,5862],{},[76,12568,12569],{"class":78,"line":116},[76,12570,5867],{},[76,12572,12573],{"class":78,"line":122},[76,12574,5872],{},[76,12576,12577],{"class":78,"line":128},[76,12578,89],{"emptyLinePlaceholder":88},[76,12580,12581],{"class":78,"line":134},[76,12582,5881],{},[76,12584,12585],{"class":78,"line":140},[76,12586,89],{"emptyLinePlaceholder":88},[76,12588,12589],{"class":78,"line":145},[76,12590,5890],{},[10,12592,174],{},[67,12594,12596],{"className":12595,"code":5896,"language":180,"meta":72},[178],[43,12597,5896],{"__ignoreMap":72},[10,12599,185],{},[14,12601,188],{"id":188},[190,12603,12604,12614],{},[40,12605,12606,5910,12608,5914,12610,5917,12612,5921],{},[43,12607,5909],{},[43,12609,5913],{},[43,12611,5704],{},[43,12613,5920],{},[40,12615,12616,5926,12618,5929],{},[43,12617,4641],{},[43,12619,2267],{},[213,12621,215],{"id":215},[10,12623,5934],{},[10,12625,12626],{},[26,12627],{"alt":5939,"src":5940},[10,12629,5943],{},[14,12631,234],{"id":234},[37,12633,12634,12636],{},[40,12635,5950],{},[40,12637,5953],{},[14,12639,248],{"id":248},[190,12641,12642,12644],{},[40,12643,5960],{},[40,12645,5963],{},[10,12647,263],{},[14,12649,266],{"id":266},[10,12651,5970],{},[271,12653,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12655},[12656,12657,12658,12659,12660,12663,12664,12665],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":12661},[12662],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5785,"description":5790},[286,5992,5993],{"id":5996,"title":5997,"body":12670,"category":286,"cover":287,"description":6002,"extension":288,"meta":12793,"navigation":88,"path":6153,"pinned":291,"publishedAt":292,"seo":12794,"slug":6155,"stem":6156,"summary":6157,"tags":12795,"updatedAt":292,"visible":88,"__hash__":6161},{"type":7,"value":12671,"toc":12783},[12672,12674,12676,12678,12680,12684,12686,12688,12702,12704,12706,12734,12736,12741,12743,12745,12755,12757,12765,12767,12775,12777,12779,12781],[10,12673,6002],{},[14,12675,16],{"id":16},[10,12677,6007],{},[14,12679,22],{"id":22},[10,12681,12682],{},[26,12683],{"alt":6014,"src":6015},[10,12685,6018],{},[14,12687,35],{"id":35},[37,12689,12690,12692,12694],{},[40,12691,6025],{},[40,12693,6028],{},[40,12695,6031,12696,2316,12698,2316,12700,6039],{},[43,12697,2319],{},[43,12699,2485],{},[43,12701,6038],{},[14,12703,62],{"id":62},[10,12705,65],{},[67,12707,12708],{"className":69,"code":6046,"language":71,"meta":72,"style":72},[43,12709,12710,12714,12718,12722,12726,12730],{"__ignoreMap":72},[76,12711,12712],{"class":78,"line":79},[76,12713,6053],{},[76,12715,12716],{"class":78,"line":85},[76,12717,6058],{},[76,12719,12720],{"class":78,"line":92},[76,12721,6063],{},[76,12723,12724],{"class":78,"line":98},[76,12725,89],{"emptyLinePlaceholder":88},[76,12727,12728],{"class":78,"line":104},[76,12729,6072],{},[76,12731,12732],{"class":78,"line":110},[76,12733,6077],{},[10,12735,174],{},[67,12737,12739],{"className":12738,"code":6083,"language":180,"meta":72},[178],[43,12740,6083],{"__ignoreMap":72},[10,12742,185],{},[14,12744,188],{"id":188},[190,12746,12747,12753],{},[40,12748,6094,12749,6098,12751,6101],{},[43,12750,6097],{},[43,12752,2305],{},[40,12754,6104],{},[14,12756,234],{"id":234},[37,12758,12759,12763],{},[40,12760,6111,12761,6115],{},[43,12762,6114],{},[40,12764,6118],{},[14,12766,248],{"id":248},[190,12768,12769,12771],{},[40,12770,6125],{},[40,12772,6128,12773,6132],{},[43,12774,6131],{},[10,12776,263],{},[14,12778,266],{"id":266},[10,12780,6139],{},[271,12782,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12784},[12785,12786,12787,12788,12789,12790,12791,12792],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5997,"description":6002},[286,6159,6160],{"id":6163,"title":6164,"body":12797,"category":286,"cover":287,"description":6169,"extension":288,"meta":12974,"navigation":88,"path":6395,"pinned":291,"publishedAt":292,"seo":12975,"slug":6397,"stem":6398,"summary":6399,"tags":12976,"updatedAt":292,"visible":88,"__hash__":6403},{"type":7,"value":12798,"toc":12962},[12799,12801,12803,12807,12809,12813,12819,12821,12833,12835,12839,12863,12867,12883,12889,12891,12896,12898,12900,12916,12918,12920,12924,12928,12930,12942,12944,12954,12956,12958,12960],[10,12800,6169],{},[14,12802,16],{"id":16},[10,12804,6174,12805,6177],{},[355,12806,6097],{},[14,12808,22],{"id":22},[10,12810,12811],{},[26,12812],{"alt":6184,"src":6185},[10,12814,6188,12815,6192,12817,6196],{},[43,12816,6191],{},[43,12818,6195],{},[14,12820,35],{"id":35},[37,12822,12823,12827,12829],{},[40,12824,6203,12825,6206],{},[43,12826,1230],{},[40,12828,6209],{},[40,12830,6212,12831,6216],{},[43,12832,6215],{},[14,12834,62],{"id":62},[10,12836,6221,12837,6225],{},[43,12838,6224],{},[67,12840,12841],{"className":69,"code":6228,"language":71,"meta":72,"style":72},[43,12842,12843,12847,12851,12855,12859],{"__ignoreMap":72},[76,12844,12845],{"class":78,"line":79},[76,12846,154],{},[76,12848,12849],{"class":78,"line":85},[76,12850,160],{},[76,12852,12853],{"class":78,"line":92},[76,12854,89],{"emptyLinePlaceholder":88},[76,12856,12857],{"class":78,"line":98},[76,12858,6247],{},[76,12860,12861],{"class":78,"line":104},[76,12862,6252],{},[10,12864,6255,12865,6259],{},[43,12866,6258],{},[67,12868,12869],{"className":69,"code":6262,"language":71,"meta":72,"style":72},[43,12870,12871,12875,12879],{"__ignoreMap":72},[76,12872,12873],{"class":78,"line":79},[76,12874,6269],{},[76,12876,12877],{"class":78,"line":85},[76,12878,89],{"emptyLinePlaceholder":88},[76,12880,12881],{"class":78,"line":92},[76,12882,6278],{},[10,12884,6281,12885,1216,12887,50],{},[43,12886,6284],{},[43,12888,6287],{},[10,12890,174],{},[67,12892,12894],{"className":12893,"code":6293,"language":180,"meta":72},[178],[43,12895,6293],{"__ignoreMap":72},[10,12897,185],{},[14,12899,188],{"id":188},[190,12901,12902,12908],{},[40,12903,6304,12904,6307,12906,6311],{},[43,12905,6224],{},[43,12907,6310],{},[40,12909,12910,6316,12912,6319,12914,6322],{},[43,12911,6258],{},[43,12913,6224],{},[43,12915,6258],{},[213,12917,215],{"id":215},[10,12919,6327],{},[10,12921,12922],{},[26,12923],{"alt":6332,"src":6333},[10,12925,6336,12926,6339],{},[43,12927,6310],{},[14,12929,234],{"id":234},[37,12931,12932,12938],{},[40,12933,6346,12934,1216,12936,50],{},[43,12935,6224],{},[43,12937,6258],{},[40,12939,6353,12940,6357],{},[43,12941,6356],{},[14,12943,248],{"id":248},[190,12945,12946,12950],{},[40,12947,2413,12948,6367],{},[43,12949,6366],{},[40,12951,6370,12952,50],{},[43,12953,6191],{},[10,12955,263],{},[14,12957,266],{"id":266},[10,12959,6379],{},[271,12961,273],{},{"title":72,"searchDepth":85,"depth":85,"links":12963},[12964,12965,12966,12967,12968,12971,12972,12973],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":12969},[12970],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":6164,"description":6169},[286,6401,6402],{"id":6405,"title":6406,"body":12978,"category":286,"cover":287,"description":6411,"extension":288,"meta":13117,"navigation":88,"path":6577,"pinned":291,"publishedAt":292,"seo":13118,"slug":6579,"stem":6580,"summary":6581,"tags":13119,"updatedAt":292,"visible":88,"__hash__":6584},{"type":7,"value":12979,"toc":13107},[12980,12982,12984,12986,12988,12992,12994,12996,13006,13008,13010,13050,13052,13057,13059,13061,13079,13081,13089,13091,13099,13101,13103,13105],[10,12981,6411],{},[14,12983,16],{"id":16},[10,12985,6416],{},[14,12987,22],{"id":22},[10,12989,12990],{},[26,12991],{"alt":6423,"src":6424},[10,12993,6427],{},[14,12995,35],{"id":35},[37,12997,12998,13002,13004],{},[40,12999,13000,6437],{},[43,13001,6436],{},[40,13003,6440],{},[40,13005,6443],{},[14,13007,62],{"id":62},[10,13009,1633],{},[67,13011,13012],{"className":650,"code":6450,"language":652,"meta":72,"style":72},[43,13013,13014,13024,13030,13036,13046],{"__ignoreMap":72},[76,13015,13016,13018,13020,13022],{"class":78,"line":79},[76,13017,750],{"class":659},[76,13019,692],{"class":662},[76,13021,6461],{"class":695},[76,13023,6464],{"class":695},[76,13025,13026,13028],{"class":78,"line":85},[76,13027,6469],{"class":662},[76,13029,6472],{"class":695},[76,13031,13032,13034],{"class":78,"line":92},[76,13033,71],{"class":659},[76,13035,663],{"class":662},[76,13037,13038,13040,13042,13044],{"class":78,"line":98},[76,13039,71],{"class":659},[76,13041,692],{"class":662},[76,13043,696],{"class":695},[76,13045,663],{"class":662},[76,13047,13048],{"class":78,"line":104},[76,13049,6493],{"class":659},[10,13051,174],{},[67,13053,13055],{"className":13054,"code":6499,"language":180,"meta":72},[178],[43,13056,6499],{"__ignoreMap":72},[10,13058,185],{},[14,13060,188],{"id":188},[190,13062,13063,13069],{},[40,13064,13065,6513,13067,6516],{},[43,13066,6512],{},[43,13068,750],{},[40,13070,6519,13071,2235,13073,6525,13075,3786,13077,6531],{},[43,13072,71],{},[43,13074,6524],{},[43,13076,6436],{},[43,13078,6530],{},[14,13080,234],{"id":234},[37,13082,13083,13085],{},[40,13084,6538],{},[40,13086,3525,13087,6543],{},[43,13088,6436],{},[14,13090,248],{"id":248},[190,13092,13093,13097],{},[40,13094,6550,13095,50],{},[43,13096,6553],{},[40,13098,6556],{},[10,13100,263],{},[14,13102,266],{"id":266},[10,13104,6563],{},[271,13106,1717],{},{"title":72,"searchDepth":85,"depth":85,"links":13108},[13109,13110,13111,13112,13113,13114,13115,13116],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":6406,"description":6411},[286,6583,321],{"id":6586,"title":6587,"body":13121,"category":286,"cover":287,"description":6592,"extension":288,"meta":13274,"navigation":88,"path":6781,"pinned":291,"publishedAt":292,"seo":13275,"slug":6783,"stem":6784,"summary":6785,"tags":13276,"updatedAt":292,"visible":88,"__hash__":6789},{"type":7,"value":13122,"toc":13264},[13123,13125,13127,13129,13131,13135,13141,13143,13159,13161,13163,13207,13209,13214,13216,13218,13230,13232,13246,13248,13256,13258,13260,13262],[10,13124,6592],{},[14,13126,16],{"id":16},[10,13128,6597],{},[14,13130,22],{"id":22},[10,13132,13133],{},[26,13134],{"alt":6604,"src":6605},[10,13136,13137,6611,13139,6614],{},[43,13138,6610],{},[43,13140,2495],{},[14,13142,35],{"id":35},[37,13144,13145,13147,13155],{},[40,13146,6621],{},[40,13148,13149,2316,13151,2316,13153,6633],{},[43,13150,6626],{},[43,13152,6629],{},[43,13154,6632],{},[40,13156,6636,13157,6640],{},[43,13158,6639],{},[14,13160,62],{"id":62},[10,13162,65],{},[67,13164,13165],{"className":69,"code":6647,"language":71,"meta":72,"style":72},[43,13166,13167,13171,13175,13179,13183,13187,13191,13195,13199,13203],{"__ignoreMap":72},[76,13168,13169],{"class":78,"line":79},[76,13170,6654],{},[76,13172,13173],{"class":78,"line":85},[76,13174,89],{"emptyLinePlaceholder":88},[76,13176,13177],{"class":78,"line":92},[76,13178,6663],{},[76,13180,13181],{"class":78,"line":98},[76,13182,6668],{},[76,13184,13185],{"class":78,"line":104},[76,13186,6673],{},[76,13188,13189],{"class":78,"line":110},[76,13190,89],{"emptyLinePlaceholder":88},[76,13192,13193],{"class":78,"line":116},[76,13194,6682],{},[76,13196,13197],{"class":78,"line":122},[76,13198,6687],{},[76,13200,13201],{"class":78,"line":128},[76,13202,6692],{},[76,13204,13205],{"class":78,"line":134},[76,13206,6697],{},[10,13208,174],{},[67,13210,13212],{"className":13211,"code":6703,"language":180,"meta":72},[178],[43,13213,6703],{"__ignoreMap":72},[10,13215,185],{},[14,13217,188],{"id":188},[190,13219,13220,13224],{},[40,13221,13222,6717],{},[43,13223,6716],{},[40,13225,2398,13226,6722,13228,6725],{},[43,13227,2495],{},[43,13229,6610],{},[14,13231,234],{"id":234},[37,13233,13234,13240],{},[40,13235,3525,13236,6734,13238,6737],{},[43,13237,6610],{},[43,13239,6626],{},[40,13241,6740,13242,1068,13244,6746],{},[43,13243,2495],{},[43,13245,6745],{},[14,13247,248],{"id":248},[190,13249,13250,13254],{},[40,13251,6753,13252,6757],{},[43,13253,6756],{},[40,13255,6760],{},[10,13257,263],{},[14,13259,266],{"id":266},[10,13261,6767],{},[271,13263,273],{},{"title":72,"searchDepth":85,"depth":85,"links":13265},[13266,13267,13268,13269,13270,13271,13272,13273],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":6587,"description":6592},[286,6787,6788],{"id":6791,"title":6792,"body":13278,"category":286,"cover":287,"description":6797,"extension":288,"meta":13425,"navigation":88,"path":6976,"pinned":291,"publishedAt":292,"seo":13426,"slug":6978,"stem":6979,"summary":6980,"tags":13427,"updatedAt":292,"visible":88,"__hash__":6984},{"type":7,"value":13279,"toc":13415},[13280,13282,13284,13286,13288,13292,13294,13296,13314,13316,13318,13366,13368,13373,13375,13377,13385,13387,13397,13399,13407,13409,13411,13413],[10,13281,6797],{},[14,13283,16],{"id":16},[10,13285,6802],{},[14,13287,22],{"id":22},[10,13289,13290],{},[26,13291],{"alt":6809,"src":6810},[10,13293,6813],{},[14,13295,35],{"id":35},[37,13297,13298,13302,13308],{},[40,13299,13300,6823],{},[43,13301,6822],{},[40,13303,13304,6829,13306,50],{},[43,13305,6828],{},[43,13307,6832],{},[40,13309,6835,13310,6839,13312,6843],{},[43,13311,6838],{},[43,13313,6842],{},[14,13315,62],{"id":62},[10,13317,65],{},[67,13319,13320],{"className":69,"code":6850,"language":71,"meta":72,"style":72},[43,13321,13322,13326,13330,13334,13338,13342,13346,13350,13354,13358,13362],{"__ignoreMap":72},[76,13323,13324],{"class":78,"line":79},[76,13325,6654],{},[76,13327,13328],{"class":78,"line":85},[76,13329,89],{"emptyLinePlaceholder":88},[76,13331,13332],{"class":78,"line":92},[76,13333,6865],{},[76,13335,13336],{"class":78,"line":98},[76,13337,6870],{},[76,13339,13340],{"class":78,"line":104},[76,13341,6875],{},[76,13343,13344],{"class":78,"line":110},[76,13345,6880],{},[76,13347,13348],{"class":78,"line":116},[76,13349,89],{"emptyLinePlaceholder":88},[76,13351,13352],{"class":78,"line":122},[76,13353,6889],{},[76,13355,13356],{"class":78,"line":128},[76,13357,6894],{},[76,13359,13360],{"class":78,"line":134},[76,13361,6899],{},[76,13363,13364],{"class":78,"line":140},[76,13365,6904],{},[10,13367,174],{},[67,13369,13371],{"className":13370,"code":6910,"language":180,"meta":72},[178],[43,13372,6910],{"__ignoreMap":72},[10,13374,185],{},[14,13376,188],{"id":188},[190,13378,13379,13383],{},[40,13380,6921,13381,6924],{},[43,13382,6838],{},[40,13384,6927],{},[14,13386,234],{"id":234},[37,13388,13389,13393],{},[40,13390,2398,13391,6936],{},[43,13392,6822],{},[40,13394,6939,13395,50],{},[43,13396,6942],{},[14,13398,248],{"id":248},[190,13400,13401,13403],{},[40,13402,6949],{},[40,13404,6952,13405,6955],{},[43,13406,396],{},[10,13408,263],{},[14,13410,266],{"id":266},[10,13412,6962],{},[271,13414,273],{},{"title":72,"searchDepth":85,"depth":85,"links":13416},[13417,13418,13419,13420,13421,13422,13423,13424],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":6792,"description":6797},[286,6982,6983],{"id":6986,"title":6987,"body":13429,"category":286,"cover":287,"description":6992,"extension":288,"meta":13572,"navigation":88,"path":7160,"pinned":291,"publishedAt":292,"seo":13573,"slug":7162,"stem":7163,"summary":7164,"tags":13574,"updatedAt":292,"visible":88,"__hash__":7168},{"type":7,"value":13430,"toc":13562},[13431,13433,13435,13437,13439,13443,13449,13451,13461,13463,13465,13517,13519,13524,13526,13528,13538,13540,13546,13548,13554,13556,13558,13560],[10,13432,6992],{},[14,13434,16],{"id":16},[10,13436,6997],{},[14,13438,22],{"id":22},[10,13440,13441],{},[26,13442],{"alt":7004,"src":7005},[10,13444,13445,7011,13447,7015],{},[43,13446,7010],{},[43,13448,7014],{},[14,13450,35],{"id":35},[37,13452,13453,13455,13459],{},[40,13454,7022],{},[40,13456,13457,7028],{},[43,13458,7027],{},[40,13460,7031],{},[14,13462,62],{"id":62},[10,13464,65],{},[67,13466,13467],{"className":69,"code":7038,"language":71,"meta":72,"style":72},[43,13468,13469,13473,13477,13481,13485,13489,13493,13497,13501,13505,13509,13513],{"__ignoreMap":72},[76,13470,13471],{"class":78,"line":79},[76,13472,7045],{},[76,13474,13475],{"class":78,"line":85},[76,13476,89],{"emptyLinePlaceholder":88},[76,13478,13479],{"class":78,"line":92},[76,13480,7054],{},[76,13482,13483],{"class":78,"line":98},[76,13484,89],{"emptyLinePlaceholder":88},[76,13486,13487],{"class":78,"line":104},[76,13488,7063],{},[76,13490,13491],{"class":78,"line":110},[76,13492,7068],{},[76,13494,13495],{"class":78,"line":116},[76,13496,6880],{},[76,13498,13499],{"class":78,"line":122},[76,13500,89],{"emptyLinePlaceholder":88},[76,13502,13503],{"class":78,"line":128},[76,13504,7081],{},[76,13506,13507],{"class":78,"line":134},[76,13508,7086],{},[76,13510,13511],{"class":78,"line":140},[76,13512,6899],{},[76,13514,13515],{"class":78,"line":145},[76,13516,7095],{},[10,13518,174],{},[67,13520,13522],{"className":13521,"code":7101,"language":180,"meta":72},[178],[43,13523,7101],{"__ignoreMap":72},[10,13525,185],{},[14,13527,188],{"id":188},[190,13529,13530,13534],{},[40,13531,13532,7114],{},[43,13533,7010],{},[40,13535,13536,7119],{},[43,13537,7014],{},[14,13539,234],{"id":234},[37,13541,13542,13544],{},[40,13543,7126],{},[40,13545,7129],{},[14,13547,248],{"id":248},[190,13549,13550,13552],{},[40,13551,7136],{},[40,13553,7139],{},[10,13555,263],{},[14,13557,266],{"id":266},[10,13559,7146],{},[271,13561,273],{},{"title":72,"searchDepth":85,"depth":85,"links":13563},[13564,13565,13566,13567,13568,13569,13570,13571],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":6987,"description":6992},[286,7166,7167],{"id":7170,"title":7171,"body":13576,"category":286,"cover":287,"description":7176,"extension":288,"meta":13727,"navigation":88,"path":7361,"pinned":291,"publishedAt":292,"seo":13728,"slug":7363,"stem":7364,"summary":7365,"tags":13729,"updatedAt":292,"visible":88,"__hash__":7369},{"type":7,"value":13577,"toc":13717},[13578,13580,13582,13584,13586,13590,13594,13596,13610,13612,13614,13666,13668,13673,13675,13677,13689,13691,13701,13703,13709,13711,13713,13715],[10,13579,7176],{},[14,13581,16],{"id":16},[10,13583,7181],{},[14,13585,22],{"id":22},[10,13587,13588],{},[26,13589],{"alt":7188,"src":7189},[10,13591,13592,7195],{},[43,13593,7194],{},[14,13595,35],{"id":35},[37,13597,13598,13604,13608],{},[40,13599,2398,13600,7205,13602,7209],{},[43,13601,7204],{},[43,13603,7208],{},[40,13605,7212,13606,7216],{},[43,13607,7215],{},[40,13609,7219],{},[14,13611,62],{"id":62},[10,13613,65],{},[67,13615,13616],{"className":69,"code":7226,"language":71,"meta":72,"style":72},[43,13617,13618,13622,13626,13630,13634,13638,13642,13646,13650,13654,13658,13662],{"__ignoreMap":72},[76,13619,13620],{"class":78,"line":79},[76,13621,7233],{},[76,13623,13624],{"class":78,"line":85},[76,13625,89],{"emptyLinePlaceholder":88},[76,13627,13628],{"class":78,"line":92},[76,13629,7242],{},[76,13631,13632],{"class":78,"line":98},[76,13633,7247],{},[76,13635,13636],{"class":78,"line":104},[76,13637,7252],{},[76,13639,13640],{"class":78,"line":110},[76,13641,7257],{},[76,13643,13644],{"class":78,"line":116},[76,13645,7262],{},[76,13647,13648],{"class":78,"line":122},[76,13649,89],{"emptyLinePlaceholder":88},[76,13651,13652],{"class":78,"line":128},[76,13653,7271],{},[76,13655,13656],{"class":78,"line":134},[76,13657,7276],{},[76,13659,13660],{"class":78,"line":140},[76,13661,7281],{},[76,13663,13664],{"class":78,"line":145},[76,13665,7286],{},[10,13667,174],{},[67,13669,13671],{"className":13670,"code":7292,"language":180,"meta":72},[178],[43,13672,7292],{"__ignoreMap":72},[10,13674,185],{},[14,13676,188],{"id":188},[190,13678,13679,13685],{},[40,13680,13681,7306,13683,7309],{},[43,13682,7305],{},[43,13684,7215],{},[40,13686,13687,7314],{},[43,13688,7194],{},[14,13690,234],{"id":234},[37,13692,13693,13695],{},[40,13694,7321],{},[40,13696,7324,13697,7327,13699,7330],{},[43,13698,7204],{},[43,13700,7208],{},[14,13702,248],{"id":248},[190,13704,13705,13707],{},[40,13706,7337],{},[40,13708,7340],{},[10,13710,263],{},[14,13712,266],{"id":266},[10,13714,7347],{},[271,13716,273],{},{"title":72,"searchDepth":85,"depth":85,"links":13718},[13719,13720,13721,13722,13723,13724,13725,13726],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":7171,"description":7176},[286,7367,7368],{"id":7371,"title":7372,"body":13731,"category":286,"cover":287,"description":7377,"extension":288,"meta":13945,"navigation":88,"path":7649,"pinned":291,"publishedAt":292,"seo":13946,"slug":7651,"stem":7652,"summary":7653,"tags":13947,"updatedAt":292,"visible":88,"__hash__":7657},{"type":7,"value":13732,"toc":13932},[13733,13735,13737,13739,13741,13745,13751,13753,13765,13767,13769,13829,13831,13836,13838,13840,13858,13860,13868,13872,13880,13882,13886,13890,13896,13898,13908,13910,13924,13926,13928,13930],[10,13734,7377],{},[14,13736,16],{"id":16},[10,13738,7382],{},[14,13740,22],{"id":22},[10,13742,13743],{},[26,13744],{"alt":7389,"src":7390},[10,13746,7393,13747,7397,13749,7401],{},[43,13748,7396],{},[43,13750,7400],{},[14,13752,35],{"id":35},[37,13754,13755,13759,13763],{},[40,13756,7408,13757,7411],{},[43,13758,7396],{},[40,13760,13761,7417],{},[43,13762,7416],{},[40,13764,7420],{},[14,13766,62],{"id":62},[10,13768,65],{},[67,13770,13771],{"className":69,"code":7427,"language":71,"meta":72,"style":72},[43,13772,13773,13777,13781,13785,13789,13793,13797,13801,13805,13809,13813,13817,13821,13825],{"__ignoreMap":72},[76,13774,13775],{"class":78,"line":79},[76,13776,7434],{},[76,13778,13779],{"class":78,"line":85},[76,13780,7439],{},[76,13782,13783],{"class":78,"line":92},[76,13784,7444],{},[76,13786,13787],{"class":78,"line":98},[76,13788,7449],{},[76,13790,13791],{"class":78,"line":104},[76,13792,7454],{},[76,13794,13795],{"class":78,"line":110},[76,13796,89],{"emptyLinePlaceholder":88},[76,13798,13799],{"class":78,"line":116},[76,13800,7463],{},[76,13802,13803],{"class":78,"line":122},[76,13804,7468],{},[76,13806,13807],{"class":78,"line":128},[76,13808,7473],{},[76,13810,13811],{"class":78,"line":134},[76,13812,7478],{},[76,13814,13815],{"class":78,"line":140},[76,13816,1205],{},[76,13818,13819],{"class":78,"line":145},[76,13820,7487],{},[76,13822,13823],{"class":78,"line":151},[76,13824,7492],{},[76,13826,13827],{"class":78,"line":157},[76,13828,7497],{},[10,13830,174],{},[67,13832,13834],{"className":13833,"code":7503,"language":180,"meta":72},[178],[43,13835,7503],{"__ignoreMap":72},[10,13837,185],{},[14,13839,188],{"id":188},[190,13841,13842,13850],{},[40,13843,13844,7516,13846,7519,13848,7523],{},[43,13845,3094],{},[43,13847,7416],{},[43,13849,7522],{},[40,13851,7526,13852,7529,13854,7532,13856,50],{},[43,13853,7396],{},[43,13855,1219],{},[43,13857,7400],{},[213,13859,215],{"id":215},[10,13861,13862,2316,13864,1216,13866,7545],{},[43,13863,7396],{},[43,13865,1219],{},[43,13867,7400],{},[10,13869,13870],{},[26,13871],{"alt":7550,"src":7551},[10,13873,13874,7556,13876,7559,13878,7562],{},[43,13875,7396],{},[43,13877,1219],{},[43,13879,7400],{},[213,13881,215],{"id":4276},[10,13883,13884,7570],{},[43,13885,7569],{},[10,13887,13888],{},[26,13889],{"alt":7575,"src":7576},[10,13891,7579,13892,7582,13894,7585],{},[43,13893,7569],{},[43,13895,1219],{},[14,13897,234],{"id":234},[37,13899,13900,13904],{},[40,13901,7592,13902,7596],{},[43,13903,7595],{},[40,13905,7599,13906,7602],{},[43,13907,7569],{},[14,13909,248],{"id":248},[190,13911,13912,13920],{},[40,13913,7609,13914,7613,13916,1216,13918,50],{},[43,13915,7612],{},[43,13917,7616],{},[43,13919,7619],{},[40,13921,7622,13922,7625],{},[43,13923,6832],{},[10,13925,263],{},[14,13927,266],{"id":266},[10,13929,7632],{},[271,13931,273],{},{"title":72,"searchDepth":85,"depth":85,"links":13933},[13934,13935,13936,13937,13938,13942,13943,13944],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":13939},[13940,13941],{"id":215,"depth":92,"text":215},{"id":4276,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":7372,"description":7377},[286,7655,7656],{"id":7659,"title":7660,"body":13949,"category":286,"cover":287,"description":7665,"extension":288,"meta":14100,"navigation":88,"path":7842,"pinned":291,"publishedAt":292,"seo":14101,"slug":7844,"stem":7845,"summary":7846,"tags":14102,"updatedAt":292,"visible":88,"__hash__":7849},{"type":7,"value":13950,"toc":14090},[13951,13953,13955,13957,13959,13963,13967,13969,13981,13983,13985,14033,14035,14040,14042,14044,14054,14056,14066,14068,14082,14084,14086,14088],[10,13952,7665],{},[14,13954,16],{"id":16},[10,13956,7670],{},[14,13958,22],{"id":22},[10,13960,13961],{},[26,13962],{"alt":7677,"src":7678},[10,13964,7681,13965,7684],{},[43,13966,6842],{},[14,13968,35],{"id":35},[37,13970,13971,13975,13979],{},[40,13972,13973,7693],{},[43,13974,6842],{},[40,13976,13977,7699],{},[43,13978,7698],{},[40,13980,7702],{},[14,13982,62],{"id":62},[10,13984,65],{},[67,13986,13987],{"className":69,"code":7709,"language":71,"meta":72,"style":72},[43,13988,13989,13993,13997,14001,14005,14009,14013,14017,14021,14025,14029],{"__ignoreMap":72},[76,13990,13991],{"class":78,"line":79},[76,13992,6654],{},[76,13994,13995],{"class":78,"line":85},[76,13996,89],{"emptyLinePlaceholder":88},[76,13998,13999],{"class":78,"line":92},[76,14000,6865],{},[76,14002,14003],{"class":78,"line":98},[76,14004,89],{"emptyLinePlaceholder":88},[76,14006,14007],{"class":78,"line":104},[76,14008,7732],{},[76,14010,14011],{"class":78,"line":110},[76,14012,7737],{},[76,14014,14015],{"class":78,"line":116},[76,14016,89],{"emptyLinePlaceholder":88},[76,14018,14019],{"class":78,"line":122},[76,14020,7746],{},[76,14022,14023],{"class":78,"line":128},[76,14024,7751],{},[76,14026,14027],{"class":78,"line":134},[76,14028,89],{"emptyLinePlaceholder":88},[76,14030,14031],{"class":78,"line":140},[76,14032,7760],{},[10,14034,174],{},[67,14036,14038],{"className":14037,"code":7766,"language":180,"meta":72},[178],[43,14039,7766],{"__ignoreMap":72},[10,14041,185],{},[14,14043,188],{"id":188},[190,14045,14046,14052],{},[40,14047,7681,14048,7779,14050,50],{},[43,14049,6842],{},[43,14051,7782],{},[40,14053,7785],{},[14,14055,234],{"id":234},[37,14057,14058,14062],{},[40,14059,4844,14060,7794],{},[43,14061,6842],{},[40,14063,7797,14064,7800],{},[43,14065,6842],{},[14,14067,248],{"id":248},[190,14069,14070,14076],{},[40,14071,7807,14072,7811,14074,50],{},[43,14073,7810],{},[43,14075,6842],{},[40,14077,4844,14078,7818,14080,50],{},[43,14079,6842],{},[43,14081,7821],{},[10,14083,263],{},[14,14085,266],{"id":266},[10,14087,7828],{},[271,14089,273],{},{"title":72,"searchDepth":85,"depth":85,"links":14091},[14092,14093,14094,14095,14096,14097,14098,14099],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":7660,"description":7665},[286,6842,7848],{"id":7851,"title":7852,"body":14104,"category":286,"cover":287,"description":7857,"extension":288,"meta":14275,"navigation":88,"path":8070,"pinned":291,"publishedAt":292,"seo":14276,"slug":8072,"stem":8073,"summary":8074,"tags":14277,"updatedAt":292,"visible":88,"__hash__":8078},{"type":7,"value":14105,"toc":14263},[14106,14108,14110,14112,14114,14118,14120,14122,14134,14136,14138,14194,14196,14201,14203,14205,14221,14223,14225,14229,14235,14237,14245,14247,14255,14257,14259,14261],[10,14107,7857],{},[14,14109,16],{"id":16},[10,14111,7862],{},[14,14113,22],{"id":22},[10,14115,14116],{},[26,14117],{"alt":7869,"src":7870},[10,14119,7873],{},[14,14121,35],{"id":35},[37,14123,14124,14128,14132],{},[40,14125,14126,7883],{},[43,14127,7882],{},[40,14129,14130,7889],{},[43,14131,7888],{},[40,14133,7892],{},[14,14135,62],{"id":62},[10,14137,65],{},[67,14139,14140],{"className":69,"code":7899,"language":71,"meta":72,"style":72},[43,14141,14142,14146,14150,14154,14158,14162,14166,14170,14174,14178,14182,14186,14190],{"__ignoreMap":72},[76,14143,14144],{"class":78,"line":79},[76,14145,7906],{},[76,14147,14148],{"class":78,"line":85},[76,14149,7911],{},[76,14151,14152],{"class":78,"line":92},[76,14153,7916],{},[76,14155,14156],{"class":78,"line":98},[76,14157,7921],{},[76,14159,14160],{"class":78,"line":104},[76,14161,89],{"emptyLinePlaceholder":88},[76,14163,14164],{"class":78,"line":110},[76,14165,7930],{},[76,14167,14168],{"class":78,"line":116},[76,14169,7935],{},[76,14171,14172],{"class":78,"line":122},[76,14173,7940],{},[76,14175,14176],{"class":78,"line":128},[76,14177,7945],{},[76,14179,14180],{"class":78,"line":134},[76,14181,89],{"emptyLinePlaceholder":88},[76,14183,14184],{"class":78,"line":140},[76,14185,7954],{},[76,14187,14188],{"class":78,"line":145},[76,14189,7959],{},[76,14191,14192],{"class":78,"line":151},[76,14193,7964],{},[10,14195,174],{},[67,14197,14199],{"className":14198,"code":7970,"language":180,"meta":72},[178],[43,14200,7970],{"__ignoreMap":72},[10,14202,185],{},[14,14204,188],{"id":188},[190,14206,14207,14213],{},[40,14208,7981,14209,7985,14211,7988],{},[43,14210,7984],{},[43,14212,7888],{},[40,14214,14215,7994,14217,7998,14219,8001],{},[43,14216,7993],{},[43,14218,7997],{},[43,14220,7882],{},[213,14222,215],{"id":215},[10,14224,8006],{},[10,14226,14227],{},[26,14228],{"alt":8011,"src":8012},[10,14230,8015,14231,1216,14233,8021],{},[43,14232,4641],{},[43,14234,8020],{},[14,14236,234],{"id":234},[37,14238,14239,14243],{},[40,14240,8028,14241,8031],{},[43,14242,7882],{},[40,14244,8034],{},[14,14246,248],{"id":248},[190,14248,14249,14253],{},[40,14250,5354,14251,8044],{},[43,14252,8043],{},[40,14254,8047],{},[10,14256,263],{},[14,14258,266],{"id":266},[10,14260,8054],{},[271,14262,273],{},{"title":72,"searchDepth":85,"depth":85,"links":14264},[14265,14266,14267,14268,14269,14272,14273,14274],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":14270},[14271],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":7852,"description":7857},[286,8076,8077],{"id":8080,"title":8081,"body":14279,"category":286,"cover":287,"description":8086,"extension":288,"meta":14426,"navigation":88,"path":8265,"pinned":291,"publishedAt":292,"seo":14427,"slug":8267,"stem":8268,"summary":8269,"tags":14428,"updatedAt":292,"visible":88,"__hash__":8273},{"type":7,"value":14280,"toc":14416},[14281,14283,14285,14287,14289,14293,14295,14297,14305,14307,14309,14365,14367,14372,14374,14376,14388,14390,14396,14398,14408,14410,14412,14414],[10,14282,8086],{},[14,14284,16],{"id":16},[10,14286,8091],{},[14,14288,22],{"id":22},[10,14290,14291],{},[26,14292],{"alt":8098,"src":8099},[10,14294,8102],{},[14,14296,35],{"id":35},[37,14298,14299,14301,14303],{},[40,14300,8109],{},[40,14302,8112],{},[40,14304,8115],{},[14,14306,62],{"id":62},[10,14308,65],{},[67,14310,14311],{"className":69,"code":8122,"language":71,"meta":72,"style":72},[43,14312,14313,14317,14321,14325,14329,14333,14337,14341,14345,14349,14353,14357,14361],{"__ignoreMap":72},[76,14314,14315],{"class":78,"line":79},[76,14316,8129],{},[76,14318,14319],{"class":78,"line":85},[76,14320,8134],{},[76,14322,14323],{"class":78,"line":92},[76,14324,8139],{},[76,14326,14327],{"class":78,"line":98},[76,14328,89],{"emptyLinePlaceholder":88},[76,14330,14331],{"class":78,"line":104},[76,14332,8148],{},[76,14334,14335],{"class":78,"line":110},[76,14336,8153],{},[76,14338,14339],{"class":78,"line":116},[76,14340,8158],{},[76,14342,14343],{"class":78,"line":122},[76,14344,89],{"emptyLinePlaceholder":88},[76,14346,14347],{"class":78,"line":128},[76,14348,8167],{},[76,14350,14351],{"class":78,"line":134},[76,14352,8172],{},[76,14354,14355],{"class":78,"line":140},[76,14356,89],{"emptyLinePlaceholder":88},[76,14358,14359],{"class":78,"line":145},[76,14360,8181],{},[76,14362,14363],{"class":78,"line":151},[76,14364,8186],{},[10,14366,174],{},[67,14368,14370],{"className":14369,"code":8192,"language":180,"meta":72},[178],[43,14371,8192],{"__ignoreMap":72},[10,14373,185],{},[14,14375,188],{"id":188},[190,14377,14378,14384],{},[40,14379,14380,8206,14382,8210],{},[43,14381,8205],{},[43,14383,8209],{},[40,14385,8213,14386,8217],{},[43,14387,8216],{},[14,14389,234],{"id":234},[37,14391,14392,14394],{},[40,14393,8224],{},[40,14395,8227],{},[14,14397,248],{"id":248},[190,14399,14400,14406],{},[40,14401,8234,14402,8238,14404,50],{},[43,14403,8237],{},[43,14405,8241],{},[40,14407,8244],{},[10,14409,263],{},[14,14411,266],{"id":266},[10,14413,8251],{},[271,14415,273],{},{"title":72,"searchDepth":85,"depth":85,"links":14417},[14418,14419,14420,14421,14422,14423,14424,14425],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":8081,"description":8086},[286,8271,8272],{"id":8275,"title":8276,"body":14430,"category":286,"cover":287,"description":8281,"extension":288,"meta":14593,"navigation":88,"path":8485,"pinned":291,"publishedAt":292,"seo":14594,"slug":8487,"stem":8488,"summary":8489,"tags":14595,"updatedAt":292,"visible":88,"__hash__":8493},{"type":7,"value":14431,"toc":14581},[14432,14434,14436,14438,14440,14444,14448,14450,14466,14468,14470,14514,14516,14521,14523,14525,14539,14541,14545,14549,14553,14555,14561,14563,14573,14575,14577,14579],[10,14433,8281],{},[14,14435,16],{"id":16},[10,14437,8286],{},[14,14439,22],{"id":22},[10,14441,14442],{},[26,14443],{"alt":8293,"src":8294},[10,14445,8297,14446,8301],{},[43,14447,8300],{},[14,14449,35],{"id":35},[37,14451,14452,14458,14464],{},[40,14453,14454,8311,14456,8315],{},[43,14455,8310],{},[43,14457,8314],{},[40,14459,8318,14460,8322,14462,8325],{},[43,14461,8321],{},[43,14463,4395],{},[40,14465,8328],{},[14,14467,62],{"id":62},[10,14469,65],{},[67,14471,14472],{"className":69,"code":8335,"language":71,"meta":72,"style":72},[43,14473,14474,14478,14482,14486,14490,14494,14498,14502,14506,14510],{"__ignoreMap":72},[76,14475,14476],{"class":78,"line":79},[76,14477,8342],{},[76,14479,14480],{"class":78,"line":85},[76,14481,8347],{},[76,14483,14484],{"class":78,"line":92},[76,14485,8352],{},[76,14487,14488],{"class":78,"line":98},[76,14489,8357],{},[76,14491,14492],{"class":78,"line":104},[76,14493,8362],{},[76,14495,14496],{"class":78,"line":110},[76,14497,89],{"emptyLinePlaceholder":88},[76,14499,14500],{"class":78,"line":116},[76,14501,8371],{},[76,14503,14504],{"class":78,"line":122},[76,14505,8376],{},[76,14507,14508],{"class":78,"line":128},[76,14509,8376],{},[76,14511,14512],{"class":78,"line":134},[76,14513,8376],{},[10,14515,174],{},[67,14517,14519],{"className":14518,"code":8390,"language":180,"meta":72},[178],[43,14520,8390],{"__ignoreMap":72},[10,14522,185],{},[14,14524,188],{"id":188},[190,14526,14527,14531],{},[40,14528,7981,14529,8404],{},[43,14530,8403],{},[40,14532,8407,14533,8410,14535,8413,14537,8417],{},[43,14534,8314],{},[43,14536,8300],{},[43,14538,8416],{},[213,14540,215],{"id":215},[10,14542,8422,14543,8425],{},[43,14544,8314],{},[10,14546,14547],{},[26,14548],{"alt":8430,"src":8431},[10,14550,8434,14551,8437],{},[43,14552,8300],{},[14,14554,234],{"id":234},[37,14556,14557,14559],{},[40,14558,8444],{},[40,14560,8447],{},[14,14562,248],{"id":248},[190,14564,14565,14567],{},[40,14566,8454],{},[40,14568,4068,14569,8459,14571,8462],{},[43,14570,4395],{},[43,14572,8314],{},[10,14574,263],{},[14,14576,266],{"id":266},[10,14578,8469],{},[271,14580,273],{},{"title":72,"searchDepth":85,"depth":85,"links":14582},[14583,14584,14585,14586,14587,14590,14591,14592],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":14588},[14589],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":8276,"description":8281},[286,8491,8492],{"id":4,"title":5,"body":14597,"category":286,"cover":287,"description":12,"extension":288,"meta":14780,"navigation":88,"path":290,"pinned":291,"publishedAt":292,"seo":14781,"slug":294,"stem":295,"summary":296,"tags":14782,"updatedAt":292,"visible":88,"__hash__":300},{"type":7,"value":14598,"toc":14768},[14599,14601,14603,14605,14607,14611,14613,14615,14629,14631,14633,14701,14703,14708,14710,14712,14726,14728,14730,14734,14740,14742,14750,14752,14760,14762,14764,14766],[10,14600,12],{},[14,14602,16],{"id":16},[10,14604,19],{},[14,14606,22],{"id":22},[10,14608,14609],{},[26,14610],{"alt":28,"src":29},[10,14612,32],{},[14,14614,35],{"id":35},[37,14616,14617,14623,14625],{},[40,14618,14619,46,14621,50],{},[43,14620,45],{},[43,14622,49],{},[40,14624,53],{},[40,14626,14627,59],{},[43,14628,58],{},[14,14630,62],{"id":62},[10,14632,65],{},[67,14634,14635],{"className":69,"code":70,"language":71,"meta":72,"style":72},[43,14636,14637,14641,14645,14649,14653,14657,14661,14665,14669,14673,14677,14681,14685,14689,14693,14697],{"__ignoreMap":72},[76,14638,14639],{"class":78,"line":79},[76,14640,82],{},[76,14642,14643],{"class":78,"line":85},[76,14644,89],{"emptyLinePlaceholder":88},[76,14646,14647],{"class":78,"line":92},[76,14648,95],{},[76,14650,14651],{"class":78,"line":98},[76,14652,101],{},[76,14654,14655],{"class":78,"line":104},[76,14656,107],{},[76,14658,14659],{"class":78,"line":110},[76,14660,113],{},[76,14662,14663],{"class":78,"line":116},[76,14664,119],{},[76,14666,14667],{"class":78,"line":122},[76,14668,125],{},[76,14670,14671],{"class":78,"line":128},[76,14672,131],{},[76,14674,14675],{"class":78,"line":134},[76,14676,137],{},[76,14678,14679],{"class":78,"line":140},[76,14680,89],{"emptyLinePlaceholder":88},[76,14682,14683],{"class":78,"line":145},[76,14684,148],{},[76,14686,14687],{"class":78,"line":151},[76,14688,154],{},[76,14690,14691],{"class":78,"line":157},[76,14692,160],{},[76,14694,14695],{"class":78,"line":163},[76,14696,89],{"emptyLinePlaceholder":88},[76,14698,14699],{"class":78,"line":168},[76,14700,171],{},[10,14702,174],{},[67,14704,14706],{"className":14705,"code":179,"language":180,"meta":72},[178],[43,14707,179],{"__ignoreMap":72},[10,14709,185],{},[14,14711,188],{"id":188},[190,14713,14714,14724],{},[40,14715,194,14716,198,14718,202,14720,206,14722,50],{},[43,14717,197],{},[43,14719,201],{},[43,14721,205],{},[43,14723,197],{},[40,14725,211],{},[213,14727,215],{"id":215},[10,14729,218],{},[10,14731,14732],{},[26,14733],{"alt":223,"src":224},[10,14735,14736,229,14738,50],{},[43,14737,45],{},[43,14739,49],{},[14,14741,234],{"id":234},[37,14743,14744,14748],{},[40,14745,239,14746,50],{},[43,14747,242],{},[40,14749,245],{},[14,14751,248],{"id":248},[190,14753,14754,14756],{},[40,14755,253],{},[40,14757,256,14758,260],{},[43,14759,259],{},[10,14761,263],{},[14,14763,266],{"id":266},[10,14765,269],{},[271,14767,273],{},{"title":72,"searchDepth":85,"depth":85,"links":14769},[14770,14771,14772,14773,14774,14777,14778,14779],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":14775},[14776],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":5,"description":12},[286,298,299],{"id":8682,"title":8683,"body":14784,"category":286,"cover":287,"description":8688,"extension":288,"meta":14943,"navigation":88,"path":8876,"pinned":291,"publishedAt":292,"seo":14944,"slug":8878,"stem":8879,"summary":8880,"tags":14945,"updatedAt":292,"visible":88,"__hash__":8884},{"type":7,"value":14785,"toc":14931},[14786,14788,14790,14792,14794,14798,14800,14802,14810,14812,14814,14878,14880,14885,14887,14889,14897,14899,14901,14905,14907,14909,14915,14917,14923,14925,14927,14929],[10,14787,8688],{},[14,14789,16],{"id":16},[10,14791,8693],{},[14,14793,22],{"id":22},[10,14795,14796],{},[26,14797],{"alt":8700,"src":8701},[10,14799,8704],{},[14,14801,35],{"id":35},[37,14803,14804,14806,14808],{},[40,14805,8711],{},[40,14807,8714],{},[40,14809,8717],{},[14,14811,62],{"id":62},[10,14813,65],{},[67,14815,14816],{"className":69,"code":8724,"language":71,"meta":72,"style":72},[43,14817,14818,14822,14826,14830,14834,14838,14842,14846,14850,14854,14858,14862,14866,14870,14874],{"__ignoreMap":72},[76,14819,14820],{"class":78,"line":79},[76,14821,8731],{},[76,14823,14824],{"class":78,"line":85},[76,14825,8736],{},[76,14827,14828],{"class":78,"line":92},[76,14829,89],{"emptyLinePlaceholder":88},[76,14831,14832],{"class":78,"line":98},[76,14833,8745],{},[76,14835,14836],{"class":78,"line":104},[76,14837,89],{"emptyLinePlaceholder":88},[76,14839,14840],{"class":78,"line":110},[76,14841,8754],{},[76,14843,14844],{"class":78,"line":116},[76,14845,8759],{},[76,14847,14848],{"class":78,"line":122},[76,14849,8764],{},[76,14851,14852],{"class":78,"line":128},[76,14853,89],{"emptyLinePlaceholder":88},[76,14855,14856],{"class":78,"line":134},[76,14857,8773],{},[76,14859,14860],{"class":78,"line":140},[76,14861,8778],{},[76,14863,14864],{"class":78,"line":145},[76,14865,8783],{},[76,14867,14868],{"class":78,"line":151},[76,14869,89],{"emptyLinePlaceholder":88},[76,14871,14872],{"class":78,"line":157},[76,14873,6247],{},[76,14875,14876],{"class":78,"line":163},[76,14877,8796],{},[10,14879,174],{},[67,14881,14883],{"className":14882,"code":8802,"language":180,"meta":72},[178],[43,14884,8802],{"__ignoreMap":72},[10,14886,185],{},[14,14888,188],{"id":188},[190,14890,14891,14895],{},[40,14892,14893,8816],{},[43,14894,8815],{},[40,14896,8819],{},[213,14898,215],{"id":215},[10,14900,8824],{},[10,14902,14903],{},[26,14904],{"alt":8829,"src":8830},[10,14906,8833],{},[14,14908,234],{"id":234},[37,14910,14911,14913],{},[40,14912,8840],{},[40,14914,8843],{},[14,14916,248],{"id":248},[190,14918,14919,14921],{},[40,14920,8850],{},[40,14922,8853],{},[10,14924,263],{},[14,14926,266],{"id":266},[10,14928,8860],{},[271,14930,273],{},{"title":72,"searchDepth":85,"depth":85,"links":14932},[14933,14934,14935,14936,14937,14940,14941,14942],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":14938},[14939],{"id":215,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":8683,"description":8688},[286,8882,8883],{"id":8886,"title":8887,"body":14947,"category":286,"cover":287,"description":8892,"extension":288,"meta":15185,"navigation":88,"path":9193,"pinned":291,"publishedAt":292,"seo":15186,"slug":9195,"stem":9196,"summary":9197,"tags":15187,"updatedAt":292,"visible":88,"__hash__":9201},{"type":7,"value":14948,"toc":15172},[14949,14951,14953,14955,14957,14961,14963,14965,14975,14977,14979,15095,15097,15102,15104,15106,15116,15118,15120,15124,15126,15128,15130,15134,15138,15140,15148,15150,15164,15166,15168,15170],[10,14950,8892],{},[14,14952,16],{"id":16},[10,14954,8897],{},[14,14956,22],{"id":22},[10,14958,14959],{},[26,14960],{"alt":8904,"src":8905},[10,14962,8908],{},[14,14964,35],{"id":35},[37,14966,14967,14969,14971],{},[40,14968,8915],{},[40,14970,8918],{},[40,14972,8921,14973,8925],{},[43,14974,8924],{},[14,14976,62],{"id":62},[10,14978,65],{},[67,14980,14981],{"className":69,"code":8932,"language":71,"meta":72,"style":72},[43,14982,14983,14987,14991,14995,14999,15003,15007,15011,15015,15019,15023,15027,15031,15035,15039,15043,15047,15051,15055,15059,15063,15067,15071,15075,15079,15083,15087,15091],{"__ignoreMap":72},[76,14984,14985],{"class":78,"line":79},[76,14986,7045],{},[76,14988,14989],{"class":78,"line":85},[76,14990,6654],{},[76,14992,14993],{"class":78,"line":92},[76,14994,89],{"emptyLinePlaceholder":88},[76,14996,14997],{"class":78,"line":98},[76,14998,8951],{},[76,15000,15001],{"class":78,"line":104},[76,15002,8956],{},[76,15004,15005],{"class":78,"line":110},[76,15006,8961],{},[76,15008,15009],{"class":78,"line":116},[76,15010,8966],{},[76,15012,15013],{"class":78,"line":122},[76,15014,89],{"emptyLinePlaceholder":88},[76,15016,15017],{"class":78,"line":128},[76,15018,8975],{},[76,15020,15021],{"class":78,"line":134},[76,15022,8980],{},[76,15024,15025],{"class":78,"line":140},[76,15026,8985],{},[76,15028,15029],{"class":78,"line":145},[76,15030,8990],{},[76,15032,15033],{"class":78,"line":151},[76,15034,8995],{},[76,15036,15037],{"class":78,"line":157},[76,15038,89],{"emptyLinePlaceholder":88},[76,15040,15041],{"class":78,"line":163},[76,15042,9004],{},[76,15044,15045],{"class":78,"line":168},[76,15046,9009],{},[76,15048,15049],{"class":78,"line":9012},[76,15050,9015],{},[76,15052,15053],{"class":78,"line":9018},[76,15054,89],{"emptyLinePlaceholder":88},[76,15056,15057],{"class":78,"line":9023},[76,15058,9026],{},[76,15060,15061],{"class":78,"line":9029},[76,15062,89],{"emptyLinePlaceholder":88},[76,15064,15065],{"class":78,"line":9034},[76,15066,7463],{},[76,15068,15069],{"class":78,"line":9039},[76,15070,9042],{},[76,15072,15073],{"class":78,"line":9045},[76,15074,9048],{},[76,15076,15077],{"class":78,"line":9051},[76,15078,9054],{},[76,15080,15081],{"class":78,"line":9057},[76,15082,7473],{},[76,15084,15085],{"class":78,"line":9062},[76,15086,9065],{},[76,15088,15089],{"class":78,"line":9068},[76,15090,1205],{},[76,15092,15093],{"class":78,"line":9073},[76,15094,9076],{},[10,15096,174],{},[67,15098,15100],{"className":15099,"code":9082,"language":180,"meta":72},[178],[43,15101,9082],{"__ignoreMap":72},[10,15103,185],{},[14,15105,188],{"id":188},[190,15107,15108,15112],{},[40,15109,9093,15110,9096],{},[43,15111,8924],{},[40,15113,15114,9101],{},[43,15115,8209],{},[213,15117,215],{"id":215},[10,15119,9106],{},[10,15121,15122],{},[26,15123],{"alt":9111,"src":9112},[10,15125,9115],{},[213,15127,215],{"id":4276},[10,15129,9120],{},[10,15131,15132],{},[26,15133],{"alt":9125,"src":9126},[10,15135,9129,15136,9133],{},[43,15137,9132],{},[14,15139,234],{"id":234},[37,15141,15142,15144],{},[40,15143,9140],{},[40,15145,9143,15146,9146],{},[43,15147,9132],{},[14,15149,248],{"id":248},[190,15151,15152,15156,15158],{},[40,15153,9153,15154,9156],{},[43,15155,9132],{},[40,15157,9159],{},[40,15159,9162,15160,9166,15162,9169],{},[43,15161,9165],{},[43,15163,6191],{},[10,15165,263],{},[14,15167,266],{"id":266},[10,15169,9176],{},[271,15171,273],{},{"title":72,"searchDepth":85,"depth":85,"links":15173},[15174,15175,15176,15177,15178,15182,15183,15184],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":35,"depth":85,"text":35},{"id":62,"depth":85,"text":62},{"id":188,"depth":85,"text":188,"children":15179},[15180,15181],{"id":215,"depth":92,"text":215},{"id":4276,"depth":92,"text":215},{"id":234,"depth":85,"text":234},{"id":248,"depth":85,"text":248},{"id":266,"depth":85,"text":266},{},{"title":8887,"description":8892},[286,9199,9200],{"id":1115,"title":1116,"body":15189,"category":286,"cover":1124,"description":72,"extension":288,"meta":15425,"navigation":88,"path":1441,"pinned":291,"publishedAt":1442,"seo":15426,"slug":1444,"stem":1445,"summary":1446,"tags":15427,"updatedAt":1442,"visible":88,"__hash__":1450},{"type":7,"value":15190,"toc":15410},[15191,15195,15197,15199,15201,15203,15223,15225,15230,15232,15234,15262,15268,15270,15274,15276,15296,15298,15308,15310,15312,15314,15316,15318,15320,15322,15324,15326,15346,15348,15350,15354,15356,15358,15360,15362,15366,15368,15386,15388,15390,15392,15394,15396,15398,15400,15402,15404,15406,15408],[10,15192,15193],{},[26,15194],{"alt":1123,"src":1124},[10,15196,1127],{},[10,15198,1130],{},[14,15200,1134],{"id":1133},[10,15202,1137],{},[67,15204,15205],{"className":69,"code":1140,"language":71,"meta":72,"style":72},[43,15206,15207,15211,15215,15219],{"__ignoreMap":72},[76,15208,15209],{"class":78,"line":79},[76,15210,1147],{},[76,15212,15213],{"class":78,"line":85},[76,15214,1152],{},[76,15216,15217],{"class":78,"line":92},[76,15218,89],{"emptyLinePlaceholder":88},[76,15220,15221],{"class":78,"line":98},[76,15222,1161],{},[10,15224,1164],{},[67,15226,15228],{"className":15227,"code":1168,"language":180,"meta":72},[178],[43,15229,1168],{"__ignoreMap":72},[10,15231,1173],{},[10,15233,1176],{},[67,15235,15236],{"className":69,"code":1179,"language":71,"meta":72,"style":72},[43,15237,15238,15242,15246,15250,15254,15258],{"__ignoreMap":72},[76,15239,15240],{"class":78,"line":79},[76,15241,1186],{},[76,15243,15244],{"class":78,"line":85},[76,15245,89],{"emptyLinePlaceholder":88},[76,15247,15248],{"class":78,"line":92},[76,15249,1195],{},[76,15251,15252],{"class":78,"line":98},[76,15253,1200],{},[76,15255,15256],{"class":78,"line":104},[76,15257,1205],{},[76,15259,15260],{"class":78,"line":110},[76,15261,1210],{},[10,15263,15264,1216,15266,1220],{},[43,15265,1215],{},[43,15267,1219],{},[14,15269,1224],{"id":1223},[10,15271,1227,15272,1231],{},[43,15273,1230],{},[10,15275,1234],{},[67,15277,15278],{"className":69,"code":1237,"language":71,"meta":72,"style":72},[43,15279,15280,15284,15288,15292],{"__ignoreMap":72},[76,15281,15282],{"class":78,"line":79},[76,15283,1244],{},[76,15285,15286],{"class":78,"line":85},[76,15287,1249],{},[76,15289,15290],{"class":78,"line":92},[76,15291,1254],{},[76,15293,15294],{"class":78,"line":98},[76,15295,1259],{},[10,15297,1262],{},[67,15299,15300],{"className":650,"code":1265,"language":652,"meta":72,"style":72},[43,15301,15302],{"__ignoreMap":72},[76,15303,15304,15306],{"class":78,"line":79},[76,15305,750],{"class":659},[76,15307,1274],{"class":695},[10,15309,1277],{},[14,15311,1281],{"id":1280},[213,15313,1284],{"id":1284},[10,15315,1287],{},[213,15317,1290],{"id":1290},[10,15319,1293],{},[213,15321,1296],{"id":1296},[10,15323,1299],{},[10,15325,1302],{},[67,15327,15328],{"className":69,"code":1305,"language":71,"meta":72,"style":72},[43,15329,15330,15334,15338,15342],{"__ignoreMap":72},[76,15331,15332],{"class":78,"line":79},[76,15333,1312],{},[76,15335,15336],{"class":78,"line":85},[76,15337,89],{"emptyLinePlaceholder":88},[76,15339,15340],{"class":78,"line":92},[76,15341,1321],{},[76,15343,15344],{"class":78,"line":98},[76,15345,1326],{},[10,15347,1329],{},[213,15349,1332],{"id":1332},[10,15351,1335,15352,1338],{},[43,15353,321],{},[10,15355,1341],{},[213,15357,1344],{"id":1344},[10,15359,1347],{},[14,15361,1351],{"id":1350},[10,15363,15364],{},[26,15365],{"alt":1356,"src":1357},[10,15367,1360],{},[37,15369,15370,15372,15374,15376,15378,15380,15382,15384],{},[40,15371,1365],{},[40,15373,1368],{},[40,15375,1371],{},[40,15377,1374],{},[40,15379,1377],{},[40,15381,1380],{},[40,15383,1383],{},[40,15385,1386],{},[10,15387,1389],{},[14,15389,1393],{"id":1392},[10,15391,1396],{},[10,15393,1399],{},[14,15395,1403],{"id":1402},[10,15397,1406],{},[10,15399,1409],{},[10,15401,1412],{},[14,15403,1415],{"id":1415},[10,15405,1418],{},[10,15407,1421],{},[271,15409,1424],{},{"title":72,"searchDepth":85,"depth":85,"links":15411},[15412,15413,15414,15421,15422,15423,15424],{"id":1133,"depth":85,"text":1134},{"id":1223,"depth":85,"text":1224},{"id":1280,"depth":85,"text":1281,"children":15415},[15416,15417,15418,15419,15420],{"id":1284,"depth":92,"text":1284},{"id":1290,"depth":92,"text":1290},{"id":1296,"depth":92,"text":1296},{"id":1332,"depth":92,"text":1332},{"id":1344,"depth":92,"text":1344},{"id":1350,"depth":85,"text":1351},{"id":1392,"depth":85,"text":1393},{"id":1402,"depth":85,"text":1403},{"id":1415,"depth":85,"text":1415},{},{"title":1116,"description":72},[286,1448,1449],{"id":303,"title":304,"body":15429,"category":286,"cover":287,"description":72,"extension":288,"meta":16008,"navigation":88,"path":1104,"pinned":291,"publishedAt":1105,"seo":16009,"slug":1107,"stem":1108,"summary":1109,"tags":16010,"updatedAt":1105,"visible":88,"__hash__":1113},{"type":7,"value":15430,"toc":15984},[15431,15433,15435,15437,15441,15443,15445,15469,15481,15483,15485,15490,15494,15498,15510,15514,15518,15522,15524,15558,15560,15564,15568,15570,15592,15622,15634,15644,15652,15654,15660,15670,15672,15677,15681,15683,15697,15703,15723,15725,15727,15729,15739,15743,15745,15754,15758,15760,15762,15782,15786,15788,15790,15792,15794,15814,15816,15818,15820,15846,15848,15864,15866,15882,15886,15888,15890,15910,15912,15914,15916,15920,15930,15932,15934,15936,15946,15954,15956,15958,15972,15982],[14,15432,309],{"id":309},[10,15434,312],{},[10,15436,315],{},[10,15438,318,15439,322],{},[43,15440,321],{},[14,15442,325],{"id":325},[10,15444,328],{},[330,15446,15447,15449],{},[10,15448,334],{},[330,15450,15451,15457,15459,15463,15465],{},[10,15452,339,15453,343,15455,347],{},[43,15454,342],{},[43,15456,346],{},[10,15458,350],{},[10,15460,353,15461,358],{},[355,15462,357],{},[10,15464,361],{},[10,15466,15467],{},[26,15468],{"alt":366,"src":367},[330,15470,15471,15473],{},[10,15472,372],{},[330,15474,15475,15477],{},[10,15476,377],{},[10,15478,15479],{},[26,15480],{"alt":382,"src":383},[14,15482,387],{"id":386},[213,15484,391],{"id":390},[10,15486,394,15487,402],{},[396,15488,401],{"href":398,"rel":15489},[400],[330,15491,15492],{},[10,15493,407],{},[10,15495,15496],{},[26,15497],{"alt":412,"src":413},[37,15499,15500,15504,15508],{},[40,15501,418,15502,50],{},[355,15503,421],{},[40,15505,424,15506,50],{},[355,15507,427],{},[40,15509,430],{},[10,15511,15512],{},[26,15513],{"alt":435,"src":436},[330,15515,15516],{},[10,15517,441],{},[10,15519,15520],{},[26,15521],{"alt":446,"src":447},[213,15523,451],{"id":450},[330,15525,15526,15530,15534,15554],{},[330,15527,15528],{},[10,15529,458],{},[10,15531,461,15532,465],{},[355,15533,464],{},[67,15535,15536],{"className":69,"code":468,"language":71,"meta":72,"style":72},[43,15537,15538,15542,15546,15550],{"__ignoreMap":72},[76,15539,15540],{"class":78,"line":79},[76,15541,475],{},[76,15543,15544],{"class":78,"line":85},[76,15545,480],{},[76,15547,15548],{"class":78,"line":92},[76,15549,485],{},[76,15551,15552],{"class":78,"line":98},[76,15553,490],{},[10,15555,493,15556,497],{},[355,15557,496],{},[10,15559,500],{},[10,15561,503,15562,506],{},[43,15563,71],{},[10,15565,15566],{},[26,15567],{"alt":511,"src":512},[10,15569,515],{},[330,15571,15572,15574,15578],{},[10,15573,520],{},[10,15575,15576],{},[355,15577,525],{},[330,15579,15580,15584,15588],{},[10,15581,530,15582,533],{},[43,15583,71],{},[10,15585,536,15586,539],{},[43,15587,71],{},[10,15589,542,15590,546],{},[355,15591,545],{},[330,15593,15594,15596,15600],{},[10,15595,551],{},[10,15597,15598],{},[355,15599,556],{},[330,15601,15602,15608,15616,15618],{},[10,15603,15604,564,15606,568],{},[43,15605,563],{},[43,15607,567],{},[10,15609,571,15610,574,15612,578,15614,582],{},[43,15611,563],{},[355,15613,577],{},[355,15615,581],{},[10,15617,585],{},[10,15619,15620,591],{},[355,15621,590],{},[330,15623,15624,15626],{},[10,15625,596],{},[330,15627,15628,15632],{},[10,15629,601,15630,605],{},[355,15631,604],{},[10,15633,608],{},[330,15635,15636,15640],{},[10,15637,613,15638],{},[355,15639,616],{},[10,15641,15642],{},[26,15643],{"alt":621,"src":622},[330,15645,15646,15648],{},[10,15647,627],{},[10,15649,15650],{},[26,15651],{"alt":621,"src":632},[213,15653,636],{"id":635},[10,15655,639,15656,643,15658,647],{},[43,15657,642],{},[43,15659,646],{},[67,15661,15662],{"className":650,"code":651,"language":652,"meta":72,"style":72},[43,15663,15664],{"__ignoreMap":72},[76,15665,15666,15668],{"class":78,"line":79},[76,15667,71],{"class":659},[76,15669,663],{"class":662},[10,15671,666],{},[67,15673,15675],{"className":15674,"code":670,"language":180,"meta":72},[178],[43,15676,670],{"__ignoreMap":72},[10,15678,15679],{},[26,15680],{"alt":621,"src":677},[10,15682,680],{},[67,15684,15685],{"className":650,"code":683,"language":652,"meta":72,"style":72},[43,15686,15687],{"__ignoreMap":72},[76,15688,15689,15691,15693,15695],{"class":78,"line":79},[76,15690,71],{"class":659},[76,15692,692],{"class":662},[76,15694,696],{"class":695},[76,15696,663],{"class":662},[10,15698,701,15699,704,15701,708],{},[43,15700,71],{},[43,15702,707],{},[67,15704,15705],{"className":650,"code":711,"language":652,"meta":72,"style":72},[43,15706,15707,15713],{"__ignoreMap":72},[76,15708,15709,15711],{"class":78,"line":79},[76,15710,567],{"class":659},[76,15712,663],{"class":662},[76,15714,15715,15717,15719,15721],{"class":78,"line":85},[76,15716,567],{"class":659},[76,15718,692],{"class":662},[76,15720,696],{"class":695},[76,15722,663],{"class":662},[14,15724,733],{"id":732},[213,15726,737],{"id":736},[10,15728,740],{},[67,15730,15731],{"className":650,"code":743,"language":652,"meta":72,"style":72},[43,15732,15733],{"__ignoreMap":72},[76,15734,15735,15737],{"class":78,"line":79},[76,15736,750],{"class":659},[76,15738,663],{"class":662},[10,15740,755,15741,759],{},[43,15742,758],{},[213,15744,763],{"id":762},[10,15746,394,15747,771,15750,50,15752,778],{},[396,15748,770],{"href":768,"rel":15749},[400],[355,15751,774],{},[43,15753,777],{},[10,15755,781,15756,785],{},[43,15757,784],{},[213,15759,789],{"id":788},[10,15761,792],{},[67,15763,15764],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,15765,15766,15772],{"__ignoreMap":72},[76,15767,15768,15770],{"class":78,"line":79},[76,15769,750],{"class":659},[76,15771,663],{"class":662},[76,15773,15774,15776,15778,15780],{"class":78,"line":85},[76,15775,750],{"class":659},[76,15777,692],{"class":662},[76,15779,696],{"class":695},[76,15781,663],{"class":662},[10,15783,816,15784,819],{},[43,15785,750],{},[14,15787,823],{"id":822},[10,15789,826],{},[213,15791,830],{"id":829},[10,15793,833],{},[67,15795,15796],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,15797,15798,15804],{"__ignoreMap":72},[76,15799,15800,15802],{"class":78,"line":79},[76,15801,750],{"class":659},[76,15803,663],{"class":662},[76,15805,15806,15808,15810,15812],{"class":78,"line":85},[76,15807,750],{"class":659},[76,15809,692],{"class":662},[76,15811,696],{"class":695},[76,15813,663],{"class":662},[10,15815,856],{},[213,15817,860],{"id":859},[10,15819,863],{},[67,15821,15822],{"className":650,"code":866,"language":652,"meta":72,"style":72},[43,15823,15824,15832],{"__ignoreMap":72},[76,15825,15826,15828,15830],{"class":78,"line":79},[76,15827,873],{"class":659},[76,15829,876],{"class":695},[76,15831,879],{"class":695},[76,15833,15834,15836,15838,15840,15842,15844],{"class":78,"line":85},[76,15835,873],{"class":659},[76,15837,876],{"class":695},[76,15839,888],{"class":695},[76,15841,891],{"class":695},[76,15843,894],{"class":695},[76,15845,897],{"class":695},[10,15847,900],{},[67,15849,15850],{"className":650,"code":903,"language":652,"meta":72,"style":72},[43,15851,15852],{"__ignoreMap":72},[76,15853,15854,15856,15858,15860,15862],{"class":78,"line":79},[76,15855,873],{"class":659},[76,15857,912],{"class":695},[76,15859,888],{"class":695},[76,15861,891],{"class":695},[76,15863,919],{"class":695},[10,15865,922],{},[67,15867,15868],{"className":650,"code":925,"language":652,"meta":72,"style":72},[43,15869,15870],{"__ignoreMap":72},[76,15871,15872,15874,15876,15878,15880],{"class":78,"line":79},[76,15873,873],{"class":659},[76,15875,934],{"class":695},[76,15877,937],{"class":662},[76,15879,940],{"class":695},[76,15881,943],{"class":695},[10,15883,15884,948],{},[43,15885,873],{},[213,15887,952],{"id":951},[10,15889,955],{},[67,15891,15892],{"className":650,"code":795,"language":652,"meta":72,"style":72},[43,15893,15894,15900],{"__ignoreMap":72},[76,15895,15896,15898],{"class":78,"line":79},[76,15897,750],{"class":659},[76,15899,663],{"class":662},[76,15901,15902,15904,15906,15908],{"class":78,"line":85},[76,15903,750],{"class":659},[76,15905,692],{"class":662},[76,15907,696],{"class":695},[76,15909,663],{"class":662},[10,15911,978],{},[14,15913,981],{"id":981},[213,15915,985],{"id":984},[10,15917,988,15918,992],{},[43,15919,991],{},[190,15921,15922,15926,15928],{},[40,15923,997,15924,1000],{},[43,15925,707],{},[40,15927,1003],{},[40,15929,1006],{},[10,15931,1009],{},[213,15933,1013],{"id":1012},[10,15935,1016],{},[67,15937,15938],{"className":650,"code":743,"language":652,"meta":72,"style":72},[43,15939,15940],{"__ignoreMap":72},[76,15941,15942,15944],{"class":78,"line":79},[76,15943,750],{"class":659},[76,15945,663],{"class":662},[10,15947,1029,15948,1032,15950,1035,15952,50],{},[43,15949,750],{},[43,15951,71],{},[43,15953,750],{},[213,15955,1041],{"id":1040},[10,15957,1044],{},[67,15959,15960],{"className":650,"code":1047,"language":652,"meta":72,"style":72},[43,15961,15962],{"__ignoreMap":72},[76,15963,15964,15966,15968,15970],{"class":78,"line":79},[76,15965,750],{"class":659},[76,15967,692],{"class":662},[76,15969,696],{"class":695},[76,15971,663],{"class":662},[10,15973,1062,15974,1065,15976,1068,15978,1071,15980,1075],{},[43,15975,750],{},[43,15977,71],{},[43,15979,567],{},[43,15981,1074],{},[271,15983,1078],{},{"title":72,"searchDepth":85,"depth":85,"links":15985},[15986,15987,15988,15993,15998,16003],{"id":309,"depth":85,"text":309},{"id":325,"depth":85,"text":325},{"id":386,"depth":85,"text":387,"children":15989},[15990,15991,15992],{"id":390,"depth":92,"text":391},{"id":450,"depth":92,"text":451},{"id":635,"depth":92,"text":636},{"id":732,"depth":85,"text":733,"children":15994},[15995,15996,15997],{"id":736,"depth":92,"text":737},{"id":762,"depth":92,"text":763},{"id":788,"depth":92,"text":789},{"id":822,"depth":85,"text":823,"children":15999},[16000,16001,16002],{"id":829,"depth":92,"text":830},{"id":859,"depth":92,"text":860},{"id":951,"depth":92,"text":952},{"id":981,"depth":85,"text":981,"children":16004},[16005,16006,16007],{"id":984,"depth":92,"text":985},{"id":1012,"depth":92,"text":1013},{"id":1040,"depth":92,"text":1041},{},{"title":304,"description":72},[286,1111,1112],1786973366426]