[{"data":1,"prerenderedAt":15971},["ShallowReactive",2],{"post-python-json-data":3,"sidebar-posts":238,"post-related-source":9162},{"id":4,"title":5,"body":6,"category":223,"cover":224,"description":12,"extension":225,"meta":226,"navigation":88,"path":227,"pinned":228,"publishedAt":229,"seo":230,"slug":231,"stem":232,"summary":233,"tags":234,"updatedAt":229,"visible":88,"__hash__":237},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":8,"toc":213},"minimark",[9,13,17,20,23,30,41,44,60,63,66,148,151,159,162,165,178,181,189,192,200,203,206,209],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,15,16],"h2",{"id":16},"本篇要解决的问题",[10,18,19],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,21,22],{"id":22},"先看清一个容易误解的细节",[10,24,25],{},[26,27],"img",{"alt":28,"src":29},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,31,32,36,37,40],{},[33,34,35],"code",{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[33,38,39],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,42,43],{"id":43},"核心概念",[45,46,47,51,57],"ul",{},[48,49,50],"li",{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[48,52,53,56],{},[33,54,55],{},"ensure_ascii=False"," 让中文以可读字符写入。",[48,58,59],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[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","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","python","",[33,74,75,83,90,96,101,107,113,119,124,130,136,142],{"__ignoreMap":72},[76,77,80],"span",{"class":78,"line":79},"line",1,[76,81,82],{},"import json\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],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[76,97,99],{"class":78,"line":98},4,[76,100,89],{"emptyLinePlaceholder":88},[76,102,104],{"class":78,"line":103},5,[76,105,106],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[76,108,110],{"class":78,"line":109},6,[76,111,112],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[76,114,116],{"class":78,"line":115},7,[76,117,118],{},"writer.close()\n",[76,120,122],{"class":78,"line":121},8,[76,123,89],{"emptyLinePlaceholder":88},[76,125,127],{"class":78,"line":126},9,[76,128,129],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[76,131,133],{"class":78,"line":132},10,[76,134,135],{},"loaded = json.load(reader)\n",[76,137,139],{"class":78,"line":138},11,[76,140,141],{},"reader.close()\n",[76,143,145],{"class":78,"line":144},12,[76,146,147],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,149,150],{},"预期结果：",[67,152,157],{"className":153,"code":155,"language":156,"meta":72},[154],"language-text","Python 60\n","text",[33,158,155],{"__ignoreMap":72},[10,160,161],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,163,164],{"id":164},"按执行顺序拆开看",[166,167,168,173],"ol",{},[48,169,170,172],{},[33,171,35],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[48,174,175,177],{},[33,176,39],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,179,180],{"id":180},"初学者容易混淆的地方",[45,182,183,186],{},[48,184,185],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[48,187,188],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,190,191],{"id":191},"练习",[166,193,194,197],{},[48,195,196],{},"保存包含两条学习记录的列表。",[48,198,199],{},"读取后修改进度，再重新写回文件。",[10,201,202],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,204,205],{"id":205},"本篇边界",[10,207,208],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,211,212],"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":214},[215,216,217,218,219,220,221,222],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F31-python-json-data",false,"2026-08-17",{"title":5,"description":12},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[223,235,236],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",[239,1053,1390,1524,1676,1855,2043,2208,2392,2573,2766,2997,3181,3358,3515,3686,3851,4065,4293,4475,4639,4828,5016,5171,5331,5528,5725,5937,6104,6348,6529,6734,6927,7074,7275,7565,7757,7986,8181,8401,8641,8845],{"id":240,"title":241,"body":242,"category":223,"cover":224,"description":72,"extension":225,"meta":1042,"navigation":88,"path":1043,"pinned":228,"publishedAt":1044,"seo":1045,"slug":1046,"stem":1047,"summary":1048,"tags":1049,"updatedAt":1044,"visible":88,"__hash__":1052},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":243,"toc":1018},[244,247,250,253,260,263,266,305,321,325,330,341,346,352,370,376,381,387,391,437,440,446,452,455,486,531,548,562,572,576,587,603,606,612,617,620,638,648,669,673,677,680,692,699,703,718,725,729,732,753,759,763,766,770,773,793,796,800,803,837,840,859,862,883,888,892,895,915,918,921,925,932,946,949,953,956,966,977,981,984,999,1015],[14,245,246],{"id":246},"引言",[10,248,249],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,251,252],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,254,255,256,259],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[33,257,258],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,261,262],{"id":262},"扫盲",[10,264,265],{},"那么这里有几个概念：",[267,268,269,272],"blockquote",{},[10,270,271],{},"为什么需要安装python解释器？",[267,273,274,285,288,296,299],{},[10,275,276,277,280,281,284],{},"我们写的代码，电脑其实看不懂，电脑只认识",[33,278,279],{},"0","和",[33,282,283],{},"1","组成的机器指令。",[10,286,287],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,289,290,291,295],{},"这样，我们就能用",[292,293,294],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,297,298],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,300,301],{},[26,302],{"alt":303,"src":304},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[267,306,307,310],{},[10,308,309],{},"pip又是什么？",[267,311,312,315],{},[10,313,314],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,316,317],{},[26,318],{"alt":319,"src":320},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,322,324],{"id":323},"windows-安装","Windows 安装",[326,327,329],"h3",{"id":328},"_1-下载官方安装程序","1. 下载官方安装程序",[10,331,332,333,340],{},"打开 ",[334,335,339],"a",{"href":336,"rel":337},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[338],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[267,342,343],{},[10,344,345],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,347,348],{},[26,349],{"alt":350,"src":351},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[45,353,354,361,367],{},[48,355,356,357,360],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[292,358,359],{},"Windows installer (64-bit)","。",[48,362,363,364,360],{},"搭载 ARM 处理器的 Windows 设备选择 ",[292,365,366],{},"Windows installer (ARM64)",[48,368,369],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,371,372],{},[26,373],{"alt":374,"src":375},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[267,377,378],{},[10,379,380],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,382,383],{},[26,384],{"alt":385,"src":386},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[326,388,390],{"id":389},"_2-安装并加入-path","2. 安装并加入 PATH",[267,392,393,398,405,430],{},[267,394,395],{},[10,396,397],{},"PATH 环境变量",[10,399,400,401,404],{},"Windows 有一个特殊的变量叫 ",[292,402,403],{},"PATH","，它里面存了一串文件夹路径，比如：",[67,406,408],{"className":69,"code":407,"language":71,"meta":72,"style":72},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[33,409,410,415,420,425],{"__ignoreMap":72},[76,411,412],{"class":78,"line":79},[76,413,414],{},"D:\\Python313\\\n",[76,416,417],{"class":78,"line":85},[76,418,419],{},"D:\\Python313\\Scripts\\\n",[76,421,422],{"class":78,"line":92},[76,423,424],{},"C:\\Windows\\System32\\\n",[76,426,427],{"class":78,"line":98},[76,428,429],{},"...\n",[10,431,432,433,436],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[292,434,435],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,438,439],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,441,442,443,445],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[33,444,71],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,447,448],{},[26,449],{"alt":450,"src":451},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,453,454],{},"对安装界面最底部的两个勾选项分别解释 :",[267,456,457,460,465],{},[10,458,459],{},"Add python.exe to PATH",[10,461,462],{},[292,463,464],{},"把 Python 添加到系统环境变量",[267,466,467,473,479],{},[10,468,469,470,472],{},"勾选后，你可以在命令行任意位置直接输入 ",[33,471,71],{}," 就能运行",[10,474,475,476,478],{},"不勾选的话，命令行输入 ",[33,477,71],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,480,481,482,485],{},"必须",[292,483,484],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[267,487,488,491,496],{},[10,489,490],{},"Use admin privileges when installing py.exe",[10,492,493],{},[292,494,495],{},"使用管理员权限安装 py.exe（Python 启动器）",[267,497,498,508,522,525],{},[10,499,500,503,504,507],{},[33,501,502],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[33,505,506],{},"py"," 来启动 Python。",[10,509,510,511,513,514,517,518,521],{},"勾选后，",[33,512,502],{}," 会安装到",[292,515,516],{},"系统级目录","，电脑上",[292,519,520],{},"所有用户账户","都能用",[10,523,524],{},"不勾选，只有当前用户能用",[10,526,527,530],{},[292,528,529],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[267,532,533,536],{},[10,534,535],{},"操作建议",[267,537,538,545],{},[10,539,540,541,544],{},"两个都勾上之后，再点 ",[292,542,543],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,546,547],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[267,549,550,556],{},[10,551,552,553],{},"Python 安装的",[292,554,555],{},"可选功能页",[10,557,558],{},[26,559],{"alt":560,"src":561},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[267,563,564,567],{},[10,565,566],{},"高级选项页",[10,568,569],{},[26,570],{"alt":560,"src":571},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[326,573,575],{"id":574},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,577,578,579,582,583,586],{},"按 ",[33,580,581],{},"Win + R","，输入 ",[33,584,585],{},"cmd"," 并回车，然后执行：",[67,588,592],{"className":589,"code":590,"language":591,"meta":72,"style":72},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[33,593,594],{"__ignoreMap":72},[76,595,596,599],{"class":78,"line":79},[76,597,71],{"class":598},"svObZ",[76,600,602],{"class":601},"sDLfK"," --version\n",[10,604,605],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[67,607,610],{"className":608,"code":609,"language":156,"meta":72},[154],"Python 3.x.x\n",[33,611,609],{"__ignoreMap":72},[10,613,614],{},[26,615],{"alt":560,"src":616},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,618,619],{},"继续检查 pip：",[67,621,623],{"className":589,"code":622,"language":591,"meta":72,"style":72},"python -m pip --version\n",[33,624,625],{"__ignoreMap":72},[76,626,627,629,632,636],{"class":78,"line":79},[76,628,71],{"class":598},[76,630,631],{"class":601}," -m",[76,633,635],{"class":634},"sU2Wk"," pip",[76,637,602],{"class":601},[10,639,640,641,643,644,647],{},"如果 ",[33,642,71],{}," 无法识别，但 ",[33,645,646],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[67,649,651],{"className":589,"code":650,"language":591,"meta":72,"style":72},"py --version\npy -m pip --version\n",[33,652,653,659],{"__ignoreMap":72},[76,654,655,657],{"class":78,"line":79},[76,656,506],{"class":598},[76,658,602],{"class":601},[76,660,661,663,665,667],{"class":78,"line":85},[76,662,506],{"class":598},[76,664,631],{"class":601},[76,666,635],{"class":634},[76,668,602],{"class":601},[14,670,672],{"id":671},"macos-安装","macOS 安装",[326,674,676],{"id":675},"_1-先检查现有环境","1. 先检查现有环境",[10,678,679],{},"打开“终端”应用，执行：",[67,681,683],{"className":589,"code":682,"language":591,"meta":72,"style":72},"python3 --version\n",[33,684,685],{"__ignoreMap":72},[76,686,687,690],{"class":78,"line":79},[76,688,689],{"class":598},"python3",[76,691,602],{"class":601},[10,693,694,695,698],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[33,696,697],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[326,700,702],{"id":701},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,704,332,705,710,711,360,714,717],{},[334,706,709],{"href":707,"rel":708},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[338],"Python macOS 下载页","，下载当前稳定版的 ",[292,712,713],{},"macOS 64-bit universal2 installer",[33,715,716],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,719,720,721,724],{},"下载完成后打开 ",[33,722,723],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[326,726,728],{"id":727},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,730,731],{},"安装完成后重新打开终端，执行：",[67,733,735],{"className":589,"code":734,"language":591,"meta":72,"style":72},"python3 --version\npython3 -m pip --version\n",[33,736,737,743],{"__ignoreMap":72},[76,738,739,741],{"class":78,"line":79},[76,740,689],{"class":598},[76,742,602],{"class":601},[76,744,745,747,749,751],{"class":78,"line":85},[76,746,689],{"class":598},[76,748,631],{"class":601},[76,750,635],{"class":634},[76,752,602],{"class":601},[10,754,755,756,758],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[33,757,689],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,760,762],{"id":761},"linux-安装","Linux 安装",[10,764,765],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[326,767,769],{"id":768},"_1-检查是否已经安装","1. 检查是否已经安装",[10,771,772],{},"打开终端，执行：",[67,774,775],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,776,777,783],{"__ignoreMap":72},[76,778,779,781],{"class":78,"line":79},[76,780,689],{"class":598},[76,782,602],{"class":601},[76,784,785,787,789,791],{"class":78,"line":85},[76,786,689],{"class":598},[76,788,631],{"class":601},[76,790,635],{"class":634},[76,792,602],{"class":601},[10,794,795],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[326,797,799],{"id":798},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,801,802],{},"Ubuntu 或 Debian：",[67,804,806],{"className":589,"code":805,"language":591,"meta":72,"style":72},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[33,807,808,819],{"__ignoreMap":72},[76,809,810,813,816],{"class":78,"line":79},[76,811,812],{"class":598},"sudo",[76,814,815],{"class":634}," apt",[76,817,818],{"class":634}," update\n",[76,820,821,823,825,828,831,834],{"class":78,"line":85},[76,822,812],{"class":598},[76,824,815],{"class":634},[76,826,827],{"class":634}," install",[76,829,830],{"class":634}," python3",[76,832,833],{"class":634}," python3-pip",[76,835,836],{"class":634}," python3-venv\n",[10,838,839],{},"Fedora：",[67,841,843],{"className":589,"code":842,"language":591,"meta":72,"style":72},"sudo dnf install python3 python3-pip\n",[33,844,845],{"__ignoreMap":72},[76,846,847,849,852,854,856],{"class":78,"line":79},[76,848,812],{"class":598},[76,850,851],{"class":634}," dnf",[76,853,827],{"class":634},[76,855,830],{"class":634},[76,857,858],{"class":634}," python3-pip\n",[10,860,861],{},"Arch Linux：",[67,863,865],{"className":589,"code":864,"language":591,"meta":72,"style":72},"sudo pacman -S python python-pip\n",[33,866,867],{"__ignoreMap":72},[76,868,869,871,874,877,880],{"class":78,"line":79},[76,870,812],{"class":598},[76,872,873],{"class":634}," pacman",[76,875,876],{"class":601}," -S",[76,878,879],{"class":634}," python",[76,881,882],{"class":634}," python-pip\n",[10,884,885,887],{},[33,886,812],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[326,889,891],{"id":890},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,893,894],{},"安装结束后执行：",[67,896,897],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,898,899,905],{"__ignoreMap":72},[76,900,901,903],{"class":78,"line":79},[76,902,689],{"class":598},[76,904,602],{"class":601},[76,906,907,909,911,913],{"class":78,"line":85},[76,908,689],{"class":598},[76,910,631],{"class":601},[76,912,635],{"class":634},[76,914,602],{"class":601},[10,916,917],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,919,920],{"id":920},"常见问题",[326,922,924],{"id":923},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,926,927,928,931],{},"先关闭当前命令提示符并重新打开，再执行 ",[33,929,930],{},"python --version","。如果仍然失败，按下面的顺序检查：",[166,933,934,940,943],{},[48,935,936,937,939],{},"执行 ",[33,938,646],{},"，确认 Python Launcher 是否可用。",[48,941,942],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[48,944,945],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,947,948],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[326,950,952],{"id":951},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,954,955],{},"先尝试：",[67,957,958],{"className":589,"code":682,"language":591,"meta":72,"style":72},[33,959,960],{"__ignoreMap":72},[76,961,962,964],{"class":78,"line":79},[76,963,689],{"class":598},[76,965,602],{"class":601},[10,967,968,969,971,972,974,975,360],{},"在这两个系统中，只有 ",[33,970,689],{}," 命令而没有 ",[33,973,71],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[33,976,689],{},[326,978,980],{"id":979},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,982,983],{},"先使用模块方式检查：",[67,985,987],{"className":589,"code":986,"language":591,"meta":72,"style":72},"python3 -m pip --version\n",[33,988,989],{"__ignoreMap":72},[76,990,991,993,995,997],{"class":78,"line":79},[76,992,689],{"class":598},[76,994,631],{"class":601},[76,996,635],{"class":634},[76,998,602],{"class":601},[10,1000,1001,1002,1004,1005,1007,1008,1010,1011,1014],{},"Windows 用户将命令中的 ",[33,1003,689],{}," 换成 ",[33,1006,71],{}," 或 ",[33,1009,506],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[33,1012,1013],{},"python3-pip","；不要直接使用其他系统的安装命令。",[210,1016,1017],{},"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":1019},[1020,1021,1022,1027,1032,1037],{"id":246,"depth":85,"text":246},{"id":262,"depth":85,"text":262},{"id":323,"depth":85,"text":324,"children":1023},[1024,1025,1026],{"id":328,"depth":92,"text":329},{"id":389,"depth":92,"text":390},{"id":574,"depth":92,"text":575},{"id":671,"depth":85,"text":672,"children":1028},[1029,1030,1031],{"id":675,"depth":92,"text":676},{"id":701,"depth":92,"text":702},{"id":727,"depth":92,"text":728},{"id":761,"depth":85,"text":762,"children":1033},[1034,1035,1036],{"id":768,"depth":92,"text":769},{"id":798,"depth":92,"text":799},{"id":890,"depth":92,"text":891},{"id":920,"depth":85,"text":920,"children":1038},[1039,1040,1041],{"id":923,"depth":92,"text":924},{"id":951,"depth":92,"text":952},{"id":979,"depth":92,"text":980},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":241,"description":72},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[223,1050,1051],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1054,"title":1055,"body":1056,"category":223,"cover":1063,"description":72,"extension":225,"meta":1379,"navigation":88,"path":1380,"pinned":228,"publishedAt":1381,"seo":1382,"slug":1383,"stem":1384,"summary":1385,"tags":1386,"updatedAt":1381,"visible":88,"__hash__":1389},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1057,"toc":1364},[1058,1064,1067,1070,1074,1077,1101,1104,1110,1113,1116,1150,1160,1164,1171,1174,1199,1202,1214,1217,1221,1224,1227,1230,1233,1236,1239,1242,1266,1269,1272,1278,1281,1284,1287,1291,1297,1300,1326,1329,1333,1336,1339,1343,1346,1349,1352,1355,1358,1361],[10,1059,1060],{},[26,1061],{"alt":1062,"src":1063},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1065,1066],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1068,1069],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1071,1073],{"id":1072},"python-代码是什么样的","Python 代码是什么样的",[10,1075,1076],{},"下面是一段简单的 Python 代码：",[67,1078,1080],{"className":69,"code":1079,"language":71,"meta":72,"style":72},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[33,1081,1082,1087,1092,1096],{"__ignoreMap":72},[76,1083,1084],{"class":78,"line":79},[76,1085,1086],{},"name = \"Python\"\n",[76,1088,1089],{"class":78,"line":85},[76,1090,1091],{},"year = 2026\n",[76,1093,1094],{"class":78,"line":92},[76,1095,89],{"emptyLinePlaceholder":88},[76,1097,1098],{"class":78,"line":98},[76,1099,1100],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1102,1103],{},"运行结果：",[67,1105,1108],{"className":1106,"code":1107,"language":156,"meta":72},[154],"正在学习 Python，当前年份是 2026\n",[33,1109,1107],{"__ignoreMap":72},[10,1111,1112],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1114,1115],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[67,1117,1119],{"className":69,"code":1118,"language":71,"meta":72,"style":72},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[33,1120,1121,1126,1130,1135,1140,1145],{"__ignoreMap":72},[76,1122,1123],{"class":78,"line":79},[76,1124,1125],{},"score = 85\n",[76,1127,1128],{"class":78,"line":85},[76,1129,89],{"emptyLinePlaceholder":88},[76,1131,1132],{"class":78,"line":92},[76,1133,1134],{},"if score >= 60:\n",[76,1136,1137],{"class":78,"line":98},[76,1138,1139],{},"    print(\"成绩合格\")\n",[76,1141,1142],{"class":78,"line":103},[76,1143,1144],{},"else:\n",[76,1146,1147],{"class":78,"line":109},[76,1148,1149],{},"    print(\"需要继续学习\")\n",[10,1151,1152,1155,1156,1159],{},[33,1153,1154],{},"if"," 和 ",[33,1157,1158],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1161,1163],{"id":1162},"python-如何运行代码","Python 如何运行代码",[10,1165,1166,1167,1170],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[33,1168,1169],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1172,1173],{},"交互式环境适合快速验证一个表达式：",[67,1175,1177],{"className":69,"code":1176,"language":71,"meta":72,"style":72},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[33,1178,1179,1184,1189,1194],{"__ignoreMap":72},[76,1180,1181],{"class":78,"line":79},[76,1182,1183],{},">>> 10 + 20\n",[76,1185,1186],{"class":78,"line":85},[76,1187,1188],{},"30\n",[76,1190,1191],{"class":78,"line":92},[76,1192,1193],{},">>> \"Python\".lower()\n",[76,1195,1196],{"class":78,"line":98},[76,1197,1198],{},"'python'\n",[10,1200,1201],{},"需要保存和重复运行的程序，则可以写入文件：",[67,1203,1205],{"className":589,"code":1204,"language":591,"meta":72,"style":72},"python3 hello.py\n",[33,1206,1207],{"__ignoreMap":72},[76,1208,1209,1211],{"class":78,"line":79},[76,1210,689],{"class":598},[76,1212,1213],{"class":634}," hello.py\n",[10,1215,1216],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1218,1220],{"id":1219},"python-的特点","Python 的特点",[326,1222,1223],{"id":1223},"语法相对简洁",[10,1225,1226],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[326,1228,1229],{"id":1229},"支持多种编程方式",[10,1231,1232],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[326,1234,1235],{"id":1235},"标准库比较完整",[10,1237,1238],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1240,1241],{},"例如，获取当前时间：",[67,1243,1245],{"className":69,"code":1244,"language":71,"meta":72,"style":72},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[33,1246,1247,1252,1256,1261],{"__ignoreMap":72},[76,1248,1249],{"class":78,"line":79},[76,1250,1251],{},"from datetime import datetime\n",[76,1253,1254],{"class":78,"line":85},[76,1255,89],{"emptyLinePlaceholder":88},[76,1257,1258],{"class":78,"line":92},[76,1259,1260],{},"now = datetime.now()\n",[76,1262,1263],{"class":78,"line":98},[76,1264,1265],{},"print(now)\n",[10,1267,1268],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[326,1270,1271],{"id":1271},"第三方工具丰富",[10,1273,1274,1275,1277],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[33,1276,258],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1279,1280],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[326,1282,1283],{"id":1283},"支持多个操作系统",[10,1285,1286],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1288,1290],{"id":1289},"python-可以做什么","Python 可以做什么",[10,1292,1293],{},[26,1294],{"alt":1295,"src":1296},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1298,1299],{},"Python 的应用范围比较广，常见方向包括：",[45,1301,1302,1305,1308,1311,1314,1317,1320,1323],{},[48,1303,1304],{},"编写自动化脚本，批量处理文件和重复任务；",[48,1306,1307],{},"开发网站后端和 API 服务；",[48,1309,1310],{},"进行数据清洗、统计分析和图表展示；",[48,1312,1313],{},"编写网络爬虫和信息采集工具；",[48,1315,1316],{},"开发自动化测试程序；",[48,1318,1319],{},"进行机器学习和人工智能开发；",[48,1321,1322],{},"编写运维、监控和辅助开发工具；",[48,1324,1325],{},"开发部分桌面应用和插件。",[10,1327,1328],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1330,1332],{"id":1331},"python-的发展","Python 的发展",[10,1334,1335],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1337,1338],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1340,1342],{"id":1341},"python-也有局限","Python 也有局限",[10,1344,1345],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1347,1348],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1350,1351],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1353,1354],{"id":1354},"写在最后",[10,1356,1357],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1359,1360],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[210,1362,1363],{},"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":1365},[1366,1367,1368,1375,1376,1377,1378],{"id":1072,"depth":85,"text":1073},{"id":1162,"depth":85,"text":1163},{"id":1219,"depth":85,"text":1220,"children":1369},[1370,1371,1372,1373,1374],{"id":1223,"depth":92,"text":1223},{"id":1229,"depth":92,"text":1229},{"id":1235,"depth":92,"text":1235},{"id":1271,"depth":92,"text":1271},{"id":1283,"depth":92,"text":1283},{"id":1289,"depth":85,"text":1290},{"id":1331,"depth":85,"text":1332},{"id":1341,"depth":85,"text":1342},{"id":1354,"depth":85,"text":1354},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1055,"description":72},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[223,1387,1388],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1391,"title":1392,"body":1393,"category":223,"cover":224,"description":1397,"extension":225,"meta":1515,"navigation":88,"path":1516,"pinned":228,"publishedAt":229,"seo":1517,"slug":1518,"stem":1519,"summary":1520,"tags":1521,"updatedAt":229,"visible":88,"__hash__":1523},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1394,"toc":1505},[1395,1398,1400,1403,1405,1411,1416,1418,1432,1434,1436,1445,1447,1453,1455,1457,1473,1475,1486,1488,1496,1498,1500,1503],[10,1396,1397],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1399,16],{"id":16},[10,1401,1402],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1404,22],{"id":22},[10,1406,1407],{},[26,1408],{"alt":1409,"src":1410},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1412,1413,1415],{},[33,1414,1169],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1417,43],{"id":43},[45,1419,1420,1426,1429],{},[48,1421,1422,1423,1425],{},"源代码是人编写的文本，通常保存在 ",[33,1424,1169],{}," 文件中。",[48,1427,1428],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[48,1430,1431],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1433,62],{"id":62},[10,1435,65],{},[67,1437,1439],{"className":69,"code":1438,"language":71,"meta":72,"style":72},"print(\"你好，Python\")\n",[33,1440,1441],{"__ignoreMap":72},[76,1442,1443],{"class":78,"line":79},[76,1444,1438],{},[10,1446,150],{},[67,1448,1451],{"className":1449,"code":1450,"language":156,"meta":72},[154],"你好，Python\n",[33,1452,1450],{"__ignoreMap":72},[10,1454,161],{},[14,1456,164],{"id":164},[166,1458,1459,1466],{},[48,1460,1461,1462,1465],{},"终端启动解释器后，解释器读取 ",[33,1463,1464],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[48,1467,1468,1469,1472],{},"字符串对象先准备好，再交给 ",[33,1470,1471],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1474,180],{"id":180},[45,1476,1477,1480],{},[48,1478,1479],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[48,1481,1482,1483,1485],{},"认为 ",[33,1484,1169],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1487,191],{"id":191},[166,1489,1490,1493],{},[48,1491,1492],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[48,1494,1495],{},"把示例文字改成自己的学习目标并重新运行。",[10,1497,202],{},[14,1499,205],{"id":205},[10,1501,1502],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,1504,212],{},{"title":72,"searchDepth":85,"depth":85,"links":1506},[1507,1508,1509,1510,1511,1512,1513,1514],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1392,"description":1397},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[223,1387,1522],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1525,"title":1526,"body":1527,"category":223,"cover":224,"description":1531,"extension":225,"meta":1667,"navigation":88,"path":1668,"pinned":228,"publishedAt":229,"seo":1669,"slug":1670,"stem":1671,"summary":1672,"tags":1673,"updatedAt":229,"visible":88,"__hash__":1675},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1528,"toc":1657},[1529,1532,1534,1537,1539,1545,1551,1553,1568,1570,1573,1593,1595,1601,1603,1605,1618,1620,1634,1636,1647,1649,1651,1654],[10,1530,1531],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1533,16],{"id":16},[10,1535,1536],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1538,22],{"id":22},[10,1540,1541],{},[26,1542],{"alt":1543,"src":1544},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1546,1547,1548,1550],{},"终端收到 ",[33,1549,689],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1552,43],{"id":43},[45,1554,1555,1558,1561],{},[48,1556,1557],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[48,1559,1560],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[48,1562,1563,1564,1567],{},"检查 pip 时使用 ",[33,1565,1566],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1569,62],{"id":62},[10,1571,1572],{},"在 macOS 终端执行：",[67,1574,1575],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,1576,1577,1583],{"__ignoreMap":72},[76,1578,1579,1581],{"class":78,"line":79},[76,1580,689],{"class":598},[76,1582,602],{"class":601},[76,1584,1585,1587,1589,1591],{"class":78,"line":85},[76,1586,689],{"class":598},[76,1588,631],{"class":601},[76,1590,635],{"class":634},[76,1592,602],{"class":601},[10,1594,150],{},[67,1596,1599],{"className":1597,"code":1598,"language":156,"meta":72},[154],"Python 3.14.x\npip 版本信息与安装路径\n",[33,1600,1598],{"__ignoreMap":72},[10,1602,161],{},[14,1604,164],{"id":164},[166,1606,1607,1613],{},[48,1608,1609,1612],{},[33,1610,1611],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[48,1614,1615,1617],{},[33,1616,697],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1619,180],{"id":180},[45,1621,1622,1628],{},[48,1623,1624,1625,1627],{},"看到系统已有 ",[33,1626,689],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[48,1629,1630,1631,1633],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[33,1632,689],{},"，不修改系统自带工具。",[14,1635,191],{"id":191},[166,1637,1638,1644],{},[48,1639,936,1640,1643],{},[33,1641,1642],{},"which python3","，记录当前解释器路径。",[48,1645,1646],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1648,202],{},[14,1650,205],{"id":205},[10,1652,1653],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,1655,1656],{},"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":1658},[1659,1660,1661,1662,1663,1664,1665,1666],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1526,"description":1531},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[223,1674,1050],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1677,"title":1678,"body":1679,"category":223,"cover":224,"description":1844,"extension":225,"meta":1845,"navigation":88,"path":1846,"pinned":228,"publishedAt":229,"seo":1847,"slug":1848,"stem":1849,"summary":1850,"tags":1851,"updatedAt":229,"visible":88,"__hash__":1854},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1680,"toc":1834},[1681,1687,1689,1692,1694,1700,1703,1705,1729,1731,1733,1760,1762,1768,1770,1772,1790,1792,1806,1808,1822,1824,1826,1832],[10,1682,1683,1684,1686],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[33,1685,1169],{}," 脚本。",[14,1688,16],{"id":16},[10,1690,1691],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1693,22],{"id":22},[10,1695,1696],{},[26,1697],{"alt":1698,"src":1699},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1701,1702],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1704,43],{"id":43},[45,1706,1707,1716,1723],{},[48,1708,1709,1710,1712,1713,360],{},"在终端输入 ",[33,1711,689],{}," 进入 REPL，提示符通常是 ",[33,1714,1715],{},">>>",[48,1717,1718,1719,1722],{},"输入 ",[33,1720,1721],{},"exit()"," 或按 Control-D 退出 REPL。",[48,1724,1725,1726,1728],{},"需要保存、复查或多次运行的代码应写入 ",[33,1727,1169],{}," 文件。",[14,1730,62],{"id":62},[10,1732,65],{},[67,1734,1738],{"className":1735,"code":1736,"language":1737,"meta":72,"style":72},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[33,1739,1740,1745,1750,1755],{"__ignoreMap":72},[76,1741,1742],{"class":78,"line":79},[76,1743,1744],{},">>> 2 + 3\n",[76,1746,1747],{"class":78,"line":85},[76,1748,1749],{},"5\n",[76,1751,1752],{"class":78,"line":92},[76,1753,1754],{},">>> \"python\".upper()\n",[76,1756,1757],{"class":78,"line":98},[76,1758,1759],{},"'PYTHON'\n",[10,1761,150],{},[67,1763,1766],{"className":1764,"code":1765,"language":156,"meta":72},[154],"REPL 会直接显示表达式结果\n",[33,1767,1765],{"__ignoreMap":72},[10,1769,161],{},[14,1771,164],{"id":164},[166,1773,1774,1784],{},[48,1775,1776,1777,1780,1781,360],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[33,1778,1779],{},"2 + 3"," 能直接看到 ",[33,1782,1783],{},"5",[48,1785,1786,1787,1789],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[33,1788,1471],{}," 才会写到标准输出。",[14,1791,180],{"id":180},[45,1793,1794,1803],{},[48,1795,1796,1797,1799,1800,1802],{},"把提示符 ",[33,1798,1715],{}," 复制进 ",[33,1801,1169],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[48,1804,1805],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1807,191],{"id":191},[166,1809,1810,1816],{},[48,1811,1812,1813,360],{},"在 REPL 计算 ",[33,1814,1815],{},"12 * 8",[48,1817,1818,1819,1821],{},"把同一表达式写入脚本；观察脚本中不调用 ",[33,1820,1471],{}," 时是否显示结果。",[10,1823,202],{},[14,1825,205],{"id":205},[10,1827,1828,1829,1831],{},"本篇目标是根据任务选择 REPL 或 ",[33,1830,1169],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,1833,212],{},{"title":72,"searchDepth":85,"depth":85,"links":1835},[1836,1837,1838,1839,1840,1841,1842,1843],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1678,"description":1844},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[223,1852,1853],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1856,"title":1857,"body":1858,"category":223,"cover":224,"description":1862,"extension":225,"meta":2033,"navigation":88,"path":2034,"pinned":228,"publishedAt":229,"seo":2035,"slug":2036,"stem":2037,"summary":2038,"tags":2039,"updatedAt":229,"visible":88,"__hash__":2042},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1859,"toc":2023},[1860,1863,1865,1868,1870,1876,1882,1884,1902,1904,1906,1951,1953,1959,1961,1963,1985,1987,1999,2001,2013,2015,2017,2020],[10,1861,1862],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1864,16],{"id":16},[10,1866,1867],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1869,22],{"id":22},[10,1871,1872],{},[26,1873],{"alt":1874,"src":1875},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1877,1878,1881],{},[33,1879,1880],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1883,43],{"id":43},[45,1885,1886,1889,1899],{},[48,1887,1888],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[48,1890,1891,1894,1895,1898],{},[33,1892,1893],{},"pwd"," 显示当前目录，",[33,1896,1897],{},"ls"," 显示目录里的文件。",[48,1900,1901],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1903,62],{"id":62},[10,1905,1572],{},[67,1907,1909],{"className":589,"code":1908,"language":591,"meta":72,"style":72},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[33,1910,1911,1919,1926,1931,1945],{"__ignoreMap":72},[76,1912,1913,1916],{"class":78,"line":79},[76,1914,1915],{"class":598},"mkdir",[76,1917,1918],{"class":634}," python-study\n",[76,1920,1921,1924],{"class":78,"line":85},[76,1922,1923],{"class":601},"cd",[76,1925,1918],{"class":634},[76,1927,1928],{"class":78,"line":92},[76,1929,1930],{"class":601},"pwd\n",[76,1932,1933,1936,1939,1943],{"class":78,"line":98},[76,1934,1935],{"class":601},"printf",[76,1937,1938],{"class":634}," 'print(\"项目已经运行\")\\n'",[76,1940,1942],{"class":1941},"snl16"," >",[76,1944,1213],{"class":634},[76,1946,1947,1949],{"class":78,"line":103},[76,1948,689],{"class":598},[76,1950,1213],{"class":634},[10,1952,150],{},[67,1954,1957],{"className":1955,"code":1956,"language":156,"meta":72},[154],"项目已经运行\n",[33,1958,1956],{"__ignoreMap":72},[10,1960,161],{},[14,1962,164],{"id":164},[166,1964,1965,1976],{},[48,1966,1967,1969,1970,1972,1973,1975],{},[33,1968,1915],{}," 创建目录，",[33,1971,1923],{}," 改变终端当前目录，",[33,1974,1893],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[48,1977,1978,1980,1981,1984],{},[33,1979,1880],{}," 会在当前目录寻找 ",[33,1982,1983],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,1986,180],{"id":180},[45,1988,1989,1996],{},[48,1990,1991,1992,1155,1994,360],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[33,1993,1893],{},[33,1995,1897],{},[48,1997,1998],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2000,191],{"id":191},[166,2002,2003,2010],{},[48,2004,2005,2006,2009],{},"新建 ",[33,2007,2008],{},"lesson01.py"," 并输出课程编号。",[48,2011,2012],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2014,202],{},[14,2016,205],{"id":205},[10,2018,2019],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,2021,2022],{},"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":2024},[2025,2026,2027,2028,2029,2030,2031,2032],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1857,"description":1862},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[223,2040,2041],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2044,"title":2045,"body":2046,"category":223,"cover":224,"description":2050,"extension":225,"meta":2198,"navigation":88,"path":2199,"pinned":228,"publishedAt":229,"seo":2200,"slug":2201,"stem":2202,"summary":2203,"tags":2204,"updatedAt":229,"visible":88,"__hash__":2207},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2047,"toc":2188},[2048,2051,2053,2056,2058,2064,2075,2077,2097,2099,2101,2121,2123,2129,2131,2133,2152,2154,2162,2164,2179,2181,2183,2186],[10,2049,2050],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2052,16],{"id":16},[10,2054,2055],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2057,22],{"id":22},[10,2059,2060],{},[26,2061],{"alt":2062,"src":2063},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2065,2066,2067,360,2069,2072,2073,360],{},"Python 先计算表达式，再把得到的对象交给 ",[33,2068,1471],{},[33,2070,2071],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[33,2074,1779],{},[14,2076,43],{"id":43},[45,2078,2079,2085,2094],{},[48,2080,2081,2084],{},[33,2082,2083],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[48,2086,2087,2090,2091,360],{},[33,2088,2089],{},"7 + 5"," 是表达式，运行时先求值得到 ",[33,2092,2093],{},"12",[48,2095,2096],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2098,62],{"id":62},[10,2100,65],{},[67,2102,2104],{"className":69,"code":2103,"language":71,"meta":72,"style":72},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[33,2105,2106,2111,2116],{"__ignoreMap":72},[76,2107,2108],{"class":78,"line":79},[76,2109,2110],{},"print(42)\n",[76,2112,2113],{"class":78,"line":85},[76,2114,2115],{},"print(7 + 5)\n",[76,2117,2118],{"class":78,"line":92},[76,2119,2120],{},"print(\"Python 基础课\")\n",[10,2122,150],{},[67,2124,2127],{"className":2125,"code":2126,"language":156,"meta":72},[154],"42\n12\nPython 基础课\n",[33,2128,2126],{"__ignoreMap":72},[10,2130,161],{},[14,2132,164],{"id":164},[166,2134,2135,2143],{},[48,2136,2137,2140,2141,360],{},[33,2138,2139],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[33,2142,2093],{},[48,2144,2145,2147,2148,2151],{},[33,2146,1471],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[33,2149,2150],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2153,180],{"id":180},[45,2155,2156,2159],{},[48,2157,2158],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[48,2160,2161],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2163,191],{"id":191},[166,2165,2166,2169],{},[48,2167,2168],{},"分别输出一个整数、一个小数和一段文本。",[48,2170,2171,2172,2174,2175,2178],{},"比较 ",[33,2173,2071],{}," 与 ",[33,2176,2177],{},"print(\"2 + 3\")"," 的结果。",[10,2180,202],{},[14,2182,205],{"id":205},[10,2184,2185],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,2187,212],{},{"title":72,"searchDepth":85,"depth":85,"links":2189},[2190,2191,2192,2193,2194,2195,2196,2197],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2045,"description":2050},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[223,2205,2206],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2209,"title":2210,"body":2211,"category":223,"cover":224,"description":2215,"extension":225,"meta":2382,"navigation":88,"path":2383,"pinned":228,"publishedAt":229,"seo":2384,"slug":2385,"stem":2386,"summary":2387,"tags":2388,"updatedAt":229,"visible":88,"__hash__":2391},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2212,"toc":2372},[2213,2216,2218,2221,2223,2229,2232,2234,2260,2262,2264,2292,2294,2300,2302,2304,2328,2330,2346,2348,2363,2365,2367,2370],[10,2214,2215],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2217,16],{"id":16},[10,2219,2220],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2222,22],{"id":22},[10,2224,2225],{},[26,2226],{"alt":2227,"src":2228},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2230,2231],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2233,43],{"id":43},[45,2235,2236,2239,2249],{},[48,2237,2238],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[48,2240,2241,2242,2174,2245,2248],{},"变量名区分大小写，",[33,2243,2244],{},"score",[33,2246,2247],{},"Score"," 是两个名字。",[48,2250,2251,2252,2255,2256,2259],{},"使用能表达含义的名称；不要用 ",[33,2253,2254],{},"list","、",[33,2257,2258],{},"str"," 等内置名称作为普通变量名。",[14,2261,62],{"id":62},[10,2263,65],{},[67,2265,2267],{"className":69,"code":2266,"language":71,"meta":72,"style":72},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[33,2268,2269,2274,2279,2283,2288],{"__ignoreMap":72},[76,2270,2271],{"class":78,"line":79},[76,2272,2273],{},"score = 90\n",[76,2275,2276],{"class":78,"line":85},[76,2277,2278],{},"print(score)\n",[76,2280,2281],{"class":78,"line":92},[76,2282,89],{"emptyLinePlaceholder":88},[76,2284,2285],{"class":78,"line":98},[76,2286,2287],{},"score = 95\n",[76,2289,2290],{"class":78,"line":103},[76,2291,2278],{},[10,2293,150],{},[67,2295,2298],{"className":2296,"code":2297,"language":156,"meta":72},[154],"90\n95\n",[33,2299,2297],{"__ignoreMap":72},[10,2301,161],{},[14,2303,164],{"id":164},[166,2305,2306,2315],{},[48,2307,936,2308,2311,2312,2314],{},[33,2309,2310],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[33,2313,2244],{}," 再绑定到它。",[48,2316,936,2317,2320,2321,2324,2325,360],{},[33,2318,2319],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[33,2322,2323],{},"90"," 没有被改造成 ",[33,2326,2327],{},"95",[14,2329,180],{"id":180},[45,2331,2332,2335],{},[48,2333,2334],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[48,2336,2337,2338,2255,2340,2255,2342,2345],{},"使用 ",[33,2339,2254],{},[33,2341,2258],{},[33,2343,2344],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2347,191],{"id":191},[166,2349,2350,2360],{},[48,2351,2352,2353,1155,2356,2359],{},"创建 ",[33,2354,2355],{},"course_name",[33,2357,2358],{},"lesson_count"," 两个变量并输出。",[48,2361,2362],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2364,202],{},[14,2366,205],{"id":205},[10,2368,2369],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,2371,212],{},{"title":72,"searchDepth":85,"depth":85,"links":2373},[2374,2375,2376,2377,2378,2379,2380,2381],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2210,"description":2215},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[223,2389,2390],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2393,"title":2394,"body":2395,"category":223,"cover":224,"description":2399,"extension":225,"meta":2563,"navigation":88,"path":2564,"pinned":228,"publishedAt":229,"seo":2565,"slug":2566,"stem":2567,"summary":2568,"tags":2569,"updatedAt":229,"visible":88,"__hash__":2572},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2396,"toc":2553},[2397,2400,2402,2405,2407,2413,2416,2418,2447,2449,2451,2495,2497,2503,2505,2507,2521,2523,2534,2536,2544,2546,2548,2551],[10,2398,2399],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2401,16],{"id":16},[10,2403,2404],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2406,22],{"id":22},[10,2408,2409],{},[26,2410],{"alt":2411,"src":2412},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2414,2415],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2417,43],{"id":43},[45,2419,2420,2430,2444],{},[48,2421,2422,2425,2426,2429],{},[33,2423,2424],{},"int"," 表示整数，",[33,2427,2428],{},"float"," 表示浮点数。",[48,2431,2432,2435,2436,2439,2440,2443],{},[33,2433,2434],{},"\u002F"," 总是进行真除法；",[33,2437,2438],{},"\u002F\u002F"," 是向下取整除法，",[33,2441,2442],{},"%"," 得到余数。",[48,2445,2446],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2448,62],{"id":62},[10,2450,65],{},[67,2452,2454],{"className":69,"code":2453,"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",[33,2455,2456,2461,2466,2471,2475,2480,2485,2490],{"__ignoreMap":72},[76,2457,2458],{"class":78,"line":79},[76,2459,2460],{},"price = 25\n",[76,2462,2463],{"class":78,"line":85},[76,2464,2465],{},"count = 4\n",[76,2467,2468],{"class":78,"line":92},[76,2469,2470],{},"discount = 0.9\n",[76,2472,2473],{"class":78,"line":98},[76,2474,89],{"emptyLinePlaceholder":88},[76,2476,2477],{"class":78,"line":103},[76,2478,2479],{},"total = price * count * discount\n",[76,2481,2482],{"class":78,"line":109},[76,2483,2484],{},"average = total \u002F count\n",[76,2486,2487],{"class":78,"line":115},[76,2488,2489],{},"print(total)\n",[76,2491,2492],{"class":78,"line":121},[76,2493,2494],{},"print(average)\n",[10,2496,150],{},[67,2498,2501],{"className":2499,"code":2500,"language":156,"meta":72},[154],"90.0\n22.5\n",[33,2502,2500],{"__ignoreMap":72},[10,2504,161],{},[14,2506,164],{"id":164},[166,2508,2509,2515],{},[48,2510,2511,2514],{},[33,2512,2513],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[48,2516,2517,2520],{},[33,2518,2519],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2522,180],{"id":180},[45,2524,2525,2531],{},[48,2526,2527,2528,360],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[33,2529,2530],{},"decimal.Decimal",[48,2532,2533],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2535,191],{"id":191},[166,2537,2538,2541],{},[48,2539,2540],{},"计算 137 除以 10 的商和余数。",[48,2542,2543],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2545,202],{},[14,2547,205],{"id":205},[10,2549,2550],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,2552,212],{},{"title":72,"searchDepth":85,"depth":85,"links":2554},[2555,2556,2557,2558,2559,2560,2561,2562],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2394,"description":2399},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[223,2570,2571],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2574,"title":2575,"body":2576,"category":223,"cover":224,"description":2580,"extension":225,"meta":2756,"navigation":88,"path":2757,"pinned":228,"publishedAt":229,"seo":2758,"slug":2759,"stem":2760,"summary":2761,"tags":2762,"updatedAt":229,"visible":88,"__hash__":2765},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2577,"toc":2744},[2578,2581,2583,2586,2588,2594,2604,2606,2617,2619,2621,2651,2653,2659,2661,2663,2693,2696,2699,2705,2708,2710,2718,2720,2735,2737,2739,2742],[10,2579,2580],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2582,16],{"id":16},[10,2584,2585],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2587,22],{"id":22},[10,2589,2590],{},[26,2591],{"alt":2592,"src":2593},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2595,2596,2597,2600,2601,360],{},"切片 ",[33,2598,2599],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[33,2602,2603],{},"stop - start",[14,2605,43],{"id":43},[45,2607,2608,2611,2614],{},[48,2609,2610],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[48,2612,2613],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[48,2615,2616],{},"切片会创建新的字符串，不会修改原字符串。",[14,2618,62],{"id":62},[10,2620,65],{},[67,2622,2624],{"className":69,"code":2623,"language":71,"meta":72,"style":72},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[33,2625,2626,2631,2636,2641,2646],{"__ignoreMap":72},[76,2627,2628],{"class":78,"line":79},[76,2629,2630],{},"language = \"Python\"\n",[76,2632,2633],{"class":78,"line":85},[76,2634,2635],{},"print(language[0])\n",[76,2637,2638],{"class":78,"line":92},[76,2639,2640],{},"print(language[-1])\n",[76,2642,2643],{"class":78,"line":98},[76,2644,2645],{},"print(language[0:3])\n",[76,2647,2648],{"class":78,"line":103},[76,2649,2650],{},"print(language + \" 3.14\")\n",[10,2652,150],{},[67,2654,2657],{"className":2655,"code":2656,"language":156,"meta":72},[154],"P\nn\nPyt\nPython 3.14\n",[33,2658,2656],{"__ignoreMap":72},[10,2660,161],{},[14,2662,164],{"id":164},[166,2664,2665,2679],{},[48,2666,2667,2668,2670,2671,2674,2675,2678],{},"字符串 ",[33,2669,223],{}," 的正索引从 ",[33,2672,2673],{},"P"," 的 0 开始，负索引从末尾 ",[33,2676,2677],{},"n"," 的 -1 开始。",[48,2680,2681,2684,2685,2688,2689,2692],{},[33,2682,2683],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[33,2686,2687],{},"Pyt","；索引 3 的 ",[33,2690,2691],{},"h"," 不在结果中。",[326,2694,2695],{"id":2695},"再看一个具体细节",[10,2697,2698],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2700,2701],{},[26,2702],{"alt":2703,"src":2704},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2706,2707],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2709,180],{"id":180},[45,2711,2712,2715],{},[48,2713,2714],{},"把第一个字符写成索引 1，造成整体偏移一位。",[48,2716,2717],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2719,191],{"id":191},[166,2721,2722,2732],{},[48,2723,2724,2725,2728,2729,360],{},"从 ",[33,2726,2727],{},"\"programming\""," 中切出 ",[33,2730,2731],{},"\"gram\"",[48,2733,2734],{},"使用负索引取得字符串倒数第二个字符。",[10,2736,202],{},[14,2738,205],{"id":205},[10,2740,2741],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,2743,212],{},{"title":72,"searchDepth":85,"depth":85,"links":2745},[2746,2747,2748,2749,2750,2753,2754,2755],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":2751},[2752],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2575,"description":2580},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[223,2763,2764],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2767,"title":2768,"body":2769,"category":223,"cover":224,"description":2773,"extension":225,"meta":2987,"navigation":88,"path":2988,"pinned":228,"publishedAt":229,"seo":2989,"slug":2990,"stem":2991,"summary":2992,"tags":2993,"updatedAt":229,"visible":88,"__hash__":2996},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2770,"toc":2975},[2771,2774,2776,2779,2781,2787,2797,2799,2832,2834,2836,2880,2882,2888,2890,2892,2913,2915,2918,2924,2932,2934,2948,2950,2966,2968,2970,2973],[10,2772,2773],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2775,16],{"id":16},[10,2777,2778],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2780,22],{"id":22},[10,2782,2783],{},[26,2784],{"alt":2785,"src":2786},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2788,2789,2790,1007,2793,2796],{},"比较表达式先产生 ",[33,2791,2792],{},"True",[33,2794,2795],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2798,43],{"id":43},[45,2800,2801,2815,2829],{},[48,2802,2803,2806,2807,2810,2811,2814],{},[33,2804,2805],{},"=="," 判断是否相等，",[33,2808,2809],{},"!="," 判断是否不等；单个 ",[33,2812,2813],{},"="," 是赋值。",[48,2816,2817,2820,2821,2824,2825,2828],{},[33,2818,2819],{},"and"," 要求两侧都为真，",[33,2822,2823],{},"or"," 只需一侧为真，",[33,2826,2827],{},"not"," 取反。",[48,2830,2831],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2833,62],{"id":62},[10,2835,65],{},[67,2837,2839],{"className":69,"code":2838,"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",[33,2840,2841,2846,2851,2855,2860,2865,2870,2875],{"__ignoreMap":72},[76,2842,2843],{"class":78,"line":79},[76,2844,2845],{},"age = 20\n",[76,2847,2848],{"class":78,"line":85},[76,2849,2850],{},"has_ticket = True\n",[76,2852,2853],{"class":78,"line":92},[76,2854,89],{"emptyLinePlaceholder":88},[76,2856,2857],{"class":78,"line":98},[76,2858,2859],{},"is_adult = age >= 18\n",[76,2861,2862],{"class":78,"line":103},[76,2863,2864],{},"can_enter = is_adult and has_ticket\n",[76,2866,2867],{"class":78,"line":109},[76,2868,2869],{},"print(is_adult)\n",[76,2871,2872],{"class":78,"line":115},[76,2873,2874],{},"print(can_enter)\n",[76,2876,2877],{"class":78,"line":121},[76,2878,2879],{},"print(not has_ticket)\n",[10,2881,150],{},[67,2883,2886],{"className":2884,"code":2885,"language":156,"meta":72},[154],"True\nTrue\nFalse\n",[33,2887,2885],{"__ignoreMap":72},[10,2889,161],{},[14,2891,164],{"id":164},[166,2893,2894,2904],{},[48,2895,2896,2899,2900,2903],{},[33,2897,2898],{},"age >= 18"," 先产生布尔值并绑定给 ",[33,2901,2902],{},"is_adult","，这一步没有任何分支跳转。",[48,2905,2906,2909,2910,2912],{},[33,2907,2908],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[33,2911,2827],{}," 只对紧随其后的值取反。",[326,2914,2695],{"id":2695},[10,2916,2917],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2919,2920],{},[26,2921],{"alt":2922,"src":2923},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2925,2926,2928,2929,2931],{},[33,2927,2819],{}," 只有“真、真”得到真；",[33,2930,2823],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2933,180],{"id":180},[45,2935,2936,2945],{},[48,2937,2938,2939,2941,2942,2944],{},"用单个等号判断相等。",[33,2940,2813],{}," 是赋值，",[33,2943,2805],{}," 才是相等比较。",[48,2946,2947],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,2949,191],{"id":191},[166,2951,2952,2959],{},[48,2953,2954,2955,2958],{},"判断数字 ",[33,2956,2957],{},"15"," 是否同时大于 10 且小于 20。",[48,2960,2961,2962,2965],{},"分别修改年龄和票据状态，记录 ",[33,2963,2964],{},"can_enter"," 的四种组合结果。",[10,2967,202],{},[14,2969,205],{"id":205},[10,2971,2972],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,2974,212],{},{"title":72,"searchDepth":85,"depth":85,"links":2976},[2977,2978,2979,2980,2981,2984,2985,2986],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":2982},[2983],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2768,"description":2773},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[223,2994,2995],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":2998,"title":2999,"body":3000,"category":223,"cover":224,"description":3004,"extension":225,"meta":3172,"navigation":88,"path":3173,"pinned":228,"publishedAt":229,"seo":3174,"slug":3175,"stem":3176,"summary":3177,"tags":3178,"updatedAt":229,"visible":88,"__hash__":3180},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3001,"toc":3162},[3002,3005,3007,3010,3012,3018,3036,3038,3051,3053,3055,3089,3091,3097,3099,3101,3123,3125,3137,3139,3153,3155,3157,3160],[10,3003,3004],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3006,16],{"id":16},[10,3008,3009],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3011,22],{"id":22},[10,3013,3014],{},[26,3015],{"alt":3016,"src":3017},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3019,3020,3023,3024,3027,3028,3031,3032,3035],{},[33,3021,3022],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[33,3025,3026],{},"18","，程序首先得到的也是 ",[33,3029,3030],{},"\"18\"","，需要 ",[33,3033,3034],{},"int()"," 后才能按整数参与计算。",[14,3037,43],{"id":43},[45,3039,3040,3043,3048],{},[48,3041,3042],{},"提示文字应告诉用户需要输入什么。",[48,3044,3045,3047],{},[33,3046,3034],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[48,3049,3050],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3052,62],{"id":62},[10,3054,65],{},[67,3056,3058],{"className":69,"code":3057,"language":71,"meta":72,"style":72},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[33,3059,3060,3065,3070,3075,3079,3084],{"__ignoreMap":72},[76,3061,3062],{"class":78,"line":79},[76,3063,3064],{},"name = input(\"请输入姓名：\")\n",[76,3066,3067],{"class":78,"line":85},[76,3068,3069],{},"age_text = input(\"请输入年龄：\")\n",[76,3071,3072],{"class":78,"line":92},[76,3073,3074],{},"age = int(age_text)\n",[76,3076,3077],{"class":78,"line":98},[76,3078,89],{"emptyLinePlaceholder":88},[76,3080,3081],{"class":78,"line":103},[76,3082,3083],{},"print(\"你好，\" + name)\n",[76,3085,3086],{"class":78,"line":109},[76,3087,3088],{},"print(age + 1)\n",[10,3090,150],{},[67,3092,3095],{"className":3093,"code":3094,"language":156,"meta":72},[154],"根据输入显示姓名，并输出下一年的年龄\n",[33,3096,3094],{"__ignoreMap":72},[10,3098,161],{},[14,3100,164],{"id":164},[166,3102,3103,3113],{},[48,3104,3105,3106,3108,3109,3112],{},"两次 ",[33,3107,3022],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[33,3110,3111],{},"age_text"," 用来提醒这仍是文本。",[48,3114,3115,3118,3119,3122],{},[33,3116,3117],{},"int(age_text)"," 创建整数对象，后面的 ",[33,3120,3121],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3124,180],{"id":180},[45,3126,3127,3134],{},[48,3128,3129,3130,3133],{},"直接计算 ",[33,3131,3132],{},"input(...) + 1","，忽略输入结果是字符串。",[48,3135,3136],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3138,191],{"id":191},[166,3140,3141,3144],{},[48,3142,3143],{},"接收两个整数并输出它们的和。",[48,3145,1718,3146,3149,3150,3152],{},[33,3147,3148],{},"18.5"," 给 ",[33,3151,3034],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3154,202],{},[14,3156,205],{"id":205},[10,3158,3159],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,3161,212],{},{"title":72,"searchDepth":85,"depth":85,"links":3163},[3164,3165,3166,3167,3168,3169,3170,3171],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":2999,"description":3004},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[223,2344,3179],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3182,"title":3183,"body":3184,"category":223,"cover":224,"description":3188,"extension":225,"meta":3348,"navigation":88,"path":3349,"pinned":228,"publishedAt":229,"seo":3350,"slug":3351,"stem":3352,"summary":3353,"tags":3354,"updatedAt":229,"visible":88,"__hash__":3357},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3185,"toc":3338},[3186,3189,3191,3194,3196,3202,3209,3211,3225,3227,3229,3268,3270,3276,3278,3280,3299,3301,3316,3318,3329,3331,3333,3336],[10,3187,3188],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3190,16],{"id":16},[10,3192,3193],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3195,22],{"id":22},[10,3197,3198],{},[26,3199],{"alt":3200,"src":3201},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3203,3204,3205,3208],{},"列表为元素维护从 0 开始的位置索引。修改 ",[33,3206,3207],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3210,43],{"id":43},[45,3212,3213,3216,3219],{},[48,3214,3215],{},"列表使用方括号，元素之间用逗号分隔。",[48,3217,3218],{},"列表可变，可以替换、追加和删除元素。",[48,3220,3221,3222,360],{},"访问不存在的索引会产生 ",[33,3223,3224],{},"IndexError",[14,3226,62],{"id":62},[10,3228,65],{},[67,3230,3232],{"className":69,"code":3231,"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",[33,3233,3234,3239,3244,3248,3253,3258,3263],{"__ignoreMap":72},[76,3235,3236],{"class":78,"line":79},[76,3237,3238],{},"scores = [82, 90, 76]\n",[76,3240,3241],{"class":78,"line":85},[76,3242,3243],{},"print(scores[0])\n",[76,3245,3246],{"class":78,"line":92},[76,3247,89],{"emptyLinePlaceholder":88},[76,3249,3250],{"class":78,"line":98},[76,3251,3252],{},"scores[1] = 95\n",[76,3254,3255],{"class":78,"line":103},[76,3256,3257],{},"scores.append(88)\n",[76,3259,3260],{"class":78,"line":109},[76,3261,3262],{},"print(scores)\n",[76,3264,3265],{"class":78,"line":115},[76,3266,3267],{},"print(len(scores))\n",[10,3269,150],{},[67,3271,3274],{"className":3272,"code":3273,"language":156,"meta":72},[154],"82\n[82, 95, 76, 88]\n4\n",[33,3275,3273],{"__ignoreMap":72},[10,3277,161],{},[14,3279,164],{"id":164},[166,3281,3282,3285],{},[48,3283,3284],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[48,3286,3287,3290,3291,3294,3295,3298],{},[33,3288,3289],{},"scores[1] = 95"," 替换第二个位置，",[33,3292,3293],{},"append(88)"," 在末尾增加新位置，",[33,3296,3297],{},"len()"," 因而从 3 变为 4。",[14,3300,180],{"id":180},[45,3302,3303,3313],{},[48,3304,3305,3306,3309,3310,360],{},"访问 ",[33,3307,3308],{},"scores[len(scores)]","。最后一个合法正索引是 ",[33,3311,3312],{},"len(scores) - 1",[48,3314,3315],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3317,191],{"id":191},[166,3319,3320,3323],{},[48,3321,3322],{},"建立三项学习任务列表，再追加第四项。",[48,3324,3325,3326,3328],{},"修改第二项，并用 ",[33,3327,3297],{}," 检查元素数量。",[10,3330,202],{},[14,3332,205],{"id":205},[10,3334,3335],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,3337,212],{},{"title":72,"searchDepth":85,"depth":85,"links":3339},[3340,3341,3342,3343,3344,3345,3346,3347],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3183,"description":3188},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[223,3355,3356],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3359,"title":3360,"body":3361,"category":223,"cover":224,"description":3365,"extension":225,"meta":3506,"navigation":88,"path":3507,"pinned":228,"publishedAt":229,"seo":3508,"slug":3509,"stem":3510,"summary":3511,"tags":3512,"updatedAt":229,"visible":88,"__hash__":3514},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3362,"toc":3496},[3363,3366,3368,3371,3373,3379,3382,3384,3395,3397,3399,3433,3435,3441,3443,3445,3459,3461,3473,3475,3487,3489,3491,3494],[10,3364,3365],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3367,16],{"id":16},[10,3369,3370],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3372,22],{"id":22},[10,3374,3375],{},[26,3376],{"alt":3377,"src":3378},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3380,3381],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3383,43],{"id":43},[45,3385,3386,3389,3392],{},[48,3387,3388],{},"元组常用来表达固定数量、固定含义的一组值。",[48,3390,3391],{},"只有一个元素的元组必须保留尾随逗号。",[48,3393,3394],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3396,62],{"id":62},[10,3398,65],{},[67,3400,3402],{"className":69,"code":3401,"language":71,"meta":72,"style":72},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[33,3403,3404,3409,3414,3419,3423,3428],{"__ignoreMap":72},[76,3405,3406],{"class":78,"line":79},[76,3407,3408],{},"point = (120, 80)\n",[76,3410,3411],{"class":78,"line":85},[76,3412,3413],{},"print(point[0])\n",[76,3415,3416],{"class":78,"line":92},[76,3417,3418],{},"print(point[1])\n",[76,3420,3421],{"class":78,"line":98},[76,3422,89],{"emptyLinePlaceholder":88},[76,3424,3425],{"class":78,"line":103},[76,3426,3427],{},"single = (5,)\n",[76,3429,3430],{"class":78,"line":109},[76,3431,3432],{},"print(single)\n",[10,3434,150],{},[67,3436,3439],{"className":3437,"code":3438,"language":156,"meta":72},[154],"120\n80\n(5,)\n",[33,3440,3438],{"__ignoreMap":72},[10,3442,161],{},[14,3444,164],{"id":164},[166,3446,3447,3453],{},[48,3448,3449,3452],{},[33,3450,3451],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[48,3454,3455,3458],{},[33,3456,3457],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3460,180],{"id":180},[45,3462,3463,3470],{},[48,3464,3465,3466,3469],{},"把 ",[33,3467,3468],{},"(5)"," 当作元组，实际它仍是整数。",[48,3471,3472],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3474,191],{"id":191},[166,3476,3477,3480],{},[48,3478,3479],{},"用元组表示宽度和高度。",[48,3481,2171,3482,2174,3484,3486],{},[33,3483,3468],{},[33,3485,3457],{}," 的类型。",[10,3488,202],{},[14,3490,205],{"id":205},[10,3492,3493],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,3495,212],{},{"title":72,"searchDepth":85,"depth":85,"links":3497},[3498,3499,3500,3501,3502,3503,3504,3505],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3360,"description":3365},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[223,3513,3356],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3516,"title":3517,"body":3518,"category":223,"cover":224,"description":3522,"extension":225,"meta":3677,"navigation":88,"path":3678,"pinned":228,"publishedAt":229,"seo":3679,"slug":3680,"stem":3681,"summary":3682,"tags":3683,"updatedAt":229,"visible":88,"__hash__":3685},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3519,"toc":3667},[3520,3523,3525,3528,3530,3536,3546,3548,3562,3564,3566,3600,3602,3608,3610,3612,3627,3629,3648,3650,3658,3660,3662,3665],[10,3521,3522],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3524,16],{"id":16},[10,3526,3527],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3529,22],{"id":22},[10,3531,3532],{},[26,3533],{"alt":3534,"src":3535},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3537,3538,3539,3542,3543,3545],{},"字典通过键定位值，不使用连续位置表达含义。",[33,3540,3541],{},"student[\"score\"]"," 读取的是键 ",[33,3544,2244],{}," 对应的值，而不是“第几个元素”。",[14,3547,43],{"id":43},[45,3549,3550,3553,3559],{},[48,3551,3552],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[48,3554,2337,3555,3558],{},[33,3556,3557],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[48,3560,3561],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3563,62],{"id":62},[10,3565,65],{},[67,3567,3569],{"className":69,"code":3568,"language":71,"meta":72,"style":72},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[33,3570,3571,3576,3581,3585,3590,3595],{"__ignoreMap":72},[76,3572,3573],{"class":78,"line":79},[76,3574,3575],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[76,3577,3578],{"class":78,"line":85},[76,3579,3580],{},"print(student[\"name\"])\n",[76,3582,3583],{"class":78,"line":92},[76,3584,89],{"emptyLinePlaceholder":88},[76,3586,3587],{"class":78,"line":98},[76,3588,3589],{},"student[\"score\"] = 95\n",[76,3591,3592],{"class":78,"line":103},[76,3593,3594],{},"student[\"city\"] = \"郑州\"\n",[76,3596,3597],{"class":78,"line":109},[76,3598,3599],{},"print(student)\n",[10,3601,150],{},[67,3603,3606],{"className":3604,"code":3605,"language":156,"meta":72},[154],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[33,3607,3605],{"__ignoreMap":72},[10,3609,161],{},[14,3611,164],{"id":164},[166,3613,3614,3617],{},[48,3615,3616],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[48,3618,3619,3620,3622,3623,3626],{},"给已有键 ",[33,3621,2244],{}," 赋值会更新映射，给新键 ",[33,3624,3625],{},"city"," 赋值会增加映射。",[14,3628,180],{"id":180},[45,3630,3631,3638],{},[48,3632,3633,3634,3637],{},"按位置理解字典并尝试 ",[33,3635,3636],{},"student[0]","，而实际键是字符串。",[48,3639,3640,3641,3644,3645,360],{},"直接读取不确定存在的键并忽略 ",[33,3642,3643],{},"KeyError","；后续可根据场景使用成员检查或 ",[33,3646,3647],{},"get()",[14,3649,191],{"id":191},[166,3651,3652,3655],{},[48,3653,3654],{},"建立一本书的标题、作者和页数字典。",[48,3656,3657],{},"添加分类键，再修改页数。",[10,3659,202],{},[14,3661,205],{"id":205},[10,3663,3664],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,3666,212],{},{"title":72,"searchDepth":85,"depth":85,"links":3668},[3669,3670,3671,3672,3673,3674,3675,3676],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3517,"description":3522},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[223,3684,3356],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3687,"title":3688,"body":3689,"category":223,"cover":224,"description":3693,"extension":225,"meta":3842,"navigation":88,"path":3843,"pinned":228,"publishedAt":229,"seo":3844,"slug":3845,"stem":3846,"summary":3847,"tags":3848,"updatedAt":229,"visible":88,"__hash__":3850},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3690,"toc":3832},[3691,3694,3696,3699,3701,3707,3710,3712,3731,3733,3735,3769,3771,3777,3779,3781,3796,3798,3810,3812,3823,3825,3827,3830],[10,3692,3693],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3695,16],{"id":16},[10,3697,3698],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3700,22],{"id":22},[10,3702,3703],{},[26,3704],{"alt":3705,"src":3706},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3708,3709],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3711,43],{"id":43},[45,3713,3714,3717,3720],{},[48,3715,3716],{},"集合中的元素不重复。",[48,3718,3719],{},"集合是无序容器，不要依赖打印顺序或索引。",[48,3721,3722,3723,3726,3727,3730],{},"创建空集合必须写 ",[33,3724,3725],{},"set()","；",[33,3728,3729],{},"{}"," 创建的是空字典。",[14,3732,62],{"id":62},[10,3734,65],{},[67,3736,3738],{"className":69,"code":3737,"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",[33,3739,3740,3745,3750,3754,3759,3764],{"__ignoreMap":72},[76,3741,3742],{"class":78,"line":79},[76,3743,3744],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[76,3746,3747],{"class":78,"line":85},[76,3748,3749],{},"right = {\"Python\", \"Docker\"}\n",[76,3751,3752],{"class":78,"line":92},[76,3753,89],{"emptyLinePlaceholder":88},[76,3755,3756],{"class":78,"line":98},[76,3757,3758],{},"print(left & right)\n",[76,3760,3761],{"class":78,"line":103},[76,3762,3763],{},"print(left | right)\n",[76,3765,3766],{"class":78,"line":109},[76,3767,3768],{},"print(\"Git\" in left)\n",[10,3770,150],{},[67,3772,3775],{"className":3773,"code":3774,"language":156,"meta":72},[154],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[33,3776,3774],{"__ignoreMap":72},[10,3778,161],{},[14,3780,164],{"id":164},[166,3782,3783,3786],{},[48,3784,3785],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[48,3787,3788,3791,3792,3795],{},[33,3789,3790],{},"&"," 计算交集，",[33,3793,3794],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3797,180],{"id":180},[45,3799,3800,3807],{},[48,3801,2337,3802,3804,3805,360],{},[33,3803,3729],{}," 创建空集合，实际得到空字典；空集合应写 ",[33,3806,3725],{},[48,3808,3809],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3811,191],{"id":191},[166,3813,3814,3820],{},[48,3815,3816,3817,3819],{},"把包含重复标签的列表交给 ",[33,3818,3725],{}," 去重。",[48,3821,3822],{},"计算两组课程标签的交集和差集。",[10,3824,202],{},[14,3826,205],{"id":205},[10,3828,3829],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,3831,212],{},{"title":72,"searchDepth":85,"depth":85,"links":3833},[3834,3835,3836,3837,3838,3839,3840,3841],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3688,"description":3693},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[223,3849,3356],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3852,"title":3853,"body":3854,"category":223,"cover":224,"description":3858,"extension":225,"meta":4055,"navigation":88,"path":4056,"pinned":228,"publishedAt":229,"seo":4057,"slug":4058,"stem":4059,"summary":4060,"tags":4061,"updatedAt":229,"visible":88,"__hash__":4064},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3855,"toc":4043},[3856,3859,3861,3864,3866,3872,3882,3884,3901,3903,3905,3954,3956,3962,3964,3966,3988,3990,3993,3999,4002,4004,4017,4019,4034,4036,4038,4041],[10,3857,3858],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3860,16],{"id":16},[10,3862,3863],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3865,22],{"id":22},[10,3867,3868],{},[26,3869],{"alt":3870,"src":3871},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3873,3874,3877,3878,3881],{},[33,3875,3876],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[33,3879,3880],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3883,43],{"id":43},[45,3885,3886,3895,3898],{},[48,3887,3888,3890,3891,3894],{},[33,3889,2805],{}," 比较内容是否相等，",[33,3892,3893],{},"is"," 比较是否为同一个对象。",[48,3896,3897],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[48,3899,3900],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3902,62],{"id":62},[10,3904,65],{},[67,3906,3908],{"className":69,"code":3907,"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",[33,3909,3910,3915,3920,3925,3929,3934,3939,3944,3949],{"__ignoreMap":72},[76,3911,3912],{"class":78,"line":79},[76,3913,3914],{},"tasks = [\"变量\", \"字符串\"]\n",[76,3916,3917],{"class":78,"line":85},[76,3918,3919],{},"shared = tasks\n",[76,3921,3922],{"class":78,"line":92},[76,3923,3924],{},"backup = tasks.copy()\n",[76,3926,3927],{"class":78,"line":98},[76,3928,89],{"emptyLinePlaceholder":88},[76,3930,3931],{"class":78,"line":103},[76,3932,3933],{},"tasks.append(\"列表\")\n",[76,3935,3936],{"class":78,"line":109},[76,3937,3938],{},"print(shared)\n",[76,3940,3941],{"class":78,"line":115},[76,3942,3943],{},"print(backup)\n",[76,3945,3946],{"class":78,"line":121},[76,3947,3948],{},"print(tasks is shared)\n",[76,3950,3951],{"class":78,"line":126},[76,3952,3953],{},"print(tasks is backup)\n",[10,3955,150],{},[67,3957,3960],{"className":3958,"code":3959,"language":156,"meta":72},[154],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[33,3961,3959],{"__ignoreMap":72},[10,3963,161],{},[14,3965,164],{"id":164},[166,3967,3968,3974],{},[48,3969,3970,3973],{},[33,3971,3972],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[48,3975,3976,3979,3980,3983,3984,3987],{},[33,3977,3978],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[33,3981,3982],{},"shared"," 能观察到变化，",[33,3985,3986],{},"backup"," 不会。",[326,3989,2695],{"id":2695},[10,3991,3992],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,3994,3995],{},[26,3996],{"alt":3997,"src":3998},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4000,4001],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4003,180],{"id":180},[45,4005,4006,4014],{},[48,4007,4008,4009,4011,4012,360],{},"用 ",[33,4010,2805],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[33,4013,3893],{},[48,4015,4016],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4018,191],{"id":191},[166,4020,4021,4024],{},[48,4022,4023],{},"让两个变量引用同一个字典并修改其中一个。",[48,4025,2337,4026,4029,4030,1155,4032,360],{},[33,4027,4028],{},"copy()"," 创建外层副本，再比较 ",[33,4031,3893],{},[33,4033,2805],{},[10,4035,202],{},[14,4037,205],{"id":205},[10,4039,4040],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,4042,212],{},{"title":72,"searchDepth":85,"depth":85,"links":4044},[4045,4046,4047,4048,4049,4052,4053,4054],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":4050},[4051],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3853,"description":3858},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[223,4062,4063],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4066,"title":4067,"body":4068,"category":223,"cover":224,"description":4072,"extension":225,"meta":4284,"navigation":88,"path":4285,"pinned":228,"publishedAt":229,"seo":4286,"slug":4287,"stem":4288,"summary":4289,"tags":4290,"updatedAt":229,"visible":88,"__hash__":4292},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4069,"toc":4271},[4070,4073,4075,4078,4080,4086,4096,4098,4109,4111,4113,4165,4167,4173,4175,4177,4195,4197,4200,4206,4214,4217,4220,4226,4232,4234,4252,4254,4262,4264,4266,4269],[10,4071,4072],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4074,16],{"id":16},[10,4076,4077],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4079,22],{"id":22},[10,4081,4082],{},[26,4083],{"alt":4084,"src":4085},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4087,4088,2255,4090,2255,4093,4095],{},[33,4089,1154],{},[33,4091,4092],{},"elif",[33,4094,1158],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4097,43],{"id":43},[45,4099,4100,4103,4106],{},[48,4101,4102],{},"冒号表示接下来开始一个代码块。",[48,4104,4105],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[48,4107,4108],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4110,62],{"id":62},[10,4112,65],{},[67,4114,4116],{"className":69,"code":4115,"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",[33,4117,4118,4123,4127,4132,4137,4142,4147,4151,4156,4160],{"__ignoreMap":72},[76,4119,4120],{"class":78,"line":79},[76,4121,4122],{},"score = int(input(\"请输入分数：\"))\n",[76,4124,4125],{"class":78,"line":85},[76,4126,89],{"emptyLinePlaceholder":88},[76,4128,4129],{"class":78,"line":92},[76,4130,4131],{},"if score >= 90:\n",[76,4133,4134],{"class":78,"line":98},[76,4135,4136],{},"    level = \"优秀\"\n",[76,4138,4139],{"class":78,"line":103},[76,4140,4141],{},"elif score >= 60:\n",[76,4143,4144],{"class":78,"line":109},[76,4145,4146],{},"    level = \"合格\"\n",[76,4148,4149],{"class":78,"line":115},[76,4150,1144],{},[76,4152,4153],{"class":78,"line":121},[76,4154,4155],{},"    level = \"需要继续学习\"\n",[76,4157,4158],{"class":78,"line":126},[76,4159,89],{"emptyLinePlaceholder":88},[76,4161,4162],{"class":78,"line":132},[76,4163,4164],{},"print(level)\n",[10,4166,150],{},[67,4168,4171],{"className":4169,"code":4170,"language":156,"meta":72},[154],"输入 85 时输出：合格\n",[33,4172,4170],{"__ignoreMap":72},[10,4174,161],{},[14,4176,164],{"id":164},[166,4178,4179,4186],{},[48,4180,4181,4182,4185],{},"输入先转换为整数，程序从 ",[33,4183,4184],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[48,4187,4188,4191,4192,4194],{},[33,4189,4190],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[33,4193,1158],{}," 被跳过；最终三个分支只会选择一个。",[326,4196,2695],{"id":2695},[10,4198,4199],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4201,4202],{},[26,4203],{"alt":4204,"src":4205},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4207,4208,4210,4211,4213],{},[33,4209,4184],{}," 必须放在 ",[33,4212,4190],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[326,4215,2695],{"id":4216},"再看一个具体细节-1",[10,4218,4219],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4221,4222],{},[26,4223],{"alt":4224,"src":4225},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4227,4228,4229,4231],{},"同一缩进层级属于同一个代码块；回到 ",[33,4230,1154],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4233,180],{"id":180},[45,4235,4236,4242],{},[48,4237,4238,4239,4241],{},"先写 ",[33,4240,4190],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[48,4243,4244,4245,4247,4248,4251],{},"混用多个独立 ",[33,4246,1154],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[33,4249,4250],{},"if\u002Felif\u002Felse"," 链。",[14,4253,191],{"id":191},[166,4255,4256,4259],{},[48,4257,4258],{},"根据温度输出“冷、适中、热”三个等级。",[48,4260,4261],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4263,202],{},[14,4265,205],{"id":205},[10,4267,4268],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,4270,212],{},{"title":72,"searchDepth":85,"depth":85,"links":4272},[4273,4274,4275,4276,4277,4281,4282,4283],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":4278},[4279,4280],{"id":2695,"depth":92,"text":2695},{"id":4216,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4067,"description":4072},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[223,1154,4291],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4294,"title":4295,"body":4296,"category":223,"cover":224,"description":4300,"extension":225,"meta":4466,"navigation":88,"path":4467,"pinned":228,"publishedAt":229,"seo":4468,"slug":4469,"stem":4470,"summary":4471,"tags":4472,"updatedAt":229,"visible":88,"__hash__":4474},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4297,"toc":4454},[4298,4301,4303,4306,4308,4314,4320,4322,4337,4339,4341,4379,4381,4387,4389,4391,4406,4408,4411,4417,4423,4425,4433,4435,4445,4447,4449,4452],[10,4299,4300],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4302,16],{"id":16},[10,4304,4305],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4307,22],{"id":22},[10,4309,4310],{},[26,4311],{"alt":4312,"src":4313},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4315,4316,4319],{},[33,4317,4318],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4321,43],{"id":43},[45,4323,4324,4327,4330],{},[48,4325,4326],{},"进入循环前先准备参与条件判断的状态。",[48,4328,4329],{},"循环体中必须有机会让条件变为假。",[48,4331,4332,4333,4336],{},"能够预先确定遍历对象时，后续介绍的 ",[33,4334,4335],{},"for"," 通常更直接。",[14,4338,62],{"id":62},[10,4340,65],{},[67,4342,4344],{"className":69,"code":4343,"language":71,"meta":72,"style":72},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[33,4345,4346,4351,4355,4360,4365,4370,4374],{"__ignoreMap":72},[76,4347,4348],{"class":78,"line":79},[76,4349,4350],{},"count = 1\n",[76,4352,4353],{"class":78,"line":85},[76,4354,89],{"emptyLinePlaceholder":88},[76,4356,4357],{"class":78,"line":92},[76,4358,4359],{},"while count \u003C= 3:\n",[76,4361,4362],{"class":78,"line":98},[76,4363,4364],{},"    print(\"第\", count, \"次练习\")\n",[76,4366,4367],{"class":78,"line":103},[76,4368,4369],{},"    count = count + 1\n",[76,4371,4372],{"class":78,"line":109},[76,4373,89],{"emptyLinePlaceholder":88},[76,4375,4376],{"class":78,"line":115},[76,4377,4378],{},"print(\"练习结束\")\n",[10,4380,150],{},[67,4382,4385],{"className":4383,"code":4384,"language":156,"meta":72},[154],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[33,4386,4384],{"__ignoreMap":72},[10,4388,161],{},[14,4390,164],{"id":164},[166,4392,4393,4400],{},[48,4394,4395,4396,4399],{},"进入循环前 ",[33,4397,4398],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[48,4401,4402,4403,4405],{},"循环体末尾把 ",[33,4404,4398],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[326,4407,2695],{"id":2695},[10,4409,4410],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4412,4413],{},[26,4414],{"alt":4415,"src":4416},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4418,4419,4420,4422],{},"第4次检查时 ",[33,4421,4398],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4424,180],{"id":180},[45,4426,4427,4430],{},[48,4428,4429],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[48,4431,4432],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4434,191],{"id":191},[166,4436,4437,4442],{},[48,4438,2337,4439,4441],{},[33,4440,4318],{}," 输出 1 到 5。",[48,4443,4444],{},"计算 1 到 10 的累加和。",[10,4446,202],{},[14,4448,205],{"id":205},[10,4450,4451],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,4453,212],{},{"title":72,"searchDepth":85,"depth":85,"links":4455},[4456,4457,4458,4459,4460,4463,4464,4465],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":4461},[4462],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4295,"description":4300},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[223,4318,4473],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4476,"title":4477,"body":4478,"category":223,"cover":224,"description":4482,"extension":225,"meta":4630,"navigation":88,"path":4631,"pinned":228,"publishedAt":229,"seo":4632,"slug":4633,"stem":4634,"summary":4635,"tags":4636,"updatedAt":229,"visible":88,"__hash__":4638},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4479,"toc":4620},[4480,4483,4485,4488,4490,4496,4501,4503,4517,4519,4521,4559,4561,4567,4569,4571,4588,4590,4598,4600,4611,4613,4615,4618],[10,4481,4482],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4484,16],{"id":16},[10,4486,4487],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4489,22],{"id":22},[10,4491,4492],{},[26,4493],{"alt":4494,"src":4495},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4497,4498,4500],{},[33,4499,4335],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4502,43],{"id":43},[45,4504,4505,4511,4514],{},[48,4506,4507,4510],{},[33,4508,4509],{},"range(1, 4)"," 包含 1，不包含 4。",[48,4512,4513],{},"只需要元素时直接遍历元素，不必手工维护索引。",[48,4515,4516],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4518,62],{"id":62},[10,4520,65],{},[67,4522,4524],{"className":69,"code":4523,"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",[33,4525,4526,4531,4535,4540,4545,4549,4554],{"__ignoreMap":72},[76,4527,4528],{"class":78,"line":79},[76,4529,4530],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[76,4532,4533],{"class":78,"line":85},[76,4534,89],{"emptyLinePlaceholder":88},[76,4536,4537],{"class":78,"line":92},[76,4538,4539],{},"for course in courses:\n",[76,4541,4542],{"class":78,"line":98},[76,4543,4544],{},"    print(course)\n",[76,4546,4547],{"class":78,"line":103},[76,4548,89],{"emptyLinePlaceholder":88},[76,4550,4551],{"class":78,"line":109},[76,4552,4553],{},"for number in range(1, 4):\n",[76,4555,4556],{"class":78,"line":115},[76,4557,4558],{},"    print(number)\n",[10,4560,150],{},[67,4562,4565],{"className":4563,"code":4564,"language":156,"meta":72},[154],"变量\n字符串\n列表\n1\n2\n3\n",[33,4566,4564],{"__ignoreMap":72},[10,4568,161],{},[14,4570,164],{"id":164},[166,4572,4573,4583],{},[48,4574,4575,4576,4578,4579,4582],{},"第一个 ",[33,4577,4335],{}," 依次从列表取得字符串，循环变量 ",[33,4580,4581],{},"course"," 每轮重新绑定。",[48,4584,4585,4587],{},[33,4586,4509],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4589,180],{"id":180},[45,4591,4592,4595],{},[48,4593,4594],{},"只需要元素却手工维护索引，增加越界风险。",[48,4596,4597],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4599,191],{"id":191},[166,4601,4602,4605],{},[48,4603,4604],{},"逐项输出一个字符串中的字符。",[48,4606,2337,4607,4610],{},[33,4608,4609],{},"range()"," 输出 2、4、6、8。",[10,4612,202],{},[14,4614,205],{"id":205},[10,4616,4617],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,4619,212],{},{"title":72,"searchDepth":85,"depth":85,"links":4621},[4622,4623,4624,4625,4626,4627,4628,4629],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4477,"description":4482},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[223,4335,4637],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4640,"title":4641,"body":4642,"category":223,"cover":224,"description":4646,"extension":225,"meta":4820,"navigation":88,"path":4821,"pinned":228,"publishedAt":229,"seo":4822,"slug":4823,"stem":4824,"summary":4825,"tags":4826,"updatedAt":229,"visible":88,"__hash__":4827},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4643,"toc":4810},[4644,4647,4649,4652,4654,4660,4670,4672,4691,4693,4695,4747,4749,4755,4757,4759,4773,4775,4791,4793,4801,4803,4805,4808],[10,4645,4646],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4648,16],{"id":16},[10,4650,4651],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4653,22],{"id":22},[10,4655,4656],{},[26,4657],{"alt":4658,"src":4659},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4661,4662,4665,4666,4669],{},[33,4663,4664],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[33,4667,4668],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4671,43],{"id":43},[45,4673,4674,4677,4685],{},[48,4675,4676],{},"先写普通循环，再在确有需要时加入流程控制语句。",[48,4678,4679,4681,4682,4684],{},[33,4680,4664],{}," 前要确认不会跳过 ",[33,4683,4318],{}," 循环中的状态更新。",[48,4686,4687,4688,4690],{},"多层嵌套中 ",[33,4689,4668],{}," 只结束它所在的最内层循环。",[14,4692,62],{"id":62},[10,4694,65],{},[67,4696,4698],{"className":69,"code":4697,"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",[33,4699,4700,4705,4709,4714,4719,4724,4729,4734,4738,4742],{"__ignoreMap":72},[76,4701,4702],{"class":78,"line":79},[76,4703,4704],{},"numbers = [3, -1, 0, 8, 12]\n",[76,4706,4707],{"class":78,"line":85},[76,4708,89],{"emptyLinePlaceholder":88},[76,4710,4711],{"class":78,"line":92},[76,4712,4713],{},"for number in numbers:\n",[76,4715,4716],{"class":78,"line":98},[76,4717,4718],{},"    if number \u003C 0:\n",[76,4720,4721],{"class":78,"line":103},[76,4722,4723],{},"        continue\n",[76,4725,4726],{"class":78,"line":109},[76,4727,4728],{},"    if number == 0:\n",[76,4730,4731],{"class":78,"line":115},[76,4732,4733],{},"        break\n",[76,4735,4736],{"class":78,"line":121},[76,4737,4558],{},[76,4739,4740],{"class":78,"line":126},[76,4741,89],{"emptyLinePlaceholder":88},[76,4743,4744],{"class":78,"line":132},[76,4745,4746],{},"print(\"循环结束\")\n",[10,4748,150],{},[67,4750,4753],{"className":4751,"code":4752,"language":156,"meta":72},[154],"3\n循环结束\n",[33,4754,4752],{"__ignoreMap":72},[10,4756,161],{},[14,4758,164],{"id":164},[166,4760,4761,4767],{},[48,4762,4763,4764,4766],{},"遇到 -1 时 ",[33,4765,4664],{}," 立即结束本轮，后面的判断和输出都不执行。",[48,4768,4769,4770,4772],{},"遇到 0 时 ",[33,4771,4668],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4774,180],{"id":180},[45,4776,4777,4782],{},[48,4778,3465,4779,4781],{},[33,4780,4664],{}," 当作结束循环，实际它只跳到下一轮。",[48,4783,4784,4785,4787,4788,4790],{},"在 ",[33,4786,4318],{}," 中把状态更新放在可能被 ",[33,4789,4664],{}," 跳过的位置，造成无限循环。",[14,4792,191],{"id":191},[166,4794,4795,4798],{},[48,4796,4797],{},"跳过列表中的空字符串并输出其他内容。",[48,4799,4800],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4802,202],{},[14,4804,205],{"id":205},[10,4806,4807],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,4809,212],{},{"title":72,"searchDepth":85,"depth":85,"links":4811},[4812,4813,4814,4815,4816,4817,4818,4819],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4641,"description":4646},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[223,4668,4664],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4829,"title":4830,"body":4831,"category":223,"cover":224,"description":4835,"extension":225,"meta":5006,"navigation":88,"path":5007,"pinned":228,"publishedAt":229,"seo":5008,"slug":5009,"stem":5010,"summary":5011,"tags":5012,"updatedAt":229,"visible":88,"__hash__":5015},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4832,"toc":4994},[4833,4836,4838,4841,4843,4849,4852,4854,4878,4880,4882,4916,4918,4924,4926,4928,4945,4947,4950,4956,4959,4961,4975,4977,4985,4987,4989,4992],[10,4834,4835],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4837,16],{"id":16},[10,4839,4840],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4842,22],{"id":22},[10,4844,4845],{},[26,4846],{"alt":4847,"src":4848},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4850,4851],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4853,43],{"id":43},[45,4855,4856,4859,4862],{},[48,4857,4858],{},"每增加一层嵌套，阅读成本都会上升。",[48,4860,4861],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[48,4863,4864,4865,2255,4868,4871,4872,2255,4875,360],{},"变量名使用 ",[33,4866,4867],{},"row",[33,4869,4870],{},"cell"," 等层级含义，避免全部写成 ",[33,4873,4874],{},"i",[33,4876,4877],{},"j",[14,4879,62],{"id":62},[10,4881,65],{},[67,4883,4885],{"className":69,"code":4884,"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",[33,4886,4887,4892,4896,4901,4906,4911],{"__ignoreMap":72},[76,4888,4889],{"class":78,"line":79},[76,4890,4891],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[76,4893,4894],{"class":78,"line":85},[76,4895,89],{"emptyLinePlaceholder":88},[76,4897,4898],{"class":78,"line":92},[76,4899,4900],{},"for row in table:\n",[76,4902,4903],{"class":78,"line":98},[76,4904,4905],{},"    for cell in row:\n",[76,4907,4908],{"class":78,"line":103},[76,4909,4910],{},"        print(cell)\n",[76,4912,4913],{"class":78,"line":109},[76,4914,4915],{},"    print(\"一行结束\")\n",[10,4917,150],{},[67,4919,4922],{"className":4920,"code":4921,"language":156,"meta":72},[154],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[33,4923,4921],{"__ignoreMap":72},[10,4925,161],{},[14,4927,164],{"id":164},[166,4929,4930,4942],{},[48,4931,4932,4933,4935,4936,1155,4939,360],{},"外层变量 ",[33,4934,4867],{}," 先引用第一行列表，内层才依次处理 ",[33,4937,4938],{},"A1",[33,4940,4941],{},"A2",[48,4943,4944],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[326,4946,2695],{"id":2695},[10,4948,4949],{},"二维列表的输出顺序可以展开成一条时间线。",[10,4951,4952],{},[26,4953],{"alt":4954,"src":4955},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,4957,4958],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,4960,180],{"id":180},[45,4962,4963,4972],{},[48,4964,4965,4966,1007,4969,4971],{},"把两层循环变量都叫 ",[33,4967,4968],{},"item",[33,4970,4874],{},"，难以确认当前层级。",[48,4973,4974],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,4976,191],{"id":191},[166,4978,4979,4982],{},[48,4980,4981],{},"打印一个 2×3 数字表。",[48,4983,4984],{},"在内层增加条件，只输出大于 3 的元素。",[10,4986,202],{},[14,4988,205],{"id":205},[10,4990,4991],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,4993,212],{},{"title":72,"searchDepth":85,"depth":85,"links":4995},[4996,4997,4998,4999,5000,5003,5004,5005],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":5001},[5002],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4830,"description":4835},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[223,5013,5014],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5017,"title":5018,"body":5019,"category":223,"cover":224,"description":5023,"extension":225,"meta":5161,"navigation":88,"path":5162,"pinned":228,"publishedAt":229,"seo":5163,"slug":5164,"stem":5165,"summary":5166,"tags":5167,"updatedAt":229,"visible":88,"__hash__":5170},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5020,"toc":5151},[5021,5024,5026,5029,5031,5037,5040,5042,5053,5055,5057,5095,5097,5103,5105,5107,5119,5121,5132,5134,5142,5144,5146,5149],[10,5022,5023],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5025,16],{"id":16},[10,5027,5028],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5030,22],{"id":22},[10,5032,5033],{},[26,5034],{"alt":5035,"src":5036},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5038,5039],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5041,43],{"id":43},[45,5043,5044,5047,5050],{},[48,5045,5046],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[48,5048,5049],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[48,5051,5052],{},"推导式创建新列表，不修改输入列表。",[14,5054,62],{"id":62},[10,5056,65],{},[67,5058,5060],{"className":69,"code":5059,"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",[33,5061,5062,5067,5071,5076,5081,5085,5090],{"__ignoreMap":72},[76,5063,5064],{"class":78,"line":79},[76,5065,5066],{},"numbers = [1, 2, 3, 4, 5]\n",[76,5068,5069],{"class":78,"line":85},[76,5070,89],{"emptyLinePlaceholder":88},[76,5072,5073],{"class":78,"line":92},[76,5074,5075],{},"squares = [number * number for number in numbers]\n",[76,5077,5078],{"class":78,"line":98},[76,5079,5080],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[76,5082,5083],{"class":78,"line":103},[76,5084,89],{"emptyLinePlaceholder":88},[76,5086,5087],{"class":78,"line":109},[76,5088,5089],{},"print(squares)\n",[76,5091,5092],{"class":78,"line":115},[76,5093,5094],{},"print(even_squares)\n",[10,5096,150],{},[67,5098,5101],{"className":5099,"code":5100,"language":156,"meta":72},[154],"[1, 4, 9, 16, 25]\n[4, 16]\n",[33,5102,5100],{"__ignoreMap":72},[10,5104,161],{},[14,5106,164],{"id":164},[166,5108,5109,5112],{},[48,5110,5111],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[48,5113,5114,5115,5118],{},"第二条先用 ",[33,5116,5117],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5120,180],{"id":180},[45,5122,5123,5129],{},[48,5124,5125,5126,5128],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[33,5127,4335],{}," 开始找输入。",[48,5130,5131],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5133,191],{"id":191},[166,5135,5136,5139],{},[48,5137,5138],{},"把字符串列表转换为长度列表。",[48,5140,5141],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5143,202],{},[14,5145,205],{"id":205},[10,5147,5148],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,5150,212],{},{"title":72,"searchDepth":85,"depth":85,"links":5152},[5153,5154,5155,5156,5157,5158,5159,5160],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5018,"description":5023},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[223,5168,5169],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5172,"title":5173,"body":5174,"category":223,"cover":224,"description":5178,"extension":225,"meta":5321,"navigation":88,"path":5322,"pinned":228,"publishedAt":229,"seo":5323,"slug":5324,"stem":5325,"summary":5326,"tags":5327,"updatedAt":229,"visible":88,"__hash__":5330},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5175,"toc":5311},[5176,5179,5181,5184,5186,5192,5195,5197,5208,5210,5212,5251,5253,5259,5261,5263,5278,5280,5288,5290,5302,5304,5306,5309],[10,5177,5178],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5180,16],{"id":16},[10,5182,5183],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5185,22],{"id":22},[10,5187,5188],{},[26,5189],{"alt":5190,"src":5191},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5193,5194],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5196,43],{"id":43},[45,5198,5199,5202,5205],{},[48,5200,5201],{},"函数名描述动作，使用小写字母和下划线。",[48,5203,5204],{},"函数定义要先执行，之后才能调用。",[48,5206,5207],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5209,62],{"id":62},[10,5211,65],{},[67,5213,5215],{"className":69,"code":5214,"language":71,"meta":72,"style":72},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[33,5216,5217,5222,5227,5232,5236,5241,5246],{"__ignoreMap":72},[76,5218,5219],{"class":78,"line":79},[76,5220,5221],{},"def show_progress():\n",[76,5223,5224],{"class":78,"line":85},[76,5225,5226],{},"    print(\"正在学习函数\")\n",[76,5228,5229],{"class":78,"line":92},[76,5230,5231],{},"    print(\"本节完成 50%\")\n",[76,5233,5234],{"class":78,"line":98},[76,5235,89],{"emptyLinePlaceholder":88},[76,5237,5238],{"class":78,"line":103},[76,5239,5240],{},"print(\"调用前\")\n",[76,5242,5243],{"class":78,"line":109},[76,5244,5245],{},"show_progress()\n",[76,5247,5248],{"class":78,"line":115},[76,5249,5250],{},"print(\"调用后\")\n",[10,5252,150],{},[67,5254,5257],{"className":5255,"code":5256,"language":156,"meta":72},[154],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[33,5258,5256],{"__ignoreMap":72},[10,5260,161],{},[14,5262,164],{"id":164},[166,5264,5265,5271],{},[48,5266,936,5267,5270],{},[33,5268,5269],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[48,5272,5273,5274,5277],{},"运行到 ",[33,5275,5276],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5279,180],{"id":180},[45,5281,5282,5285],{},[48,5283,5284],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[48,5286,5287],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5289,191],{"id":191},[166,5291,5292,5299],{},[48,5293,5294,5295,5298],{},"定义 ",[33,5296,5297],{},"show_plan()"," 输出两行学习计划。",[48,5300,5301],{},"连续调用同一个函数两次，观察执行顺序。",[10,5303,202],{},[14,5305,205],{"id":205},[10,5307,5308],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,5310,212],{},{"title":72,"searchDepth":85,"depth":85,"links":5312},[5313,5314,5315,5316,5317,5318,5319,5320],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5173,"description":5178},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[223,5328,5329],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5332,"title":5333,"body":5334,"category":223,"cover":224,"description":5338,"extension":225,"meta":5518,"navigation":88,"path":5519,"pinned":228,"publishedAt":229,"seo":5520,"slug":5521,"stem":5522,"summary":5523,"tags":5524,"updatedAt":229,"visible":88,"__hash__":5527},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5335,"toc":5506},[5336,5339,5341,5344,5346,5352,5359,5361,5378,5380,5382,5416,5418,5424,5426,5428,5449,5451,5454,5460,5470,5472,5487,5489,5497,5499,5501,5504],[10,5337,5338],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5340,16],{"id":16},[10,5342,5343],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5345,22],{"id":22},[10,5347,5348],{},[26,5349],{"alt":5350,"src":5351},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5353,5354,5355,5358],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[33,5356,5357],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5360,43],{"id":43},[45,5362,5363,5366,5369],{},[48,5364,5365],{},"形参出现在函数定义中，实参出现在函数调用中。",[48,5367,5368],{},"局部变量默认只在函数内部可见。",[48,5370,5371,5372,5374,5375,360],{},"没有显式 ",[33,5373,5357],{}," 的函数会返回 ",[33,5376,5377],{},"None",[14,5379,62],{"id":62},[10,5381,65],{},[67,5383,5385],{"className":69,"code":5384,"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",[33,5386,5387,5392,5397,5402,5406,5411],{"__ignoreMap":72},[76,5388,5389],{"class":78,"line":79},[76,5390,5391],{},"def calculate_total(price, count):\n",[76,5393,5394],{"class":78,"line":85},[76,5395,5396],{},"    total = price * count\n",[76,5398,5399],{"class":78,"line":92},[76,5400,5401],{},"    return total\n",[76,5403,5404],{"class":78,"line":98},[76,5405,89],{"emptyLinePlaceholder":88},[76,5407,5408],{"class":78,"line":103},[76,5409,5410],{},"result = calculate_total(25, 4)\n",[76,5412,5413],{"class":78,"line":109},[76,5414,5415],{},"print(result)\n",[10,5417,150],{},[67,5419,5422],{"className":5420,"code":5421,"language":156,"meta":72},[154],"100\n",[33,5423,5421],{"__ignoreMap":72},[10,5425,161],{},[14,5427,164],{"id":164},[166,5429,5430,5439],{},[48,5431,5432,5433,2255,5436,5438],{},"调用时 25 和 4 分别绑定到 ",[33,5434,5435],{},"price",[33,5437,4398],{},"，它们只在本次函数调用的局部范围中使用。",[48,5440,5441,5444,5445,5448],{},[33,5442,5443],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[33,5446,5447],{},"result"," 并输出。",[326,5450,2695],{"id":2695},[10,5452,5453],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5455,5456],{},[26,5457],{"alt":5458,"src":5459},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5461,5462,2255,5464,1155,5466,5469],{},[33,5463,5435],{},[33,5465,4398],{},[33,5467,5468],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5471,180],{"id":180},[45,5473,5474,5481],{},[48,5475,5476,5477,5480],{},"在函数内部只 ",[33,5478,5479],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[48,5482,5483,5484,5486],{},"试图在函数外直接访问局部变量 ",[33,5485,5468],{},"，它的名字只在调用期间的局部作用域存在。",[14,5488,191],{"id":191},[166,5490,5491,5494],{},[48,5492,5493],{},"编写计算长方形面积的函数。",[48,5495,5496],{},"让函数返回结果后在调用方加上单位再输出。",[10,5498,202],{},[14,5500,205],{"id":205},[10,5502,5503],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,5505,212],{},{"title":72,"searchDepth":85,"depth":85,"links":5507},[5508,5509,5510,5511,5512,5515,5516,5517],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":5513},[5514],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5333,"description":5338},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[223,5525,5526],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5529,"title":5530,"body":5531,"category":223,"cover":224,"description":5535,"extension":225,"meta":5715,"navigation":88,"path":5716,"pinned":228,"publishedAt":229,"seo":5717,"slug":5718,"stem":5719,"summary":5720,"tags":5721,"updatedAt":229,"visible":88,"__hash__":5724},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5532,"toc":5703},[5533,5536,5538,5541,5543,5549,5552,5554,5571,5573,5575,5627,5629,5635,5637,5639,5657,5659,5662,5668,5671,5673,5684,5686,5694,5696,5698,5701],[10,5534,5535],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5537,16],{"id":16},[10,5539,5540],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5542,22],{"id":22},[10,5544,5545],{},[26,5546],{"alt":5547,"src":5548},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5550,5551],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5553,43],{"id":43},[45,5555,5556,5559,5565],{},[48,5557,5558],{},"必需参数应放在有默认值的参数之前。",[48,5560,5561,5564],{},[33,5562,5563],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[48,5566,5567,5570],{},[33,5568,5569],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5572,62],{"id":62},[10,5574,65],{},[67,5576,5578],{"className":69,"code":5577,"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",[33,5579,5580,5585,5590,5594,5599,5604,5608,5613,5618,5622],{"__ignoreMap":72},[76,5581,5582],{"class":78,"line":79},[76,5583,5584],{},"def build_title(name, level=\"基础\"):\n",[76,5586,5587],{"class":78,"line":85},[76,5588,5589],{},"    return name + \"｜\" + level\n",[76,5591,5592],{"class":78,"line":92},[76,5593,89],{"emptyLinePlaceholder":88},[76,5595,5596],{"class":78,"line":98},[76,5597,5598],{},"print(build_title(\"Python\"))\n",[76,5600,5601],{"class":78,"line":103},[76,5602,5603],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[76,5605,5606],{"class":78,"line":109},[76,5607,89],{"emptyLinePlaceholder":88},[76,5609,5610],{"class":78,"line":115},[76,5611,5612],{},"def total(*numbers):\n",[76,5614,5615],{"class":78,"line":121},[76,5616,5617],{},"    return sum(numbers)\n",[76,5619,5620],{"class":78,"line":126},[76,5621,89],{"emptyLinePlaceholder":88},[76,5623,5624],{"class":78,"line":132},[76,5625,5626],{},"print(total(10, 20, 30))\n",[10,5628,150],{},[67,5630,5633],{"className":5631,"code":5632,"language":156,"meta":72},[154],"Python｜基础\n异常处理｜进阶\n60\n",[33,5634,5632],{"__ignoreMap":72},[10,5636,161],{},[14,5638,164],{"id":164},[166,5640,5641,5648],{},[48,5642,5643,5644,5647],{},"第一次调用只提供必需参数，",[33,5645,5646],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[48,5649,5650,5653,5654,360],{},[33,5651,5652],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[33,5655,5656],{},"sum()",[326,5658,2695],{"id":2695},[10,5660,5661],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5663,5664],{},[26,5665],{"alt":5666,"src":5667},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5669,5670],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5672,180],{"id":180},[45,5674,5675,5681],{},[48,5676,5677,5678,5680],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[33,5679,5377],{}," 再在函数内创建。",[48,5682,5683],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5685,191],{"id":191},[166,5687,5688,5691],{},[48,5689,5690],{},"给问候函数增加默认称呼。",[48,5692,5693],{},"编写接收任意数量分数并返回总分的函数。",[10,5695,202],{},[14,5697,205],{"id":205},[10,5699,5700],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,5702,212],{},{"title":72,"searchDepth":85,"depth":85,"links":5704},[5705,5706,5707,5708,5709,5712,5713,5714],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":5710},[5711],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5530,"description":5535},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[223,5722,5723],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5726,"title":5727,"body":5728,"category":223,"cover":224,"description":5732,"extension":225,"meta":5927,"navigation":88,"path":5928,"pinned":228,"publishedAt":229,"seo":5929,"slug":5930,"stem":5931,"summary":5932,"tags":5933,"updatedAt":229,"visible":88,"__hash__":5936},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5729,"toc":5915},[5730,5733,5735,5738,5740,5746,5749,5751,5768,5770,5772,5833,5835,5841,5843,5845,5872,5874,5877,5883,5886,5888,5896,5898,5906,5908,5910,5913],[10,5731,5732],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5734,16],{"id":16},[10,5736,5737],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5739,22],{"id":22},[10,5741,5742],{},[26,5743],{"alt":5744,"src":5745},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5747,5748],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5750,43],{"id":43},[45,5752,5753,5756,5759],{},[48,5754,5755],{},"函数内部赋值默认创建局部变量。",[48,5757,5758],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[48,5760,5761,2174,5764,5767],{},[33,5762,5763],{},"global",[33,5765,5766],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5769,62],{"id":62},[10,5771,65],{},[67,5773,5775],{"className":69,"code":5774,"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",[33,5776,5777,5782,5786,5791,5796,5800,5805,5810,5815,5819,5824,5828],{"__ignoreMap":72},[76,5778,5779],{"class":78,"line":79},[76,5780,5781],{},"course = \"Python\"\n",[76,5783,5784],{"class":78,"line":85},[76,5785,89],{"emptyLinePlaceholder":88},[76,5787,5788],{"class":78,"line":92},[76,5789,5790],{},"def outer():\n",[76,5792,5793],{"class":78,"line":98},[76,5794,5795],{},"    level = \"基础\"\n",[76,5797,5798],{"class":78,"line":103},[76,5799,89],{"emptyLinePlaceholder":88},[76,5801,5802],{"class":78,"line":109},[76,5803,5804],{},"    def show():\n",[76,5806,5807],{"class":78,"line":115},[76,5808,5809],{},"        lesson = \"作用域\"\n",[76,5811,5812],{"class":78,"line":121},[76,5813,5814],{},"        print(course, level, lesson)\n",[76,5816,5817],{"class":78,"line":126},[76,5818,89],{"emptyLinePlaceholder":88},[76,5820,5821],{"class":78,"line":132},[76,5822,5823],{},"    show()\n",[76,5825,5826],{"class":78,"line":138},[76,5827,89],{"emptyLinePlaceholder":88},[76,5829,5830],{"class":78,"line":144},[76,5831,5832],{},"outer()\n",[10,5834,150],{},[67,5836,5839],{"className":5837,"code":5838,"language":156,"meta":72},[154],"Python 基础 作用域\n",[33,5840,5838],{"__ignoreMap":72},[10,5842,161],{},[14,5844,164],{"id":164},[166,5846,5847,5864],{},[48,5848,5849,5852,5853,5856,5857,5859,5860,5863],{},[33,5850,5851],{},"show()"," 中查找 ",[33,5854,5855],{},"lesson"," 时先在局部找到，查找 ",[33,5858,5646],{}," 时到外层 ",[33,5861,5862],{},"outer()"," 找到。",[48,5865,5866,5868,5869,5871],{},[33,5867,4581],{}," 在局部和外层都不存在，继续到模块全局找到；",[33,5870,2206],{}," 最后在内置作用域找到。",[326,5873,2695],{"id":2695},[10,5875,5876],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5878,5879],{},[26,5880],{"alt":5881,"src":5882},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5884,5885],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5887,180],{"id":180},[45,5889,5890,5893],{},[48,5891,5892],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[48,5894,5895],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5897,191],{"id":191},[166,5899,5900,5903],{},[48,5901,5902],{},"在内外层定义同名变量，观察最近作用域优先。",[48,5904,5905],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5907,202],{},[14,5909,205],{"id":205},[10,5911,5912],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,5914,212],{},{"title":72,"searchDepth":85,"depth":85,"links":5916},[5917,5918,5919,5920,5921,5924,5925,5926],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":5922},[5923],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5727,"description":5732},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[223,5934,5935],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5938,"title":5939,"body":5940,"category":223,"cover":224,"description":5944,"extension":225,"meta":6094,"navigation":88,"path":6095,"pinned":228,"publishedAt":229,"seo":6096,"slug":6097,"stem":6098,"summary":6099,"tags":6100,"updatedAt":229,"visible":88,"__hash__":6103},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5941,"toc":6084},[5942,5945,5947,5950,5952,5958,5961,5963,5982,5984,5986,6020,6022,6028,6030,6032,6047,6049,6061,6063,6075,6077,6079,6082],[10,5943,5944],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,5946,16],{"id":16},[10,5948,5949],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5951,22],{"id":22},[10,5953,5954],{},[26,5955],{"alt":5956,"src":5957},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,5959,5960],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,5962,43],{"id":43},[45,5964,5965,5968,5971],{},[48,5966,5967],{},"文档字符串紧跟在函数定义后的第一条语句。",[48,5969,5970],{},"注解表达接口意图，不代替输入校验和测试。",[48,5972,5973,5974,2255,5976,2255,5978,5981],{},"基础注解优先使用 ",[33,5975,2258],{},[33,5977,2424],{},[33,5979,5980],{},"list[str]"," 等直接写法。",[14,5983,62],{"id":62},[10,5985,65],{},[67,5987,5989],{"className":69,"code":5988,"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",[33,5990,5991,5996,6001,6006,6010,6015],{"__ignoreMap":72},[76,5992,5993],{"class":78,"line":79},[76,5994,5995],{},"def format_score(name: str, score: int) -> str:\n",[76,5997,5998],{"class":78,"line":85},[76,5999,6000],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[76,6002,6003],{"class":78,"line":92},[76,6004,6005],{},"    return name + \"：\" + str(score)\n",[76,6007,6008],{"class":78,"line":98},[76,6009,89],{"emptyLinePlaceholder":88},[76,6011,6012],{"class":78,"line":103},[76,6013,6014],{},"print(format_score(\"小郑\", 95))\n",[76,6016,6017],{"class":78,"line":109},[76,6018,6019],{},"print(format_score.__doc__)\n",[10,6021,150],{},[67,6023,6026],{"className":6024,"code":6025,"language":156,"meta":72},[154],"小郑：95\n返回带姓名的分数文本。\n",[33,6027,6025],{"__ignoreMap":72},[10,6029,161],{},[14,6031,164],{"id":164},[166,6033,6034,6044],{},[48,6035,6036,6037,6040,6041,6043],{},"函数签名说明 ",[33,6038,6039],{},"name"," 预期为字符串、",[33,6042,2244],{}," 预期为整数，返回值预期为字符串。",[48,6045,6046],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6048,180],{"id":180},[45,6050,6051,6058],{},[48,6052,6053,6054,6057],{},"认为加了 ",[33,6055,6056],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[48,6059,6060],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6062,191],{"id":191},[166,6064,6065,6068],{},[48,6066,6067],{},"为面积函数补充参数和返回值注解。",[48,6069,6070,6071,6074],{},"通过 ",[33,6072,6073],{},"函数名.__doc__"," 查看文档字符串。",[10,6076,202],{},[14,6078,205],{"id":205},[10,6080,6081],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,6083,212],{},{"title":72,"searchDepth":85,"depth":85,"links":6085},[6086,6087,6088,6089,6090,6091,6092,6093],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5939,"description":5944},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[223,6101,6102],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6105,"title":6106,"body":6107,"category":223,"cover":224,"description":6111,"extension":225,"meta":6338,"navigation":88,"path":6339,"pinned":228,"publishedAt":229,"seo":6340,"slug":6341,"stem":6342,"summary":6343,"tags":6344,"updatedAt":229,"visible":88,"__hash__":6347},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6108,"toc":6326},[6109,6112,6114,6120,6122,6128,6139,6141,6159,6161,6168,6197,6204,6223,6232,6234,6240,6242,6244,6267,6269,6272,6278,6284,6286,6302,6304,6317,6319,6321,6324],[10,6110,6111],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6113,16],{"id":16},[10,6115,6116,6117,6119],{},"本篇只处理“模块、import 与 ",[292,6118,6039],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6121,22],{"id":22},[10,6123,6124],{},[26,6125],{"alt":6126,"src":6127},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6129,6130,6131,6134,6135,6138],{},"同一个文件直接运行时 ",[33,6132,6133],{},"__name__"," 等于 ",[33,6136,6137],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6140,43],{"id":43},[45,6142,6143,6149,6152],{},[48,6144,6145,6146,6148],{},"一个 ",[33,6147,1169],{}," 文件就是一个模块。",[48,6150,6151],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[48,6153,6154,6155,6158],{},"避免使用 ",[33,6156,6157],{},"from module import *","，它会让名字来源不清楚。",[14,6160,62],{"id":62},[10,6162,6163,6164,6167],{},"先在同一个目录中创建两个文件。把函数放进 ",[33,6165,6166],{},"calculator.py","：",[67,6169,6171],{"className":69,"code":6170,"language":71,"meta":72,"style":72},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[33,6172,6173,6178,6183,6187,6192],{"__ignoreMap":72},[76,6174,6175],{"class":78,"line":79},[76,6176,6177],{},"def add(left, right):\n",[76,6179,6180],{"class":78,"line":85},[76,6181,6182],{},"    return left + right\n",[76,6184,6185],{"class":78,"line":92},[76,6186,89],{"emptyLinePlaceholder":88},[76,6188,6189],{"class":78,"line":98},[76,6190,6191],{},"if __name__ == \"__main__\":\n",[76,6193,6194],{"class":78,"line":103},[76,6195,6196],{},"    print(add(2, 3))\n",[10,6198,6199,6200,6203],{},"再创建 ",[33,6201,6202],{},"app.py","，从模块中导入函数：",[67,6205,6207],{"className":69,"code":6206,"language":71,"meta":72,"style":72},"from calculator import add\n\nprint(add(10, 20))\n",[33,6208,6209,6214,6218],{"__ignoreMap":72},[76,6210,6211],{"class":78,"line":79},[76,6212,6213],{},"from calculator import add\n",[76,6215,6216],{"class":78,"line":85},[76,6217,89],{"emptyLinePlaceholder":88},[76,6219,6220],{"class":78,"line":92},[76,6221,6222],{},"print(add(10, 20))\n",[10,6224,6225,6226,1155,6229,360],{},"分别执行 ",[33,6227,6228],{},"python3 calculator.py",[33,6230,6231],{},"python3 app.py",[10,6233,150],{},[67,6235,6238],{"className":6236,"code":6237,"language":156,"meta":72},[154],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[33,6239,6237],{"__ignoreMap":72},[10,6241,161],{},[14,6243,164],{"id":164},[166,6245,6246,6256],{},[48,6247,6248,6249,6251,6252,6255],{},"直接运行 ",[33,6250,6166],{}," 时，模块名是 ",[33,6253,6254],{},"__main__","，入口代码输出 5。",[48,6257,6258,6260,6261,6263,6264,6266],{},[33,6259,6202],{}," 导入模块时，",[33,6262,6166],{}," 的函数定义会执行，但入口判断为假；随后 ",[33,6265,6202],{}," 调用函数输出 30。",[326,6268,2695],{"id":2695},[10,6270,6271],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6273,6274],{},[26,6275],{"alt":6276,"src":6277},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6279,6280,6281,6283],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[33,6282,6254],{}," 保护下的演示代码。",[14,6285,180],{"id":180},[45,6287,6288,6295],{},[48,6289,6290,6291,1155,6293,360],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[33,6292,6166],{},[33,6294,6202],{},[48,6296,6297,6298,6301],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[33,6299,6300],{},"json.py","，导致导入目标被遮蔽。",[14,6303,191],{"id":191},[166,6305,6306,6312],{},[48,6307,2352,6308,6311],{},[33,6309,6310],{},"text_tools.py"," 并导出一个格式化函数。",[48,6313,6314,6315,360],{},"分别直接运行模块和从另一个脚本导入，输出 ",[33,6316,6133],{},[10,6318,202],{},[14,6320,205],{"id":205},[10,6322,6323],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,6325,212],{},{"title":72,"searchDepth":85,"depth":85,"links":6327},[6328,6329,6330,6331,6332,6335,6336,6337],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":6333},[6334],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6106,"description":6111},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[223,6345,6346],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6349,"title":6350,"body":6351,"category":223,"cover":224,"description":6355,"extension":225,"meta":6520,"navigation":88,"path":6521,"pinned":228,"publishedAt":229,"seo":6522,"slug":6523,"stem":6524,"summary":6525,"tags":6526,"updatedAt":229,"visible":88,"__hash__":6528},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6352,"toc":6510},[6353,6356,6358,6361,6363,6369,6372,6374,6388,6390,6392,6438,6440,6446,6448,6450,6476,6478,6488,6490,6501,6503,6505,6508],[10,6354,6355],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6357,16],{"id":16},[10,6359,6360],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6362,22],{"id":22},[10,6364,6365],{},[26,6366],{"alt":6367,"src":6368},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6370,6371],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6373,43],{"id":43},[45,6375,6376,6382,6385],{},[48,6377,6378,6381],{},[33,6379,6380],{},".venv"," 是常见目录名，不应提交到 Git。",[48,6383,6384],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[48,6386,6387],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6389,62],{"id":62},[10,6391,1572],{},[67,6393,6395],{"className":589,"code":6394,"language":591,"meta":72,"style":72},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[33,6396,6397,6409,6417,6423,6433],{"__ignoreMap":72},[76,6398,6399,6401,6403,6406],{"class":78,"line":79},[76,6400,689],{"class":598},[76,6402,631],{"class":601},[76,6404,6405],{"class":634}," venv",[76,6407,6408],{"class":634}," .venv\n",[76,6410,6411,6414],{"class":78,"line":85},[76,6412,6413],{"class":601},"source",[76,6415,6416],{"class":634}," .venv\u002Fbin\u002Factivate\n",[76,6418,6419,6421],{"class":78,"line":92},[76,6420,71],{"class":598},[76,6422,602],{"class":601},[76,6424,6425,6427,6429,6431],{"class":78,"line":98},[76,6426,71],{"class":598},[76,6428,631],{"class":601},[76,6430,635],{"class":634},[76,6432,602],{"class":601},[76,6434,6435],{"class":78,"line":103},[76,6436,6437],{"class":598},"deactivate\n",[10,6439,150],{},[67,6441,6444],{"className":6442,"code":6443,"language":156,"meta":72},[154],"Python 和 pip 的路径应指向当前项目的 .venv\n",[33,6445,6443],{"__ignoreMap":72},[10,6447,161],{},[14,6449,164],{"id":164},[166,6451,6452,6461],{},[48,6453,6454,6457,6458,6460],{},[33,6455,6456],{},"venv"," 根据当前 ",[33,6459,689],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[48,6462,6463,6464,2174,6466,6469,6470,3726,6472,6475],{},"激活后 ",[33,6465,71],{},[33,6467,6468],{},"python -m pip"," 优先指向 ",[33,6471,6380],{},[33,6473,6474],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6477,180],{"id":180},[45,6479,6480,6483],{},[48,6481,6482],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[48,6484,3465,6485,6487],{},[33,6486,6380],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6489,191],{"id":191},[166,6491,6492,6498],{},[48,6493,6494,6495,360],{},"创建虚拟环境并记录激活前后的 ",[33,6496,6497],{},"which python",[48,6499,6500],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6502,202],{},[14,6504,205],{"id":205},[10,6506,6507],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,6509,1656],{},{"title":72,"searchDepth":85,"depth":85,"links":6511},[6512,6513,6514,6515,6516,6517,6518,6519],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6350,"description":6355},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[223,6527,258],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6530,"title":6531,"body":6532,"category":223,"cover":224,"description":6536,"extension":225,"meta":6724,"navigation":88,"path":6725,"pinned":228,"publishedAt":229,"seo":6726,"slug":6727,"stem":6728,"summary":6729,"tags":6730,"updatedAt":229,"visible":88,"__hash__":6733},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6533,"toc":6714},[6534,6537,6539,6542,6544,6550,6559,6561,6585,6587,6589,6642,6644,6650,6652,6654,6670,6672,6691,6693,6705,6707,6709,6712],[10,6535,6536],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6538,16],{"id":16},[10,6540,6541],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6543,22],{"id":22},[10,6545,6546],{},[26,6547],{"alt":6548,"src":6549},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6551,6552,6555,6556,6558],{},[33,6553,6554],{},"Path"," 使用 ",[33,6557,2434],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6560,43],{"id":43},[45,6562,6563,6566,6578],{},[48,6564,6565],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[48,6567,6568,2255,6571,2255,6574,6577],{},[33,6569,6570],{},"exists()",[33,6572,6573],{},"is_file()",[33,6575,6576],{},"is_dir()"," 检查真实文件系统状态。",[48,6579,6580,6581,6584],{},"创建目录前明确目标；",[33,6582,6583],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6586,62],{"id":62},[10,6588,65],{},[67,6590,6592],{"className":69,"code":6591,"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",[33,6593,6594,6599,6603,6608,6613,6618,6622,6627,6632,6637],{"__ignoreMap":72},[76,6595,6596],{"class":78,"line":79},[76,6597,6598],{},"from pathlib import Path\n",[76,6600,6601],{"class":78,"line":85},[76,6602,89],{"emptyLinePlaceholder":88},[76,6604,6605],{"class":78,"line":92},[76,6606,6607],{},"project = Path.cwd()\n",[76,6609,6610],{"class":78,"line":98},[76,6611,6612],{},"data_dir = project \u002F \"data\"\n",[76,6614,6615],{"class":78,"line":103},[76,6616,6617],{},"file_path = data_dir \u002F \"records.json\"\n",[76,6619,6620],{"class":78,"line":109},[76,6621,89],{"emptyLinePlaceholder":88},[76,6623,6624],{"class":78,"line":115},[76,6625,6626],{},"print(project)\n",[76,6628,6629],{"class":78,"line":121},[76,6630,6631],{},"print(file_path.name)\n",[76,6633,6634],{"class":78,"line":126},[76,6635,6636],{},"print(file_path.suffix)\n",[76,6638,6639],{"class":78,"line":132},[76,6640,6641],{},"print(file_path.exists())\n",[10,6643,150],{},[67,6645,6648],{"className":6646,"code":6647,"language":156,"meta":72},[154],"显示当前项目路径、records.json、.json 和存在状态\n",[33,6649,6647],{"__ignoreMap":72},[10,6651,161],{},[14,6653,164],{"id":164},[166,6655,6656,6662],{},[48,6657,6658,6661],{},[33,6659,6660],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[48,6663,2337,6664,6666,6667,6669],{},[33,6665,2434],{}," 组合路径片段只创建新的 ",[33,6668,6554],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6671,180],{"id":180},[45,6673,6674,6682],{},[48,6675,3465,6676,6678,6679,6681],{},[33,6677,6554],{}," 对象存在当成真实文件存在，仍需调用 ",[33,6680,6570],{}," 等方法确认。",[48,6683,6684,6685,1007,6687,6690],{},"手工拼接 ",[33,6686,2434],{},[33,6688,6689],{},"\\"," 分隔符，降低跨平台可读性。",[14,6692,191],{"id":191},[166,6694,6695,6702],{},[48,6696,6697,6698,6701],{},"组合 ",[33,6699,6700],{},"output\u002Freport.txt"," 路径但先不创建文件。",[48,6703,6704],{},"输出路径的父目录、文件名和扩展名。",[10,6706,202],{},[14,6708,205],{"id":205},[10,6710,6711],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,6713,212],{},{"title":72,"searchDepth":85,"depth":85,"links":6715},[6716,6717,6718,6719,6720,6721,6722,6723],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6531,"description":6536},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[223,6731,6732],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6735,"title":6736,"body":6737,"category":223,"cover":224,"description":6741,"extension":225,"meta":6917,"navigation":88,"path":6918,"pinned":228,"publishedAt":229,"seo":6919,"slug":6920,"stem":6921,"summary":6922,"tags":6923,"updatedAt":229,"visible":88,"__hash__":6926},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6738,"toc":6907},[6739,6742,6744,6747,6749,6755,6758,6760,6788,6790,6792,6847,6849,6855,6857,6859,6870,6872,6885,6887,6898,6900,6902,6905],[10,6740,6741],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6743,16],{"id":16},[10,6745,6746],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6748,22],{"id":22},[10,6750,6751],{},[26,6752],{"alt":6753,"src":6754},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6756,6757],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6759,43],{"id":43},[45,6761,6762,6768,6777],{},[48,6763,6764,6767],{},[33,6765,6766],{},"w"," 模式会截断原文件，写入前必须确认目标。",[48,6769,6770,6773,6774,360],{},[33,6771,6772],{},"r"," 模式读取不存在文件会产生 ",[33,6775,6776],{},"FileNotFoundError",[48,6778,6779,6780,6783,6784,6787],{},"本篇显式调用 ",[33,6781,6782],{},"close()","；第 34 篇会用 ",[33,6785,6786],{},"with"," 更可靠地管理关闭动作。",[14,6789,62],{"id":62},[10,6791,65],{},[67,6793,6795],{"className":69,"code":6794,"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",[33,6796,6797,6801,6805,6810,6815,6820,6824,6828,6833,6838,6842],{"__ignoreMap":72},[76,6798,6799],{"class":78,"line":79},[76,6800,6598],{},[76,6802,6803],{"class":78,"line":85},[76,6804,89],{"emptyLinePlaceholder":88},[76,6806,6807],{"class":78,"line":92},[76,6808,6809],{},"file_path = Path(\"notes.txt\")\n",[76,6811,6812],{"class":78,"line":98},[76,6813,6814],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[76,6816,6817],{"class":78,"line":103},[76,6818,6819],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[76,6821,6822],{"class":78,"line":109},[76,6823,118],{},[76,6825,6826],{"class":78,"line":115},[76,6827,89],{"emptyLinePlaceholder":88},[76,6829,6830],{"class":78,"line":121},[76,6831,6832],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[76,6834,6835],{"class":78,"line":126},[76,6836,6837],{},"content = reader.read()\n",[76,6839,6840],{"class":78,"line":132},[76,6841,141],{},[76,6843,6844],{"class":78,"line":138},[76,6845,6846],{},"print(content)\n",[10,6848,150],{},[67,6850,6853],{"className":6851,"code":6852,"language":156,"meta":72},[154],"变量\n循环\n函数\n",[33,6854,6852],{"__ignoreMap":72},[10,6856,161],{},[14,6858,164],{"id":164},[166,6860,6861,6867],{},[48,6862,6863,6864,6866],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[33,6865,6782],{}," 确保缓冲内容交给文件系统。",[48,6868,6869],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6871,180],{"id":180},[45,6873,6874,6879],{},[48,6875,2337,6876,6878],{},[33,6877,6766],{}," 模式打开重要文件却未确认覆盖风险。",[48,6880,6881,6882,360],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[33,6883,6884],{},"encoding=\"utf-8\"",[14,6886,191],{"id":191},[166,6888,6889,6892],{},[48,6890,6891],{},"写入三行学习记录并读取。",[48,6893,6894,6895,6897],{},"改用 ",[33,6896,334],{}," 模式追加一行，确认原内容仍保留。",[10,6899,202],{},[14,6901,205],{"id":205},[10,6903,6904],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,6906,212],{},{"title":72,"searchDepth":85,"depth":85,"links":6908},[6909,6910,6911,6912,6913,6914,6915,6916],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6736,"description":6741},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[223,6924,6925],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":4,"title":5,"body":6928,"category":223,"cover":224,"description":12,"extension":225,"meta":7071,"navigation":88,"path":227,"pinned":228,"publishedAt":229,"seo":7072,"slug":231,"stem":232,"summary":233,"tags":7073,"updatedAt":229,"visible":88,"__hash__":237},{"type":7,"value":6929,"toc":7061},[6930,6932,6934,6936,6938,6942,6948,6950,6960,6962,6964,7016,7018,7023,7025,7027,7037,7039,7045,7047,7053,7055,7057,7059],[10,6931,12],{},[14,6933,16],{"id":16},[10,6935,19],{},[14,6937,22],{"id":22},[10,6939,6940],{},[26,6941],{"alt":28,"src":29},[10,6943,6944,36,6946,40],{},[33,6945,35],{},[33,6947,39],{},[14,6949,43],{"id":43},[45,6951,6952,6954,6958],{},[48,6953,50],{},[48,6955,6956,56],{},[33,6957,55],{},[48,6959,59],{},[14,6961,62],{"id":62},[10,6963,65],{},[67,6965,6966],{"className":69,"code":70,"language":71,"meta":72,"style":72},[33,6967,6968,6972,6976,6980,6984,6988,6992,6996,7000,7004,7008,7012],{"__ignoreMap":72},[76,6969,6970],{"class":78,"line":79},[76,6971,82],{},[76,6973,6974],{"class":78,"line":85},[76,6975,89],{"emptyLinePlaceholder":88},[76,6977,6978],{"class":78,"line":92},[76,6979,95],{},[76,6981,6982],{"class":78,"line":98},[76,6983,89],{"emptyLinePlaceholder":88},[76,6985,6986],{"class":78,"line":103},[76,6987,106],{},[76,6989,6990],{"class":78,"line":109},[76,6991,112],{},[76,6993,6994],{"class":78,"line":115},[76,6995,118],{},[76,6997,6998],{"class":78,"line":121},[76,6999,89],{"emptyLinePlaceholder":88},[76,7001,7002],{"class":78,"line":126},[76,7003,129],{},[76,7005,7006],{"class":78,"line":132},[76,7007,135],{},[76,7009,7010],{"class":78,"line":138},[76,7011,141],{},[76,7013,7014],{"class":78,"line":144},[76,7015,147],{},[10,7017,150],{},[67,7019,7021],{"className":7020,"code":155,"language":156,"meta":72},[154],[33,7022,155],{"__ignoreMap":72},[10,7024,161],{},[14,7026,164],{"id":164},[166,7028,7029,7033],{},[48,7030,7031,172],{},[33,7032,35],{},[48,7034,7035,177],{},[33,7036,39],{},[14,7038,180],{"id":180},[45,7040,7041,7043],{},[48,7042,185],{},[48,7044,188],{},[14,7046,191],{"id":191},[166,7048,7049,7051],{},[48,7050,196],{},[48,7052,199],{},[10,7054,202],{},[14,7056,205],{"id":205},[10,7058,208],{},[210,7060,212],{},{"title":72,"searchDepth":85,"depth":85,"links":7062},[7063,7064,7065,7066,7067,7068,7069,7070],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5,"description":12},[223,235,236],{"id":7075,"title":7076,"body":7077,"category":223,"cover":224,"description":7081,"extension":225,"meta":7265,"navigation":88,"path":7266,"pinned":228,"publishedAt":229,"seo":7267,"slug":7268,"stem":7269,"summary":7270,"tags":7271,"updatedAt":229,"visible":88,"__hash__":7274},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7078,"toc":7255},[7079,7082,7084,7087,7089,7095,7101,7103,7125,7127,7129,7192,7194,7200,7202,7204,7220,7222,7236,7238,7246,7248,7250,7253],[10,7080,7081],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7083,16],{"id":16},[10,7085,7086],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7088,22],{"id":22},[10,7090,7091],{},[26,7092],{"alt":7093,"src":7094},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7096,7097,7100],{},[33,7098,7099],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7102,43],{"id":43},[45,7104,7105,7115,7122],{},[48,7106,2337,7107,7110,7111,7114],{},[33,7108,7109],{},"newline=\"\""," 让 ",[33,7112,7113],{},"csv"," 模块正确处理换行。",[48,7116,7117,7118,7121],{},"字段顺序由 ",[33,7119,7120],{},"fieldnames"," 决定，字典键需要与字段名一致。",[48,7123,7124],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7126,62],{"id":62},[10,7128,65],{},[67,7130,7132],{"className":69,"code":7131,"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",[33,7133,7134,7139,7143,7148,7153,7158,7163,7168,7172,7177,7182,7187],{"__ignoreMap":72},[76,7135,7136],{"class":78,"line":79},[76,7137,7138],{},"import csv\n",[76,7140,7141],{"class":78,"line":85},[76,7142,89],{"emptyLinePlaceholder":88},[76,7144,7145],{"class":78,"line":92},[76,7146,7147],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[76,7149,7150],{"class":78,"line":98},[76,7151,7152],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[76,7154,7155],{"class":78,"line":103},[76,7156,7157],{},"writer.writeheader()\n",[76,7159,7160],{"class":78,"line":109},[76,7161,7162],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[76,7164,7165],{"class":78,"line":115},[76,7166,7167],{},"writer_file.close()\n",[76,7169,7170],{"class":78,"line":121},[76,7171,89],{"emptyLinePlaceholder":88},[76,7173,7174],{"class":78,"line":126},[76,7175,7176],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[76,7178,7179],{"class":78,"line":132},[76,7180,7181],{},"for row in csv.DictReader(reader_file):\n",[76,7183,7184],{"class":78,"line":138},[76,7185,7186],{},"    print(row[\"name\"], row[\"score\"])\n",[76,7188,7189],{"class":78,"line":144},[76,7190,7191],{},"reader_file.close()\n",[10,7193,150],{},[67,7195,7198],{"className":7196,"code":7197,"language":156,"meta":72},[154],"小郑 95\n",[33,7199,7197],{"__ignoreMap":72},[10,7201,161],{},[14,7203,164],{"id":164},[166,7205,7206,7215],{},[48,7207,7208,7211,7212,7214],{},[33,7209,7210],{},"DictWriter"," 按 ",[33,7213,7120],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[48,7216,7217,7219],{},[33,7218,7099],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7221,180],{"id":180},[45,7223,7224,7227],{},[48,7225,7226],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[48,7228,7229,7230,7232,7233,7235],{},"在 macOS 以外环境忽略 ",[33,7231,7109],{}," 可能出现额外空行；统一交给 ",[33,7234,7113],{}," 模块管理换行。",[14,7237,191],{"id":191},[166,7239,7240,7243],{},[48,7241,7242],{},"写入三名学习者的课程和分数。",[48,7244,7245],{},"读取 CSV 后把分数字符串转换为整数。",[10,7247,202],{},[14,7249,205],{"id":205},[10,7251,7252],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,7254,212],{},{"title":72,"searchDepth":85,"depth":85,"links":7256},[7257,7258,7259,7260,7261,7262,7263,7264],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7076,"description":7081},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[223,7272,7273],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7276,"title":7277,"body":7278,"category":223,"cover":224,"description":7282,"extension":225,"meta":7555,"navigation":88,"path":7556,"pinned":228,"publishedAt":229,"seo":7557,"slug":7558,"stem":7559,"summary":7560,"tags":7561,"updatedAt":229,"visible":88,"__hash__":7564},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7279,"toc":7542},[7280,7283,7285,7288,7290,7296,7307,7309,7326,7328,7330,7405,7407,7413,7415,7417,7442,7444,7453,7459,7470,7472,7478,7484,7493,7495,7510,7512,7533,7535,7537,7540],[10,7281,7282],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7284,16],{"id":16},[10,7286,7287],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7289,22],{"id":22},[10,7291,7292],{},[26,7293],{"alt":7294,"src":7295},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7297,7298,7299,7302,7303,7306],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[33,7300,7301],{},"except","；无论是否异常，",[33,7304,7305],{},"finally"," 都会在离开结构前执行。",[14,7308,43],{"id":43},[45,7310,7311,7317,7323],{},[48,7312,7313,7314,7316],{},"只捕获能够处理的具体异常，不使用空的 ",[33,7315,7301],{}," 吞掉全部错误。",[48,7318,7319,7322],{},[33,7320,7321],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[48,7324,7325],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7327,62],{"id":62},[10,7329,65],{},[67,7331,7333],{"className":69,"code":7332,"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",[33,7334,7335,7340,7345,7350,7355,7360,7364,7369,7374,7379,7384,7388,7393,7399],{"__ignoreMap":72},[76,7336,7337],{"class":78,"line":79},[76,7338,7339],{},"def parse_age(text):\n",[76,7341,7342],{"class":78,"line":85},[76,7343,7344],{},"    age = int(text)\n",[76,7346,7347],{"class":78,"line":92},[76,7348,7349],{},"    if age \u003C 0:\n",[76,7351,7352],{"class":78,"line":98},[76,7353,7354],{},"        raise ValueError(\"年龄不能为负数\")\n",[76,7356,7357],{"class":78,"line":103},[76,7358,7359],{},"    return age\n",[76,7361,7362],{"class":78,"line":109},[76,7363,89],{"emptyLinePlaceholder":88},[76,7365,7366],{"class":78,"line":115},[76,7367,7368],{},"try:\n",[76,7370,7371],{"class":78,"line":121},[76,7372,7373],{},"    age = parse_age(\"18\")\n",[76,7375,7376],{"class":78,"line":126},[76,7377,7378],{},"except ValueError as error:\n",[76,7380,7381],{"class":78,"line":132},[76,7382,7383],{},"    print(\"输入错误：\", error)\n",[76,7385,7386],{"class":78,"line":138},[76,7387,1144],{},[76,7389,7390],{"class":78,"line":144},[76,7391,7392],{},"    print(\"年龄：\", age)\n",[76,7394,7396],{"class":78,"line":7395},13,[76,7397,7398],{},"finally:\n",[76,7400,7402],{"class":78,"line":7401},14,[76,7403,7404],{},"    print(\"处理结束\")\n",[10,7406,150],{},[67,7408,7411],{"className":7409,"code":7410,"language":156,"meta":72},[154],"年龄： 18\n处理结束\n",[33,7412,7410],{"__ignoreMap":72},[10,7414,161],{},[14,7416,164],{"id":164},[166,7418,7419,7431],{},[48,7420,7421,7423,7424,7426,7427,7430],{},[33,7422,3034],{}," 或主动 ",[33,7425,7321],{}," 都可能产生 ",[33,7428,7429],{},"ValueError","，控制流立即离开当前正常路径。",[48,7432,7433,7434,7436,7437,7439,7440,360],{},"有异常时进入匹配的 ",[33,7435,7301],{},"；没有异常时执行 ",[33,7438,1158],{},"；两种情况最后都会执行 ",[33,7441,7305],{},[326,7443,2695],{"id":2695},[10,7445,7446,2255,7448,1155,7450,7452],{},[33,7447,7301],{},[33,7449,1158],{},[33,7451,7305],{}," 的职责不同，不能只看它们出现的顺序。",[10,7454,7455],{},[26,7456],{"alt":7457,"src":7458},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7460,7461,7463,7464,7466,7467,7469],{},[33,7462,7301],{}," 处理匹配异常，",[33,7465,1158],{}," 只在无异常时运行，",[33,7468,7305],{}," 负责两条路径都需要的清理动作。",[326,7471,2695],{"id":4216},[10,7473,7474,7477],{},[33,7475,7476],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7479,7480],{},[26,7481],{"alt":7482,"src":7483},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7485,7486,7487,7489,7490,7492],{},"只把可能产生预期异常的操作放进 ",[33,7488,7476],{},"，后续正常业务放进 ",[33,7491,1158],{},"，错误边界会更清楚。",[14,7494,180],{"id":180},[45,7496,7497,7504],{},[48,7498,7499,7500,7503],{},"使用裸 ",[33,7501,7502],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[48,7505,7506,7507,7509],{},"把整个程序包在一个巨大 ",[33,7508,7476],{}," 中，无法判断究竟哪一步允许失败。",[14,7511,191],{"id":191},[166,7513,7514,7527],{},[48,7515,7516,7517,7520,7521,1155,7524,360],{},"让 ",[33,7518,7519],{},"parse_age"," 分别处理 ",[33,7522,7523],{},"\"abc\"",[33,7525,7526],{},"\"-1\"",[48,7528,7529,7530,7532],{},"为文件读取捕获 ",[33,7531,6776],{}," 并给出清晰提示。",[10,7534,202],{},[14,7536,205],{"id":205},[10,7538,7539],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,7541,212],{},{"title":72,"searchDepth":85,"depth":85,"links":7543},[7544,7545,7546,7547,7548,7552,7553,7554],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":7549},[7550,7551],{"id":2695,"depth":92,"text":2695},{"id":4216,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7277,"description":7282},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[223,7562,7563],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7566,"title":7567,"body":7568,"category":223,"cover":224,"description":7572,"extension":225,"meta":7748,"navigation":88,"path":7749,"pinned":228,"publishedAt":229,"seo":7750,"slug":7751,"stem":7752,"summary":7753,"tags":7754,"updatedAt":229,"visible":88,"__hash__":7756},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7569,"toc":7738},[7570,7573,7575,7578,7580,7586,7592,7594,7610,7612,7614,7668,7670,7676,7678,7680,7693,7695,7708,7710,7729,7731,7733,7736],[10,7571,7572],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7574,16],{"id":16},[10,7576,7577],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7579,22],{"id":22},[10,7581,7582],{},[26,7583],{"alt":7584,"src":7585},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7587,7588,7589,7591],{},"进入 ",[33,7590,6786],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7593,43],{"id":43},[45,7595,7596,7601,7607],{},[48,7597,7598,7600],{},[33,7599,6786],{}," 把资源获取和释放配成一个清晰边界。",[48,7602,7603,7606],{},[33,7604,7605],{},"as file"," 得到的是上下文返回的资源对象。",[48,7608,7609],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7611,62],{"id":62},[10,7613,65],{},[67,7615,7617],{"className":69,"code":7616,"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",[33,7618,7619,7623,7627,7631,7635,7640,7645,7649,7654,7659,7663],{"__ignoreMap":72},[76,7620,7621],{"class":78,"line":79},[76,7622,6598],{},[76,7624,7625],{"class":78,"line":85},[76,7626,89],{"emptyLinePlaceholder":88},[76,7628,7629],{"class":78,"line":92},[76,7630,6809],{},[76,7632,7633],{"class":78,"line":98},[76,7634,89],{"emptyLinePlaceholder":88},[76,7636,7637],{"class":78,"line":103},[76,7638,7639],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[76,7641,7642],{"class":78,"line":109},[76,7643,7644],{},"    file.write(\"上下文管理器\\n\")\n",[76,7646,7647],{"class":78,"line":115},[76,7648,89],{"emptyLinePlaceholder":88},[76,7650,7651],{"class":78,"line":121},[76,7652,7653],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[76,7655,7656],{"class":78,"line":126},[76,7657,7658],{},"    print(file.read())\n",[76,7660,7661],{"class":78,"line":132},[76,7662,89],{"emptyLinePlaceholder":88},[76,7664,7665],{"class":78,"line":138},[76,7666,7667],{},"print(file.closed)\n",[10,7669,150],{},[67,7671,7674],{"className":7672,"code":7673,"language":156,"meta":72},[154],"上下文管理器\n\nTrue\n",[33,7675,7673],{"__ignoreMap":72},[10,7677,161],{},[14,7679,164],{"id":164},[166,7681,7682,7690],{},[48,7683,7588,7684,7686,7687,360],{},[33,7685,6786],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[33,7688,7689],{},"file",[48,7691,7692],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7694,180],{"id":180},[45,7696,7697,7702],{},[48,7698,4784,7699,7701],{},[33,7700,6786],{}," 代码块外继续读写已经关闭的文件对象。",[48,7703,7704,7705,7707],{},"误以为 ",[33,7706,6786],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7709,191],{"id":191},[166,7711,7712,7721],{},[48,7713,7714,7715,7718,7719,360],{},"把第 30 篇的手动 ",[33,7716,7717],{},"open\u002Fclose"," 改写为 ",[33,7720,6786],{},[48,7722,4784,7723,7725,7726,360],{},[33,7724,6786],{}," 块后检查 ",[33,7727,7728],{},"file.closed",[10,7730,202],{},[14,7732,205],{"id":205},[10,7734,7735],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,7737,212],{},{"title":72,"searchDepth":85,"depth":85,"links":7739},[7740,7741,7742,7743,7744,7745,7746,7747],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7567,"description":7572},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[223,6786,7755],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7758,"title":7759,"body":7760,"category":223,"cover":224,"description":7764,"extension":225,"meta":7976,"navigation":88,"path":7977,"pinned":228,"publishedAt":229,"seo":7978,"slug":7979,"stem":7980,"summary":7981,"tags":7982,"updatedAt":229,"visible":88,"__hash__":7985},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7761,"toc":7964},[7762,7765,7767,7770,7772,7778,7781,7783,7800,7802,7804,7872,7874,7880,7882,7884,7909,7911,7914,7920,7929,7931,7942,7944,7955,7957,7959,7962],[10,7763,7764],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7766,16],{"id":16},[10,7768,7769],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7771,22],{"id":22},[10,7773,7774],{},[26,7775],{"alt":7776,"src":7777},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7779,7780],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7782,43],{"id":43},[45,7784,7785,7791,7797],{},[48,7786,7787,7790],{},[33,7788,7789],{},"self"," 表示当前实例，由方法调用自动传入。",[48,7792,7793,7796],{},[33,7794,7795],{},"__init__"," 在实例创建过程中初始化属性。",[48,7798,7799],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7801,62],{"id":62},[10,7803,65],{},[67,7805,7807],{"className":69,"code":7806,"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",[33,7808,7809,7814,7819,7824,7829,7833,7838,7843,7848,7853,7857,7862,7867],{"__ignoreMap":72},[76,7810,7811],{"class":78,"line":79},[76,7812,7813],{},"class LearningRecord:\n",[76,7815,7816],{"class":78,"line":85},[76,7817,7818],{},"    def __init__(self, course, progress=0):\n",[76,7820,7821],{"class":78,"line":92},[76,7822,7823],{},"        self.course = course\n",[76,7825,7826],{"class":78,"line":98},[76,7827,7828],{},"        self.progress = progress\n",[76,7830,7831],{"class":78,"line":103},[76,7832,89],{"emptyLinePlaceholder":88},[76,7834,7835],{"class":78,"line":109},[76,7836,7837],{},"    def advance(self, amount):\n",[76,7839,7840],{"class":78,"line":115},[76,7841,7842],{},"        self.progress = self.progress + amount\n",[76,7844,7845],{"class":78,"line":121},[76,7846,7847],{},"        if self.progress > 100:\n",[76,7849,7850],{"class":78,"line":126},[76,7851,7852],{},"            self.progress = 100\n",[76,7854,7855],{"class":78,"line":132},[76,7856,89],{"emptyLinePlaceholder":88},[76,7858,7859],{"class":78,"line":138},[76,7860,7861],{},"record = LearningRecord(\"Python\", 40)\n",[76,7863,7864],{"class":78,"line":144},[76,7865,7866],{},"record.advance(15)\n",[76,7868,7869],{"class":78,"line":7395},[76,7870,7871],{},"print(record.course, record.progress)\n",[10,7873,150],{},[67,7875,7878],{"className":7876,"code":7877,"language":156,"meta":72},[154],"Python 55\n",[33,7879,7877],{"__ignoreMap":72},[10,7881,161],{},[14,7883,164],{"id":164},[166,7885,7886,7896],{},[48,7887,7888,7889,7892,7893,7895],{},"调用 ",[33,7890,7891],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[33,7894,7795],{}," 把课程和进度保存在该实例属性中。",[48,7897,7898,7901,7902,7905,7906,7908],{},[33,7899,7900],{},"record.advance(15)"," 自动把 ",[33,7903,7904],{},"record"," 作为 ",[33,7907,7789],{},"，方法更新同一实例的进度并限制上限。",[326,7910,2695],{"id":2695},[10,7912,7913],{},"类是共同定义，实例则各自保存状态。",[10,7915,7916],{},[26,7917],{"alt":7918,"src":7919},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7921,7922,7923,1155,7925,7928],{},"两个实例共享同一套方法定义，但 ",[33,7924,4581],{},[33,7926,7927],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,7930,180],{"id":180},[45,7932,7933,7939],{},[48,7934,7935,7936,7938],{},"调用实例方法时手工再传一次 ",[33,7937,7789],{},"。通过实例调用时 Python 会自动绑定。",[48,7940,7941],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,7943,191],{"id":191},[166,7945,7946,7952],{},[48,7947,5294,7948,7951],{},[33,7949,7950],{},"Book"," 类，保存标题和阅读页数。",[48,7953,7954],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,7956,202],{},[14,7958,205],{"id":205},[10,7960,7961],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,7963,212],{},{"title":72,"searchDepth":85,"depth":85,"links":7965},[7966,7967,7968,7969,7970,7973,7974,7975],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":7971},[7972],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7759,"description":7764},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[223,7983,7984],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":7987,"title":7988,"body":7989,"category":223,"cover":224,"description":7993,"extension":225,"meta":8171,"navigation":88,"path":8172,"pinned":228,"publishedAt":229,"seo":8173,"slug":8174,"stem":8175,"summary":8176,"tags":8177,"updatedAt":229,"visible":88,"__hash__":8180},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":7990,"toc":8161},[7991,7994,7996,7999,8001,8007,8010,8012,8023,8025,8027,8094,8096,8102,8104,8106,8125,8127,8135,8137,8152,8154,8156,8159],[10,7992,7993],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,7995,16],{"id":16},[10,7997,7998],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8000,22],{"id":22},[10,8002,8003],{},[26,8004],{"alt":8005,"src":8006},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8008,8009],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8011,43],{"id":43},[45,8013,8014,8017,8020],{},[48,8015,8016],{},"封装让对象通过方法维护自己的有效状态。",[48,8018,8019],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[48,8021,8022],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8024,62],{"id":62},[10,8026,65],{},[67,8028,8030],{"className":69,"code":8029,"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",[33,8031,8032,8037,8042,8047,8051,8056,8061,8066,8070,8075,8080,8084,8089],{"__ignoreMap":72},[76,8033,8034],{"class":78,"line":79},[76,8035,8036],{},"class Storage:\n",[76,8038,8039],{"class":78,"line":85},[76,8040,8041],{},"    def save(self, text):\n",[76,8043,8044],{"class":78,"line":92},[76,8045,8046],{},"        print(\"保存：\", text)\n",[76,8048,8049],{"class":78,"line":98},[76,8050,89],{"emptyLinePlaceholder":88},[76,8052,8053],{"class":78,"line":103},[76,8054,8055],{},"class LearningService:\n",[76,8057,8058],{"class":78,"line":109},[76,8059,8060],{},"    def __init__(self, storage):\n",[76,8062,8063],{"class":78,"line":115},[76,8064,8065],{},"        self.storage = storage\n",[76,8067,8068],{"class":78,"line":121},[76,8069,89],{"emptyLinePlaceholder":88},[76,8071,8072],{"class":78,"line":126},[76,8073,8074],{},"    def finish_lesson(self, title):\n",[76,8076,8077],{"class":78,"line":132},[76,8078,8079],{},"        self.storage.save(title)\n",[76,8081,8082],{"class":78,"line":138},[76,8083,89],{"emptyLinePlaceholder":88},[76,8085,8086],{"class":78,"line":144},[76,8087,8088],{},"service = LearningService(Storage())\n",[76,8090,8091],{"class":78,"line":7395},[76,8092,8093],{},"service.finish_lesson(\"异常处理\")\n",[10,8095,150],{},[67,8097,8100],{"className":8098,"code":8099,"language":156,"meta":72},[154],"保存： 异常处理\n",[33,8101,8099],{"__ignoreMap":72},[10,8103,161],{},[14,8105,164],{"id":164},[166,8107,8108,8118],{},[48,8109,8110,8113,8114,8117],{},[33,8111,8112],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[33,8115,8116],{},"save()"," 的协作对象。",[48,8119,8120,8121,8124],{},"调用业务方法时，服务把保存动作委托给 ",[33,8122,8123],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8126,180],{"id":180},[45,8128,8129,8132],{},[48,8130,8131],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[48,8133,8134],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8136,191],{"id":191},[166,8138,8139,8149],{},[48,8140,8141,8142,8145,8146,360],{},"用组合让 ",[33,8143,8144],{},"OrderService"," 使用一个 ",[33,8147,8148],{},"Notifier",[48,8150,8151],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8153,202],{},[14,8155,205],{"id":205},[10,8157,8158],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,8160,212],{},{"title":72,"searchDepth":85,"depth":85,"links":8162},[8163,8164,8165,8166,8167,8168,8169,8170],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":7988,"description":7993},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[223,8178,8179],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8182,"title":8183,"body":8184,"category":223,"cover":224,"description":8188,"extension":225,"meta":8391,"navigation":88,"path":8392,"pinned":228,"publishedAt":229,"seo":8393,"slug":8394,"stem":8395,"summary":8396,"tags":8397,"updatedAt":229,"visible":88,"__hash__":8400},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8185,"toc":8379},[8186,8189,8191,8194,8196,8202,8209,8211,8236,8238,8240,8292,8294,8300,8302,8304,8325,8327,8333,8339,8345,8347,8355,8357,8370,8372,8374,8377],[10,8187,8188],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8190,16],{"id":16},[10,8192,8193],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8195,22],{"id":22},[10,8197,8198],{},[26,8199],{"alt":8200,"src":8201},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8203,8204,8205,8208],{},"生成器运行到 ",[33,8206,8207],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8210,43],{"id":43},[45,8212,8213,8223,8233],{},[48,8214,8215,8218,8219,8222],{},[33,8216,8217],{},"iter()"," 从可迭代对象取得迭代器，",[33,8220,8221],{},"next()"," 请求下一个值。",[48,8224,8225,8226,8229,8230,8232],{},"没有更多值时迭代器抛出 ",[33,8227,8228],{},"StopIteration","，",[33,8231,4335],{}," 会自动处理。",[48,8234,8235],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8237,62],{"id":62},[10,8239,65],{},[67,8241,8243],{"className":69,"code":8242,"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",[33,8244,8245,8250,8255,8260,8265,8270,8274,8279,8284,8288],{"__ignoreMap":72},[76,8246,8247],{"class":78,"line":79},[76,8248,8249],{},"def countdown(start):\n",[76,8251,8252],{"class":78,"line":85},[76,8253,8254],{},"    current = start\n",[76,8256,8257],{"class":78,"line":92},[76,8258,8259],{},"    while current > 0:\n",[76,8261,8262],{"class":78,"line":98},[76,8263,8264],{},"        yield current\n",[76,8266,8267],{"class":78,"line":103},[76,8268,8269],{},"        current = current - 1\n",[76,8271,8272],{"class":78,"line":109},[76,8273,89],{"emptyLinePlaceholder":88},[76,8275,8276],{"class":78,"line":115},[76,8277,8278],{},"iterator = countdown(3)\n",[76,8280,8281],{"class":78,"line":121},[76,8282,8283],{},"print(next(iterator))\n",[76,8285,8286],{"class":78,"line":126},[76,8287,8283],{},[76,8289,8290],{"class":78,"line":132},[76,8291,8283],{},[10,8293,150],{},[67,8295,8298],{"className":8296,"code":8297,"language":156,"meta":72},[154],"3\n2\n1\n",[33,8299,8297],{"__ignoreMap":72},[10,8301,161],{},[14,8303,164],{"id":164},[166,8305,8306,8312],{},[48,8307,7888,8308,8311],{},[33,8309,8310],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[48,8313,8314,8315,8317,8318,8320,8321,8324],{},"每次 ",[33,8316,8221],{}," 运行到下一个 ",[33,8319,8207],{}," 并暂停，局部变量 ",[33,8322,8323],{},"current"," 和执行位置被保留。",[326,8326,2695],{"id":2695},[10,8328,8329,8330,8332],{},"生成器的暂停位置可以展开成多次 ",[33,8331,8221],{}," 的时间线。",[10,8334,8335],{},[26,8336],{"alt":8337,"src":8338},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8340,8341,8342,8344],{},"每次请求只推进到下一个 ",[33,8343,8207],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8346,180],{"id":180},[45,8348,8349,8352],{},[48,8350,8351],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[48,8353,8354],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8356,191],{"id":191},[166,8358,8359,8362],{},[48,8360,8361],{},"编写产生 1 到指定上限偶数的生成器。",[48,8363,4008,8364,8366,8367,8369],{},[33,8365,4335],{}," 遍历生成器，比较手动 ",[33,8368,8221],{}," 的差异。",[10,8371,202],{},[14,8373,205],{"id":205},[10,8375,8376],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,8378,212],{},{"title":72,"searchDepth":85,"depth":85,"links":8380},[8381,8382,8383,8384,8385,8388,8389,8390],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":8386},[8387],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8183,"description":8188},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[223,8398,8399],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8402,"title":8403,"body":8404,"category":223,"cover":224,"description":8408,"extension":225,"meta":8632,"navigation":88,"path":8633,"pinned":228,"publishedAt":229,"seo":8634,"slug":8635,"stem":8636,"summary":8637,"tags":8638,"updatedAt":229,"visible":88,"__hash__":8640},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8405,"toc":8620},[8406,8409,8411,8414,8416,8422,8425,8427,8447,8449,8451,8533,8535,8541,8543,8545,8567,8569,8572,8578,8585,8587,8597,8599,8611,8613,8615,8618],[10,8407,8408],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8410,16],{"id":16},[10,8412,8413],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8415,22],{"id":22},[10,8417,8418],{},[26,8419],{"alt":8420,"src":8421},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8423,8424],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8426,43],{"id":43},[45,8428,8429,8438,8441],{},[48,8430,8431,8434,8435,360],{},[33,8432,8433],{},"@trace"," 等价于 ",[33,8436,8437],{},"add = trace(add)",[48,8439,8440],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[48,8442,8443,8446],{},[33,8444,8445],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8448,62],{"id":62},[10,8450,65],{},[67,8452,8454],{"className":69,"code":8453,"language":71,"meta":72,"style":72},"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",[33,8455,8456,8461,8465,8470,8475,8480,8485,8490,8495,8500,8505,8509,8514,8518,8522,8527],{"__ignoreMap":72},[76,8457,8458],{"class":78,"line":79},[76,8459,8460],{},"from functools import wraps\n",[76,8462,8463],{"class":78,"line":85},[76,8464,89],{"emptyLinePlaceholder":88},[76,8466,8467],{"class":78,"line":92},[76,8468,8469],{},"def trace(function):\n",[76,8471,8472],{"class":78,"line":98},[76,8473,8474],{},"    @wraps(function)\n",[76,8476,8477],{"class":78,"line":103},[76,8478,8479],{},"    def wrapper(*args, **kwargs):\n",[76,8481,8482],{"class":78,"line":109},[76,8483,8484],{},"        print(\"开始：\", function.__name__)\n",[76,8486,8487],{"class":78,"line":115},[76,8488,8489],{},"        result = function(*args, **kwargs)\n",[76,8491,8492],{"class":78,"line":121},[76,8493,8494],{},"        print(\"结束：\", function.__name__)\n",[76,8496,8497],{"class":78,"line":126},[76,8498,8499],{},"        return result\n",[76,8501,8502],{"class":78,"line":132},[76,8503,8504],{},"    return wrapper\n",[76,8506,8507],{"class":78,"line":138},[76,8508,89],{"emptyLinePlaceholder":88},[76,8510,8511],{"class":78,"line":144},[76,8512,8513],{},"@trace\n",[76,8515,8516],{"class":78,"line":7395},[76,8517,6177],{},[76,8519,8520],{"class":78,"line":7401},[76,8521,6182],{},[76,8523,8525],{"class":78,"line":8524},15,[76,8526,89],{"emptyLinePlaceholder":88},[76,8528,8530],{"class":78,"line":8529},16,[76,8531,8532],{},"print(add(2, 3))\n",[10,8534,150],{},[67,8536,8539],{"className":8537,"code":8538,"language":156,"meta":72},[154],"开始： add\n结束： add\n5\n",[33,8540,8538],{"__ignoreMap":72},[10,8542,161],{},[14,8544,164],{"id":164},[166,8546,8547,8564],{},[48,8548,8549,8550,8553,8554,8557,8558,8561,8562,360],{},"解释器执行定义时，把原 ",[33,8551,8552],{},"add"," 函数交给 ",[33,8555,8556],{},"trace","，返回的 ",[33,8559,8560],{},"wrapper"," 重新绑定到名字 ",[33,8563,8552],{},[48,8565,8566],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[326,8568,2695],{"id":2695},[10,8570,8571],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8573,8574],{},[26,8575],{"alt":8576,"src":8577},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8579,8580,8582,8583,360],{},[33,8581,8433],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[33,8584,8437],{},[14,8586,180],{"id":180},[45,8588,8589,8594],{},[48,8590,8591,8592,360],{},"包装函数忘记返回原函数结果，调用方得到 ",[33,8593,5377],{},[48,8595,8596],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8598,191],{"id":191},[166,8600,8601,8604],{},[48,8602,8603],{},"编写只记录调用次数的简单装饰器。",[48,8605,8606,8607,8610],{},"删除包装函数的 ",[33,8608,8609],{},"return result","，观察调用方得到什么。",[10,8612,202],{},[14,8614,205],{"id":205},[10,8616,8617],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,8619,212],{},{"title":72,"searchDepth":85,"depth":85,"links":8621},[8622,8623,8624,8625,8626,8629,8630,8631],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":8627},[8628],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8403,"description":8408},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[223,8639,5328],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8642,"title":8643,"body":8644,"category":223,"cover":224,"description":8648,"extension":225,"meta":8835,"navigation":88,"path":8836,"pinned":228,"publishedAt":229,"seo":8837,"slug":8838,"stem":8839,"summary":8840,"tags":8841,"updatedAt":229,"visible":88,"__hash__":8844},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8645,"toc":8823},[8646,8649,8651,8654,8656,8662,8665,8667,8678,8680,8682,8757,8759,8765,8767,8769,8780,8782,8785,8791,8794,8796,8804,8806,8814,8816,8818,8821],[10,8647,8648],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8650,16],{"id":16},[10,8652,8653],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8655,22],{"id":22},[10,8657,8658],{},[26,8659],{"alt":8660,"src":8661},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8663,8664],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8666,43],{"id":43},[45,8668,8669,8672,8675],{},[48,8670,8671],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[48,8673,8674],{},"日志记录运行状态，测试判断结果是否符合约定。",[48,8676,8677],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8679,62],{"id":62},[10,8681,65],{},[67,8683,8685],{"className":69,"code":8684,"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",[33,8686,8687,8692,8697,8701,8706,8710,8715,8720,8725,8729,8734,8739,8744,8748,8752],{"__ignoreMap":72},[76,8688,8689],{"class":78,"line":79},[76,8690,8691],{},"import logging\n",[76,8693,8694],{"class":78,"line":85},[76,8695,8696],{},"import unittest\n",[76,8698,8699],{"class":78,"line":92},[76,8700,89],{"emptyLinePlaceholder":88},[76,8702,8703],{"class":78,"line":98},[76,8704,8705],{},"logging.basicConfig(level=logging.INFO)\n",[76,8707,8708],{"class":78,"line":103},[76,8709,89],{"emptyLinePlaceholder":88},[76,8711,8712],{"class":78,"line":109},[76,8713,8714],{},"def clamp_progress(value):\n",[76,8716,8717],{"class":78,"line":115},[76,8718,8719],{},"    logging.info(\"检查进度：%s\", value)\n",[76,8721,8722],{"class":78,"line":121},[76,8723,8724],{},"    return max(0, min(100, value))\n",[76,8726,8727],{"class":78,"line":126},[76,8728,89],{"emptyLinePlaceholder":88},[76,8730,8731],{"class":78,"line":132},[76,8732,8733],{},"class ProgressTest(unittest.TestCase):\n",[76,8735,8736],{"class":78,"line":138},[76,8737,8738],{},"    def test_upper_limit(self):\n",[76,8740,8741],{"class":78,"line":144},[76,8742,8743],{},"        self.assertEqual(clamp_progress(120), 100)\n",[76,8745,8746],{"class":78,"line":7395},[76,8747,89],{"emptyLinePlaceholder":88},[76,8749,8750],{"class":78,"line":7401},[76,8751,6191],{},[76,8753,8754],{"class":78,"line":8524},[76,8755,8756],{},"    unittest.main()\n",[10,8758,150],{},[67,8760,8763],{"className":8761,"code":8762,"language":156,"meta":72},[154],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[33,8764,8762],{"__ignoreMap":72},[10,8766,161],{},[14,8768,164],{"id":164},[166,8770,8771,8777],{},[48,8772,8773,8776],{},[33,8774,8775],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[48,8778,8779],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[326,8781,2695],{"id":2695},[10,8783,8784],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8786,8787],{},[26,8788],{"alt":8789,"src":8790},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8792,8793],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8795,180],{"id":180},[45,8797,8798,8801],{},[48,8799,8800],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[48,8802,8803],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8805,191],{"id":191},[166,8807,8808,8811],{},[48,8809,8810],{},"为负数进度增加测试。",[48,8812,8813],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8815,202],{},[14,8817,205],{"id":205},[10,8819,8820],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,8822,212],{},{"title":72,"searchDepth":85,"depth":85,"links":8824},[8825,8826,8827,8828,8829,8832,8833,8834],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":8830},[8831],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8643,"description":8648},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[223,8842,8843],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8846,"title":8847,"body":8848,"category":223,"cover":224,"description":8852,"extension":225,"meta":9152,"navigation":88,"path":9153,"pinned":228,"publishedAt":229,"seo":9154,"slug":9155,"stem":9156,"summary":9157,"tags":9158,"updatedAt":229,"visible":88,"__hash__":9161},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8849,"toc":9139},[8850,8853,8855,8858,8860,8866,8869,8871,8886,8888,8890,9037,9039,9045,9047,9049,9062,9064,9067,9073,9076,9078,9081,9087,9094,9096,9107,9109,9130,9132,9134,9137],[10,8851,8852],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8854,16],{"id":16},[10,8856,8857],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8859,22],{"id":22},[10,8861,8862],{},[26,8863],{"alt":8864,"src":8865},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8867,8868],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8870,43],{"id":43},[45,8872,8873,8876,8879],{},[48,8874,8875],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[48,8877,8878],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[48,8880,8881,8882,8885],{},"实际扩展前先为 ",[33,8883,8884],{},"add()"," 和存储边界补充测试。",[14,8887,62],{"id":62},[10,8889,65],{},[67,8891,8893],{"className":69,"code":8892,"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",[33,8894,8895,8899,8903,8907,8912,8917,8922,8927,8931,8936,8941,8946,8951,8956,8960,8965,8970,8976,8981,8987,8992,8997,9003,9009,9015,9020,9026,9031],{"__ignoreMap":72},[76,8896,8897],{"class":78,"line":79},[76,8898,82],{},[76,8900,8901],{"class":78,"line":85},[76,8902,6598],{},[76,8904,8905],{"class":78,"line":92},[76,8906,89],{"emptyLinePlaceholder":88},[76,8908,8909],{"class":78,"line":98},[76,8910,8911],{},"class LearningRecords:\n",[76,8913,8914],{"class":78,"line":103},[76,8915,8916],{},"    def __init__(self, file_path):\n",[76,8918,8919],{"class":78,"line":109},[76,8920,8921],{},"        self.file_path = Path(file_path)\n",[76,8923,8924],{"class":78,"line":115},[76,8925,8926],{},"        self.items = []\n",[76,8928,8929],{"class":78,"line":121},[76,8930,89],{"emptyLinePlaceholder":88},[76,8932,8933],{"class":78,"line":126},[76,8934,8935],{},"    def add(self, title):\n",[76,8937,8938],{"class":78,"line":132},[76,8939,8940],{},"        title = title.strip()\n",[76,8942,8943],{"class":78,"line":138},[76,8944,8945],{},"        if not title:\n",[76,8947,8948],{"class":78,"line":144},[76,8949,8950],{},"            raise ValueError(\"课程名称不能为空\")\n",[76,8952,8953],{"class":78,"line":7395},[76,8954,8955],{},"        self.items.append({\"title\": title, \"done\": False})\n",[76,8957,8958],{"class":78,"line":7401},[76,8959,89],{"emptyLinePlaceholder":88},[76,8961,8962],{"class":78,"line":8524},[76,8963,8964],{},"    def save(self):\n",[76,8966,8967],{"class":78,"line":8529},[76,8968,8969],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[76,8971,8973],{"class":78,"line":8972},17,[76,8974,8975],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[76,8977,8979],{"class":78,"line":8978},18,[76,8980,89],{"emptyLinePlaceholder":88},[76,8982,8984],{"class":78,"line":8983},19,[76,8985,8986],{},"records = LearningRecords(\"learning-records.json\")\n",[76,8988,8990],{"class":78,"line":8989},20,[76,8991,89],{"emptyLinePlaceholder":88},[76,8993,8995],{"class":78,"line":8994},21,[76,8996,7368],{},[76,8998,9000],{"class":78,"line":8999},22,[76,9001,9002],{},"    title = input(\"输入已学习课程：\")\n",[76,9004,9006],{"class":78,"line":9005},23,[76,9007,9008],{},"    records.add(title)\n",[76,9010,9012],{"class":78,"line":9011},24,[76,9013,9014],{},"    records.save()\n",[76,9016,9018],{"class":78,"line":9017},25,[76,9019,7378],{},[76,9021,9023],{"class":78,"line":9022},26,[76,9024,9025],{},"    print(\"无法保存：\", error)\n",[76,9027,9029],{"class":78,"line":9028},27,[76,9030,1144],{},[76,9032,9034],{"class":78,"line":9033},28,[76,9035,9036],{},"    print(\"已保存 1 条学习记录\")\n",[10,9038,150],{},[67,9040,9043],{"className":9041,"code":9042,"language":156,"meta":72},[154],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[33,9044,9042],{"__ignoreMap":72},[10,9046,161],{},[14,9048,164],{"id":164},[166,9050,9051,9057],{},[48,9052,9053,9054,9056],{},"输入层取得课程名后，",[33,9055,8884],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[48,9058,9059,9061],{},[33,9060,8116],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[326,9063,2695],{"id":2695},[10,9065,9066],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9068,9069],{},[26,9070],{"alt":9071,"src":9072},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9074,9075],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[326,9077,2695],{"id":4216},[10,9079,9080],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9082,9083],{},[26,9084],{"alt":9085,"src":9086},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9088,9089,9090,9093],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[33,9091,9092],{},"load()"," 把文件状态恢复到内存。",[14,9095,180],{"id":180},[45,9097,9098,9101],{},[48,9099,9100],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[48,9102,9103,9104,9106],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[33,9105,9092],{}," 是下一项必要扩展。",[14,9108,191],{"id":191},[166,9110,9111,9117,9120],{},[48,9112,9113,9114,9116],{},"增加 ",[33,9115,9092],{},"，文件不存在时从空列表开始。",[48,9118,9119],{},"增加按序号标记完成的功能，并校验序号范围。",[48,9121,9122,9123,9126,9127,9129],{},"把输入循环放进 ",[33,9124,9125],{},"main()","，通过 ",[33,9128,6133],{}," 控制程序入口。",[10,9131,202],{},[14,9133,205],{"id":205},[10,9135,9136],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[210,9138,212],{},{"title":72,"searchDepth":85,"depth":85,"links":9140},[9141,9142,9143,9144,9145,9149,9150,9151],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":9146},[9147,9148],{"id":2695,"depth":92,"text":2695},{"id":4216,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8847,"description":8852},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[223,9159,9160],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9163,9266,9385,9516,9659,9784,9921,10058,10199,10368,10505,10638,10761,10890,11017,11180,11356,11497,11626,11775,11918,12039,12162,12311,12464,12629,12756,12937,13080,13237,13388,13535,13690,13908,14063,14238,14389,14556,14743,14906,15148,15388],{"id":1391,"title":1392,"body":9164,"category":223,"cover":224,"description":1397,"extension":225,"meta":9263,"navigation":88,"path":1516,"pinned":228,"publishedAt":229,"seo":9264,"slug":1518,"stem":1519,"summary":1520,"tags":9265,"updatedAt":229,"visible":88,"__hash__":1523},{"type":7,"value":9165,"toc":9253},[9166,9168,9170,9172,9174,9178,9182,9184,9194,9196,9198,9206,9208,9213,9215,9217,9227,9229,9237,9239,9245,9247,9249,9251],[10,9167,1397],{},[14,9169,16],{"id":16},[10,9171,1402],{},[14,9173,22],{"id":22},[10,9175,9176],{},[26,9177],{"alt":1409,"src":1410},[10,9179,9180,1415],{},[33,9181,1169],{},[14,9183,43],{"id":43},[45,9185,9186,9190,9192],{},[48,9187,1422,9188,1425],{},[33,9189,1169],{},[48,9191,1428],{},[48,9193,1431],{},[14,9195,62],{"id":62},[10,9197,65],{},[67,9199,9200],{"className":69,"code":1438,"language":71,"meta":72,"style":72},[33,9201,9202],{"__ignoreMap":72},[76,9203,9204],{"class":78,"line":79},[76,9205,1438],{},[10,9207,150],{},[67,9209,9211],{"className":9210,"code":1450,"language":156,"meta":72},[154],[33,9212,1450],{"__ignoreMap":72},[10,9214,161],{},[14,9216,164],{"id":164},[166,9218,9219,9223],{},[48,9220,1461,9221,1465],{},[33,9222,1464],{},[48,9224,1468,9225,1472],{},[33,9226,1471],{},[14,9228,180],{"id":180},[45,9230,9231,9233],{},[48,9232,1479],{},[48,9234,1482,9235,1485],{},[33,9236,1169],{},[14,9238,191],{"id":191},[166,9240,9241,9243],{},[48,9242,1492],{},[48,9244,1495],{},[10,9246,202],{},[14,9248,205],{"id":205},[10,9250,1502],{},[210,9252,212],{},{"title":72,"searchDepth":85,"depth":85,"links":9254},[9255,9256,9257,9258,9259,9260,9261,9262],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":1392,"description":1397},[223,1387,1522],{"id":1525,"title":1526,"body":9267,"category":223,"cover":224,"description":1531,"extension":225,"meta":9382,"navigation":88,"path":1668,"pinned":228,"publishedAt":229,"seo":9383,"slug":1670,"stem":1671,"summary":1672,"tags":9384,"updatedAt":229,"visible":88,"__hash__":1675},{"type":7,"value":9268,"toc":9372},[9269,9271,9273,9275,9277,9281,9285,9287,9297,9299,9301,9321,9323,9328,9330,9332,9342,9344,9354,9356,9364,9366,9368,9370],[10,9270,1531],{},[14,9272,16],{"id":16},[10,9274,1536],{},[14,9276,22],{"id":22},[10,9278,9279],{},[26,9280],{"alt":1543,"src":1544},[10,9282,1547,9283,1550],{},[33,9284,689],{},[14,9286,43],{"id":43},[45,9288,9289,9291,9293],{},[48,9290,1557],{},[48,9292,1560],{},[48,9294,1563,9295,1567],{},[33,9296,1566],{},[14,9298,62],{"id":62},[10,9300,1572],{},[67,9302,9303],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,9304,9305,9311],{"__ignoreMap":72},[76,9306,9307,9309],{"class":78,"line":79},[76,9308,689],{"class":598},[76,9310,602],{"class":601},[76,9312,9313,9315,9317,9319],{"class":78,"line":85},[76,9314,689],{"class":598},[76,9316,631],{"class":601},[76,9318,635],{"class":634},[76,9320,602],{"class":601},[10,9322,150],{},[67,9324,9326],{"className":9325,"code":1598,"language":156,"meta":72},[154],[33,9327,1598],{"__ignoreMap":72},[10,9329,161],{},[14,9331,164],{"id":164},[166,9333,9334,9338],{},[48,9335,9336,1612],{},[33,9337,1611],{},[48,9339,9340,1617],{},[33,9341,697],{},[14,9343,180],{"id":180},[45,9345,9346,9350],{},[48,9347,1624,9348,1627],{},[33,9349,689],{},[48,9351,1630,9352,1633],{},[33,9353,689],{},[14,9355,191],{"id":191},[166,9357,9358,9362],{},[48,9359,936,9360,1643],{},[33,9361,1642],{},[48,9363,1646],{},[10,9365,202],{},[14,9367,205],{"id":205},[10,9369,1653],{},[210,9371,1656],{},{"title":72,"searchDepth":85,"depth":85,"links":9373},[9374,9375,9376,9377,9378,9379,9380,9381],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":1526,"description":1531},[223,1674,1050],{"id":1677,"title":1678,"body":9386,"category":223,"cover":224,"description":1844,"extension":225,"meta":9513,"navigation":88,"path":1846,"pinned":228,"publishedAt":229,"seo":9514,"slug":1848,"stem":1849,"summary":1850,"tags":9515,"updatedAt":229,"visible":88,"__hash__":1854},{"type":7,"value":9387,"toc":9503},[9388,9392,9394,9396,9398,9402,9404,9406,9422,9424,9426,9446,9448,9453,9455,9457,9469,9471,9481,9483,9493,9495,9497,9501],[10,9389,1683,9390,1686],{},[33,9391,1169],{},[14,9393,16],{"id":16},[10,9395,1691],{},[14,9397,22],{"id":22},[10,9399,9400],{},[26,9401],{"alt":1698,"src":1699},[10,9403,1702],{},[14,9405,43],{"id":43},[45,9407,9408,9414,9418],{},[48,9409,1709,9410,1712,9412,360],{},[33,9411,689],{},[33,9413,1715],{},[48,9415,1718,9416,1722],{},[33,9417,1721],{},[48,9419,1725,9420,1728],{},[33,9421,1169],{},[14,9423,62],{"id":62},[10,9425,65],{},[67,9427,9428],{"className":1735,"code":1736,"language":1737,"meta":72,"style":72},[33,9429,9430,9434,9438,9442],{"__ignoreMap":72},[76,9431,9432],{"class":78,"line":79},[76,9433,1744],{},[76,9435,9436],{"class":78,"line":85},[76,9437,1749],{},[76,9439,9440],{"class":78,"line":92},[76,9441,1754],{},[76,9443,9444],{"class":78,"line":98},[76,9445,1759],{},[10,9447,150],{},[67,9449,9451],{"className":9450,"code":1765,"language":156,"meta":72},[154],[33,9452,1765],{"__ignoreMap":72},[10,9454,161],{},[14,9456,164],{"id":164},[166,9458,9459,9465],{},[48,9460,1776,9461,1780,9463,360],{},[33,9462,1779],{},[33,9464,1783],{},[48,9466,1786,9467,1789],{},[33,9468,1471],{},[14,9470,180],{"id":180},[45,9472,9473,9479],{},[48,9474,1796,9475,1799,9477,1802],{},[33,9476,1715],{},[33,9478,1169],{},[48,9480,1805],{},[14,9482,191],{"id":191},[166,9484,9485,9489],{},[48,9486,1812,9487,360],{},[33,9488,1815],{},[48,9490,1818,9491,1821],{},[33,9492,1471],{},[10,9494,202],{},[14,9496,205],{"id":205},[10,9498,1828,9499,1831],{},[33,9500,1169],{},[210,9502,212],{},{"title":72,"searchDepth":85,"depth":85,"links":9504},[9505,9506,9507,9508,9509,9510,9511,9512],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":1678,"description":1844},[223,1852,1853],{"id":1856,"title":1857,"body":9517,"category":223,"cover":224,"description":1862,"extension":225,"meta":9656,"navigation":88,"path":2034,"pinned":228,"publishedAt":229,"seo":9657,"slug":2036,"stem":2037,"summary":2038,"tags":9658,"updatedAt":229,"visible":88,"__hash__":2042},{"type":7,"value":9518,"toc":9646},[9519,9521,9523,9525,9527,9531,9535,9537,9549,9551,9553,9589,9591,9596,9598,9600,9616,9618,9628,9630,9638,9640,9642,9644],[10,9520,1862],{},[14,9522,16],{"id":16},[10,9524,1867],{},[14,9526,22],{"id":22},[10,9528,9529],{},[26,9530],{"alt":1874,"src":1875},[10,9532,9533,1881],{},[33,9534,1880],{},[14,9536,43],{"id":43},[45,9538,9539,9541,9547],{},[48,9540,1888],{},[48,9542,9543,1894,9545,1898],{},[33,9544,1893],{},[33,9546,1897],{},[48,9548,1901],{},[14,9550,62],{"id":62},[10,9552,1572],{},[67,9554,9555],{"className":589,"code":1908,"language":591,"meta":72,"style":72},[33,9556,9557,9563,9569,9573,9583],{"__ignoreMap":72},[76,9558,9559,9561],{"class":78,"line":79},[76,9560,1915],{"class":598},[76,9562,1918],{"class":634},[76,9564,9565,9567],{"class":78,"line":85},[76,9566,1923],{"class":601},[76,9568,1918],{"class":634},[76,9570,9571],{"class":78,"line":92},[76,9572,1930],{"class":601},[76,9574,9575,9577,9579,9581],{"class":78,"line":98},[76,9576,1935],{"class":601},[76,9578,1938],{"class":634},[76,9580,1942],{"class":1941},[76,9582,1213],{"class":634},[76,9584,9585,9587],{"class":78,"line":103},[76,9586,689],{"class":598},[76,9588,1213],{"class":634},[10,9590,150],{},[67,9592,9594],{"className":9593,"code":1956,"language":156,"meta":72},[154],[33,9595,1956],{"__ignoreMap":72},[10,9597,161],{},[14,9599,164],{"id":164},[166,9601,9602,9610],{},[48,9603,9604,1969,9606,1972,9608,1975],{},[33,9605,1915],{},[33,9607,1923],{},[33,9609,1893],{},[48,9611,9612,1980,9614,1984],{},[33,9613,1880],{},[33,9615,1983],{},[14,9617,180],{"id":180},[45,9619,9620,9626],{},[48,9621,1991,9622,1155,9624,360],{},[33,9623,1893],{},[33,9625,1897],{},[48,9627,1998],{},[14,9629,191],{"id":191},[166,9631,9632,9636],{},[48,9633,2005,9634,2009],{},[33,9635,2008],{},[48,9637,2012],{},[10,9639,202],{},[14,9641,205],{"id":205},[10,9643,2019],{},[210,9645,2022],{},{"title":72,"searchDepth":85,"depth":85,"links":9647},[9648,9649,9650,9651,9652,9653,9654,9655],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":1857,"description":1862},[223,2040,2041],{"id":2044,"title":2045,"body":9660,"category":223,"cover":224,"description":2050,"extension":225,"meta":9781,"navigation":88,"path":2199,"pinned":228,"publishedAt":229,"seo":9782,"slug":2201,"stem":2202,"summary":2203,"tags":9783,"updatedAt":229,"visible":88,"__hash__":2207},{"type":7,"value":9661,"toc":9771},[9662,9664,9666,9668,9670,9674,9682,9684,9698,9700,9702,9718,9720,9725,9727,9729,9743,9745,9751,9753,9763,9765,9767,9769],[10,9663,2050],{},[14,9665,16],{"id":16},[10,9667,2055],{},[14,9669,22],{"id":22},[10,9671,9672],{},[26,9673],{"alt":2062,"src":2063},[10,9675,2066,9676,360,9678,2072,9680,360],{},[33,9677,1471],{},[33,9679,2071],{},[33,9681,1779],{},[14,9683,43],{"id":43},[45,9685,9686,9690,9696],{},[48,9687,9688,2084],{},[33,9689,2083],{},[48,9691,9692,2090,9694,360],{},[33,9693,2089],{},[33,9695,2093],{},[48,9697,2096],{},[14,9699,62],{"id":62},[10,9701,65],{},[67,9703,9704],{"className":69,"code":2103,"language":71,"meta":72,"style":72},[33,9705,9706,9710,9714],{"__ignoreMap":72},[76,9707,9708],{"class":78,"line":79},[76,9709,2110],{},[76,9711,9712],{"class":78,"line":85},[76,9713,2115],{},[76,9715,9716],{"class":78,"line":92},[76,9717,2120],{},[10,9719,150],{},[67,9721,9723],{"className":9722,"code":2126,"language":156,"meta":72},[154],[33,9724,2126],{"__ignoreMap":72},[10,9726,161],{},[14,9728,164],{"id":164},[166,9730,9731,9737],{},[48,9732,9733,2140,9735,360],{},[33,9734,2139],{},[33,9736,2093],{},[48,9738,9739,2147,9741,2151],{},[33,9740,1471],{},[33,9742,2150],{},[14,9744,180],{"id":180},[45,9746,9747,9749],{},[48,9748,2158],{},[48,9750,2161],{},[14,9752,191],{"id":191},[166,9754,9755,9757],{},[48,9756,2168],{},[48,9758,2171,9759,2174,9761,2178],{},[33,9760,2071],{},[33,9762,2177],{},[10,9764,202],{},[14,9766,205],{"id":205},[10,9768,2185],{},[210,9770,212],{},{"title":72,"searchDepth":85,"depth":85,"links":9772},[9773,9774,9775,9776,9777,9778,9779,9780],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":2045,"description":2050},[223,2205,2206],{"id":2209,"title":2210,"body":9785,"category":223,"cover":224,"description":2215,"extension":225,"meta":9918,"navigation":88,"path":2383,"pinned":228,"publishedAt":229,"seo":9919,"slug":2385,"stem":2386,"summary":2387,"tags":9920,"updatedAt":229,"visible":88,"__hash__":2391},{"type":7,"value":9786,"toc":9908},[9787,9789,9791,9793,9795,9799,9801,9803,9819,9821,9823,9847,9849,9854,9856,9858,9874,9876,9888,9890,9900,9902,9904,9906],[10,9788,2215],{},[14,9790,16],{"id":16},[10,9792,2220],{},[14,9794,22],{"id":22},[10,9796,9797],{},[26,9798],{"alt":2227,"src":2228},[10,9800,2231],{},[14,9802,43],{"id":43},[45,9804,9805,9807,9813],{},[48,9806,2238],{},[48,9808,2241,9809,2174,9811,2248],{},[33,9810,2244],{},[33,9812,2247],{},[48,9814,2251,9815,2255,9817,2259],{},[33,9816,2254],{},[33,9818,2258],{},[14,9820,62],{"id":62},[10,9822,65],{},[67,9824,9825],{"className":69,"code":2266,"language":71,"meta":72,"style":72},[33,9826,9827,9831,9835,9839,9843],{"__ignoreMap":72},[76,9828,9829],{"class":78,"line":79},[76,9830,2273],{},[76,9832,9833],{"class":78,"line":85},[76,9834,2278],{},[76,9836,9837],{"class":78,"line":92},[76,9838,89],{"emptyLinePlaceholder":88},[76,9840,9841],{"class":78,"line":98},[76,9842,2287],{},[76,9844,9845],{"class":78,"line":103},[76,9846,2278],{},[10,9848,150],{},[67,9850,9852],{"className":9851,"code":2297,"language":156,"meta":72},[154],[33,9853,2297],{"__ignoreMap":72},[10,9855,161],{},[14,9857,164],{"id":164},[166,9859,9860,9866],{},[48,9861,936,9862,2311,9864,2314],{},[33,9863,2310],{},[33,9865,2244],{},[48,9867,936,9868,2320,9870,2324,9872,360],{},[33,9869,2319],{},[33,9871,2323],{},[33,9873,2327],{},[14,9875,180],{"id":180},[45,9877,9878,9880],{},[48,9879,2334],{},[48,9881,2337,9882,2255,9884,2255,9886,2345],{},[33,9883,2254],{},[33,9885,2258],{},[33,9887,2344],{},[14,9889,191],{"id":191},[166,9891,9892,9898],{},[48,9893,2352,9894,1155,9896,2359],{},[33,9895,2355],{},[33,9897,2358],{},[48,9899,2362],{},[10,9901,202],{},[14,9903,205],{"id":205},[10,9905,2369],{},[210,9907,212],{},{"title":72,"searchDepth":85,"depth":85,"links":9909},[9910,9911,9912,9913,9914,9915,9916,9917],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":2210,"description":2215},[223,2389,2390],{"id":2393,"title":2394,"body":9922,"category":223,"cover":224,"description":2399,"extension":225,"meta":10055,"navigation":88,"path":2564,"pinned":228,"publishedAt":229,"seo":10056,"slug":2566,"stem":2567,"summary":2568,"tags":10057,"updatedAt":229,"visible":88,"__hash__":2572},{"type":7,"value":9923,"toc":10045},[9924,9926,9928,9930,9932,9936,9938,9940,9958,9960,9962,9998,10000,10005,10007,10009,10019,10021,10029,10031,10037,10039,10041,10043],[10,9925,2399],{},[14,9927,16],{"id":16},[10,9929,2404],{},[14,9931,22],{"id":22},[10,9933,9934],{},[26,9935],{"alt":2411,"src":2412},[10,9937,2415],{},[14,9939,43],{"id":43},[45,9941,9942,9948,9956],{},[48,9943,9944,2425,9946,2429],{},[33,9945,2424],{},[33,9947,2428],{},[48,9949,9950,2435,9952,2439,9954,2443],{},[33,9951,2434],{},[33,9953,2438],{},[33,9955,2442],{},[48,9957,2446],{},[14,9959,62],{"id":62},[10,9961,65],{},[67,9963,9964],{"className":69,"code":2453,"language":71,"meta":72,"style":72},[33,9965,9966,9970,9974,9978,9982,9986,9990,9994],{"__ignoreMap":72},[76,9967,9968],{"class":78,"line":79},[76,9969,2460],{},[76,9971,9972],{"class":78,"line":85},[76,9973,2465],{},[76,9975,9976],{"class":78,"line":92},[76,9977,2470],{},[76,9979,9980],{"class":78,"line":98},[76,9981,89],{"emptyLinePlaceholder":88},[76,9983,9984],{"class":78,"line":103},[76,9985,2479],{},[76,9987,9988],{"class":78,"line":109},[76,9989,2484],{},[76,9991,9992],{"class":78,"line":115},[76,9993,2489],{},[76,9995,9996],{"class":78,"line":121},[76,9997,2494],{},[10,9999,150],{},[67,10001,10003],{"className":10002,"code":2500,"language":156,"meta":72},[154],[33,10004,2500],{"__ignoreMap":72},[10,10006,161],{},[14,10008,164],{"id":164},[166,10010,10011,10015],{},[48,10012,10013,2514],{},[33,10014,2513],{},[48,10016,10017,2520],{},[33,10018,2519],{},[14,10020,180],{"id":180},[45,10022,10023,10027],{},[48,10024,2527,10025,360],{},[33,10026,2530],{},[48,10028,2533],{},[14,10030,191],{"id":191},[166,10032,10033,10035],{},[48,10034,2540],{},[48,10036,2543],{},[10,10038,202],{},[14,10040,205],{"id":205},[10,10042,2550],{},[210,10044,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10046},[10047,10048,10049,10050,10051,10052,10053,10054],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":2394,"description":2399},[223,2570,2571],{"id":2574,"title":2575,"body":10059,"category":223,"cover":224,"description":2580,"extension":225,"meta":10196,"navigation":88,"path":2757,"pinned":228,"publishedAt":229,"seo":10197,"slug":2759,"stem":2760,"summary":2761,"tags":10198,"updatedAt":229,"visible":88,"__hash__":2765},{"type":7,"value":10060,"toc":10184},[10061,10063,10065,10067,10069,10073,10079,10081,10089,10091,10093,10117,10119,10124,10126,10128,10146,10148,10150,10154,10156,10158,10164,10166,10176,10178,10180,10182],[10,10062,2580],{},[14,10064,16],{"id":16},[10,10066,2585],{},[14,10068,22],{"id":22},[10,10070,10071],{},[26,10072],{"alt":2592,"src":2593},[10,10074,2596,10075,2600,10077,360],{},[33,10076,2599],{},[33,10078,2603],{},[14,10080,43],{"id":43},[45,10082,10083,10085,10087],{},[48,10084,2610],{},[48,10086,2613],{},[48,10088,2616],{},[14,10090,62],{"id":62},[10,10092,65],{},[67,10094,10095],{"className":69,"code":2623,"language":71,"meta":72,"style":72},[33,10096,10097,10101,10105,10109,10113],{"__ignoreMap":72},[76,10098,10099],{"class":78,"line":79},[76,10100,2630],{},[76,10102,10103],{"class":78,"line":85},[76,10104,2635],{},[76,10106,10107],{"class":78,"line":92},[76,10108,2640],{},[76,10110,10111],{"class":78,"line":98},[76,10112,2645],{},[76,10114,10115],{"class":78,"line":103},[76,10116,2650],{},[10,10118,150],{},[67,10120,10122],{"className":10121,"code":2656,"language":156,"meta":72},[154],[33,10123,2656],{"__ignoreMap":72},[10,10125,161],{},[14,10127,164],{"id":164},[166,10129,10130,10138],{},[48,10131,2667,10132,2670,10134,2674,10136,2678],{},[33,10133,223],{},[33,10135,2673],{},[33,10137,2677],{},[48,10139,10140,2684,10142,2688,10144,2692],{},[33,10141,2683],{},[33,10143,2687],{},[33,10145,2691],{},[326,10147,2695],{"id":2695},[10,10149,2698],{},[10,10151,10152],{},[26,10153],{"alt":2703,"src":2704},[10,10155,2707],{},[14,10157,180],{"id":180},[45,10159,10160,10162],{},[48,10161,2714],{},[48,10163,2717],{},[14,10165,191],{"id":191},[166,10167,10168,10174],{},[48,10169,2724,10170,2728,10172,360],{},[33,10171,2727],{},[33,10173,2731],{},[48,10175,2734],{},[10,10177,202],{},[14,10179,205],{"id":205},[10,10181,2741],{},[210,10183,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10185},[10186,10187,10188,10189,10190,10193,10194,10195],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":10191},[10192],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":2575,"description":2580},[223,2763,2764],{"id":2767,"title":2768,"body":10200,"category":223,"cover":224,"description":2773,"extension":225,"meta":10365,"navigation":88,"path":2988,"pinned":228,"publishedAt":229,"seo":10366,"slug":2990,"stem":2991,"summary":2992,"tags":10367,"updatedAt":229,"visible":88,"__hash__":2996},{"type":7,"value":10201,"toc":10353},[10202,10204,10206,10208,10210,10214,10220,10222,10242,10244,10246,10282,10284,10289,10291,10293,10307,10309,10311,10315,10321,10323,10333,10335,10345,10347,10349,10351],[10,10203,2773],{},[14,10205,16],{"id":16},[10,10207,2778],{},[14,10209,22],{"id":22},[10,10211,10212],{},[26,10213],{"alt":2785,"src":2786},[10,10215,2789,10216,1007,10218,2796],{},[33,10217,2792],{},[33,10219,2795],{},[14,10221,43],{"id":43},[45,10223,10224,10232,10240],{},[48,10225,10226,2806,10228,2810,10230,2814],{},[33,10227,2805],{},[33,10229,2809],{},[33,10231,2813],{},[48,10233,10234,2820,10236,2824,10238,2828],{},[33,10235,2819],{},[33,10237,2823],{},[33,10239,2827],{},[48,10241,2831],{},[14,10243,62],{"id":62},[10,10245,65],{},[67,10247,10248],{"className":69,"code":2838,"language":71,"meta":72,"style":72},[33,10249,10250,10254,10258,10262,10266,10270,10274,10278],{"__ignoreMap":72},[76,10251,10252],{"class":78,"line":79},[76,10253,2845],{},[76,10255,10256],{"class":78,"line":85},[76,10257,2850],{},[76,10259,10260],{"class":78,"line":92},[76,10261,89],{"emptyLinePlaceholder":88},[76,10263,10264],{"class":78,"line":98},[76,10265,2859],{},[76,10267,10268],{"class":78,"line":103},[76,10269,2864],{},[76,10271,10272],{"class":78,"line":109},[76,10273,2869],{},[76,10275,10276],{"class":78,"line":115},[76,10277,2874],{},[76,10279,10280],{"class":78,"line":121},[76,10281,2879],{},[10,10283,150],{},[67,10285,10287],{"className":10286,"code":2885,"language":156,"meta":72},[154],[33,10288,2885],{"__ignoreMap":72},[10,10290,161],{},[14,10292,164],{"id":164},[166,10294,10295,10301],{},[48,10296,10297,2899,10299,2903],{},[33,10298,2898],{},[33,10300,2902],{},[48,10302,10303,2909,10305,2912],{},[33,10304,2908],{},[33,10306,2827],{},[326,10308,2695],{"id":2695},[10,10310,2917],{},[10,10312,10313],{},[26,10314],{"alt":2922,"src":2923},[10,10316,10317,2928,10319,2931],{},[33,10318,2819],{},[33,10320,2823],{},[14,10322,180],{"id":180},[45,10324,10325,10331],{},[48,10326,2938,10327,2941,10329,2944],{},[33,10328,2813],{},[33,10330,2805],{},[48,10332,2947],{},[14,10334,191],{"id":191},[166,10336,10337,10341],{},[48,10338,2954,10339,2958],{},[33,10340,2957],{},[48,10342,2961,10343,2965],{},[33,10344,2964],{},[10,10346,202],{},[14,10348,205],{"id":205},[10,10350,2972],{},[210,10352,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10354},[10355,10356,10357,10358,10359,10362,10363,10364],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":10360},[10361],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":2768,"description":2773},[223,2994,2995],{"id":2998,"title":2999,"body":10369,"category":223,"cover":224,"description":3004,"extension":225,"meta":10502,"navigation":88,"path":3173,"pinned":228,"publishedAt":229,"seo":10503,"slug":3175,"stem":3176,"summary":3177,"tags":10504,"updatedAt":229,"visible":88,"__hash__":3180},{"type":7,"value":10370,"toc":10492},[10371,10373,10375,10377,10379,10383,10393,10395,10405,10407,10409,10437,10439,10444,10446,10448,10462,10464,10472,10474,10484,10486,10488,10490],[10,10372,3004],{},[14,10374,16],{"id":16},[10,10376,3009],{},[14,10378,22],{"id":22},[10,10380,10381],{},[26,10382],{"alt":3016,"src":3017},[10,10384,10385,3023,10387,3027,10389,3031,10391,3035],{},[33,10386,3022],{},[33,10388,3026],{},[33,10390,3030],{},[33,10392,3034],{},[14,10394,43],{"id":43},[45,10396,10397,10399,10403],{},[48,10398,3042],{},[48,10400,10401,3047],{},[33,10402,3034],{},[48,10404,3050],{},[14,10406,62],{"id":62},[10,10408,65],{},[67,10410,10411],{"className":69,"code":3057,"language":71,"meta":72,"style":72},[33,10412,10413,10417,10421,10425,10429,10433],{"__ignoreMap":72},[76,10414,10415],{"class":78,"line":79},[76,10416,3064],{},[76,10418,10419],{"class":78,"line":85},[76,10420,3069],{},[76,10422,10423],{"class":78,"line":92},[76,10424,3074],{},[76,10426,10427],{"class":78,"line":98},[76,10428,89],{"emptyLinePlaceholder":88},[76,10430,10431],{"class":78,"line":103},[76,10432,3083],{},[76,10434,10435],{"class":78,"line":109},[76,10436,3088],{},[10,10438,150],{},[67,10440,10442],{"className":10441,"code":3094,"language":156,"meta":72},[154],[33,10443,3094],{"__ignoreMap":72},[10,10445,161],{},[14,10447,164],{"id":164},[166,10449,10450,10456],{},[48,10451,3105,10452,3108,10454,3112],{},[33,10453,3022],{},[33,10455,3111],{},[48,10457,10458,3118,10460,3122],{},[33,10459,3117],{},[33,10461,3121],{},[14,10463,180],{"id":180},[45,10465,10466,10470],{},[48,10467,3129,10468,3133],{},[33,10469,3132],{},[48,10471,3136],{},[14,10473,191],{"id":191},[166,10475,10476,10478],{},[48,10477,3143],{},[48,10479,1718,10480,3149,10482,3152],{},[33,10481,3148],{},[33,10483,3034],{},[10,10485,202],{},[14,10487,205],{"id":205},[10,10489,3159],{},[210,10491,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10493},[10494,10495,10496,10497,10498,10499,10500,10501],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":2999,"description":3004},[223,2344,3179],{"id":3182,"title":3183,"body":10506,"category":223,"cover":224,"description":3188,"extension":225,"meta":10635,"navigation":88,"path":3349,"pinned":228,"publishedAt":229,"seo":10636,"slug":3351,"stem":3352,"summary":3353,"tags":10637,"updatedAt":229,"visible":88,"__hash__":3357},{"type":7,"value":10507,"toc":10625},[10508,10510,10512,10514,10516,10520,10524,10526,10536,10538,10540,10572,10574,10579,10581,10583,10595,10597,10607,10609,10617,10619,10621,10623],[10,10509,3188],{},[14,10511,16],{"id":16},[10,10513,3193],{},[14,10515,22],{"id":22},[10,10517,10518],{},[26,10519],{"alt":3200,"src":3201},[10,10521,3204,10522,3208],{},[33,10523,3207],{},[14,10525,43],{"id":43},[45,10527,10528,10530,10532],{},[48,10529,3215],{},[48,10531,3218],{},[48,10533,3221,10534,360],{},[33,10535,3224],{},[14,10537,62],{"id":62},[10,10539,65],{},[67,10541,10542],{"className":69,"code":3231,"language":71,"meta":72,"style":72},[33,10543,10544,10548,10552,10556,10560,10564,10568],{"__ignoreMap":72},[76,10545,10546],{"class":78,"line":79},[76,10547,3238],{},[76,10549,10550],{"class":78,"line":85},[76,10551,3243],{},[76,10553,10554],{"class":78,"line":92},[76,10555,89],{"emptyLinePlaceholder":88},[76,10557,10558],{"class":78,"line":98},[76,10559,3252],{},[76,10561,10562],{"class":78,"line":103},[76,10563,3257],{},[76,10565,10566],{"class":78,"line":109},[76,10567,3262],{},[76,10569,10570],{"class":78,"line":115},[76,10571,3267],{},[10,10573,150],{},[67,10575,10577],{"className":10576,"code":3273,"language":156,"meta":72},[154],[33,10578,3273],{"__ignoreMap":72},[10,10580,161],{},[14,10582,164],{"id":164},[166,10584,10585,10587],{},[48,10586,3284],{},[48,10588,10589,3290,10591,3294,10593,3298],{},[33,10590,3289],{},[33,10592,3293],{},[33,10594,3297],{},[14,10596,180],{"id":180},[45,10598,10599,10605],{},[48,10600,3305,10601,3309,10603,360],{},[33,10602,3308],{},[33,10604,3312],{},[48,10606,3315],{},[14,10608,191],{"id":191},[166,10610,10611,10613],{},[48,10612,3322],{},[48,10614,3325,10615,3328],{},[33,10616,3297],{},[10,10618,202],{},[14,10620,205],{"id":205},[10,10622,3335],{},[210,10624,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10626},[10627,10628,10629,10630,10631,10632,10633,10634],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":3183,"description":3188},[223,3355,3356],{"id":3359,"title":3360,"body":10639,"category":223,"cover":224,"description":3365,"extension":225,"meta":10758,"navigation":88,"path":3507,"pinned":228,"publishedAt":229,"seo":10759,"slug":3509,"stem":3510,"summary":3511,"tags":10760,"updatedAt":229,"visible":88,"__hash__":3514},{"type":7,"value":10640,"toc":10748},[10641,10643,10645,10647,10649,10653,10655,10657,10665,10667,10669,10697,10699,10704,10706,10708,10718,10720,10728,10730,10740,10742,10744,10746],[10,10642,3365],{},[14,10644,16],{"id":16},[10,10646,3370],{},[14,10648,22],{"id":22},[10,10650,10651],{},[26,10652],{"alt":3377,"src":3378},[10,10654,3381],{},[14,10656,43],{"id":43},[45,10658,10659,10661,10663],{},[48,10660,3388],{},[48,10662,3391],{},[48,10664,3394],{},[14,10666,62],{"id":62},[10,10668,65],{},[67,10670,10671],{"className":69,"code":3401,"language":71,"meta":72,"style":72},[33,10672,10673,10677,10681,10685,10689,10693],{"__ignoreMap":72},[76,10674,10675],{"class":78,"line":79},[76,10676,3408],{},[76,10678,10679],{"class":78,"line":85},[76,10680,3413],{},[76,10682,10683],{"class":78,"line":92},[76,10684,3418],{},[76,10686,10687],{"class":78,"line":98},[76,10688,89],{"emptyLinePlaceholder":88},[76,10690,10691],{"class":78,"line":103},[76,10692,3427],{},[76,10694,10695],{"class":78,"line":109},[76,10696,3432],{},[10,10698,150],{},[67,10700,10702],{"className":10701,"code":3438,"language":156,"meta":72},[154],[33,10703,3438],{"__ignoreMap":72},[10,10705,161],{},[14,10707,164],{"id":164},[166,10709,10710,10714],{},[48,10711,10712,3452],{},[33,10713,3451],{},[48,10715,10716,3458],{},[33,10717,3457],{},[14,10719,180],{"id":180},[45,10721,10722,10726],{},[48,10723,3465,10724,3469],{},[33,10725,3468],{},[48,10727,3472],{},[14,10729,191],{"id":191},[166,10731,10732,10734],{},[48,10733,3479],{},[48,10735,2171,10736,2174,10738,3486],{},[33,10737,3468],{},[33,10739,3457],{},[10,10741,202],{},[14,10743,205],{"id":205},[10,10745,3493],{},[210,10747,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10749},[10750,10751,10752,10753,10754,10755,10756,10757],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":3360,"description":3365},[223,3513,3356],{"id":3516,"title":3517,"body":10762,"category":223,"cover":224,"description":3522,"extension":225,"meta":10887,"navigation":88,"path":3678,"pinned":228,"publishedAt":229,"seo":10888,"slug":3680,"stem":3681,"summary":3682,"tags":10889,"updatedAt":229,"visible":88,"__hash__":3685},{"type":7,"value":10763,"toc":10877},[10764,10766,10768,10770,10772,10776,10782,10784,10794,10796,10798,10826,10828,10833,10835,10837,10847,10849,10861,10863,10869,10871,10873,10875],[10,10765,3522],{},[14,10767,16],{"id":16},[10,10769,3527],{},[14,10771,22],{"id":22},[10,10773,10774],{},[26,10775],{"alt":3534,"src":3535},[10,10777,3538,10778,3542,10780,3545],{},[33,10779,3541],{},[33,10781,2244],{},[14,10783,43],{"id":43},[45,10785,10786,10788,10792],{},[48,10787,3552],{},[48,10789,2337,10790,3558],{},[33,10791,3557],{},[48,10793,3561],{},[14,10795,62],{"id":62},[10,10797,65],{},[67,10799,10800],{"className":69,"code":3568,"language":71,"meta":72,"style":72},[33,10801,10802,10806,10810,10814,10818,10822],{"__ignoreMap":72},[76,10803,10804],{"class":78,"line":79},[76,10805,3575],{},[76,10807,10808],{"class":78,"line":85},[76,10809,3580],{},[76,10811,10812],{"class":78,"line":92},[76,10813,89],{"emptyLinePlaceholder":88},[76,10815,10816],{"class":78,"line":98},[76,10817,3589],{},[76,10819,10820],{"class":78,"line":103},[76,10821,3594],{},[76,10823,10824],{"class":78,"line":109},[76,10825,3599],{},[10,10827,150],{},[67,10829,10831],{"className":10830,"code":3605,"language":156,"meta":72},[154],[33,10832,3605],{"__ignoreMap":72},[10,10834,161],{},[14,10836,164],{"id":164},[166,10838,10839,10841],{},[48,10840,3616],{},[48,10842,3619,10843,3622,10845,3626],{},[33,10844,2244],{},[33,10846,3625],{},[14,10848,180],{"id":180},[45,10850,10851,10855],{},[48,10852,3633,10853,3637],{},[33,10854,3636],{},[48,10856,3640,10857,3644,10859,360],{},[33,10858,3643],{},[33,10860,3647],{},[14,10862,191],{"id":191},[166,10864,10865,10867],{},[48,10866,3654],{},[48,10868,3657],{},[10,10870,202],{},[14,10872,205],{"id":205},[10,10874,3664],{},[210,10876,212],{},{"title":72,"searchDepth":85,"depth":85,"links":10878},[10879,10880,10881,10882,10883,10884,10885,10886],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":3517,"description":3522},[223,3684,3356],{"id":3687,"title":3688,"body":10891,"category":223,"cover":224,"description":3693,"extension":225,"meta":11014,"navigation":88,"path":3843,"pinned":228,"publishedAt":229,"seo":11015,"slug":3845,"stem":3846,"summary":3847,"tags":11016,"updatedAt":229,"visible":88,"__hash__":3850},{"type":7,"value":10892,"toc":11004},[10893,10895,10897,10899,10901,10905,10907,10909,10921,10923,10925,10953,10955,10960,10962,10964,10974,10976,10986,10988,10996,10998,11000,11002],[10,10894,3693],{},[14,10896,16],{"id":16},[10,10898,3698],{},[14,10900,22],{"id":22},[10,10902,10903],{},[26,10904],{"alt":3705,"src":3706},[10,10906,3709],{},[14,10908,43],{"id":43},[45,10910,10911,10913,10915],{},[48,10912,3716],{},[48,10914,3719],{},[48,10916,3722,10917,3726,10919,3730],{},[33,10918,3725],{},[33,10920,3729],{},[14,10922,62],{"id":62},[10,10924,65],{},[67,10926,10927],{"className":69,"code":3737,"language":71,"meta":72,"style":72},[33,10928,10929,10933,10937,10941,10945,10949],{"__ignoreMap":72},[76,10930,10931],{"class":78,"line":79},[76,10932,3744],{},[76,10934,10935],{"class":78,"line":85},[76,10936,3749],{},[76,10938,10939],{"class":78,"line":92},[76,10940,89],{"emptyLinePlaceholder":88},[76,10942,10943],{"class":78,"line":98},[76,10944,3758],{},[76,10946,10947],{"class":78,"line":103},[76,10948,3763],{},[76,10950,10951],{"class":78,"line":109},[76,10952,3768],{},[10,10954,150],{},[67,10956,10958],{"className":10957,"code":3774,"language":156,"meta":72},[154],[33,10959,3774],{"__ignoreMap":72},[10,10961,161],{},[14,10963,164],{"id":164},[166,10965,10966,10968],{},[48,10967,3785],{},[48,10969,10970,3791,10972,3795],{},[33,10971,3790],{},[33,10973,3794],{},[14,10975,180],{"id":180},[45,10977,10978,10984],{},[48,10979,2337,10980,3804,10982,360],{},[33,10981,3729],{},[33,10983,3725],{},[48,10985,3809],{},[14,10987,191],{"id":191},[166,10989,10990,10994],{},[48,10991,3816,10992,3819],{},[33,10993,3725],{},[48,10995,3822],{},[10,10997,202],{},[14,10999,205],{"id":205},[10,11001,3829],{},[210,11003,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11005},[11006,11007,11008,11009,11010,11011,11012,11013],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":3688,"description":3693},[223,3849,3356],{"id":3852,"title":3853,"body":11018,"category":223,"cover":224,"description":3858,"extension":225,"meta":11177,"navigation":88,"path":4056,"pinned":228,"publishedAt":229,"seo":11178,"slug":4058,"stem":4059,"summary":4060,"tags":11179,"updatedAt":229,"visible":88,"__hash__":4064},{"type":7,"value":11019,"toc":11165},[11020,11022,11024,11026,11028,11032,11038,11040,11052,11054,11056,11096,11098,11103,11105,11107,11121,11123,11125,11129,11131,11133,11143,11145,11157,11159,11161,11163],[10,11021,3858],{},[14,11023,16],{"id":16},[10,11025,3863],{},[14,11027,22],{"id":22},[10,11029,11030],{},[26,11031],{"alt":3870,"src":3871},[10,11033,11034,3877,11036,3881],{},[33,11035,3876],{},[33,11037,3880],{},[14,11039,43],{"id":43},[45,11041,11042,11048,11050],{},[48,11043,11044,3890,11046,3894],{},[33,11045,2805],{},[33,11047,3893],{},[48,11049,3897],{},[48,11051,3900],{},[14,11053,62],{"id":62},[10,11055,65],{},[67,11057,11058],{"className":69,"code":3907,"language":71,"meta":72,"style":72},[33,11059,11060,11064,11068,11072,11076,11080,11084,11088,11092],{"__ignoreMap":72},[76,11061,11062],{"class":78,"line":79},[76,11063,3914],{},[76,11065,11066],{"class":78,"line":85},[76,11067,3919],{},[76,11069,11070],{"class":78,"line":92},[76,11071,3924],{},[76,11073,11074],{"class":78,"line":98},[76,11075,89],{"emptyLinePlaceholder":88},[76,11077,11078],{"class":78,"line":103},[76,11079,3933],{},[76,11081,11082],{"class":78,"line":109},[76,11083,3938],{},[76,11085,11086],{"class":78,"line":115},[76,11087,3943],{},[76,11089,11090],{"class":78,"line":121},[76,11091,3948],{},[76,11093,11094],{"class":78,"line":126},[76,11095,3953],{},[10,11097,150],{},[67,11099,11101],{"className":11100,"code":3959,"language":156,"meta":72},[154],[33,11102,3959],{"__ignoreMap":72},[10,11104,161],{},[14,11106,164],{"id":164},[166,11108,11109,11113],{},[48,11110,11111,3973],{},[33,11112,3972],{},[48,11114,11115,3979,11117,3983,11119,3987],{},[33,11116,3978],{},[33,11118,3982],{},[33,11120,3986],{},[326,11122,2695],{"id":2695},[10,11124,3992],{},[10,11126,11127],{},[26,11128],{"alt":3997,"src":3998},[10,11130,4001],{},[14,11132,180],{"id":180},[45,11134,11135,11141],{},[48,11136,4008,11137,4011,11139,360],{},[33,11138,2805],{},[33,11140,3893],{},[48,11142,4016],{},[14,11144,191],{"id":191},[166,11146,11147,11149],{},[48,11148,4023],{},[48,11150,2337,11151,4029,11153,1155,11155,360],{},[33,11152,4028],{},[33,11154,3893],{},[33,11156,2805],{},[10,11158,202],{},[14,11160,205],{"id":205},[10,11162,4040],{},[210,11164,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11166},[11167,11168,11169,11170,11171,11174,11175,11176],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":11172},[11173],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":3853,"description":3858},[223,4062,4063],{"id":4066,"title":4067,"body":11181,"category":223,"cover":224,"description":4072,"extension":225,"meta":11353,"navigation":88,"path":4285,"pinned":228,"publishedAt":229,"seo":11354,"slug":4287,"stem":4288,"summary":4289,"tags":11355,"updatedAt":229,"visible":88,"__hash__":4292},{"type":7,"value":11182,"toc":11340},[11183,11185,11187,11189,11191,11195,11203,11205,11213,11215,11217,11261,11263,11268,11270,11272,11284,11286,11288,11292,11298,11300,11302,11306,11310,11312,11324,11326,11332,11334,11336,11338],[10,11184,4072],{},[14,11186,16],{"id":16},[10,11188,4077],{},[14,11190,22],{"id":22},[10,11192,11193],{},[26,11194],{"alt":4084,"src":4085},[10,11196,11197,2255,11199,2255,11201,4095],{},[33,11198,1154],{},[33,11200,4092],{},[33,11202,1158],{},[14,11204,43],{"id":43},[45,11206,11207,11209,11211],{},[48,11208,4102],{},[48,11210,4105],{},[48,11212,4108],{},[14,11214,62],{"id":62},[10,11216,65],{},[67,11218,11219],{"className":69,"code":4115,"language":71,"meta":72,"style":72},[33,11220,11221,11225,11229,11233,11237,11241,11245,11249,11253,11257],{"__ignoreMap":72},[76,11222,11223],{"class":78,"line":79},[76,11224,4122],{},[76,11226,11227],{"class":78,"line":85},[76,11228,89],{"emptyLinePlaceholder":88},[76,11230,11231],{"class":78,"line":92},[76,11232,4131],{},[76,11234,11235],{"class":78,"line":98},[76,11236,4136],{},[76,11238,11239],{"class":78,"line":103},[76,11240,4141],{},[76,11242,11243],{"class":78,"line":109},[76,11244,4146],{},[76,11246,11247],{"class":78,"line":115},[76,11248,1144],{},[76,11250,11251],{"class":78,"line":121},[76,11252,4155],{},[76,11254,11255],{"class":78,"line":126},[76,11256,89],{"emptyLinePlaceholder":88},[76,11258,11259],{"class":78,"line":132},[76,11260,4164],{},[10,11262,150],{},[67,11264,11266],{"className":11265,"code":4170,"language":156,"meta":72},[154],[33,11267,4170],{"__ignoreMap":72},[10,11269,161],{},[14,11271,164],{"id":164},[166,11273,11274,11278],{},[48,11275,4181,11276,4185],{},[33,11277,4184],{},[48,11279,11280,4191,11282,4194],{},[33,11281,4190],{},[33,11283,1158],{},[326,11285,2695],{"id":2695},[10,11287,4199],{},[10,11289,11290],{},[26,11291],{"alt":4204,"src":4205},[10,11293,11294,4210,11296,4213],{},[33,11295,4184],{},[33,11297,4190],{},[326,11299,2695],{"id":4216},[10,11301,4219],{},[10,11303,11304],{},[26,11305],{"alt":4224,"src":4225},[10,11307,4228,11308,4231],{},[33,11309,1154],{},[14,11311,180],{"id":180},[45,11313,11314,11318],{},[48,11315,4238,11316,4241],{},[33,11317,4190],{},[48,11319,4244,11320,4247,11322,4251],{},[33,11321,1154],{},[33,11323,4250],{},[14,11325,191],{"id":191},[166,11327,11328,11330],{},[48,11329,4258],{},[48,11331,4261],{},[10,11333,202],{},[14,11335,205],{"id":205},[10,11337,4268],{},[210,11339,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11341},[11342,11343,11344,11345,11346,11350,11351,11352],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":11347},[11348,11349],{"id":2695,"depth":92,"text":2695},{"id":4216,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":4067,"description":4072},[223,1154,4291],{"id":4294,"title":4295,"body":11357,"category":223,"cover":224,"description":4300,"extension":225,"meta":11494,"navigation":88,"path":4467,"pinned":228,"publishedAt":229,"seo":11495,"slug":4469,"stem":4470,"summary":4471,"tags":11496,"updatedAt":229,"visible":88,"__hash__":4474},{"type":7,"value":11358,"toc":11482},[11359,11361,11363,11365,11367,11371,11375,11377,11387,11389,11391,11423,11425,11430,11432,11434,11444,11446,11448,11452,11456,11458,11464,11466,11474,11476,11478,11480],[10,11360,4300],{},[14,11362,16],{"id":16},[10,11364,4305],{},[14,11366,22],{"id":22},[10,11368,11369],{},[26,11370],{"alt":4312,"src":4313},[10,11372,11373,4319],{},[33,11374,4318],{},[14,11376,43],{"id":43},[45,11378,11379,11381,11383],{},[48,11380,4326],{},[48,11382,4329],{},[48,11384,4332,11385,4336],{},[33,11386,4335],{},[14,11388,62],{"id":62},[10,11390,65],{},[67,11392,11393],{"className":69,"code":4343,"language":71,"meta":72,"style":72},[33,11394,11395,11399,11403,11407,11411,11415,11419],{"__ignoreMap":72},[76,11396,11397],{"class":78,"line":79},[76,11398,4350],{},[76,11400,11401],{"class":78,"line":85},[76,11402,89],{"emptyLinePlaceholder":88},[76,11404,11405],{"class":78,"line":92},[76,11406,4359],{},[76,11408,11409],{"class":78,"line":98},[76,11410,4364],{},[76,11412,11413],{"class":78,"line":103},[76,11414,4369],{},[76,11416,11417],{"class":78,"line":109},[76,11418,89],{"emptyLinePlaceholder":88},[76,11420,11421],{"class":78,"line":115},[76,11422,4378],{},[10,11424,150],{},[67,11426,11428],{"className":11427,"code":4384,"language":156,"meta":72},[154],[33,11429,4384],{"__ignoreMap":72},[10,11431,161],{},[14,11433,164],{"id":164},[166,11435,11436,11440],{},[48,11437,4395,11438,4399],{},[33,11439,4398],{},[48,11441,4402,11442,4405],{},[33,11443,4398],{},[326,11445,2695],{"id":2695},[10,11447,4410],{},[10,11449,11450],{},[26,11451],{"alt":4415,"src":4416},[10,11453,4419,11454,4422],{},[33,11455,4398],{},[14,11457,180],{"id":180},[45,11459,11460,11462],{},[48,11461,4429],{},[48,11463,4432],{},[14,11465,191],{"id":191},[166,11467,11468,11472],{},[48,11469,2337,11470,4441],{},[33,11471,4318],{},[48,11473,4444],{},[10,11475,202],{},[14,11477,205],{"id":205},[10,11479,4451],{},[210,11481,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11483},[11484,11485,11486,11487,11488,11491,11492,11493],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":11489},[11490],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":4295,"description":4300},[223,4318,4473],{"id":4476,"title":4477,"body":11498,"category":223,"cover":224,"description":4482,"extension":225,"meta":11623,"navigation":88,"path":4631,"pinned":228,"publishedAt":229,"seo":11624,"slug":4633,"stem":4634,"summary":4635,"tags":11625,"updatedAt":229,"visible":88,"__hash__":4638},{"type":7,"value":11499,"toc":11613},[11500,11502,11504,11506,11508,11512,11516,11518,11528,11530,11532,11564,11566,11571,11573,11575,11587,11589,11595,11597,11605,11607,11609,11611],[10,11501,4482],{},[14,11503,16],{"id":16},[10,11505,4487],{},[14,11507,22],{"id":22},[10,11509,11510],{},[26,11511],{"alt":4494,"src":4495},[10,11513,11514,4500],{},[33,11515,4335],{},[14,11517,43],{"id":43},[45,11519,11520,11524,11526],{},[48,11521,11522,4510],{},[33,11523,4509],{},[48,11525,4513],{},[48,11527,4516],{},[14,11529,62],{"id":62},[10,11531,65],{},[67,11533,11534],{"className":69,"code":4523,"language":71,"meta":72,"style":72},[33,11535,11536,11540,11544,11548,11552,11556,11560],{"__ignoreMap":72},[76,11537,11538],{"class":78,"line":79},[76,11539,4530],{},[76,11541,11542],{"class":78,"line":85},[76,11543,89],{"emptyLinePlaceholder":88},[76,11545,11546],{"class":78,"line":92},[76,11547,4539],{},[76,11549,11550],{"class":78,"line":98},[76,11551,4544],{},[76,11553,11554],{"class":78,"line":103},[76,11555,89],{"emptyLinePlaceholder":88},[76,11557,11558],{"class":78,"line":109},[76,11559,4553],{},[76,11561,11562],{"class":78,"line":115},[76,11563,4558],{},[10,11565,150],{},[67,11567,11569],{"className":11568,"code":4564,"language":156,"meta":72},[154],[33,11570,4564],{"__ignoreMap":72},[10,11572,161],{},[14,11574,164],{"id":164},[166,11576,11577,11583],{},[48,11578,4575,11579,4578,11581,4582],{},[33,11580,4335],{},[33,11582,4581],{},[48,11584,11585,4587],{},[33,11586,4509],{},[14,11588,180],{"id":180},[45,11590,11591,11593],{},[48,11592,4594],{},[48,11594,4597],{},[14,11596,191],{"id":191},[166,11598,11599,11601],{},[48,11600,4604],{},[48,11602,2337,11603,4610],{},[33,11604,4609],{},[10,11606,202],{},[14,11608,205],{"id":205},[10,11610,4617],{},[210,11612,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11614},[11615,11616,11617,11618,11619,11620,11621,11622],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":4477,"description":4482},[223,4335,4637],{"id":4640,"title":4641,"body":11627,"category":223,"cover":224,"description":4646,"extension":225,"meta":11772,"navigation":88,"path":4821,"pinned":228,"publishedAt":229,"seo":11773,"slug":4823,"stem":4824,"summary":4825,"tags":11774,"updatedAt":229,"visible":88,"__hash__":4827},{"type":7,"value":11628,"toc":11762},[11629,11631,11633,11635,11637,11641,11647,11649,11663,11665,11667,11711,11713,11718,11720,11722,11732,11734,11746,11748,11754,11756,11758,11760],[10,11630,4646],{},[14,11632,16],{"id":16},[10,11634,4651],{},[14,11636,22],{"id":22},[10,11638,11639],{},[26,11640],{"alt":4658,"src":4659},[10,11642,11643,4665,11645,4669],{},[33,11644,4664],{},[33,11646,4668],{},[14,11648,43],{"id":43},[45,11650,11651,11653,11659],{},[48,11652,4676],{},[48,11654,11655,4681,11657,4684],{},[33,11656,4664],{},[33,11658,4318],{},[48,11660,4687,11661,4690],{},[33,11662,4668],{},[14,11664,62],{"id":62},[10,11666,65],{},[67,11668,11669],{"className":69,"code":4697,"language":71,"meta":72,"style":72},[33,11670,11671,11675,11679,11683,11687,11691,11695,11699,11703,11707],{"__ignoreMap":72},[76,11672,11673],{"class":78,"line":79},[76,11674,4704],{},[76,11676,11677],{"class":78,"line":85},[76,11678,89],{"emptyLinePlaceholder":88},[76,11680,11681],{"class":78,"line":92},[76,11682,4713],{},[76,11684,11685],{"class":78,"line":98},[76,11686,4718],{},[76,11688,11689],{"class":78,"line":103},[76,11690,4723],{},[76,11692,11693],{"class":78,"line":109},[76,11694,4728],{},[76,11696,11697],{"class":78,"line":115},[76,11698,4733],{},[76,11700,11701],{"class":78,"line":121},[76,11702,4558],{},[76,11704,11705],{"class":78,"line":126},[76,11706,89],{"emptyLinePlaceholder":88},[76,11708,11709],{"class":78,"line":132},[76,11710,4746],{},[10,11712,150],{},[67,11714,11716],{"className":11715,"code":4752,"language":156,"meta":72},[154],[33,11717,4752],{"__ignoreMap":72},[10,11719,161],{},[14,11721,164],{"id":164},[166,11723,11724,11728],{},[48,11725,4763,11726,4766],{},[33,11727,4664],{},[48,11729,4769,11730,4772],{},[33,11731,4668],{},[14,11733,180],{"id":180},[45,11735,11736,11740],{},[48,11737,3465,11738,4781],{},[33,11739,4664],{},[48,11741,4784,11742,4787,11744,4790],{},[33,11743,4318],{},[33,11745,4664],{},[14,11747,191],{"id":191},[166,11749,11750,11752],{},[48,11751,4797],{},[48,11753,4800],{},[10,11755,202],{},[14,11757,205],{"id":205},[10,11759,4807],{},[210,11761,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11763},[11764,11765,11766,11767,11768,11769,11770,11771],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":4641,"description":4646},[223,4668,4664],{"id":4829,"title":4830,"body":11776,"category":223,"cover":224,"description":4835,"extension":225,"meta":11915,"navigation":88,"path":5007,"pinned":228,"publishedAt":229,"seo":11916,"slug":5009,"stem":5010,"summary":5011,"tags":11917,"updatedAt":229,"visible":88,"__hash__":5015},{"type":7,"value":11777,"toc":11903},[11778,11780,11782,11784,11786,11790,11792,11794,11810,11812,11814,11842,11844,11849,11851,11853,11865,11867,11869,11873,11875,11877,11887,11889,11895,11897,11899,11901],[10,11779,4835],{},[14,11781,16],{"id":16},[10,11783,4840],{},[14,11785,22],{"id":22},[10,11787,11788],{},[26,11789],{"alt":4847,"src":4848},[10,11791,4851],{},[14,11793,43],{"id":43},[45,11795,11796,11798,11800],{},[48,11797,4858],{},[48,11799,4861],{},[48,11801,4864,11802,2255,11804,4871,11806,2255,11808,360],{},[33,11803,4867],{},[33,11805,4870],{},[33,11807,4874],{},[33,11809,4877],{},[14,11811,62],{"id":62},[10,11813,65],{},[67,11815,11816],{"className":69,"code":4884,"language":71,"meta":72,"style":72},[33,11817,11818,11822,11826,11830,11834,11838],{"__ignoreMap":72},[76,11819,11820],{"class":78,"line":79},[76,11821,4891],{},[76,11823,11824],{"class":78,"line":85},[76,11825,89],{"emptyLinePlaceholder":88},[76,11827,11828],{"class":78,"line":92},[76,11829,4900],{},[76,11831,11832],{"class":78,"line":98},[76,11833,4905],{},[76,11835,11836],{"class":78,"line":103},[76,11837,4910],{},[76,11839,11840],{"class":78,"line":109},[76,11841,4915],{},[10,11843,150],{},[67,11845,11847],{"className":11846,"code":4921,"language":156,"meta":72},[154],[33,11848,4921],{"__ignoreMap":72},[10,11850,161],{},[14,11852,164],{"id":164},[166,11854,11855,11863],{},[48,11856,4932,11857,4935,11859,1155,11861,360],{},[33,11858,4867],{},[33,11860,4938],{},[33,11862,4941],{},[48,11864,4944],{},[326,11866,2695],{"id":2695},[10,11868,4949],{},[10,11870,11871],{},[26,11872],{"alt":4954,"src":4955},[10,11874,4958],{},[14,11876,180],{"id":180},[45,11878,11879,11885],{},[48,11880,4965,11881,1007,11883,4971],{},[33,11882,4968],{},[33,11884,4874],{},[48,11886,4974],{},[14,11888,191],{"id":191},[166,11890,11891,11893],{},[48,11892,4981],{},[48,11894,4984],{},[10,11896,202],{},[14,11898,205],{"id":205},[10,11900,4991],{},[210,11902,212],{},{"title":72,"searchDepth":85,"depth":85,"links":11904},[11905,11906,11907,11908,11909,11912,11913,11914],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":11910},[11911],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":4830,"description":4835},[223,5013,5014],{"id":5017,"title":5018,"body":11919,"category":223,"cover":224,"description":5023,"extension":225,"meta":12036,"navigation":88,"path":5162,"pinned":228,"publishedAt":229,"seo":12037,"slug":5164,"stem":5165,"summary":5166,"tags":12038,"updatedAt":229,"visible":88,"__hash__":5170},{"type":7,"value":11920,"toc":12026},[11921,11923,11925,11927,11929,11933,11935,11937,11945,11947,11949,11981,11983,11988,11990,11992,12000,12002,12010,12012,12018,12020,12022,12024],[10,11922,5023],{},[14,11924,16],{"id":16},[10,11926,5028],{},[14,11928,22],{"id":22},[10,11930,11931],{},[26,11932],{"alt":5035,"src":5036},[10,11934,5039],{},[14,11936,43],{"id":43},[45,11938,11939,11941,11943],{},[48,11940,5046],{},[48,11942,5049],{},[48,11944,5052],{},[14,11946,62],{"id":62},[10,11948,65],{},[67,11950,11951],{"className":69,"code":5059,"language":71,"meta":72,"style":72},[33,11952,11953,11957,11961,11965,11969,11973,11977],{"__ignoreMap":72},[76,11954,11955],{"class":78,"line":79},[76,11956,5066],{},[76,11958,11959],{"class":78,"line":85},[76,11960,89],{"emptyLinePlaceholder":88},[76,11962,11963],{"class":78,"line":92},[76,11964,5075],{},[76,11966,11967],{"class":78,"line":98},[76,11968,5080],{},[76,11970,11971],{"class":78,"line":103},[76,11972,89],{"emptyLinePlaceholder":88},[76,11974,11975],{"class":78,"line":109},[76,11976,5089],{},[76,11978,11979],{"class":78,"line":115},[76,11980,5094],{},[10,11982,150],{},[67,11984,11986],{"className":11985,"code":5100,"language":156,"meta":72},[154],[33,11987,5100],{"__ignoreMap":72},[10,11989,161],{},[14,11991,164],{"id":164},[166,11993,11994,11996],{},[48,11995,5111],{},[48,11997,5114,11998,5118],{},[33,11999,5117],{},[14,12001,180],{"id":180},[45,12003,12004,12008],{},[48,12005,5125,12006,5128],{},[33,12007,4335],{},[48,12009,5131],{},[14,12011,191],{"id":191},[166,12013,12014,12016],{},[48,12015,5138],{},[48,12017,5141],{},[10,12019,202],{},[14,12021,205],{"id":205},[10,12023,5148],{},[210,12025,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12027},[12028,12029,12030,12031,12032,12033,12034,12035],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5018,"description":5023},[223,5168,5169],{"id":5172,"title":5173,"body":12040,"category":223,"cover":224,"description":5178,"extension":225,"meta":12159,"navigation":88,"path":5322,"pinned":228,"publishedAt":229,"seo":12160,"slug":5324,"stem":5325,"summary":5326,"tags":12161,"updatedAt":229,"visible":88,"__hash__":5330},{"type":7,"value":12041,"toc":12149},[12042,12044,12046,12048,12050,12054,12056,12058,12066,12068,12070,12102,12104,12109,12111,12113,12123,12125,12131,12133,12141,12143,12145,12147],[10,12043,5178],{},[14,12045,16],{"id":16},[10,12047,5183],{},[14,12049,22],{"id":22},[10,12051,12052],{},[26,12053],{"alt":5190,"src":5191},[10,12055,5194],{},[14,12057,43],{"id":43},[45,12059,12060,12062,12064],{},[48,12061,5201],{},[48,12063,5204],{},[48,12065,5207],{},[14,12067,62],{"id":62},[10,12069,65],{},[67,12071,12072],{"className":69,"code":5214,"language":71,"meta":72,"style":72},[33,12073,12074,12078,12082,12086,12090,12094,12098],{"__ignoreMap":72},[76,12075,12076],{"class":78,"line":79},[76,12077,5221],{},[76,12079,12080],{"class":78,"line":85},[76,12081,5226],{},[76,12083,12084],{"class":78,"line":92},[76,12085,5231],{},[76,12087,12088],{"class":78,"line":98},[76,12089,89],{"emptyLinePlaceholder":88},[76,12091,12092],{"class":78,"line":103},[76,12093,5240],{},[76,12095,12096],{"class":78,"line":109},[76,12097,5245],{},[76,12099,12100],{"class":78,"line":115},[76,12101,5250],{},[10,12103,150],{},[67,12105,12107],{"className":12106,"code":5256,"language":156,"meta":72},[154],[33,12108,5256],{"__ignoreMap":72},[10,12110,161],{},[14,12112,164],{"id":164},[166,12114,12115,12119],{},[48,12116,936,12117,5270],{},[33,12118,5269],{},[48,12120,5273,12121,5277],{},[33,12122,5276],{},[14,12124,180],{"id":180},[45,12126,12127,12129],{},[48,12128,5284],{},[48,12130,5287],{},[14,12132,191],{"id":191},[166,12134,12135,12139],{},[48,12136,5294,12137,5298],{},[33,12138,5297],{},[48,12140,5301],{},[10,12142,202],{},[14,12144,205],{"id":205},[10,12146,5308],{},[210,12148,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12150},[12151,12152,12153,12154,12155,12156,12157,12158],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5173,"description":5178},[223,5328,5329],{"id":5332,"title":5333,"body":12163,"category":223,"cover":224,"description":5338,"extension":225,"meta":12308,"navigation":88,"path":5519,"pinned":228,"publishedAt":229,"seo":12309,"slug":5521,"stem":5522,"summary":5523,"tags":12310,"updatedAt":229,"visible":88,"__hash__":5527},{"type":7,"value":12164,"toc":12296},[12165,12167,12169,12171,12173,12177,12181,12183,12195,12197,12199,12227,12229,12234,12236,12238,12252,12254,12256,12260,12268,12270,12280,12282,12288,12290,12292,12294],[10,12166,5338],{},[14,12168,16],{"id":16},[10,12170,5343],{},[14,12172,22],{"id":22},[10,12174,12175],{},[26,12176],{"alt":5350,"src":5351},[10,12178,5354,12179,5358],{},[33,12180,5357],{},[14,12182,43],{"id":43},[45,12184,12185,12187,12189],{},[48,12186,5365],{},[48,12188,5368],{},[48,12190,5371,12191,5374,12193,360],{},[33,12192,5357],{},[33,12194,5377],{},[14,12196,62],{"id":62},[10,12198,65],{},[67,12200,12201],{"className":69,"code":5384,"language":71,"meta":72,"style":72},[33,12202,12203,12207,12211,12215,12219,12223],{"__ignoreMap":72},[76,12204,12205],{"class":78,"line":79},[76,12206,5391],{},[76,12208,12209],{"class":78,"line":85},[76,12210,5396],{},[76,12212,12213],{"class":78,"line":92},[76,12214,5401],{},[76,12216,12217],{"class":78,"line":98},[76,12218,89],{"emptyLinePlaceholder":88},[76,12220,12221],{"class":78,"line":103},[76,12222,5410],{},[76,12224,12225],{"class":78,"line":109},[76,12226,5415],{},[10,12228,150],{},[67,12230,12232],{"className":12231,"code":5421,"language":156,"meta":72},[154],[33,12233,5421],{"__ignoreMap":72},[10,12235,161],{},[14,12237,164],{"id":164},[166,12239,12240,12246],{},[48,12241,5432,12242,2255,12244,5438],{},[33,12243,5435],{},[33,12245,4398],{},[48,12247,12248,5444,12250,5448],{},[33,12249,5443],{},[33,12251,5447],{},[326,12253,2695],{"id":2695},[10,12255,5453],{},[10,12257,12258],{},[26,12259],{"alt":5458,"src":5459},[10,12261,12262,2255,12264,1155,12266,5469],{},[33,12263,5435],{},[33,12265,4398],{},[33,12267,5468],{},[14,12269,180],{"id":180},[45,12271,12272,12276],{},[48,12273,5476,12274,5480],{},[33,12275,5479],{},[48,12277,5483,12278,5486],{},[33,12279,5468],{},[14,12281,191],{"id":191},[166,12283,12284,12286],{},[48,12285,5493],{},[48,12287,5496],{},[10,12289,202],{},[14,12291,205],{"id":205},[10,12293,5503],{},[210,12295,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12297},[12298,12299,12300,12301,12302,12305,12306,12307],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":12303},[12304],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5333,"description":5338},[223,5525,5526],{"id":5529,"title":5530,"body":12312,"category":223,"cover":224,"description":5535,"extension":225,"meta":12461,"navigation":88,"path":5716,"pinned":228,"publishedAt":229,"seo":12462,"slug":5718,"stem":5719,"summary":5720,"tags":12463,"updatedAt":229,"visible":88,"__hash__":5724},{"type":7,"value":12313,"toc":12449},[12314,12316,12318,12320,12322,12326,12328,12330,12342,12344,12346,12390,12392,12397,12399,12401,12413,12415,12417,12421,12423,12425,12433,12435,12441,12443,12445,12447],[10,12315,5535],{},[14,12317,16],{"id":16},[10,12319,5540],{},[14,12321,22],{"id":22},[10,12323,12324],{},[26,12325],{"alt":5547,"src":5548},[10,12327,5551],{},[14,12329,43],{"id":43},[45,12331,12332,12334,12338],{},[48,12333,5558],{},[48,12335,12336,5564],{},[33,12337,5563],{},[48,12339,12340,5570],{},[33,12341,5569],{},[14,12343,62],{"id":62},[10,12345,65],{},[67,12347,12348],{"className":69,"code":5577,"language":71,"meta":72,"style":72},[33,12349,12350,12354,12358,12362,12366,12370,12374,12378,12382,12386],{"__ignoreMap":72},[76,12351,12352],{"class":78,"line":79},[76,12353,5584],{},[76,12355,12356],{"class":78,"line":85},[76,12357,5589],{},[76,12359,12360],{"class":78,"line":92},[76,12361,89],{"emptyLinePlaceholder":88},[76,12363,12364],{"class":78,"line":98},[76,12365,5598],{},[76,12367,12368],{"class":78,"line":103},[76,12369,5603],{},[76,12371,12372],{"class":78,"line":109},[76,12373,89],{"emptyLinePlaceholder":88},[76,12375,12376],{"class":78,"line":115},[76,12377,5612],{},[76,12379,12380],{"class":78,"line":121},[76,12381,5617],{},[76,12383,12384],{"class":78,"line":126},[76,12385,89],{"emptyLinePlaceholder":88},[76,12387,12388],{"class":78,"line":132},[76,12389,5626],{},[10,12391,150],{},[67,12393,12395],{"className":12394,"code":5632,"language":156,"meta":72},[154],[33,12396,5632],{"__ignoreMap":72},[10,12398,161],{},[14,12400,164],{"id":164},[166,12402,12403,12407],{},[48,12404,5643,12405,5647],{},[33,12406,5646],{},[48,12408,12409,5653,12411,360],{},[33,12410,5652],{},[33,12412,5656],{},[326,12414,2695],{"id":2695},[10,12416,5661],{},[10,12418,12419],{},[26,12420],{"alt":5666,"src":5667},[10,12422,5670],{},[14,12424,180],{"id":180},[45,12426,12427,12431],{},[48,12428,5677,12429,5680],{},[33,12430,5377],{},[48,12432,5683],{},[14,12434,191],{"id":191},[166,12436,12437,12439],{},[48,12438,5690],{},[48,12440,5693],{},[10,12442,202],{},[14,12444,205],{"id":205},[10,12446,5700],{},[210,12448,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12450},[12451,12452,12453,12454,12455,12458,12459,12460],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":12456},[12457],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5530,"description":5535},[223,5722,5723],{"id":5726,"title":5727,"body":12465,"category":223,"cover":224,"description":5732,"extension":225,"meta":12626,"navigation":88,"path":5928,"pinned":228,"publishedAt":229,"seo":12627,"slug":5930,"stem":5931,"summary":5932,"tags":12628,"updatedAt":229,"visible":88,"__hash__":5936},{"type":7,"value":12466,"toc":12614},[12467,12469,12471,12473,12475,12479,12481,12483,12495,12497,12499,12551,12553,12558,12560,12562,12580,12582,12584,12588,12590,12592,12598,12600,12606,12608,12610,12612],[10,12468,5732],{},[14,12470,16],{"id":16},[10,12472,5737],{},[14,12474,22],{"id":22},[10,12476,12477],{},[26,12478],{"alt":5744,"src":5745},[10,12480,5748],{},[14,12482,43],{"id":43},[45,12484,12485,12487,12489],{},[48,12486,5755],{},[48,12488,5758],{},[48,12490,12491,2174,12493,5767],{},[33,12492,5763],{},[33,12494,5766],{},[14,12496,62],{"id":62},[10,12498,65],{},[67,12500,12501],{"className":69,"code":5774,"language":71,"meta":72,"style":72},[33,12502,12503,12507,12511,12515,12519,12523,12527,12531,12535,12539,12543,12547],{"__ignoreMap":72},[76,12504,12505],{"class":78,"line":79},[76,12506,5781],{},[76,12508,12509],{"class":78,"line":85},[76,12510,89],{"emptyLinePlaceholder":88},[76,12512,12513],{"class":78,"line":92},[76,12514,5790],{},[76,12516,12517],{"class":78,"line":98},[76,12518,5795],{},[76,12520,12521],{"class":78,"line":103},[76,12522,89],{"emptyLinePlaceholder":88},[76,12524,12525],{"class":78,"line":109},[76,12526,5804],{},[76,12528,12529],{"class":78,"line":115},[76,12530,5809],{},[76,12532,12533],{"class":78,"line":121},[76,12534,5814],{},[76,12536,12537],{"class":78,"line":126},[76,12538,89],{"emptyLinePlaceholder":88},[76,12540,12541],{"class":78,"line":132},[76,12542,5823],{},[76,12544,12545],{"class":78,"line":138},[76,12546,89],{"emptyLinePlaceholder":88},[76,12548,12549],{"class":78,"line":144},[76,12550,5832],{},[10,12552,150],{},[67,12554,12556],{"className":12555,"code":5838,"language":156,"meta":72},[154],[33,12557,5838],{"__ignoreMap":72},[10,12559,161],{},[14,12561,164],{"id":164},[166,12563,12564,12574],{},[48,12565,12566,5852,12568,5856,12570,5859,12572,5863],{},[33,12567,5851],{},[33,12569,5855],{},[33,12571,5646],{},[33,12573,5862],{},[48,12575,12576,5868,12578,5871],{},[33,12577,4581],{},[33,12579,2206],{},[326,12581,2695],{"id":2695},[10,12583,5876],{},[10,12585,12586],{},[26,12587],{"alt":5881,"src":5882},[10,12589,5885],{},[14,12591,180],{"id":180},[45,12593,12594,12596],{},[48,12595,5892],{},[48,12597,5895],{},[14,12599,191],{"id":191},[166,12601,12602,12604],{},[48,12603,5902],{},[48,12605,5905],{},[10,12607,202],{},[14,12609,205],{"id":205},[10,12611,5912],{},[210,12613,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12615},[12616,12617,12618,12619,12620,12623,12624,12625],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":12621},[12622],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5727,"description":5732},[223,5934,5935],{"id":5938,"title":5939,"body":12630,"category":223,"cover":224,"description":5944,"extension":225,"meta":12753,"navigation":88,"path":6095,"pinned":228,"publishedAt":229,"seo":12754,"slug":6097,"stem":6098,"summary":6099,"tags":12755,"updatedAt":229,"visible":88,"__hash__":6103},{"type":7,"value":12631,"toc":12743},[12632,12634,12636,12638,12640,12644,12646,12648,12662,12664,12666,12694,12696,12701,12703,12705,12715,12717,12725,12727,12735,12737,12739,12741],[10,12633,5944],{},[14,12635,16],{"id":16},[10,12637,5949],{},[14,12639,22],{"id":22},[10,12641,12642],{},[26,12643],{"alt":5956,"src":5957},[10,12645,5960],{},[14,12647,43],{"id":43},[45,12649,12650,12652,12654],{},[48,12651,5967],{},[48,12653,5970],{},[48,12655,5973,12656,2255,12658,2255,12660,5981],{},[33,12657,2258],{},[33,12659,2424],{},[33,12661,5980],{},[14,12663,62],{"id":62},[10,12665,65],{},[67,12667,12668],{"className":69,"code":5988,"language":71,"meta":72,"style":72},[33,12669,12670,12674,12678,12682,12686,12690],{"__ignoreMap":72},[76,12671,12672],{"class":78,"line":79},[76,12673,5995],{},[76,12675,12676],{"class":78,"line":85},[76,12677,6000],{},[76,12679,12680],{"class":78,"line":92},[76,12681,6005],{},[76,12683,12684],{"class":78,"line":98},[76,12685,89],{"emptyLinePlaceholder":88},[76,12687,12688],{"class":78,"line":103},[76,12689,6014],{},[76,12691,12692],{"class":78,"line":109},[76,12693,6019],{},[10,12695,150],{},[67,12697,12699],{"className":12698,"code":6025,"language":156,"meta":72},[154],[33,12700,6025],{"__ignoreMap":72},[10,12702,161],{},[14,12704,164],{"id":164},[166,12706,12707,12713],{},[48,12708,6036,12709,6040,12711,6043],{},[33,12710,6039],{},[33,12712,2244],{},[48,12714,6046],{},[14,12716,180],{"id":180},[45,12718,12719,12723],{},[48,12720,6053,12721,6057],{},[33,12722,6056],{},[48,12724,6060],{},[14,12726,191],{"id":191},[166,12728,12729,12731],{},[48,12730,6067],{},[48,12732,6070,12733,6074],{},[33,12734,6073],{},[10,12736,202],{},[14,12738,205],{"id":205},[10,12740,6081],{},[210,12742,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12744},[12745,12746,12747,12748,12749,12750,12751,12752],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5939,"description":5944},[223,6101,6102],{"id":6105,"title":6106,"body":12757,"category":223,"cover":224,"description":6111,"extension":225,"meta":12934,"navigation":88,"path":6339,"pinned":228,"publishedAt":229,"seo":12935,"slug":6341,"stem":6342,"summary":6343,"tags":12936,"updatedAt":229,"visible":88,"__hash__":6347},{"type":7,"value":12758,"toc":12922},[12759,12761,12763,12767,12769,12773,12779,12781,12793,12795,12799,12823,12827,12843,12849,12851,12856,12858,12860,12876,12878,12880,12884,12888,12890,12902,12904,12914,12916,12918,12920],[10,12760,6111],{},[14,12762,16],{"id":16},[10,12764,6116,12765,6119],{},[292,12766,6039],{},[14,12768,22],{"id":22},[10,12770,12771],{},[26,12772],{"alt":6126,"src":6127},[10,12774,6130,12775,6134,12777,6138],{},[33,12776,6133],{},[33,12778,6137],{},[14,12780,43],{"id":43},[45,12782,12783,12787,12789],{},[48,12784,6145,12785,6148],{},[33,12786,1169],{},[48,12788,6151],{},[48,12790,6154,12791,6158],{},[33,12792,6157],{},[14,12794,62],{"id":62},[10,12796,6163,12797,6167],{},[33,12798,6166],{},[67,12800,12801],{"className":69,"code":6170,"language":71,"meta":72,"style":72},[33,12802,12803,12807,12811,12815,12819],{"__ignoreMap":72},[76,12804,12805],{"class":78,"line":79},[76,12806,6177],{},[76,12808,12809],{"class":78,"line":85},[76,12810,6182],{},[76,12812,12813],{"class":78,"line":92},[76,12814,89],{"emptyLinePlaceholder":88},[76,12816,12817],{"class":78,"line":98},[76,12818,6191],{},[76,12820,12821],{"class":78,"line":103},[76,12822,6196],{},[10,12824,6199,12825,6203],{},[33,12826,6202],{},[67,12828,12829],{"className":69,"code":6206,"language":71,"meta":72,"style":72},[33,12830,12831,12835,12839],{"__ignoreMap":72},[76,12832,12833],{"class":78,"line":79},[76,12834,6213],{},[76,12836,12837],{"class":78,"line":85},[76,12838,89],{"emptyLinePlaceholder":88},[76,12840,12841],{"class":78,"line":92},[76,12842,6222],{},[10,12844,6225,12845,1155,12847,360],{},[33,12846,6228],{},[33,12848,6231],{},[10,12850,150],{},[67,12852,12854],{"className":12853,"code":6237,"language":156,"meta":72},[154],[33,12855,6237],{"__ignoreMap":72},[10,12857,161],{},[14,12859,164],{"id":164},[166,12861,12862,12868],{},[48,12863,6248,12864,6251,12866,6255],{},[33,12865,6166],{},[33,12867,6254],{},[48,12869,12870,6260,12872,6263,12874,6266],{},[33,12871,6202],{},[33,12873,6166],{},[33,12875,6202],{},[326,12877,2695],{"id":2695},[10,12879,6271],{},[10,12881,12882],{},[26,12883],{"alt":6276,"src":6277},[10,12885,6280,12886,6283],{},[33,12887,6254],{},[14,12889,180],{"id":180},[45,12891,12892,12898],{},[48,12893,6290,12894,1155,12896,360],{},[33,12895,6166],{},[33,12897,6202],{},[48,12899,6297,12900,6301],{},[33,12901,6300],{},[14,12903,191],{"id":191},[166,12905,12906,12910],{},[48,12907,2352,12908,6311],{},[33,12909,6310],{},[48,12911,6314,12912,360],{},[33,12913,6133],{},[10,12915,202],{},[14,12917,205],{"id":205},[10,12919,6323],{},[210,12921,212],{},{"title":72,"searchDepth":85,"depth":85,"links":12923},[12924,12925,12926,12927,12928,12931,12932,12933],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":12929},[12930],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":6106,"description":6111},[223,6345,6346],{"id":6349,"title":6350,"body":12938,"category":223,"cover":224,"description":6355,"extension":225,"meta":13077,"navigation":88,"path":6521,"pinned":228,"publishedAt":229,"seo":13078,"slug":6523,"stem":6524,"summary":6525,"tags":13079,"updatedAt":229,"visible":88,"__hash__":6528},{"type":7,"value":12939,"toc":13067},[12940,12942,12944,12946,12948,12952,12954,12956,12966,12968,12970,13010,13012,13017,13019,13021,13039,13041,13049,13051,13059,13061,13063,13065],[10,12941,6355],{},[14,12943,16],{"id":16},[10,12945,6360],{},[14,12947,22],{"id":22},[10,12949,12950],{},[26,12951],{"alt":6367,"src":6368},[10,12953,6371],{},[14,12955,43],{"id":43},[45,12957,12958,12962,12964],{},[48,12959,12960,6381],{},[33,12961,6380],{},[48,12963,6384],{},[48,12965,6387],{},[14,12967,62],{"id":62},[10,12969,1572],{},[67,12971,12972],{"className":589,"code":6394,"language":591,"meta":72,"style":72},[33,12973,12974,12984,12990,12996,13006],{"__ignoreMap":72},[76,12975,12976,12978,12980,12982],{"class":78,"line":79},[76,12977,689],{"class":598},[76,12979,631],{"class":601},[76,12981,6405],{"class":634},[76,12983,6408],{"class":634},[76,12985,12986,12988],{"class":78,"line":85},[76,12987,6413],{"class":601},[76,12989,6416],{"class":634},[76,12991,12992,12994],{"class":78,"line":92},[76,12993,71],{"class":598},[76,12995,602],{"class":601},[76,12997,12998,13000,13002,13004],{"class":78,"line":98},[76,12999,71],{"class":598},[76,13001,631],{"class":601},[76,13003,635],{"class":634},[76,13005,602],{"class":601},[76,13007,13008],{"class":78,"line":103},[76,13009,6437],{"class":598},[10,13011,150],{},[67,13013,13015],{"className":13014,"code":6443,"language":156,"meta":72},[154],[33,13016,6443],{"__ignoreMap":72},[10,13018,161],{},[14,13020,164],{"id":164},[166,13022,13023,13029],{},[48,13024,13025,6457,13027,6460],{},[33,13026,6456],{},[33,13028,689],{},[48,13030,6463,13031,2174,13033,6469,13035,3726,13037,6475],{},[33,13032,71],{},[33,13034,6468],{},[33,13036,6380],{},[33,13038,6474],{},[14,13040,180],{"id":180},[45,13042,13043,13045],{},[48,13044,6482],{},[48,13046,3465,13047,6487],{},[33,13048,6380],{},[14,13050,191],{"id":191},[166,13052,13053,13057],{},[48,13054,6494,13055,360],{},[33,13056,6497],{},[48,13058,6500],{},[10,13060,202],{},[14,13062,205],{"id":205},[10,13064,6507],{},[210,13066,1656],{},{"title":72,"searchDepth":85,"depth":85,"links":13068},[13069,13070,13071,13072,13073,13074,13075,13076],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":6350,"description":6355},[223,6527,258],{"id":6530,"title":6531,"body":13081,"category":223,"cover":224,"description":6536,"extension":225,"meta":13234,"navigation":88,"path":6725,"pinned":228,"publishedAt":229,"seo":13235,"slug":6727,"stem":6728,"summary":6729,"tags":13236,"updatedAt":229,"visible":88,"__hash__":6733},{"type":7,"value":13082,"toc":13224},[13083,13085,13087,13089,13091,13095,13101,13103,13119,13121,13123,13167,13169,13174,13176,13178,13190,13192,13206,13208,13216,13218,13220,13222],[10,13084,6536],{},[14,13086,16],{"id":16},[10,13088,6541],{},[14,13090,22],{"id":22},[10,13092,13093],{},[26,13094],{"alt":6548,"src":6549},[10,13096,13097,6555,13099,6558],{},[33,13098,6554],{},[33,13100,2434],{},[14,13102,43],{"id":43},[45,13104,13105,13107,13115],{},[48,13106,6565],{},[48,13108,13109,2255,13111,2255,13113,6577],{},[33,13110,6570],{},[33,13112,6573],{},[33,13114,6576],{},[48,13116,6580,13117,6584],{},[33,13118,6583],{},[14,13120,62],{"id":62},[10,13122,65],{},[67,13124,13125],{"className":69,"code":6591,"language":71,"meta":72,"style":72},[33,13126,13127,13131,13135,13139,13143,13147,13151,13155,13159,13163],{"__ignoreMap":72},[76,13128,13129],{"class":78,"line":79},[76,13130,6598],{},[76,13132,13133],{"class":78,"line":85},[76,13134,89],{"emptyLinePlaceholder":88},[76,13136,13137],{"class":78,"line":92},[76,13138,6607],{},[76,13140,13141],{"class":78,"line":98},[76,13142,6612],{},[76,13144,13145],{"class":78,"line":103},[76,13146,6617],{},[76,13148,13149],{"class":78,"line":109},[76,13150,89],{"emptyLinePlaceholder":88},[76,13152,13153],{"class":78,"line":115},[76,13154,6626],{},[76,13156,13157],{"class":78,"line":121},[76,13158,6631],{},[76,13160,13161],{"class":78,"line":126},[76,13162,6636],{},[76,13164,13165],{"class":78,"line":132},[76,13166,6641],{},[10,13168,150],{},[67,13170,13172],{"className":13171,"code":6647,"language":156,"meta":72},[154],[33,13173,6647],{"__ignoreMap":72},[10,13175,161],{},[14,13177,164],{"id":164},[166,13179,13180,13184],{},[48,13181,13182,6661],{},[33,13183,6660],{},[48,13185,2337,13186,6666,13188,6669],{},[33,13187,2434],{},[33,13189,6554],{},[14,13191,180],{"id":180},[45,13193,13194,13200],{},[48,13195,3465,13196,6678,13198,6681],{},[33,13197,6554],{},[33,13199,6570],{},[48,13201,6684,13202,1007,13204,6690],{},[33,13203,2434],{},[33,13205,6689],{},[14,13207,191],{"id":191},[166,13209,13210,13214],{},[48,13211,6697,13212,6701],{},[33,13213,6700],{},[48,13215,6704],{},[10,13217,202],{},[14,13219,205],{"id":205},[10,13221,6711],{},[210,13223,212],{},{"title":72,"searchDepth":85,"depth":85,"links":13225},[13226,13227,13228,13229,13230,13231,13232,13233],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":6531,"description":6536},[223,6731,6732],{"id":6735,"title":6736,"body":13238,"category":223,"cover":224,"description":6741,"extension":225,"meta":13385,"navigation":88,"path":6918,"pinned":228,"publishedAt":229,"seo":13386,"slug":6920,"stem":6921,"summary":6922,"tags":13387,"updatedAt":229,"visible":88,"__hash__":6926},{"type":7,"value":13239,"toc":13375},[13240,13242,13244,13246,13248,13252,13254,13256,13274,13276,13278,13326,13328,13333,13335,13337,13345,13347,13357,13359,13367,13369,13371,13373],[10,13241,6741],{},[14,13243,16],{"id":16},[10,13245,6746],{},[14,13247,22],{"id":22},[10,13249,13250],{},[26,13251],{"alt":6753,"src":6754},[10,13253,6757],{},[14,13255,43],{"id":43},[45,13257,13258,13262,13268],{},[48,13259,13260,6767],{},[33,13261,6766],{},[48,13263,13264,6773,13266,360],{},[33,13265,6772],{},[33,13267,6776],{},[48,13269,6779,13270,6783,13272,6787],{},[33,13271,6782],{},[33,13273,6786],{},[14,13275,62],{"id":62},[10,13277,65],{},[67,13279,13280],{"className":69,"code":6794,"language":71,"meta":72,"style":72},[33,13281,13282,13286,13290,13294,13298,13302,13306,13310,13314,13318,13322],{"__ignoreMap":72},[76,13283,13284],{"class":78,"line":79},[76,13285,6598],{},[76,13287,13288],{"class":78,"line":85},[76,13289,89],{"emptyLinePlaceholder":88},[76,13291,13292],{"class":78,"line":92},[76,13293,6809],{},[76,13295,13296],{"class":78,"line":98},[76,13297,6814],{},[76,13299,13300],{"class":78,"line":103},[76,13301,6819],{},[76,13303,13304],{"class":78,"line":109},[76,13305,118],{},[76,13307,13308],{"class":78,"line":115},[76,13309,89],{"emptyLinePlaceholder":88},[76,13311,13312],{"class":78,"line":121},[76,13313,6832],{},[76,13315,13316],{"class":78,"line":126},[76,13317,6837],{},[76,13319,13320],{"class":78,"line":132},[76,13321,141],{},[76,13323,13324],{"class":78,"line":138},[76,13325,6846],{},[10,13327,150],{},[67,13329,13331],{"className":13330,"code":6852,"language":156,"meta":72},[154],[33,13332,6852],{"__ignoreMap":72},[10,13334,161],{},[14,13336,164],{"id":164},[166,13338,13339,13343],{},[48,13340,6863,13341,6866],{},[33,13342,6782],{},[48,13344,6869],{},[14,13346,180],{"id":180},[45,13348,13349,13353],{},[48,13350,2337,13351,6878],{},[33,13352,6766],{},[48,13354,6881,13355,360],{},[33,13356,6884],{},[14,13358,191],{"id":191},[166,13360,13361,13363],{},[48,13362,6891],{},[48,13364,6894,13365,6897],{},[33,13366,334],{},[10,13368,202],{},[14,13370,205],{"id":205},[10,13372,6904],{},[210,13374,212],{},{"title":72,"searchDepth":85,"depth":85,"links":13376},[13377,13378,13379,13380,13381,13382,13383,13384],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":6736,"description":6741},[223,6924,6925],{"id":4,"title":5,"body":13389,"category":223,"cover":224,"description":12,"extension":225,"meta":13532,"navigation":88,"path":227,"pinned":228,"publishedAt":229,"seo":13533,"slug":231,"stem":232,"summary":233,"tags":13534,"updatedAt":229,"visible":88,"__hash__":237},{"type":7,"value":13390,"toc":13522},[13391,13393,13395,13397,13399,13403,13409,13411,13421,13423,13425,13477,13479,13484,13486,13488,13498,13500,13506,13508,13514,13516,13518,13520],[10,13392,12],{},[14,13394,16],{"id":16},[10,13396,19],{},[14,13398,22],{"id":22},[10,13400,13401],{},[26,13402],{"alt":28,"src":29},[10,13404,13405,36,13407,40],{},[33,13406,35],{},[33,13408,39],{},[14,13410,43],{"id":43},[45,13412,13413,13415,13419],{},[48,13414,50],{},[48,13416,13417,56],{},[33,13418,55],{},[48,13420,59],{},[14,13422,62],{"id":62},[10,13424,65],{},[67,13426,13427],{"className":69,"code":70,"language":71,"meta":72,"style":72},[33,13428,13429,13433,13437,13441,13445,13449,13453,13457,13461,13465,13469,13473],{"__ignoreMap":72},[76,13430,13431],{"class":78,"line":79},[76,13432,82],{},[76,13434,13435],{"class":78,"line":85},[76,13436,89],{"emptyLinePlaceholder":88},[76,13438,13439],{"class":78,"line":92},[76,13440,95],{},[76,13442,13443],{"class":78,"line":98},[76,13444,89],{"emptyLinePlaceholder":88},[76,13446,13447],{"class":78,"line":103},[76,13448,106],{},[76,13450,13451],{"class":78,"line":109},[76,13452,112],{},[76,13454,13455],{"class":78,"line":115},[76,13456,118],{},[76,13458,13459],{"class":78,"line":121},[76,13460,89],{"emptyLinePlaceholder":88},[76,13462,13463],{"class":78,"line":126},[76,13464,129],{},[76,13466,13467],{"class":78,"line":132},[76,13468,135],{},[76,13470,13471],{"class":78,"line":138},[76,13472,141],{},[76,13474,13475],{"class":78,"line":144},[76,13476,147],{},[10,13478,150],{},[67,13480,13482],{"className":13481,"code":155,"language":156,"meta":72},[154],[33,13483,155],{"__ignoreMap":72},[10,13485,161],{},[14,13487,164],{"id":164},[166,13489,13490,13494],{},[48,13491,13492,172],{},[33,13493,35],{},[48,13495,13496,177],{},[33,13497,39],{},[14,13499,180],{"id":180},[45,13501,13502,13504],{},[48,13503,185],{},[48,13505,188],{},[14,13507,191],{"id":191},[166,13509,13510,13512],{},[48,13511,196],{},[48,13513,199],{},[10,13515,202],{},[14,13517,205],{"id":205},[10,13519,208],{},[210,13521,212],{},{"title":72,"searchDepth":85,"depth":85,"links":13523},[13524,13525,13526,13527,13528,13529,13530,13531],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":5,"description":12},[223,235,236],{"id":7075,"title":7076,"body":13536,"category":223,"cover":224,"description":7081,"extension":225,"meta":13687,"navigation":88,"path":7266,"pinned":228,"publishedAt":229,"seo":13688,"slug":7268,"stem":7269,"summary":7270,"tags":13689,"updatedAt":229,"visible":88,"__hash__":7274},{"type":7,"value":13537,"toc":13677},[13538,13540,13542,13544,13546,13550,13554,13556,13570,13572,13574,13626,13628,13633,13635,13637,13649,13651,13661,13663,13669,13671,13673,13675],[10,13539,7081],{},[14,13541,16],{"id":16},[10,13543,7086],{},[14,13545,22],{"id":22},[10,13547,13548],{},[26,13549],{"alt":7093,"src":7094},[10,13551,13552,7100],{},[33,13553,7099],{},[14,13555,43],{"id":43},[45,13557,13558,13564,13568],{},[48,13559,2337,13560,7110,13562,7114],{},[33,13561,7109],{},[33,13563,7113],{},[48,13565,7117,13566,7121],{},[33,13567,7120],{},[48,13569,7124],{},[14,13571,62],{"id":62},[10,13573,65],{},[67,13575,13576],{"className":69,"code":7131,"language":71,"meta":72,"style":72},[33,13577,13578,13582,13586,13590,13594,13598,13602,13606,13610,13614,13618,13622],{"__ignoreMap":72},[76,13579,13580],{"class":78,"line":79},[76,13581,7138],{},[76,13583,13584],{"class":78,"line":85},[76,13585,89],{"emptyLinePlaceholder":88},[76,13587,13588],{"class":78,"line":92},[76,13589,7147],{},[76,13591,13592],{"class":78,"line":98},[76,13593,7152],{},[76,13595,13596],{"class":78,"line":103},[76,13597,7157],{},[76,13599,13600],{"class":78,"line":109},[76,13601,7162],{},[76,13603,13604],{"class":78,"line":115},[76,13605,7167],{},[76,13607,13608],{"class":78,"line":121},[76,13609,89],{"emptyLinePlaceholder":88},[76,13611,13612],{"class":78,"line":126},[76,13613,7176],{},[76,13615,13616],{"class":78,"line":132},[76,13617,7181],{},[76,13619,13620],{"class":78,"line":138},[76,13621,7186],{},[76,13623,13624],{"class":78,"line":144},[76,13625,7191],{},[10,13627,150],{},[67,13629,13631],{"className":13630,"code":7197,"language":156,"meta":72},[154],[33,13632,7197],{"__ignoreMap":72},[10,13634,161],{},[14,13636,164],{"id":164},[166,13638,13639,13645],{},[48,13640,13641,7211,13643,7214],{},[33,13642,7210],{},[33,13644,7120],{},[48,13646,13647,7219],{},[33,13648,7099],{},[14,13650,180],{"id":180},[45,13652,13653,13655],{},[48,13654,7226],{},[48,13656,7229,13657,7232,13659,7235],{},[33,13658,7109],{},[33,13660,7113],{},[14,13662,191],{"id":191},[166,13664,13665,13667],{},[48,13666,7242],{},[48,13668,7245],{},[10,13670,202],{},[14,13672,205],{"id":205},[10,13674,7252],{},[210,13676,212],{},{"title":72,"searchDepth":85,"depth":85,"links":13678},[13679,13680,13681,13682,13683,13684,13685,13686],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":7076,"description":7081},[223,7272,7273],{"id":7276,"title":7277,"body":13691,"category":223,"cover":224,"description":7282,"extension":225,"meta":13905,"navigation":88,"path":7556,"pinned":228,"publishedAt":229,"seo":13906,"slug":7558,"stem":7559,"summary":7560,"tags":13907,"updatedAt":229,"visible":88,"__hash__":7564},{"type":7,"value":13692,"toc":13892},[13693,13695,13697,13699,13701,13705,13711,13713,13725,13727,13729,13789,13791,13796,13798,13800,13818,13820,13828,13832,13840,13842,13846,13850,13856,13858,13868,13870,13884,13886,13888,13890],[10,13694,7282],{},[14,13696,16],{"id":16},[10,13698,7287],{},[14,13700,22],{"id":22},[10,13702,13703],{},[26,13704],{"alt":7294,"src":7295},[10,13706,7298,13707,7302,13709,7306],{},[33,13708,7301],{},[33,13710,7305],{},[14,13712,43],{"id":43},[45,13714,13715,13719,13723],{},[48,13716,7313,13717,7316],{},[33,13718,7301],{},[48,13720,13721,7322],{},[33,13722,7321],{},[48,13724,7325],{},[14,13726,62],{"id":62},[10,13728,65],{},[67,13730,13731],{"className":69,"code":7332,"language":71,"meta":72,"style":72},[33,13732,13733,13737,13741,13745,13749,13753,13757,13761,13765,13769,13773,13777,13781,13785],{"__ignoreMap":72},[76,13734,13735],{"class":78,"line":79},[76,13736,7339],{},[76,13738,13739],{"class":78,"line":85},[76,13740,7344],{},[76,13742,13743],{"class":78,"line":92},[76,13744,7349],{},[76,13746,13747],{"class":78,"line":98},[76,13748,7354],{},[76,13750,13751],{"class":78,"line":103},[76,13752,7359],{},[76,13754,13755],{"class":78,"line":109},[76,13756,89],{"emptyLinePlaceholder":88},[76,13758,13759],{"class":78,"line":115},[76,13760,7368],{},[76,13762,13763],{"class":78,"line":121},[76,13764,7373],{},[76,13766,13767],{"class":78,"line":126},[76,13768,7378],{},[76,13770,13771],{"class":78,"line":132},[76,13772,7383],{},[76,13774,13775],{"class":78,"line":138},[76,13776,1144],{},[76,13778,13779],{"class":78,"line":144},[76,13780,7392],{},[76,13782,13783],{"class":78,"line":7395},[76,13784,7398],{},[76,13786,13787],{"class":78,"line":7401},[76,13788,7404],{},[10,13790,150],{},[67,13792,13794],{"className":13793,"code":7410,"language":156,"meta":72},[154],[33,13795,7410],{"__ignoreMap":72},[10,13797,161],{},[14,13799,164],{"id":164},[166,13801,13802,13810],{},[48,13803,13804,7423,13806,7426,13808,7430],{},[33,13805,3034],{},[33,13807,7321],{},[33,13809,7429],{},[48,13811,7433,13812,7436,13814,7439,13816,360],{},[33,13813,7301],{},[33,13815,1158],{},[33,13817,7305],{},[326,13819,2695],{"id":2695},[10,13821,13822,2255,13824,1155,13826,7452],{},[33,13823,7301],{},[33,13825,1158],{},[33,13827,7305],{},[10,13829,13830],{},[26,13831],{"alt":7457,"src":7458},[10,13833,13834,7463,13836,7466,13838,7469],{},[33,13835,7301],{},[33,13837,1158],{},[33,13839,7305],{},[326,13841,2695],{"id":4216},[10,13843,13844,7477],{},[33,13845,7476],{},[10,13847,13848],{},[26,13849],{"alt":7482,"src":7483},[10,13851,7486,13852,7489,13854,7492],{},[33,13853,7476],{},[33,13855,1158],{},[14,13857,180],{"id":180},[45,13859,13860,13864],{},[48,13861,7499,13862,7503],{},[33,13863,7502],{},[48,13865,7506,13866,7509],{},[33,13867,7476],{},[14,13869,191],{"id":191},[166,13871,13872,13880],{},[48,13873,7516,13874,7520,13876,1155,13878,360],{},[33,13875,7519],{},[33,13877,7523],{},[33,13879,7526],{},[48,13881,7529,13882,7532],{},[33,13883,6776],{},[10,13885,202],{},[14,13887,205],{"id":205},[10,13889,7539],{},[210,13891,212],{},{"title":72,"searchDepth":85,"depth":85,"links":13893},[13894,13895,13896,13897,13898,13902,13903,13904],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":13899},[13900,13901],{"id":2695,"depth":92,"text":2695},{"id":4216,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":7277,"description":7282},[223,7562,7563],{"id":7566,"title":7567,"body":13909,"category":223,"cover":224,"description":7572,"extension":225,"meta":14060,"navigation":88,"path":7749,"pinned":228,"publishedAt":229,"seo":14061,"slug":7751,"stem":7752,"summary":7753,"tags":14062,"updatedAt":229,"visible":88,"__hash__":7756},{"type":7,"value":13910,"toc":14050},[13911,13913,13915,13917,13919,13923,13927,13929,13941,13943,13945,13993,13995,14000,14002,14004,14014,14016,14026,14028,14042,14044,14046,14048],[10,13912,7572],{},[14,13914,16],{"id":16},[10,13916,7577],{},[14,13918,22],{"id":22},[10,13920,13921],{},[26,13922],{"alt":7584,"src":7585},[10,13924,7588,13925,7591],{},[33,13926,6786],{},[14,13928,43],{"id":43},[45,13930,13931,13935,13939],{},[48,13932,13933,7600],{},[33,13934,6786],{},[48,13936,13937,7606],{},[33,13938,7605],{},[48,13940,7609],{},[14,13942,62],{"id":62},[10,13944,65],{},[67,13946,13947],{"className":69,"code":7616,"language":71,"meta":72,"style":72},[33,13948,13949,13953,13957,13961,13965,13969,13973,13977,13981,13985,13989],{"__ignoreMap":72},[76,13950,13951],{"class":78,"line":79},[76,13952,6598],{},[76,13954,13955],{"class":78,"line":85},[76,13956,89],{"emptyLinePlaceholder":88},[76,13958,13959],{"class":78,"line":92},[76,13960,6809],{},[76,13962,13963],{"class":78,"line":98},[76,13964,89],{"emptyLinePlaceholder":88},[76,13966,13967],{"class":78,"line":103},[76,13968,7639],{},[76,13970,13971],{"class":78,"line":109},[76,13972,7644],{},[76,13974,13975],{"class":78,"line":115},[76,13976,89],{"emptyLinePlaceholder":88},[76,13978,13979],{"class":78,"line":121},[76,13980,7653],{},[76,13982,13983],{"class":78,"line":126},[76,13984,7658],{},[76,13986,13987],{"class":78,"line":132},[76,13988,89],{"emptyLinePlaceholder":88},[76,13990,13991],{"class":78,"line":138},[76,13992,7667],{},[10,13994,150],{},[67,13996,13998],{"className":13997,"code":7673,"language":156,"meta":72},[154],[33,13999,7673],{"__ignoreMap":72},[10,14001,161],{},[14,14003,164],{"id":164},[166,14005,14006,14012],{},[48,14007,7588,14008,7686,14010,360],{},[33,14009,6786],{},[33,14011,7689],{},[48,14013,7692],{},[14,14015,180],{"id":180},[45,14017,14018,14022],{},[48,14019,4784,14020,7701],{},[33,14021,6786],{},[48,14023,7704,14024,7707],{},[33,14025,6786],{},[14,14027,191],{"id":191},[166,14029,14030,14036],{},[48,14031,7714,14032,7718,14034,360],{},[33,14033,7717],{},[33,14035,6786],{},[48,14037,4784,14038,7725,14040,360],{},[33,14039,6786],{},[33,14041,7728],{},[10,14043,202],{},[14,14045,205],{"id":205},[10,14047,7735],{},[210,14049,212],{},{"title":72,"searchDepth":85,"depth":85,"links":14051},[14052,14053,14054,14055,14056,14057,14058,14059],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":7567,"description":7572},[223,6786,7755],{"id":7758,"title":7759,"body":14064,"category":223,"cover":224,"description":7764,"extension":225,"meta":14235,"navigation":88,"path":7977,"pinned":228,"publishedAt":229,"seo":14236,"slug":7979,"stem":7980,"summary":7981,"tags":14237,"updatedAt":229,"visible":88,"__hash__":7985},{"type":7,"value":14065,"toc":14223},[14066,14068,14070,14072,14074,14078,14080,14082,14094,14096,14098,14154,14156,14161,14163,14165,14181,14183,14185,14189,14195,14197,14205,14207,14215,14217,14219,14221],[10,14067,7764],{},[14,14069,16],{"id":16},[10,14071,7769],{},[14,14073,22],{"id":22},[10,14075,14076],{},[26,14077],{"alt":7776,"src":7777},[10,14079,7780],{},[14,14081,43],{"id":43},[45,14083,14084,14088,14092],{},[48,14085,14086,7790],{},[33,14087,7789],{},[48,14089,14090,7796],{},[33,14091,7795],{},[48,14093,7799],{},[14,14095,62],{"id":62},[10,14097,65],{},[67,14099,14100],{"className":69,"code":7806,"language":71,"meta":72,"style":72},[33,14101,14102,14106,14110,14114,14118,14122,14126,14130,14134,14138,14142,14146,14150],{"__ignoreMap":72},[76,14103,14104],{"class":78,"line":79},[76,14105,7813],{},[76,14107,14108],{"class":78,"line":85},[76,14109,7818],{},[76,14111,14112],{"class":78,"line":92},[76,14113,7823],{},[76,14115,14116],{"class":78,"line":98},[76,14117,7828],{},[76,14119,14120],{"class":78,"line":103},[76,14121,89],{"emptyLinePlaceholder":88},[76,14123,14124],{"class":78,"line":109},[76,14125,7837],{},[76,14127,14128],{"class":78,"line":115},[76,14129,7842],{},[76,14131,14132],{"class":78,"line":121},[76,14133,7847],{},[76,14135,14136],{"class":78,"line":126},[76,14137,7852],{},[76,14139,14140],{"class":78,"line":132},[76,14141,89],{"emptyLinePlaceholder":88},[76,14143,14144],{"class":78,"line":138},[76,14145,7861],{},[76,14147,14148],{"class":78,"line":144},[76,14149,7866],{},[76,14151,14152],{"class":78,"line":7395},[76,14153,7871],{},[10,14155,150],{},[67,14157,14159],{"className":14158,"code":7877,"language":156,"meta":72},[154],[33,14160,7877],{"__ignoreMap":72},[10,14162,161],{},[14,14164,164],{"id":164},[166,14166,14167,14173],{},[48,14168,7888,14169,7892,14171,7895],{},[33,14170,7891],{},[33,14172,7795],{},[48,14174,14175,7901,14177,7905,14179,7908],{},[33,14176,7900],{},[33,14178,7904],{},[33,14180,7789],{},[326,14182,2695],{"id":2695},[10,14184,7913],{},[10,14186,14187],{},[26,14188],{"alt":7918,"src":7919},[10,14190,7922,14191,1155,14193,7928],{},[33,14192,4581],{},[33,14194,7927],{},[14,14196,180],{"id":180},[45,14198,14199,14203],{},[48,14200,7935,14201,7938],{},[33,14202,7789],{},[48,14204,7941],{},[14,14206,191],{"id":191},[166,14208,14209,14213],{},[48,14210,5294,14211,7951],{},[33,14212,7950],{},[48,14214,7954],{},[10,14216,202],{},[14,14218,205],{"id":205},[10,14220,7961],{},[210,14222,212],{},{"title":72,"searchDepth":85,"depth":85,"links":14224},[14225,14226,14227,14228,14229,14232,14233,14234],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":14230},[14231],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":7759,"description":7764},[223,7983,7984],{"id":7987,"title":7988,"body":14239,"category":223,"cover":224,"description":7993,"extension":225,"meta":14386,"navigation":88,"path":8172,"pinned":228,"publishedAt":229,"seo":14387,"slug":8174,"stem":8175,"summary":8176,"tags":14388,"updatedAt":229,"visible":88,"__hash__":8180},{"type":7,"value":14240,"toc":14376},[14241,14243,14245,14247,14249,14253,14255,14257,14265,14267,14269,14325,14327,14332,14334,14336,14348,14350,14356,14358,14368,14370,14372,14374],[10,14242,7993],{},[14,14244,16],{"id":16},[10,14246,7998],{},[14,14248,22],{"id":22},[10,14250,14251],{},[26,14252],{"alt":8005,"src":8006},[10,14254,8009],{},[14,14256,43],{"id":43},[45,14258,14259,14261,14263],{},[48,14260,8016],{},[48,14262,8019],{},[48,14264,8022],{},[14,14266,62],{"id":62},[10,14268,65],{},[67,14270,14271],{"className":69,"code":8029,"language":71,"meta":72,"style":72},[33,14272,14273,14277,14281,14285,14289,14293,14297,14301,14305,14309,14313,14317,14321],{"__ignoreMap":72},[76,14274,14275],{"class":78,"line":79},[76,14276,8036],{},[76,14278,14279],{"class":78,"line":85},[76,14280,8041],{},[76,14282,14283],{"class":78,"line":92},[76,14284,8046],{},[76,14286,14287],{"class":78,"line":98},[76,14288,89],{"emptyLinePlaceholder":88},[76,14290,14291],{"class":78,"line":103},[76,14292,8055],{},[76,14294,14295],{"class":78,"line":109},[76,14296,8060],{},[76,14298,14299],{"class":78,"line":115},[76,14300,8065],{},[76,14302,14303],{"class":78,"line":121},[76,14304,89],{"emptyLinePlaceholder":88},[76,14306,14307],{"class":78,"line":126},[76,14308,8074],{},[76,14310,14311],{"class":78,"line":132},[76,14312,8079],{},[76,14314,14315],{"class":78,"line":138},[76,14316,89],{"emptyLinePlaceholder":88},[76,14318,14319],{"class":78,"line":144},[76,14320,8088],{},[76,14322,14323],{"class":78,"line":7395},[76,14324,8093],{},[10,14326,150],{},[67,14328,14330],{"className":14329,"code":8099,"language":156,"meta":72},[154],[33,14331,8099],{"__ignoreMap":72},[10,14333,161],{},[14,14335,164],{"id":164},[166,14337,14338,14344],{},[48,14339,14340,8113,14342,8117],{},[33,14341,8112],{},[33,14343,8116],{},[48,14345,8120,14346,8124],{},[33,14347,8123],{},[14,14349,180],{"id":180},[45,14351,14352,14354],{},[48,14353,8131],{},[48,14355,8134],{},[14,14357,191],{"id":191},[166,14359,14360,14366],{},[48,14361,8141,14362,8145,14364,360],{},[33,14363,8144],{},[33,14365,8148],{},[48,14367,8151],{},[10,14369,202],{},[14,14371,205],{"id":205},[10,14373,8158],{},[210,14375,212],{},{"title":72,"searchDepth":85,"depth":85,"links":14377},[14378,14379,14380,14381,14382,14383,14384,14385],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":7988,"description":7993},[223,8178,8179],{"id":8182,"title":8183,"body":14390,"category":223,"cover":224,"description":8188,"extension":225,"meta":14553,"navigation":88,"path":8392,"pinned":228,"publishedAt":229,"seo":14554,"slug":8394,"stem":8395,"summary":8396,"tags":14555,"updatedAt":229,"visible":88,"__hash__":8400},{"type":7,"value":14391,"toc":14541},[14392,14394,14396,14398,14400,14404,14408,14410,14426,14428,14430,14474,14476,14481,14483,14485,14499,14501,14505,14509,14513,14515,14521,14523,14533,14535,14537,14539],[10,14393,8188],{},[14,14395,16],{"id":16},[10,14397,8193],{},[14,14399,22],{"id":22},[10,14401,14402],{},[26,14403],{"alt":8200,"src":8201},[10,14405,8204,14406,8208],{},[33,14407,8207],{},[14,14409,43],{"id":43},[45,14411,14412,14418,14424],{},[48,14413,14414,8218,14416,8222],{},[33,14415,8217],{},[33,14417,8221],{},[48,14419,8225,14420,8229,14422,8232],{},[33,14421,8228],{},[33,14423,4335],{},[48,14425,8235],{},[14,14427,62],{"id":62},[10,14429,65],{},[67,14431,14432],{"className":69,"code":8242,"language":71,"meta":72,"style":72},[33,14433,14434,14438,14442,14446,14450,14454,14458,14462,14466,14470],{"__ignoreMap":72},[76,14435,14436],{"class":78,"line":79},[76,14437,8249],{},[76,14439,14440],{"class":78,"line":85},[76,14441,8254],{},[76,14443,14444],{"class":78,"line":92},[76,14445,8259],{},[76,14447,14448],{"class":78,"line":98},[76,14449,8264],{},[76,14451,14452],{"class":78,"line":103},[76,14453,8269],{},[76,14455,14456],{"class":78,"line":109},[76,14457,89],{"emptyLinePlaceholder":88},[76,14459,14460],{"class":78,"line":115},[76,14461,8278],{},[76,14463,14464],{"class":78,"line":121},[76,14465,8283],{},[76,14467,14468],{"class":78,"line":126},[76,14469,8283],{},[76,14471,14472],{"class":78,"line":132},[76,14473,8283],{},[10,14475,150],{},[67,14477,14479],{"className":14478,"code":8297,"language":156,"meta":72},[154],[33,14480,8297],{"__ignoreMap":72},[10,14482,161],{},[14,14484,164],{"id":164},[166,14486,14487,14491],{},[48,14488,7888,14489,8311],{},[33,14490,8310],{},[48,14492,8314,14493,8317,14495,8320,14497,8324],{},[33,14494,8221],{},[33,14496,8207],{},[33,14498,8323],{},[326,14500,2695],{"id":2695},[10,14502,8329,14503,8332],{},[33,14504,8221],{},[10,14506,14507],{},[26,14508],{"alt":8337,"src":8338},[10,14510,8341,14511,8344],{},[33,14512,8207],{},[14,14514,180],{"id":180},[45,14516,14517,14519],{},[48,14518,8351],{},[48,14520,8354],{},[14,14522,191],{"id":191},[166,14524,14525,14527],{},[48,14526,8361],{},[48,14528,4008,14529,8366,14531,8369],{},[33,14530,4335],{},[33,14532,8221],{},[10,14534,202],{},[14,14536,205],{"id":205},[10,14538,8376],{},[210,14540,212],{},{"title":72,"searchDepth":85,"depth":85,"links":14542},[14543,14544,14545,14546,14547,14550,14551,14552],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":14548},[14549],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":8183,"description":8188},[223,8398,8399],{"id":8402,"title":8403,"body":14557,"category":223,"cover":224,"description":8408,"extension":225,"meta":14740,"navigation":88,"path":8633,"pinned":228,"publishedAt":229,"seo":14741,"slug":8635,"stem":8636,"summary":8637,"tags":14742,"updatedAt":229,"visible":88,"__hash__":8640},{"type":7,"value":14558,"toc":14728},[14559,14561,14563,14565,14567,14571,14573,14575,14589,14591,14593,14661,14663,14668,14670,14672,14686,14688,14690,14694,14700,14702,14710,14712,14720,14722,14724,14726],[10,14560,8408],{},[14,14562,16],{"id":16},[10,14564,8413],{},[14,14566,22],{"id":22},[10,14568,14569],{},[26,14570],{"alt":8420,"src":8421},[10,14572,8424],{},[14,14574,43],{"id":43},[45,14576,14577,14583,14585],{},[48,14578,14579,8434,14581,360],{},[33,14580,8433],{},[33,14582,8437],{},[48,14584,8440],{},[48,14586,14587,8446],{},[33,14588,8445],{},[14,14590,62],{"id":62},[10,14592,65],{},[67,14594,14595],{"className":69,"code":8453,"language":71,"meta":72,"style":72},[33,14596,14597,14601,14605,14609,14613,14617,14621,14625,14629,14633,14637,14641,14645,14649,14653,14657],{"__ignoreMap":72},[76,14598,14599],{"class":78,"line":79},[76,14600,8460],{},[76,14602,14603],{"class":78,"line":85},[76,14604,89],{"emptyLinePlaceholder":88},[76,14606,14607],{"class":78,"line":92},[76,14608,8469],{},[76,14610,14611],{"class":78,"line":98},[76,14612,8474],{},[76,14614,14615],{"class":78,"line":103},[76,14616,8479],{},[76,14618,14619],{"class":78,"line":109},[76,14620,8484],{},[76,14622,14623],{"class":78,"line":115},[76,14624,8489],{},[76,14626,14627],{"class":78,"line":121},[76,14628,8494],{},[76,14630,14631],{"class":78,"line":126},[76,14632,8499],{},[76,14634,14635],{"class":78,"line":132},[76,14636,8504],{},[76,14638,14639],{"class":78,"line":138},[76,14640,89],{"emptyLinePlaceholder":88},[76,14642,14643],{"class":78,"line":144},[76,14644,8513],{},[76,14646,14647],{"class":78,"line":7395},[76,14648,6177],{},[76,14650,14651],{"class":78,"line":7401},[76,14652,6182],{},[76,14654,14655],{"class":78,"line":8524},[76,14656,89],{"emptyLinePlaceholder":88},[76,14658,14659],{"class":78,"line":8529},[76,14660,8532],{},[10,14662,150],{},[67,14664,14666],{"className":14665,"code":8538,"language":156,"meta":72},[154],[33,14667,8538],{"__ignoreMap":72},[10,14669,161],{},[14,14671,164],{"id":164},[166,14673,14674,14684],{},[48,14675,8549,14676,8553,14678,8557,14680,8561,14682,360],{},[33,14677,8552],{},[33,14679,8556],{},[33,14681,8560],{},[33,14683,8552],{},[48,14685,8566],{},[326,14687,2695],{"id":2695},[10,14689,8571],{},[10,14691,14692],{},[26,14693],{"alt":8576,"src":8577},[10,14695,14696,8582,14698,360],{},[33,14697,8433],{},[33,14699,8437],{},[14,14701,180],{"id":180},[45,14703,14704,14708],{},[48,14705,8591,14706,360],{},[33,14707,5377],{},[48,14709,8596],{},[14,14711,191],{"id":191},[166,14713,14714,14716],{},[48,14715,8603],{},[48,14717,8606,14718,8610],{},[33,14719,8609],{},[10,14721,202],{},[14,14723,205],{"id":205},[10,14725,8617],{},[210,14727,212],{},{"title":72,"searchDepth":85,"depth":85,"links":14729},[14730,14731,14732,14733,14734,14737,14738,14739],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":14735},[14736],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":8403,"description":8408},[223,8639,5328],{"id":8642,"title":8643,"body":14744,"category":223,"cover":224,"description":8648,"extension":225,"meta":14903,"navigation":88,"path":8836,"pinned":228,"publishedAt":229,"seo":14904,"slug":8838,"stem":8839,"summary":8840,"tags":14905,"updatedAt":229,"visible":88,"__hash__":8844},{"type":7,"value":14745,"toc":14891},[14746,14748,14750,14752,14754,14758,14760,14762,14770,14772,14774,14838,14840,14845,14847,14849,14857,14859,14861,14865,14867,14869,14875,14877,14883,14885,14887,14889],[10,14747,8648],{},[14,14749,16],{"id":16},[10,14751,8653],{},[14,14753,22],{"id":22},[10,14755,14756],{},[26,14757],{"alt":8660,"src":8661},[10,14759,8664],{},[14,14761,43],{"id":43},[45,14763,14764,14766,14768],{},[48,14765,8671],{},[48,14767,8674],{},[48,14769,8677],{},[14,14771,62],{"id":62},[10,14773,65],{},[67,14775,14776],{"className":69,"code":8684,"language":71,"meta":72,"style":72},[33,14777,14778,14782,14786,14790,14794,14798,14802,14806,14810,14814,14818,14822,14826,14830,14834],{"__ignoreMap":72},[76,14779,14780],{"class":78,"line":79},[76,14781,8691],{},[76,14783,14784],{"class":78,"line":85},[76,14785,8696],{},[76,14787,14788],{"class":78,"line":92},[76,14789,89],{"emptyLinePlaceholder":88},[76,14791,14792],{"class":78,"line":98},[76,14793,8705],{},[76,14795,14796],{"class":78,"line":103},[76,14797,89],{"emptyLinePlaceholder":88},[76,14799,14800],{"class":78,"line":109},[76,14801,8714],{},[76,14803,14804],{"class":78,"line":115},[76,14805,8719],{},[76,14807,14808],{"class":78,"line":121},[76,14809,8724],{},[76,14811,14812],{"class":78,"line":126},[76,14813,89],{"emptyLinePlaceholder":88},[76,14815,14816],{"class":78,"line":132},[76,14817,8733],{},[76,14819,14820],{"class":78,"line":138},[76,14821,8738],{},[76,14823,14824],{"class":78,"line":144},[76,14825,8743],{},[76,14827,14828],{"class":78,"line":7395},[76,14829,89],{"emptyLinePlaceholder":88},[76,14831,14832],{"class":78,"line":7401},[76,14833,6191],{},[76,14835,14836],{"class":78,"line":8524},[76,14837,8756],{},[10,14839,150],{},[67,14841,14843],{"className":14842,"code":8762,"language":156,"meta":72},[154],[33,14844,8762],{"__ignoreMap":72},[10,14846,161],{},[14,14848,164],{"id":164},[166,14850,14851,14855],{},[48,14852,14853,8776],{},[33,14854,8775],{},[48,14856,8779],{},[326,14858,2695],{"id":2695},[10,14860,8784],{},[10,14862,14863],{},[26,14864],{"alt":8789,"src":8790},[10,14866,8793],{},[14,14868,180],{"id":180},[45,14870,14871,14873],{},[48,14872,8800],{},[48,14874,8803],{},[14,14876,191],{"id":191},[166,14878,14879,14881],{},[48,14880,8810],{},[48,14882,8813],{},[10,14884,202],{},[14,14886,205],{"id":205},[10,14888,8820],{},[210,14890,212],{},{"title":72,"searchDepth":85,"depth":85,"links":14892},[14893,14894,14895,14896,14897,14900,14901,14902],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":14898},[14899],{"id":2695,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":8643,"description":8648},[223,8842,8843],{"id":8846,"title":8847,"body":14907,"category":223,"cover":224,"description":8852,"extension":225,"meta":15145,"navigation":88,"path":9153,"pinned":228,"publishedAt":229,"seo":15146,"slug":9155,"stem":9156,"summary":9157,"tags":15147,"updatedAt":229,"visible":88,"__hash__":9161},{"type":7,"value":14908,"toc":15132},[14909,14911,14913,14915,14917,14921,14923,14925,14935,14937,14939,15055,15057,15062,15064,15066,15076,15078,15080,15084,15086,15088,15090,15094,15098,15100,15108,15110,15124,15126,15128,15130],[10,14910,8852],{},[14,14912,16],{"id":16},[10,14914,8857],{},[14,14916,22],{"id":22},[10,14918,14919],{},[26,14920],{"alt":8864,"src":8865},[10,14922,8868],{},[14,14924,43],{"id":43},[45,14926,14927,14929,14931],{},[48,14928,8875],{},[48,14930,8878],{},[48,14932,8881,14933,8885],{},[33,14934,8884],{},[14,14936,62],{"id":62},[10,14938,65],{},[67,14940,14941],{"className":69,"code":8892,"language":71,"meta":72,"style":72},[33,14942,14943,14947,14951,14955,14959,14963,14967,14971,14975,14979,14983,14987,14991,14995,14999,15003,15007,15011,15015,15019,15023,15027,15031,15035,15039,15043,15047,15051],{"__ignoreMap":72},[76,14944,14945],{"class":78,"line":79},[76,14946,82],{},[76,14948,14949],{"class":78,"line":85},[76,14950,6598],{},[76,14952,14953],{"class":78,"line":92},[76,14954,89],{"emptyLinePlaceholder":88},[76,14956,14957],{"class":78,"line":98},[76,14958,8911],{},[76,14960,14961],{"class":78,"line":103},[76,14962,8916],{},[76,14964,14965],{"class":78,"line":109},[76,14966,8921],{},[76,14968,14969],{"class":78,"line":115},[76,14970,8926],{},[76,14972,14973],{"class":78,"line":121},[76,14974,89],{"emptyLinePlaceholder":88},[76,14976,14977],{"class":78,"line":126},[76,14978,8935],{},[76,14980,14981],{"class":78,"line":132},[76,14982,8940],{},[76,14984,14985],{"class":78,"line":138},[76,14986,8945],{},[76,14988,14989],{"class":78,"line":144},[76,14990,8950],{},[76,14992,14993],{"class":78,"line":7395},[76,14994,8955],{},[76,14996,14997],{"class":78,"line":7401},[76,14998,89],{"emptyLinePlaceholder":88},[76,15000,15001],{"class":78,"line":8524},[76,15002,8964],{},[76,15004,15005],{"class":78,"line":8529},[76,15006,8969],{},[76,15008,15009],{"class":78,"line":8972},[76,15010,8975],{},[76,15012,15013],{"class":78,"line":8978},[76,15014,89],{"emptyLinePlaceholder":88},[76,15016,15017],{"class":78,"line":8983},[76,15018,8986],{},[76,15020,15021],{"class":78,"line":8989},[76,15022,89],{"emptyLinePlaceholder":88},[76,15024,15025],{"class":78,"line":8994},[76,15026,7368],{},[76,15028,15029],{"class":78,"line":8999},[76,15030,9002],{},[76,15032,15033],{"class":78,"line":9005},[76,15034,9008],{},[76,15036,15037],{"class":78,"line":9011},[76,15038,9014],{},[76,15040,15041],{"class":78,"line":9017},[76,15042,7378],{},[76,15044,15045],{"class":78,"line":9022},[76,15046,9025],{},[76,15048,15049],{"class":78,"line":9028},[76,15050,1144],{},[76,15052,15053],{"class":78,"line":9033},[76,15054,9036],{},[10,15056,150],{},[67,15058,15060],{"className":15059,"code":9042,"language":156,"meta":72},[154],[33,15061,9042],{"__ignoreMap":72},[10,15063,161],{},[14,15065,164],{"id":164},[166,15067,15068,15072],{},[48,15069,9053,15070,9056],{},[33,15071,8884],{},[48,15073,15074,9061],{},[33,15075,8116],{},[326,15077,2695],{"id":2695},[10,15079,9066],{},[10,15081,15082],{},[26,15083],{"alt":9071,"src":9072},[10,15085,9075],{},[326,15087,2695],{"id":4216},[10,15089,9080],{},[10,15091,15092],{},[26,15093],{"alt":9085,"src":9086},[10,15095,9089,15096,9093],{},[33,15097,9092],{},[14,15099,180],{"id":180},[45,15101,15102,15104],{},[48,15103,9100],{},[48,15105,9103,15106,9106],{},[33,15107,9092],{},[14,15109,191],{"id":191},[166,15111,15112,15116,15118],{},[48,15113,9113,15114,9116],{},[33,15115,9092],{},[48,15117,9119],{},[48,15119,9122,15120,9126,15122,9129],{},[33,15121,9125],{},[33,15123,6133],{},[10,15125,202],{},[14,15127,205],{"id":205},[10,15129,9136],{},[210,15131,212],{},{"title":72,"searchDepth":85,"depth":85,"links":15133},[15134,15135,15136,15137,15138,15142,15143,15144],{"id":16,"depth":85,"text":16},{"id":22,"depth":85,"text":22},{"id":43,"depth":85,"text":43},{"id":62,"depth":85,"text":62},{"id":164,"depth":85,"text":164,"children":15139},[15140,15141],{"id":2695,"depth":92,"text":2695},{"id":4216,"depth":92,"text":2695},{"id":180,"depth":85,"text":180},{"id":191,"depth":85,"text":191},{"id":205,"depth":85,"text":205},{},{"title":8847,"description":8852},[223,9159,9160],{"id":1054,"title":1055,"body":15149,"category":223,"cover":1063,"description":72,"extension":225,"meta":15385,"navigation":88,"path":1380,"pinned":228,"publishedAt":1381,"seo":15386,"slug":1383,"stem":1384,"summary":1385,"tags":15387,"updatedAt":1381,"visible":88,"__hash__":1389},{"type":7,"value":15150,"toc":15370},[15151,15155,15157,15159,15161,15163,15183,15185,15190,15192,15194,15222,15228,15230,15234,15236,15256,15258,15268,15270,15272,15274,15276,15278,15280,15282,15284,15286,15306,15308,15310,15314,15316,15318,15320,15322,15326,15328,15346,15348,15350,15352,15354,15356,15358,15360,15362,15364,15366,15368],[10,15152,15153],{},[26,15154],{"alt":1062,"src":1063},[10,15156,1066],{},[10,15158,1069],{},[14,15160,1073],{"id":1072},[10,15162,1076],{},[67,15164,15165],{"className":69,"code":1079,"language":71,"meta":72,"style":72},[33,15166,15167,15171,15175,15179],{"__ignoreMap":72},[76,15168,15169],{"class":78,"line":79},[76,15170,1086],{},[76,15172,15173],{"class":78,"line":85},[76,15174,1091],{},[76,15176,15177],{"class":78,"line":92},[76,15178,89],{"emptyLinePlaceholder":88},[76,15180,15181],{"class":78,"line":98},[76,15182,1100],{},[10,15184,1103],{},[67,15186,15188],{"className":15187,"code":1107,"language":156,"meta":72},[154],[33,15189,1107],{"__ignoreMap":72},[10,15191,1112],{},[10,15193,1115],{},[67,15195,15196],{"className":69,"code":1118,"language":71,"meta":72,"style":72},[33,15197,15198,15202,15206,15210,15214,15218],{"__ignoreMap":72},[76,15199,15200],{"class":78,"line":79},[76,15201,1125],{},[76,15203,15204],{"class":78,"line":85},[76,15205,89],{"emptyLinePlaceholder":88},[76,15207,15208],{"class":78,"line":92},[76,15209,1134],{},[76,15211,15212],{"class":78,"line":98},[76,15213,1139],{},[76,15215,15216],{"class":78,"line":103},[76,15217,1144],{},[76,15219,15220],{"class":78,"line":109},[76,15221,1149],{},[10,15223,15224,1155,15226,1159],{},[33,15225,1154],{},[33,15227,1158],{},[14,15229,1163],{"id":1162},[10,15231,1166,15232,1170],{},[33,15233,1169],{},[10,15235,1173],{},[67,15237,15238],{"className":69,"code":1176,"language":71,"meta":72,"style":72},[33,15239,15240,15244,15248,15252],{"__ignoreMap":72},[76,15241,15242],{"class":78,"line":79},[76,15243,1183],{},[76,15245,15246],{"class":78,"line":85},[76,15247,1188],{},[76,15249,15250],{"class":78,"line":92},[76,15251,1193],{},[76,15253,15254],{"class":78,"line":98},[76,15255,1198],{},[10,15257,1201],{},[67,15259,15260],{"className":589,"code":1204,"language":591,"meta":72,"style":72},[33,15261,15262],{"__ignoreMap":72},[76,15263,15264,15266],{"class":78,"line":79},[76,15265,689],{"class":598},[76,15267,1213],{"class":634},[10,15269,1216],{},[14,15271,1220],{"id":1219},[326,15273,1223],{"id":1223},[10,15275,1226],{},[326,15277,1229],{"id":1229},[10,15279,1232],{},[326,15281,1235],{"id":1235},[10,15283,1238],{},[10,15285,1241],{},[67,15287,15288],{"className":69,"code":1244,"language":71,"meta":72,"style":72},[33,15289,15290,15294,15298,15302],{"__ignoreMap":72},[76,15291,15292],{"class":78,"line":79},[76,15293,1251],{},[76,15295,15296],{"class":78,"line":85},[76,15297,89],{"emptyLinePlaceholder":88},[76,15299,15300],{"class":78,"line":92},[76,15301,1260],{},[76,15303,15304],{"class":78,"line":98},[76,15305,1265],{},[10,15307,1268],{},[326,15309,1271],{"id":1271},[10,15311,1274,15312,1277],{},[33,15313,258],{},[10,15315,1280],{},[326,15317,1283],{"id":1283},[10,15319,1286],{},[14,15321,1290],{"id":1289},[10,15323,15324],{},[26,15325],{"alt":1295,"src":1296},[10,15327,1299],{},[45,15329,15330,15332,15334,15336,15338,15340,15342,15344],{},[48,15331,1304],{},[48,15333,1307],{},[48,15335,1310],{},[48,15337,1313],{},[48,15339,1316],{},[48,15341,1319],{},[48,15343,1322],{},[48,15345,1325],{},[10,15347,1328],{},[14,15349,1332],{"id":1331},[10,15351,1335],{},[10,15353,1338],{},[14,15355,1342],{"id":1341},[10,15357,1345],{},[10,15359,1348],{},[10,15361,1351],{},[14,15363,1354],{"id":1354},[10,15365,1357],{},[10,15367,1360],{},[210,15369,1363],{},{"title":72,"searchDepth":85,"depth":85,"links":15371},[15372,15373,15374,15381,15382,15383,15384],{"id":1072,"depth":85,"text":1073},{"id":1162,"depth":85,"text":1163},{"id":1219,"depth":85,"text":1220,"children":15375},[15376,15377,15378,15379,15380],{"id":1223,"depth":92,"text":1223},{"id":1229,"depth":92,"text":1229},{"id":1235,"depth":92,"text":1235},{"id":1271,"depth":92,"text":1271},{"id":1283,"depth":92,"text":1283},{"id":1289,"depth":85,"text":1290},{"id":1331,"depth":85,"text":1332},{"id":1341,"depth":85,"text":1342},{"id":1354,"depth":85,"text":1354},{},{"title":1055,"description":72},[223,1387,1388],{"id":240,"title":241,"body":15389,"category":223,"cover":224,"description":72,"extension":225,"meta":15968,"navigation":88,"path":1043,"pinned":228,"publishedAt":1044,"seo":15969,"slug":1046,"stem":1047,"summary":1048,"tags":15970,"updatedAt":1044,"visible":88,"__hash__":1052},{"type":7,"value":15390,"toc":15944},[15391,15393,15395,15397,15401,15403,15405,15429,15441,15443,15445,15450,15454,15458,15470,15474,15478,15482,15484,15518,15520,15524,15528,15530,15552,15582,15594,15604,15612,15614,15620,15630,15632,15637,15641,15643,15657,15663,15683,15685,15687,15689,15699,15703,15705,15714,15718,15720,15722,15742,15746,15748,15750,15752,15754,15774,15776,15778,15780,15806,15808,15824,15826,15842,15846,15848,15850,15870,15872,15874,15876,15880,15890,15892,15894,15896,15906,15914,15916,15918,15932,15942],[14,15392,246],{"id":246},[10,15394,249],{},[10,15396,252],{},[10,15398,255,15399,259],{},[33,15400,258],{},[14,15402,262],{"id":262},[10,15404,265],{},[267,15406,15407,15409],{},[10,15408,271],{},[267,15410,15411,15417,15419,15423,15425],{},[10,15412,276,15413,280,15415,284],{},[33,15414,279],{},[33,15416,283],{},[10,15418,287],{},[10,15420,290,15421,295],{},[292,15422,294],{},[10,15424,298],{},[10,15426,15427],{},[26,15428],{"alt":303,"src":304},[267,15430,15431,15433],{},[10,15432,309],{},[267,15434,15435,15437],{},[10,15436,314],{},[10,15438,15439],{},[26,15440],{"alt":319,"src":320},[14,15442,324],{"id":323},[326,15444,329],{"id":328},[10,15446,332,15447,340],{},[334,15448,339],{"href":336,"rel":15449},[338],[267,15451,15452],{},[10,15453,345],{},[10,15455,15456],{},[26,15457],{"alt":350,"src":351},[45,15459,15460,15464,15468],{},[48,15461,356,15462,360],{},[292,15463,359],{},[48,15465,363,15466,360],{},[292,15467,366],{},[48,15469,369],{},[10,15471,15472],{},[26,15473],{"alt":374,"src":375},[267,15475,15476],{},[10,15477,380],{},[10,15479,15480],{},[26,15481],{"alt":385,"src":386},[326,15483,390],{"id":389},[267,15485,15486,15490,15494,15514],{},[267,15487,15488],{},[10,15489,397],{},[10,15491,400,15492,404],{},[292,15493,403],{},[67,15495,15496],{"className":69,"code":407,"language":71,"meta":72,"style":72},[33,15497,15498,15502,15506,15510],{"__ignoreMap":72},[76,15499,15500],{"class":78,"line":79},[76,15501,414],{},[76,15503,15504],{"class":78,"line":85},[76,15505,419],{},[76,15507,15508],{"class":78,"line":92},[76,15509,424],{},[76,15511,15512],{"class":78,"line":98},[76,15513,429],{},[10,15515,432,15516,436],{},[292,15517,435],{},[10,15519,439],{},[10,15521,442,15522,445],{},[33,15523,71],{},[10,15525,15526],{},[26,15527],{"alt":450,"src":451},[10,15529,454],{},[267,15531,15532,15534,15538],{},[10,15533,459],{},[10,15535,15536],{},[292,15537,464],{},[267,15539,15540,15544,15548],{},[10,15541,469,15542,472],{},[33,15543,71],{},[10,15545,475,15546,478],{},[33,15547,71],{},[10,15549,481,15550,485],{},[292,15551,484],{},[267,15553,15554,15556,15560],{},[10,15555,490],{},[10,15557,15558],{},[292,15559,495],{},[267,15561,15562,15568,15576,15578],{},[10,15563,15564,503,15566,507],{},[33,15565,502],{},[33,15567,506],{},[10,15569,510,15570,513,15572,517,15574,521],{},[33,15571,502],{},[292,15573,516],{},[292,15575,520],{},[10,15577,524],{},[10,15579,15580,530],{},[292,15581,529],{},[267,15583,15584,15586],{},[10,15585,535],{},[267,15587,15588,15592],{},[10,15589,540,15590,544],{},[292,15591,543],{},[10,15593,547],{},[267,15595,15596,15600],{},[10,15597,552,15598],{},[292,15599,555],{},[10,15601,15602],{},[26,15603],{"alt":560,"src":561},[267,15605,15606,15608],{},[10,15607,566],{},[10,15609,15610],{},[26,15611],{"alt":560,"src":571},[326,15613,575],{"id":574},[10,15615,578,15616,582,15618,586],{},[33,15617,581],{},[33,15619,585],{},[67,15621,15622],{"className":589,"code":590,"language":591,"meta":72,"style":72},[33,15623,15624],{"__ignoreMap":72},[76,15625,15626,15628],{"class":78,"line":79},[76,15627,71],{"class":598},[76,15629,602],{"class":601},[10,15631,605],{},[67,15633,15635],{"className":15634,"code":609,"language":156,"meta":72},[154],[33,15636,609],{"__ignoreMap":72},[10,15638,15639],{},[26,15640],{"alt":560,"src":616},[10,15642,619],{},[67,15644,15645],{"className":589,"code":622,"language":591,"meta":72,"style":72},[33,15646,15647],{"__ignoreMap":72},[76,15648,15649,15651,15653,15655],{"class":78,"line":79},[76,15650,71],{"class":598},[76,15652,631],{"class":601},[76,15654,635],{"class":634},[76,15656,602],{"class":601},[10,15658,640,15659,643,15661,647],{},[33,15660,71],{},[33,15662,646],{},[67,15664,15665],{"className":589,"code":650,"language":591,"meta":72,"style":72},[33,15666,15667,15673],{"__ignoreMap":72},[76,15668,15669,15671],{"class":78,"line":79},[76,15670,506],{"class":598},[76,15672,602],{"class":601},[76,15674,15675,15677,15679,15681],{"class":78,"line":85},[76,15676,506],{"class":598},[76,15678,631],{"class":601},[76,15680,635],{"class":634},[76,15682,602],{"class":601},[14,15684,672],{"id":671},[326,15686,676],{"id":675},[10,15688,679],{},[67,15690,15691],{"className":589,"code":682,"language":591,"meta":72,"style":72},[33,15692,15693],{"__ignoreMap":72},[76,15694,15695,15697],{"class":78,"line":79},[76,15696,689],{"class":598},[76,15698,602],{"class":601},[10,15700,694,15701,698],{},[33,15702,697],{},[326,15704,702],{"id":701},[10,15706,332,15707,710,15710,360,15712,717],{},[334,15708,709],{"href":707,"rel":15709},[338],[292,15711,713],{},[33,15713,716],{},[10,15715,720,15716,724],{},[33,15717,723],{},[326,15719,728],{"id":727},[10,15721,731],{},[67,15723,15724],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,15725,15726,15732],{"__ignoreMap":72},[76,15727,15728,15730],{"class":78,"line":79},[76,15729,689],{"class":598},[76,15731,602],{"class":601},[76,15733,15734,15736,15738,15740],{"class":78,"line":85},[76,15735,689],{"class":598},[76,15737,631],{"class":601},[76,15739,635],{"class":634},[76,15741,602],{"class":601},[10,15743,755,15744,758],{},[33,15745,689],{},[14,15747,762],{"id":761},[10,15749,765],{},[326,15751,769],{"id":768},[10,15753,772],{},[67,15755,15756],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,15757,15758,15764],{"__ignoreMap":72},[76,15759,15760,15762],{"class":78,"line":79},[76,15761,689],{"class":598},[76,15763,602],{"class":601},[76,15765,15766,15768,15770,15772],{"class":78,"line":85},[76,15767,689],{"class":598},[76,15769,631],{"class":601},[76,15771,635],{"class":634},[76,15773,602],{"class":601},[10,15775,795],{},[326,15777,799],{"id":798},[10,15779,802],{},[67,15781,15782],{"className":589,"code":805,"language":591,"meta":72,"style":72},[33,15783,15784,15792],{"__ignoreMap":72},[76,15785,15786,15788,15790],{"class":78,"line":79},[76,15787,812],{"class":598},[76,15789,815],{"class":634},[76,15791,818],{"class":634},[76,15793,15794,15796,15798,15800,15802,15804],{"class":78,"line":85},[76,15795,812],{"class":598},[76,15797,815],{"class":634},[76,15799,827],{"class":634},[76,15801,830],{"class":634},[76,15803,833],{"class":634},[76,15805,836],{"class":634},[10,15807,839],{},[67,15809,15810],{"className":589,"code":842,"language":591,"meta":72,"style":72},[33,15811,15812],{"__ignoreMap":72},[76,15813,15814,15816,15818,15820,15822],{"class":78,"line":79},[76,15815,812],{"class":598},[76,15817,851],{"class":634},[76,15819,827],{"class":634},[76,15821,830],{"class":634},[76,15823,858],{"class":634},[10,15825,861],{},[67,15827,15828],{"className":589,"code":864,"language":591,"meta":72,"style":72},[33,15829,15830],{"__ignoreMap":72},[76,15831,15832,15834,15836,15838,15840],{"class":78,"line":79},[76,15833,812],{"class":598},[76,15835,873],{"class":634},[76,15837,876],{"class":601},[76,15839,879],{"class":634},[76,15841,882],{"class":634},[10,15843,15844,887],{},[33,15845,812],{},[326,15847,891],{"id":890},[10,15849,894],{},[67,15851,15852],{"className":589,"code":734,"language":591,"meta":72,"style":72},[33,15853,15854,15860],{"__ignoreMap":72},[76,15855,15856,15858],{"class":78,"line":79},[76,15857,689],{"class":598},[76,15859,602],{"class":601},[76,15861,15862,15864,15866,15868],{"class":78,"line":85},[76,15863,689],{"class":598},[76,15865,631],{"class":601},[76,15867,635],{"class":634},[76,15869,602],{"class":601},[10,15871,917],{},[14,15873,920],{"id":920},[326,15875,924],{"id":923},[10,15877,927,15878,931],{},[33,15879,930],{},[166,15881,15882,15886,15888],{},[48,15883,936,15884,939],{},[33,15885,646],{},[48,15887,942],{},[48,15889,945],{},[10,15891,948],{},[326,15893,952],{"id":951},[10,15895,955],{},[67,15897,15898],{"className":589,"code":682,"language":591,"meta":72,"style":72},[33,15899,15900],{"__ignoreMap":72},[76,15901,15902,15904],{"class":78,"line":79},[76,15903,689],{"class":598},[76,15905,602],{"class":601},[10,15907,968,15908,971,15910,974,15912,360],{},[33,15909,689],{},[33,15911,71],{},[33,15913,689],{},[326,15915,980],{"id":979},[10,15917,983],{},[67,15919,15920],{"className":589,"code":986,"language":591,"meta":72,"style":72},[33,15921,15922],{"__ignoreMap":72},[76,15923,15924,15926,15928,15930],{"class":78,"line":79},[76,15925,689],{"class":598},[76,15927,631],{"class":601},[76,15929,635],{"class":634},[76,15931,602],{"class":601},[10,15933,1001,15934,1004,15936,1007,15938,1010,15940,1014],{},[33,15935,689],{},[33,15937,71],{},[33,15939,506],{},[33,15941,1013],{},[210,15943,1017],{},{"title":72,"searchDepth":85,"depth":85,"links":15945},[15946,15947,15948,15953,15958,15963],{"id":246,"depth":85,"text":246},{"id":262,"depth":85,"text":262},{"id":323,"depth":85,"text":324,"children":15949},[15950,15951,15952],{"id":328,"depth":92,"text":329},{"id":389,"depth":92,"text":390},{"id":574,"depth":92,"text":575},{"id":671,"depth":85,"text":672,"children":15954},[15955,15956,15957],{"id":675,"depth":92,"text":676},{"id":701,"depth":92,"text":702},{"id":727,"depth":92,"text":728},{"id":761,"depth":85,"text":762,"children":15959},[15960,15961,15962],{"id":768,"depth":92,"text":769},{"id":798,"depth":92,"text":799},{"id":890,"depth":92,"text":891},{"id":920,"depth":85,"text":920,"children":15964},[15965,15966,15967],{"id":923,"depth":92,"text":924},{"id":951,"depth":92,"text":952},{"id":979,"depth":92,"text":980},{},{"title":241,"description":72},[223,1050,1051],1786973365754]