[{"data":1,"prerenderedAt":16042},["ShallowReactive",2],{"post-python-exceptions":3,"sidebar-posts":352,"post-related-source":9233},{"id":4,"title":5,"body":6,"category":337,"cover":338,"description":12,"extension":339,"meta":340,"navigation":116,"path":341,"pinned":342,"publishedAt":343,"seo":344,"slug":345,"stem":346,"summary":347,"tags":348,"updatedAt":343,"visible":116,"__hash__":351},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":8,"toc":324},"minimark",[9,13,17,20,23,30,42,45,64,67,70,166,169,177,180,183,212,216,227,233,244,247,253,259,268,271,286,289,311,314,317,320],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,15,16],"h2",{"id":16},"本篇要解决的问题",[10,18,19],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,21,22],{"id":22},"先看清一个容易误解的细节",[10,24,25],{},[26,27],"img",{"alt":28,"src":29},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,31,32,33,37,38,41],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[34,35,36],"code",{},"except","；无论是否异常，",[34,39,40],{},"finally"," 都会在离开结构前执行。",[14,43,44],{"id":44},"核心概念",[46,47,48,55,61],"ul",{},[49,50,51,52,54],"li",{},"只捕获能够处理的具体异常，不使用空的 ",[34,53,36],{}," 吞掉全部错误。",[49,56,57,60],{},[34,58,59],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[49,62,63],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,65,66],{"id":66},"跟着示例运行",[10,68,69],{},"把下面代码保存到本课脚本并运行：",[71,72,77],"pre",{"className":73,"code":74,"language":75,"meta":76,"style":76},"language-python shiki shiki-themes github-dark","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","python","",[34,78,79,87,93,99,105,111,118,124,130,136,142,148,154,160],{"__ignoreMap":76},[80,81,84],"span",{"class":82,"line":83},"line",1,[80,85,86],{},"def parse_age(text):\n",[80,88,90],{"class":82,"line":89},2,[80,91,92],{},"    age = int(text)\n",[80,94,96],{"class":82,"line":95},3,[80,97,98],{},"    if age \u003C 0:\n",[80,100,102],{"class":82,"line":101},4,[80,103,104],{},"        raise ValueError(\"年龄不能为负数\")\n",[80,106,108],{"class":82,"line":107},5,[80,109,110],{},"    return age\n",[80,112,114],{"class":82,"line":113},6,[80,115,117],{"emptyLinePlaceholder":116},true,"\n",[80,119,121],{"class":82,"line":120},7,[80,122,123],{},"try:\n",[80,125,127],{"class":82,"line":126},8,[80,128,129],{},"    age = parse_age(\"18\")\n",[80,131,133],{"class":82,"line":132},9,[80,134,135],{},"except ValueError as error:\n",[80,137,139],{"class":82,"line":138},10,[80,140,141],{},"    print(\"输入错误：\", error)\n",[80,143,145],{"class":82,"line":144},11,[80,146,147],{},"else:\n",[80,149,151],{"class":82,"line":150},12,[80,152,153],{},"    print(\"年龄：\", age)\n",[80,155,157],{"class":82,"line":156},13,[80,158,159],{},"finally:\n",[80,161,163],{"class":82,"line":162},14,[80,164,165],{},"    print(\"处理结束\")\n",[10,167,168],{},"预期结果：",[71,170,175],{"className":171,"code":173,"language":174,"meta":76},[172],"language-text","年龄： 18\n处理结束\n","text",[34,176,173],{"__ignoreMap":76},[10,178,179],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,181,182],{"id":182},"按执行顺序拆开看",[184,185,186,199],"ol",{},[49,187,188,191,192,194,195,198],{},[34,189,190],{},"int()"," 或主动 ",[34,193,59],{}," 都可能产生 ",[34,196,197],{},"ValueError","，控制流立即离开当前正常路径。",[49,200,201,202,204,205,208,209,211],{},"有异常时进入匹配的 ",[34,203,36],{},"；没有异常时执行 ",[34,206,207],{},"else","；两种情况最后都会执行 ",[34,210,40],{},"。",[213,214,215],"h3",{"id":215},"再看一个具体细节",[10,217,218,220,221,223,224,226],{},[34,219,36],{},"、",[34,222,207],{}," 和 ",[34,225,40],{}," 的职责不同，不能只看它们出现的顺序。",[10,228,229],{},[26,230],{"alt":231,"src":232},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,234,235,237,238,240,241,243],{},[34,236,36],{}," 处理匹配异常，",[34,239,207],{}," 只在无异常时运行，",[34,242,40],{}," 负责两条路径都需要的清理动作。",[213,245,215],{"id":246},"再看一个具体细节-1",[10,248,249,252],{},[34,250,251],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,254,255],{},[26,256],{"alt":257,"src":258},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,260,261,262,264,265,267],{},"只把可能产生预期异常的操作放进 ",[34,263,251],{},"，后续正常业务放进 ",[34,266,207],{},"，错误边界会更清楚。",[14,269,270],{"id":270},"初学者容易混淆的地方",[46,272,273,280],{},[49,274,275,276,279],{},"使用裸 ",[34,277,278],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[49,281,282,283,285],{},"把整个程序包在一个巨大 ",[34,284,251],{}," 中，无法判断究竟哪一步允许失败。",[14,287,288],{"id":288},"练习",[184,290,291,304],{},[49,292,293,294,297,298,223,301,211],{},"让 ",[34,295,296],{},"parse_age"," 分别处理 ",[34,299,300],{},"\"abc\"",[34,302,303],{},"\"-1\"",[49,305,306,307,310],{},"为文件读取捕获 ",[34,308,309],{},"FileNotFoundError"," 并给出清晰提示。",[10,312,313],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,315,316],{"id":316},"本篇边界",[10,318,319],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,322,323],"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":76,"searchDepth":89,"depth":89,"links":325},[326,327,328,329,330,334,335,336],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":331},[332,333],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",false,"2026-08-17",{"title":5,"description":12},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[337,349,350],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",[353,1165,1499,1633,1785,1964,2152,2317,2500,2681,2873,3104,3287,3464,3621,3792,3957,4171,4398,4580,4744,4933,5121,5276,5436,5633,5830,6042,6209,6453,6634,6839,7033,7217,7418,7636,7828,8057,8252,8472,8712,8916],{"id":354,"title":355,"body":356,"category":337,"cover":338,"description":76,"extension":339,"meta":1154,"navigation":116,"path":1155,"pinned":342,"publishedAt":1156,"seo":1157,"slug":1158,"stem":1159,"summary":1160,"tags":1161,"updatedAt":1156,"visible":116,"__hash__":1164},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":357,"toc":1130},[358,361,364,367,374,377,380,419,435,439,443,454,459,465,482,488,493,499,503,549,552,558,564,567,598,643,660,674,684,688,699,715,718,724,729,732,750,760,781,785,789,792,804,811,815,830,837,841,844,865,871,875,878,882,885,905,908,912,915,949,952,971,974,995,1000,1004,1007,1027,1030,1033,1037,1044,1058,1061,1065,1068,1078,1089,1093,1096,1111,1127],[14,359,360],{"id":360},"引言",[10,362,363],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,365,366],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,368,369,370,373],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[34,371,372],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,375,376],{"id":376},"扫盲",[10,378,379],{},"那么这里有几个概念：",[381,382,383,386],"blockquote",{},[10,384,385],{},"为什么需要安装python解释器？",[381,387,388,399,402,410,413],{},[10,389,390,391,394,395,398],{},"我们写的代码，电脑其实看不懂，电脑只认识",[34,392,393],{},"0","和",[34,396,397],{},"1","组成的机器指令。",[10,400,401],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,403,404,405,409],{},"这样，我们就能用",[406,407,408],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,411,412],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,414,415],{},[26,416],{"alt":417,"src":418},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[381,420,421,424],{},[10,422,423],{},"pip又是什么？",[381,425,426,429],{},[10,427,428],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,430,431],{},[26,432],{"alt":433,"src":434},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,436,438],{"id":437},"windows-安装","Windows 安装",[213,440,442],{"id":441},"_1-下载官方安装程序","1. 下载官方安装程序",[10,444,445,446,453],{},"打开 ",[447,448,452],"a",{"href":449,"rel":450},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[451],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[381,455,456],{},[10,457,458],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,460,461],{},[26,462],{"alt":463,"src":464},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[46,466,467,473,479],{},[49,468,469,470,211],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[406,471,472],{},"Windows installer (64-bit)",[49,474,475,476,211],{},"搭载 ARM 处理器的 Windows 设备选择 ",[406,477,478],{},"Windows installer (ARM64)",[49,480,481],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,483,484],{},[26,485],{"alt":486,"src":487},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[381,489,490],{},[10,491,492],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,494,495],{},[26,496],{"alt":497,"src":498},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[213,500,502],{"id":501},"_2-安装并加入-path","2. 安装并加入 PATH",[381,504,505,510,517,542],{},[381,506,507],{},[10,508,509],{},"PATH 环境变量",[10,511,512,513,516],{},"Windows 有一个特殊的变量叫 ",[406,514,515],{},"PATH","，它里面存了一串文件夹路径，比如：",[71,518,520],{"className":73,"code":519,"language":75,"meta":76,"style":76},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[34,521,522,527,532,537],{"__ignoreMap":76},[80,523,524],{"class":82,"line":83},[80,525,526],{},"D:\\Python313\\\n",[80,528,529],{"class":82,"line":89},[80,530,531],{},"D:\\Python313\\Scripts\\\n",[80,533,534],{"class":82,"line":95},[80,535,536],{},"C:\\Windows\\System32\\\n",[80,538,539],{"class":82,"line":101},[80,540,541],{},"...\n",[10,543,544,545,548],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[406,546,547],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,550,551],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,553,554,555,557],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[34,556,75],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,559,560],{},[26,561],{"alt":562,"src":563},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,565,566],{},"对安装界面最底部的两个勾选项分别解释 :",[381,568,569,572,577],{},[10,570,571],{},"Add python.exe to PATH",[10,573,574],{},[406,575,576],{},"把 Python 添加到系统环境变量",[381,578,579,585,591],{},[10,580,581,582,584],{},"勾选后，你可以在命令行任意位置直接输入 ",[34,583,75],{}," 就能运行",[10,586,587,588,590],{},"不勾选的话，命令行输入 ",[34,589,75],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,592,593,594,597],{},"必须",[406,595,596],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[381,599,600,603,608],{},[10,601,602],{},"Use admin privileges when installing py.exe",[10,604,605],{},[406,606,607],{},"使用管理员权限安装 py.exe（Python 启动器）",[381,609,610,620,634,637],{},[10,611,612,615,616,619],{},[34,613,614],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[34,617,618],{},"py"," 来启动 Python。",[10,621,622,623,625,626,629,630,633],{},"勾选后，",[34,624,614],{}," 会安装到",[406,627,628],{},"系统级目录","，电脑上",[406,631,632],{},"所有用户账户","都能用",[10,635,636],{},"不勾选，只有当前用户能用",[10,638,639,642],{},[406,640,641],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[381,644,645,648],{},[10,646,647],{},"操作建议",[381,649,650,657],{},[10,651,652,653,656],{},"两个都勾上之后，再点 ",[406,654,655],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,658,659],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[381,661,662,668],{},[10,663,664,665],{},"Python 安装的",[406,666,667],{},"可选功能页",[10,669,670],{},[26,671],{"alt":672,"src":673},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[381,675,676,679],{},[10,677,678],{},"高级选项页",[10,680,681],{},[26,682],{"alt":672,"src":683},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[213,685,687],{"id":686},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,689,690,691,694,695,698],{},"按 ",[34,692,693],{},"Win + R","，输入 ",[34,696,697],{},"cmd"," 并回车，然后执行：",[71,700,704],{"className":701,"code":702,"language":703,"meta":76,"style":76},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[34,705,706],{"__ignoreMap":76},[80,707,708,711],{"class":82,"line":83},[80,709,75],{"class":710},"svObZ",[80,712,714],{"class":713},"sDLfK"," --version\n",[10,716,717],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[71,719,722],{"className":720,"code":721,"language":174,"meta":76},[172],"Python 3.x.x\n",[34,723,721],{"__ignoreMap":76},[10,725,726],{},[26,727],{"alt":672,"src":728},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,730,731],{},"继续检查 pip：",[71,733,735],{"className":701,"code":734,"language":703,"meta":76,"style":76},"python -m pip --version\n",[34,736,737],{"__ignoreMap":76},[80,738,739,741,744,748],{"class":82,"line":83},[80,740,75],{"class":710},[80,742,743],{"class":713}," -m",[80,745,747],{"class":746},"sU2Wk"," pip",[80,749,714],{"class":713},[10,751,752,753,755,756,759],{},"如果 ",[34,754,75],{}," 无法识别，但 ",[34,757,758],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[71,761,763],{"className":701,"code":762,"language":703,"meta":76,"style":76},"py --version\npy -m pip --version\n",[34,764,765,771],{"__ignoreMap":76},[80,766,767,769],{"class":82,"line":83},[80,768,618],{"class":710},[80,770,714],{"class":713},[80,772,773,775,777,779],{"class":82,"line":89},[80,774,618],{"class":710},[80,776,743],{"class":713},[80,778,747],{"class":746},[80,780,714],{"class":713},[14,782,784],{"id":783},"macos-安装","macOS 安装",[213,786,788],{"id":787},"_1-先检查现有环境","1. 先检查现有环境",[10,790,791],{},"打开“终端”应用，执行：",[71,793,795],{"className":701,"code":794,"language":703,"meta":76,"style":76},"python3 --version\n",[34,796,797],{"__ignoreMap":76},[80,798,799,802],{"class":82,"line":83},[80,800,801],{"class":710},"python3",[80,803,714],{"class":713},[10,805,806,807,810],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[34,808,809],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[213,812,814],{"id":813},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,816,445,817,822,823,211,826,829],{},[447,818,821],{"href":819,"rel":820},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[451],"Python macOS 下载页","，下载当前稳定版的 ",[406,824,825],{},"macOS 64-bit universal2 installer",[34,827,828],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,831,832,833,836],{},"下载完成后打开 ",[34,834,835],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[213,838,840],{"id":839},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,842,843],{},"安装完成后重新打开终端，执行：",[71,845,847],{"className":701,"code":846,"language":703,"meta":76,"style":76},"python3 --version\npython3 -m pip --version\n",[34,848,849,855],{"__ignoreMap":76},[80,850,851,853],{"class":82,"line":83},[80,852,801],{"class":710},[80,854,714],{"class":713},[80,856,857,859,861,863],{"class":82,"line":89},[80,858,801],{"class":710},[80,860,743],{"class":713},[80,862,747],{"class":746},[80,864,714],{"class":713},[10,866,867,868,870],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[34,869,801],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,872,874],{"id":873},"linux-安装","Linux 安装",[10,876,877],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[213,879,881],{"id":880},"_1-检查是否已经安装","1. 检查是否已经安装",[10,883,884],{},"打开终端，执行：",[71,886,887],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,888,889,895],{"__ignoreMap":76},[80,890,891,893],{"class":82,"line":83},[80,892,801],{"class":710},[80,894,714],{"class":713},[80,896,897,899,901,903],{"class":82,"line":89},[80,898,801],{"class":710},[80,900,743],{"class":713},[80,902,747],{"class":746},[80,904,714],{"class":713},[10,906,907],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[213,909,911],{"id":910},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,913,914],{},"Ubuntu 或 Debian：",[71,916,918],{"className":701,"code":917,"language":703,"meta":76,"style":76},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[34,919,920,931],{"__ignoreMap":76},[80,921,922,925,928],{"class":82,"line":83},[80,923,924],{"class":710},"sudo",[80,926,927],{"class":746}," apt",[80,929,930],{"class":746}," update\n",[80,932,933,935,937,940,943,946],{"class":82,"line":89},[80,934,924],{"class":710},[80,936,927],{"class":746},[80,938,939],{"class":746}," install",[80,941,942],{"class":746}," python3",[80,944,945],{"class":746}," python3-pip",[80,947,948],{"class":746}," python3-venv\n",[10,950,951],{},"Fedora：",[71,953,955],{"className":701,"code":954,"language":703,"meta":76,"style":76},"sudo dnf install python3 python3-pip\n",[34,956,957],{"__ignoreMap":76},[80,958,959,961,964,966,968],{"class":82,"line":83},[80,960,924],{"class":710},[80,962,963],{"class":746}," dnf",[80,965,939],{"class":746},[80,967,942],{"class":746},[80,969,970],{"class":746}," python3-pip\n",[10,972,973],{},"Arch Linux：",[71,975,977],{"className":701,"code":976,"language":703,"meta":76,"style":76},"sudo pacman -S python python-pip\n",[34,978,979],{"__ignoreMap":76},[80,980,981,983,986,989,992],{"class":82,"line":83},[80,982,924],{"class":710},[80,984,985],{"class":746}," pacman",[80,987,988],{"class":713}," -S",[80,990,991],{"class":746}," python",[80,993,994],{"class":746}," python-pip\n",[10,996,997,999],{},[34,998,924],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[213,1001,1003],{"id":1002},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,1005,1006],{},"安装结束后执行：",[71,1008,1009],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,1010,1011,1017],{"__ignoreMap":76},[80,1012,1013,1015],{"class":82,"line":83},[80,1014,801],{"class":710},[80,1016,714],{"class":713},[80,1018,1019,1021,1023,1025],{"class":82,"line":89},[80,1020,801],{"class":710},[80,1022,743],{"class":713},[80,1024,747],{"class":746},[80,1026,714],{"class":713},[10,1028,1029],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,1031,1032],{"id":1032},"常见问题",[213,1034,1036],{"id":1035},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,1038,1039,1040,1043],{},"先关闭当前命令提示符并重新打开，再执行 ",[34,1041,1042],{},"python --version","。如果仍然失败，按下面的顺序检查：",[184,1045,1046,1052,1055],{},[49,1047,1048,1049,1051],{},"执行 ",[34,1050,758],{},"，确认 Python Launcher 是否可用。",[49,1053,1054],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[49,1056,1057],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,1059,1060],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[213,1062,1064],{"id":1063},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,1066,1067],{},"先尝试：",[71,1069,1070],{"className":701,"code":794,"language":703,"meta":76,"style":76},[34,1071,1072],{"__ignoreMap":76},[80,1073,1074,1076],{"class":82,"line":83},[80,1075,801],{"class":710},[80,1077,714],{"class":713},[10,1079,1080,1081,1083,1084,1086,1087,211],{},"在这两个系统中，只有 ",[34,1082,801],{}," 命令而没有 ",[34,1085,75],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[34,1088,801],{},[213,1090,1092],{"id":1091},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,1094,1095],{},"先使用模块方式检查：",[71,1097,1099],{"className":701,"code":1098,"language":703,"meta":76,"style":76},"python3 -m pip --version\n",[34,1100,1101],{"__ignoreMap":76},[80,1102,1103,1105,1107,1109],{"class":82,"line":83},[80,1104,801],{"class":710},[80,1106,743],{"class":713},[80,1108,747],{"class":746},[80,1110,714],{"class":713},[10,1112,1113,1114,1116,1117,1119,1120,1122,1123,1126],{},"Windows 用户将命令中的 ",[34,1115,801],{}," 换成 ",[34,1118,75],{}," 或 ",[34,1121,618],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[34,1124,1125],{},"python3-pip","；不要直接使用其他系统的安装命令。",[321,1128,1129],{},"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":76,"searchDepth":89,"depth":89,"links":1131},[1132,1133,1134,1139,1144,1149],{"id":360,"depth":89,"text":360},{"id":376,"depth":89,"text":376},{"id":437,"depth":89,"text":438,"children":1135},[1136,1137,1138],{"id":441,"depth":95,"text":442},{"id":501,"depth":95,"text":502},{"id":686,"depth":95,"text":687},{"id":783,"depth":89,"text":784,"children":1140},[1141,1142,1143],{"id":787,"depth":95,"text":788},{"id":813,"depth":95,"text":814},{"id":839,"depth":95,"text":840},{"id":873,"depth":89,"text":874,"children":1145},[1146,1147,1148],{"id":880,"depth":95,"text":881},{"id":910,"depth":95,"text":911},{"id":1002,"depth":95,"text":1003},{"id":1032,"depth":89,"text":1032,"children":1150},[1151,1152,1153],{"id":1035,"depth":95,"text":1036},{"id":1063,"depth":95,"text":1064},{"id":1091,"depth":95,"text":1092},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":355,"description":76},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[337,1162,1163],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1166,"title":1167,"body":1168,"category":337,"cover":1175,"description":76,"extension":339,"meta":1488,"navigation":116,"path":1489,"pinned":342,"publishedAt":1490,"seo":1491,"slug":1492,"stem":1493,"summary":1494,"tags":1495,"updatedAt":1490,"visible":116,"__hash__":1498},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1169,"toc":1473},[1170,1176,1179,1182,1186,1189,1213,1216,1222,1225,1228,1261,1269,1273,1280,1283,1308,1311,1323,1326,1330,1333,1336,1339,1342,1345,1348,1351,1375,1378,1381,1387,1390,1393,1396,1400,1406,1409,1435,1438,1442,1445,1448,1452,1455,1458,1461,1464,1467,1470],[10,1171,1172],{},[26,1173],{"alt":1174,"src":1175},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1177,1178],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1180,1181],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1183,1185],{"id":1184},"python-代码是什么样的","Python 代码是什么样的",[10,1187,1188],{},"下面是一段简单的 Python 代码：",[71,1190,1192],{"className":73,"code":1191,"language":75,"meta":76,"style":76},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[34,1193,1194,1199,1204,1208],{"__ignoreMap":76},[80,1195,1196],{"class":82,"line":83},[80,1197,1198],{},"name = \"Python\"\n",[80,1200,1201],{"class":82,"line":89},[80,1202,1203],{},"year = 2026\n",[80,1205,1206],{"class":82,"line":95},[80,1207,117],{"emptyLinePlaceholder":116},[80,1209,1210],{"class":82,"line":101},[80,1211,1212],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1214,1215],{},"运行结果：",[71,1217,1220],{"className":1218,"code":1219,"language":174,"meta":76},[172],"正在学习 Python，当前年份是 2026\n",[34,1221,1219],{"__ignoreMap":76},[10,1223,1224],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1226,1227],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[71,1229,1231],{"className":73,"code":1230,"language":75,"meta":76,"style":76},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[34,1232,1233,1238,1242,1247,1252,1256],{"__ignoreMap":76},[80,1234,1235],{"class":82,"line":83},[80,1236,1237],{},"score = 85\n",[80,1239,1240],{"class":82,"line":89},[80,1241,117],{"emptyLinePlaceholder":116},[80,1243,1244],{"class":82,"line":95},[80,1245,1246],{},"if score >= 60:\n",[80,1248,1249],{"class":82,"line":101},[80,1250,1251],{},"    print(\"成绩合格\")\n",[80,1253,1254],{"class":82,"line":107},[80,1255,147],{},[80,1257,1258],{"class":82,"line":113},[80,1259,1260],{},"    print(\"需要继续学习\")\n",[10,1262,1263,223,1266,1268],{},[34,1264,1265],{},"if",[34,1267,207],{}," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1270,1272],{"id":1271},"python-如何运行代码","Python 如何运行代码",[10,1274,1275,1276,1279],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[34,1277,1278],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1281,1282],{},"交互式环境适合快速验证一个表达式：",[71,1284,1286],{"className":73,"code":1285,"language":75,"meta":76,"style":76},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[34,1287,1288,1293,1298,1303],{"__ignoreMap":76},[80,1289,1290],{"class":82,"line":83},[80,1291,1292],{},">>> 10 + 20\n",[80,1294,1295],{"class":82,"line":89},[80,1296,1297],{},"30\n",[80,1299,1300],{"class":82,"line":95},[80,1301,1302],{},">>> \"Python\".lower()\n",[80,1304,1305],{"class":82,"line":101},[80,1306,1307],{},"'python'\n",[10,1309,1310],{},"需要保存和重复运行的程序，则可以写入文件：",[71,1312,1314],{"className":701,"code":1313,"language":703,"meta":76,"style":76},"python3 hello.py\n",[34,1315,1316],{"__ignoreMap":76},[80,1317,1318,1320],{"class":82,"line":83},[80,1319,801],{"class":710},[80,1321,1322],{"class":746}," hello.py\n",[10,1324,1325],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1327,1329],{"id":1328},"python-的特点","Python 的特点",[213,1331,1332],{"id":1332},"语法相对简洁",[10,1334,1335],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[213,1337,1338],{"id":1338},"支持多种编程方式",[10,1340,1341],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[213,1343,1344],{"id":1344},"标准库比较完整",[10,1346,1347],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1349,1350],{},"例如，获取当前时间：",[71,1352,1354],{"className":73,"code":1353,"language":75,"meta":76,"style":76},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[34,1355,1356,1361,1365,1370],{"__ignoreMap":76},[80,1357,1358],{"class":82,"line":83},[80,1359,1360],{},"from datetime import datetime\n",[80,1362,1363],{"class":82,"line":89},[80,1364,117],{"emptyLinePlaceholder":116},[80,1366,1367],{"class":82,"line":95},[80,1368,1369],{},"now = datetime.now()\n",[80,1371,1372],{"class":82,"line":101},[80,1373,1374],{},"print(now)\n",[10,1376,1377],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[213,1379,1380],{"id":1380},"第三方工具丰富",[10,1382,1383,1384,1386],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[34,1385,372],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1388,1389],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[213,1391,1392],{"id":1392},"支持多个操作系统",[10,1394,1395],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1397,1399],{"id":1398},"python-可以做什么","Python 可以做什么",[10,1401,1402],{},[26,1403],{"alt":1404,"src":1405},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1407,1408],{},"Python 的应用范围比较广，常见方向包括：",[46,1410,1411,1414,1417,1420,1423,1426,1429,1432],{},[49,1412,1413],{},"编写自动化脚本，批量处理文件和重复任务；",[49,1415,1416],{},"开发网站后端和 API 服务；",[49,1418,1419],{},"进行数据清洗、统计分析和图表展示；",[49,1421,1422],{},"编写网络爬虫和信息采集工具；",[49,1424,1425],{},"开发自动化测试程序；",[49,1427,1428],{},"进行机器学习和人工智能开发；",[49,1430,1431],{},"编写运维、监控和辅助开发工具；",[49,1433,1434],{},"开发部分桌面应用和插件。",[10,1436,1437],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1439,1441],{"id":1440},"python-的发展","Python 的发展",[10,1443,1444],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1446,1447],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1449,1451],{"id":1450},"python-也有局限","Python 也有局限",[10,1453,1454],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1456,1457],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1459,1460],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1462,1463],{"id":1463},"写在最后",[10,1465,1466],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1468,1469],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[321,1471,1472],{},"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":76,"searchDepth":89,"depth":89,"links":1474},[1475,1476,1477,1484,1485,1486,1487],{"id":1184,"depth":89,"text":1185},{"id":1271,"depth":89,"text":1272},{"id":1328,"depth":89,"text":1329,"children":1478},[1479,1480,1481,1482,1483],{"id":1332,"depth":95,"text":1332},{"id":1338,"depth":95,"text":1338},{"id":1344,"depth":95,"text":1344},{"id":1380,"depth":95,"text":1380},{"id":1392,"depth":95,"text":1392},{"id":1398,"depth":89,"text":1399},{"id":1440,"depth":89,"text":1441},{"id":1450,"depth":89,"text":1451},{"id":1463,"depth":89,"text":1463},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1167,"description":76},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[337,1496,1497],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1500,"title":1501,"body":1502,"category":337,"cover":338,"description":1506,"extension":339,"meta":1624,"navigation":116,"path":1625,"pinned":342,"publishedAt":343,"seo":1626,"slug":1627,"stem":1628,"summary":1629,"tags":1630,"updatedAt":343,"visible":116,"__hash__":1632},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1503,"toc":1614},[1504,1507,1509,1512,1514,1520,1525,1527,1541,1543,1545,1554,1556,1562,1564,1566,1582,1584,1595,1597,1605,1607,1609,1612],[10,1505,1506],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1508,16],{"id":16},[10,1510,1511],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1513,22],{"id":22},[10,1515,1516],{},[26,1517],{"alt":1518,"src":1519},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1521,1522,1524],{},[34,1523,1278],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1526,44],{"id":44},[46,1528,1529,1535,1538],{},[49,1530,1531,1532,1534],{},"源代码是人编写的文本，通常保存在 ",[34,1533,1278],{}," 文件中。",[49,1536,1537],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[49,1539,1540],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1542,66],{"id":66},[10,1544,69],{},[71,1546,1548],{"className":73,"code":1547,"language":75,"meta":76,"style":76},"print(\"你好，Python\")\n",[34,1549,1550],{"__ignoreMap":76},[80,1551,1552],{"class":82,"line":83},[80,1553,1547],{},[10,1555,168],{},[71,1557,1560],{"className":1558,"code":1559,"language":174,"meta":76},[172],"你好，Python\n",[34,1561,1559],{"__ignoreMap":76},[10,1563,179],{},[14,1565,182],{"id":182},[184,1567,1568,1575],{},[49,1569,1570,1571,1574],{},"终端启动解释器后，解释器读取 ",[34,1572,1573],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[49,1576,1577,1578,1581],{},"字符串对象先准备好，再交给 ",[34,1579,1580],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1583,270],{"id":270},[46,1585,1586,1589],{},[49,1587,1588],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[49,1590,1591,1592,1594],{},"认为 ",[34,1593,1278],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1596,288],{"id":288},[184,1598,1599,1602],{},[49,1600,1601],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[49,1603,1604],{},"把示例文字改成自己的学习目标并重新运行。",[10,1606,313],{},[14,1608,316],{"id":316},[10,1610,1611],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,1613,323],{},{"title":76,"searchDepth":89,"depth":89,"links":1615},[1616,1617,1618,1619,1620,1621,1622,1623],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1501,"description":1506},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[337,1496,1631],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1634,"title":1635,"body":1636,"category":337,"cover":338,"description":1640,"extension":339,"meta":1776,"navigation":116,"path":1777,"pinned":342,"publishedAt":343,"seo":1778,"slug":1779,"stem":1780,"summary":1781,"tags":1782,"updatedAt":343,"visible":116,"__hash__":1784},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1637,"toc":1766},[1638,1641,1643,1646,1648,1654,1660,1662,1677,1679,1682,1702,1704,1710,1712,1714,1727,1729,1743,1745,1756,1758,1760,1763],[10,1639,1640],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1642,16],{"id":16},[10,1644,1645],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1647,22],{"id":22},[10,1649,1650],{},[26,1651],{"alt":1652,"src":1653},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1655,1656,1657,1659],{},"终端收到 ",[34,1658,801],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1661,44],{"id":44},[46,1663,1664,1667,1670],{},[49,1665,1666],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[49,1668,1669],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[49,1671,1672,1673,1676],{},"检查 pip 时使用 ",[34,1674,1675],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1678,66],{"id":66},[10,1680,1681],{},"在 macOS 终端执行：",[71,1683,1684],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,1685,1686,1692],{"__ignoreMap":76},[80,1687,1688,1690],{"class":82,"line":83},[80,1689,801],{"class":710},[80,1691,714],{"class":713},[80,1693,1694,1696,1698,1700],{"class":82,"line":89},[80,1695,801],{"class":710},[80,1697,743],{"class":713},[80,1699,747],{"class":746},[80,1701,714],{"class":713},[10,1703,168],{},[71,1705,1708],{"className":1706,"code":1707,"language":174,"meta":76},[172],"Python 3.14.x\npip 版本信息与安装路径\n",[34,1709,1707],{"__ignoreMap":76},[10,1711,179],{},[14,1713,182],{"id":182},[184,1715,1716,1722],{},[49,1717,1718,1721],{},[34,1719,1720],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[49,1723,1724,1726],{},[34,1725,809],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1728,270],{"id":270},[46,1730,1731,1737],{},[49,1732,1733,1734,1736],{},"看到系统已有 ",[34,1735,801],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[49,1738,1739,1740,1742],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[34,1741,801],{},"，不修改系统自带工具。",[14,1744,288],{"id":288},[184,1746,1747,1753],{},[49,1748,1048,1749,1752],{},[34,1750,1751],{},"which python3","，记录当前解释器路径。",[49,1754,1755],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1757,313],{},[14,1759,316],{"id":316},[10,1761,1762],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,1764,1765],{},"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":76,"searchDepth":89,"depth":89,"links":1767},[1768,1769,1770,1771,1772,1773,1774,1775],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1635,"description":1640},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[337,1783,1162],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1786,"title":1787,"body":1788,"category":337,"cover":338,"description":1953,"extension":339,"meta":1954,"navigation":116,"path":1955,"pinned":342,"publishedAt":343,"seo":1956,"slug":1957,"stem":1958,"summary":1959,"tags":1960,"updatedAt":343,"visible":116,"__hash__":1963},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1789,"toc":1943},[1790,1796,1798,1801,1803,1809,1812,1814,1838,1840,1842,1869,1871,1877,1879,1881,1899,1901,1915,1917,1931,1933,1935,1941],[10,1791,1792,1793,1795],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[34,1794,1278],{}," 脚本。",[14,1797,16],{"id":16},[10,1799,1800],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1802,22],{"id":22},[10,1804,1805],{},[26,1806],{"alt":1807,"src":1808},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1810,1811],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1813,44],{"id":44},[46,1815,1816,1825,1832],{},[49,1817,1818,1819,1821,1822,211],{},"在终端输入 ",[34,1820,801],{}," 进入 REPL，提示符通常是 ",[34,1823,1824],{},">>>",[49,1826,1827,1828,1831],{},"输入 ",[34,1829,1830],{},"exit()"," 或按 Control-D 退出 REPL。",[49,1833,1834,1835,1837],{},"需要保存、复查或多次运行的代码应写入 ",[34,1836,1278],{}," 文件。",[14,1839,66],{"id":66},[10,1841,69],{},[71,1843,1847],{"className":1844,"code":1845,"language":1846,"meta":76,"style":76},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[34,1848,1849,1854,1859,1864],{"__ignoreMap":76},[80,1850,1851],{"class":82,"line":83},[80,1852,1853],{},">>> 2 + 3\n",[80,1855,1856],{"class":82,"line":89},[80,1857,1858],{},"5\n",[80,1860,1861],{"class":82,"line":95},[80,1862,1863],{},">>> \"python\".upper()\n",[80,1865,1866],{"class":82,"line":101},[80,1867,1868],{},"'PYTHON'\n",[10,1870,168],{},[71,1872,1875],{"className":1873,"code":1874,"language":174,"meta":76},[172],"REPL 会直接显示表达式结果\n",[34,1876,1874],{"__ignoreMap":76},[10,1878,179],{},[14,1880,182],{"id":182},[184,1882,1883,1893],{},[49,1884,1885,1886,1889,1890,211],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[34,1887,1888],{},"2 + 3"," 能直接看到 ",[34,1891,1892],{},"5",[49,1894,1895,1896,1898],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[34,1897,1580],{}," 才会写到标准输出。",[14,1900,270],{"id":270},[46,1902,1903,1912],{},[49,1904,1905,1906,1908,1909,1911],{},"把提示符 ",[34,1907,1824],{}," 复制进 ",[34,1910,1278],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[49,1913,1914],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1916,288],{"id":288},[184,1918,1919,1925],{},[49,1920,1921,1922,211],{},"在 REPL 计算 ",[34,1923,1924],{},"12 * 8",[49,1926,1927,1928,1930],{},"把同一表达式写入脚本；观察脚本中不调用 ",[34,1929,1580],{}," 时是否显示结果。",[10,1932,313],{},[14,1934,316],{"id":316},[10,1936,1937,1938,1940],{},"本篇目标是根据任务选择 REPL 或 ",[34,1939,1278],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,1942,323],{},{"title":76,"searchDepth":89,"depth":89,"links":1944},[1945,1946,1947,1948,1949,1950,1951,1952],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1787,"description":1953},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[337,1961,1962],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1965,"title":1966,"body":1967,"category":337,"cover":338,"description":1971,"extension":339,"meta":2142,"navigation":116,"path":2143,"pinned":342,"publishedAt":343,"seo":2144,"slug":2145,"stem":2146,"summary":2147,"tags":2148,"updatedAt":343,"visible":116,"__hash__":2151},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1968,"toc":2132},[1969,1972,1974,1977,1979,1985,1991,1993,2011,2013,2015,2060,2062,2068,2070,2072,2094,2096,2108,2110,2122,2124,2126,2129],[10,1970,1971],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1973,16],{"id":16},[10,1975,1976],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1978,22],{"id":22},[10,1980,1981],{},[26,1982],{"alt":1983,"src":1984},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1986,1987,1990],{},[34,1988,1989],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1992,44],{"id":44},[46,1994,1995,1998,2008],{},[49,1996,1997],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[49,1999,2000,2003,2004,2007],{},[34,2001,2002],{},"pwd"," 显示当前目录，",[34,2005,2006],{},"ls"," 显示目录里的文件。",[49,2009,2010],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,2012,66],{"id":66},[10,2014,1681],{},[71,2016,2018],{"className":701,"code":2017,"language":703,"meta":76,"style":76},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[34,2019,2020,2028,2035,2040,2054],{"__ignoreMap":76},[80,2021,2022,2025],{"class":82,"line":83},[80,2023,2024],{"class":710},"mkdir",[80,2026,2027],{"class":746}," python-study\n",[80,2029,2030,2033],{"class":82,"line":89},[80,2031,2032],{"class":713},"cd",[80,2034,2027],{"class":746},[80,2036,2037],{"class":82,"line":95},[80,2038,2039],{"class":713},"pwd\n",[80,2041,2042,2045,2048,2052],{"class":82,"line":101},[80,2043,2044],{"class":713},"printf",[80,2046,2047],{"class":746}," 'print(\"项目已经运行\")\\n'",[80,2049,2051],{"class":2050},"snl16"," >",[80,2053,1322],{"class":746},[80,2055,2056,2058],{"class":82,"line":107},[80,2057,801],{"class":710},[80,2059,1322],{"class":746},[10,2061,168],{},[71,2063,2066],{"className":2064,"code":2065,"language":174,"meta":76},[172],"项目已经运行\n",[34,2067,2065],{"__ignoreMap":76},[10,2069,179],{},[14,2071,182],{"id":182},[184,2073,2074,2085],{},[49,2075,2076,2078,2079,2081,2082,2084],{},[34,2077,2024],{}," 创建目录，",[34,2080,2032],{}," 改变终端当前目录，",[34,2083,2002],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[49,2086,2087,2089,2090,2093],{},[34,2088,1989],{}," 会在当前目录寻找 ",[34,2091,2092],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,2095,270],{"id":270},[46,2097,2098,2105],{},[49,2099,2100,2101,223,2103,211],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[34,2102,2002],{},[34,2104,2006],{},[49,2106,2107],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2109,288],{"id":288},[184,2111,2112,2119],{},[49,2113,2114,2115,2118],{},"新建 ",[34,2116,2117],{},"lesson01.py"," 并输出课程编号。",[49,2120,2121],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2123,313],{},[14,2125,316],{"id":316},[10,2127,2128],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,2130,2131],{},"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":76,"searchDepth":89,"depth":89,"links":2133},[2134,2135,2136,2137,2138,2139,2140,2141],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1966,"description":1971},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[337,2149,2150],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2153,"title":2154,"body":2155,"category":337,"cover":338,"description":2159,"extension":339,"meta":2307,"navigation":116,"path":2308,"pinned":342,"publishedAt":343,"seo":2309,"slug":2310,"stem":2311,"summary":2312,"tags":2313,"updatedAt":343,"visible":116,"__hash__":2316},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2156,"toc":2297},[2157,2160,2162,2165,2167,2173,2184,2186,2206,2208,2210,2230,2232,2238,2240,2242,2261,2263,2271,2273,2288,2290,2292,2295],[10,2158,2159],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2161,16],{"id":16},[10,2163,2164],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2166,22],{"id":22},[10,2168,2169],{},[26,2170],{"alt":2171,"src":2172},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2174,2175,2176,211,2178,2181,2182,211],{},"Python 先计算表达式，再把得到的对象交给 ",[34,2177,1580],{},[34,2179,2180],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[34,2183,1888],{},[14,2185,44],{"id":44},[46,2187,2188,2194,2203],{},[49,2189,2190,2193],{},[34,2191,2192],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[49,2195,2196,2199,2200,211],{},[34,2197,2198],{},"7 + 5"," 是表达式，运行时先求值得到 ",[34,2201,2202],{},"12",[49,2204,2205],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2207,66],{"id":66},[10,2209,69],{},[71,2211,2213],{"className":73,"code":2212,"language":75,"meta":76,"style":76},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[34,2214,2215,2220,2225],{"__ignoreMap":76},[80,2216,2217],{"class":82,"line":83},[80,2218,2219],{},"print(42)\n",[80,2221,2222],{"class":82,"line":89},[80,2223,2224],{},"print(7 + 5)\n",[80,2226,2227],{"class":82,"line":95},[80,2228,2229],{},"print(\"Python 基础课\")\n",[10,2231,168],{},[71,2233,2236],{"className":2234,"code":2235,"language":174,"meta":76},[172],"42\n12\nPython 基础课\n",[34,2237,2235],{"__ignoreMap":76},[10,2239,179],{},[14,2241,182],{"id":182},[184,2243,2244,2252],{},[49,2245,2246,2249,2250,211],{},[34,2247,2248],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[34,2251,2202],{},[49,2253,2254,2256,2257,2260],{},[34,2255,1580],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[34,2258,2259],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2262,270],{"id":270},[46,2264,2265,2268],{},[49,2266,2267],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[49,2269,2270],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2272,288],{"id":288},[184,2274,2275,2278],{},[49,2276,2277],{},"分别输出一个整数、一个小数和一段文本。",[49,2279,2280,2281,2283,2284,2287],{},"比较 ",[34,2282,2180],{}," 与 ",[34,2285,2286],{},"print(\"2 + 3\")"," 的结果。",[10,2289,313],{},[14,2291,316],{"id":316},[10,2293,2294],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,2296,323],{},{"title":76,"searchDepth":89,"depth":89,"links":2298},[2299,2300,2301,2302,2303,2304,2305,2306],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2154,"description":2159},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[337,2314,2315],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2318,"title":2319,"body":2320,"category":337,"cover":338,"description":2324,"extension":339,"meta":2490,"navigation":116,"path":2491,"pinned":342,"publishedAt":343,"seo":2492,"slug":2493,"stem":2494,"summary":2495,"tags":2496,"updatedAt":343,"visible":116,"__hash__":2499},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2321,"toc":2480},[2322,2325,2327,2330,2332,2338,2341,2343,2368,2370,2372,2400,2402,2408,2410,2412,2436,2438,2454,2456,2471,2473,2475,2478],[10,2323,2324],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2326,16],{"id":16},[10,2328,2329],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2331,22],{"id":22},[10,2333,2334],{},[26,2335],{"alt":2336,"src":2337},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2339,2340],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2342,44],{"id":44},[46,2344,2345,2348,2358],{},[49,2346,2347],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[49,2349,2350,2351,2283,2354,2357],{},"变量名区分大小写，",[34,2352,2353],{},"score",[34,2355,2356],{},"Score"," 是两个名字。",[49,2359,2360,2361,220,2364,2367],{},"使用能表达含义的名称；不要用 ",[34,2362,2363],{},"list",[34,2365,2366],{},"str"," 等内置名称作为普通变量名。",[14,2369,66],{"id":66},[10,2371,69],{},[71,2373,2375],{"className":73,"code":2374,"language":75,"meta":76,"style":76},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[34,2376,2377,2382,2387,2391,2396],{"__ignoreMap":76},[80,2378,2379],{"class":82,"line":83},[80,2380,2381],{},"score = 90\n",[80,2383,2384],{"class":82,"line":89},[80,2385,2386],{},"print(score)\n",[80,2388,2389],{"class":82,"line":95},[80,2390,117],{"emptyLinePlaceholder":116},[80,2392,2393],{"class":82,"line":101},[80,2394,2395],{},"score = 95\n",[80,2397,2398],{"class":82,"line":107},[80,2399,2386],{},[10,2401,168],{},[71,2403,2406],{"className":2404,"code":2405,"language":174,"meta":76},[172],"90\n95\n",[34,2407,2405],{"__ignoreMap":76},[10,2409,179],{},[14,2411,182],{"id":182},[184,2413,2414,2423],{},[49,2415,1048,2416,2419,2420,2422],{},[34,2417,2418],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[34,2421,2353],{}," 再绑定到它。",[49,2424,1048,2425,2428,2429,2432,2433,211],{},[34,2426,2427],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[34,2430,2431],{},"90"," 没有被改造成 ",[34,2434,2435],{},"95",[14,2437,270],{"id":270},[46,2439,2440,2443],{},[49,2441,2442],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[49,2444,2445,2446,220,2448,220,2450,2453],{},"使用 ",[34,2447,2363],{},[34,2449,2366],{},[34,2451,2452],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2455,288],{"id":288},[184,2457,2458,2468],{},[49,2459,2460,2461,223,2464,2467],{},"创建 ",[34,2462,2463],{},"course_name",[34,2465,2466],{},"lesson_count"," 两个变量并输出。",[49,2469,2470],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2472,313],{},[14,2474,316],{"id":316},[10,2476,2477],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,2479,323],{},{"title":76,"searchDepth":89,"depth":89,"links":2481},[2482,2483,2484,2485,2486,2487,2488,2489],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2319,"description":2324},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[337,2497,2498],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2501,"title":2502,"body":2503,"category":337,"cover":338,"description":2507,"extension":339,"meta":2671,"navigation":116,"path":2672,"pinned":342,"publishedAt":343,"seo":2673,"slug":2674,"stem":2675,"summary":2676,"tags":2677,"updatedAt":343,"visible":116,"__hash__":2680},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2504,"toc":2661},[2505,2508,2510,2513,2515,2521,2524,2526,2555,2557,2559,2603,2605,2611,2613,2615,2629,2631,2642,2644,2652,2654,2656,2659],[10,2506,2507],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2509,16],{"id":16},[10,2511,2512],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2514,22],{"id":22},[10,2516,2517],{},[26,2518],{"alt":2519,"src":2520},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2522,2523],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2525,44],{"id":44},[46,2527,2528,2538,2552],{},[49,2529,2530,2533,2534,2537],{},[34,2531,2532],{},"int"," 表示整数，",[34,2535,2536],{},"float"," 表示浮点数。",[49,2539,2540,2543,2544,2547,2548,2551],{},[34,2541,2542],{},"\u002F"," 总是进行真除法；",[34,2545,2546],{},"\u002F\u002F"," 是向下取整除法，",[34,2549,2550],{},"%"," 得到余数。",[49,2553,2554],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2556,66],{"id":66},[10,2558,69],{},[71,2560,2562],{"className":73,"code":2561,"language":75,"meta":76,"style":76},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[34,2563,2564,2569,2574,2579,2583,2588,2593,2598],{"__ignoreMap":76},[80,2565,2566],{"class":82,"line":83},[80,2567,2568],{},"price = 25\n",[80,2570,2571],{"class":82,"line":89},[80,2572,2573],{},"count = 4\n",[80,2575,2576],{"class":82,"line":95},[80,2577,2578],{},"discount = 0.9\n",[80,2580,2581],{"class":82,"line":101},[80,2582,117],{"emptyLinePlaceholder":116},[80,2584,2585],{"class":82,"line":107},[80,2586,2587],{},"total = price * count * discount\n",[80,2589,2590],{"class":82,"line":113},[80,2591,2592],{},"average = total \u002F count\n",[80,2594,2595],{"class":82,"line":120},[80,2596,2597],{},"print(total)\n",[80,2599,2600],{"class":82,"line":126},[80,2601,2602],{},"print(average)\n",[10,2604,168],{},[71,2606,2609],{"className":2607,"code":2608,"language":174,"meta":76},[172],"90.0\n22.5\n",[34,2610,2608],{"__ignoreMap":76},[10,2612,179],{},[14,2614,182],{"id":182},[184,2616,2617,2623],{},[49,2618,2619,2622],{},[34,2620,2621],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[49,2624,2625,2628],{},[34,2626,2627],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2630,270],{"id":270},[46,2632,2633,2639],{},[49,2634,2635,2636,211],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[34,2637,2638],{},"decimal.Decimal",[49,2640,2641],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2643,288],{"id":288},[184,2645,2646,2649],{},[49,2647,2648],{},"计算 137 除以 10 的商和余数。",[49,2650,2651],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2653,313],{},[14,2655,316],{"id":316},[10,2657,2658],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,2660,323],{},{"title":76,"searchDepth":89,"depth":89,"links":2662},[2663,2664,2665,2666,2667,2668,2669,2670],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2502,"description":2507},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[337,2678,2679],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2682,"title":2683,"body":2684,"category":337,"cover":338,"description":2688,"extension":339,"meta":2863,"navigation":116,"path":2864,"pinned":342,"publishedAt":343,"seo":2865,"slug":2866,"stem":2867,"summary":2868,"tags":2869,"updatedAt":343,"visible":116,"__hash__":2872},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2685,"toc":2851},[2686,2689,2691,2694,2696,2702,2712,2714,2725,2727,2729,2759,2761,2767,2769,2771,2801,2803,2806,2812,2815,2817,2825,2827,2842,2844,2846,2849],[10,2687,2688],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2690,16],{"id":16},[10,2692,2693],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2695,22],{"id":22},[10,2697,2698],{},[26,2699],{"alt":2700,"src":2701},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2703,2704,2705,2708,2709,211],{},"切片 ",[34,2706,2707],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[34,2710,2711],{},"stop - start",[14,2713,44],{"id":44},[46,2715,2716,2719,2722],{},[49,2717,2718],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[49,2720,2721],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[49,2723,2724],{},"切片会创建新的字符串，不会修改原字符串。",[14,2726,66],{"id":66},[10,2728,69],{},[71,2730,2732],{"className":73,"code":2731,"language":75,"meta":76,"style":76},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[34,2733,2734,2739,2744,2749,2754],{"__ignoreMap":76},[80,2735,2736],{"class":82,"line":83},[80,2737,2738],{},"language = \"Python\"\n",[80,2740,2741],{"class":82,"line":89},[80,2742,2743],{},"print(language[0])\n",[80,2745,2746],{"class":82,"line":95},[80,2747,2748],{},"print(language[-1])\n",[80,2750,2751],{"class":82,"line":101},[80,2752,2753],{},"print(language[0:3])\n",[80,2755,2756],{"class":82,"line":107},[80,2757,2758],{},"print(language + \" 3.14\")\n",[10,2760,168],{},[71,2762,2765],{"className":2763,"code":2764,"language":174,"meta":76},[172],"P\nn\nPyt\nPython 3.14\n",[34,2766,2764],{"__ignoreMap":76},[10,2768,179],{},[14,2770,182],{"id":182},[184,2772,2773,2787],{},[49,2774,2775,2776,2778,2779,2782,2783,2786],{},"字符串 ",[34,2777,337],{}," 的正索引从 ",[34,2780,2781],{},"P"," 的 0 开始，负索引从末尾 ",[34,2784,2785],{},"n"," 的 -1 开始。",[49,2788,2789,2792,2793,2796,2797,2800],{},[34,2790,2791],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[34,2794,2795],{},"Pyt","；索引 3 的 ",[34,2798,2799],{},"h"," 不在结果中。",[213,2802,215],{"id":215},[10,2804,2805],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2807,2808],{},[26,2809],{"alt":2810,"src":2811},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2813,2814],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2816,270],{"id":270},[46,2818,2819,2822],{},[49,2820,2821],{},"把第一个字符写成索引 1，造成整体偏移一位。",[49,2823,2824],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2826,288],{"id":288},[184,2828,2829,2839],{},[49,2830,2831,2832,2835,2836,211],{},"从 ",[34,2833,2834],{},"\"programming\""," 中切出 ",[34,2837,2838],{},"\"gram\"",[49,2840,2841],{},"使用负索引取得字符串倒数第二个字符。",[10,2843,313],{},[14,2845,316],{"id":316},[10,2847,2848],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,2850,323],{},{"title":76,"searchDepth":89,"depth":89,"links":2852},[2853,2854,2855,2856,2857,2860,2861,2862],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":2858},[2859],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2683,"description":2688},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[337,2870,2871],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2874,"title":2875,"body":2876,"category":337,"cover":338,"description":2880,"extension":339,"meta":3094,"navigation":116,"path":3095,"pinned":342,"publishedAt":343,"seo":3096,"slug":3097,"stem":3098,"summary":3099,"tags":3100,"updatedAt":343,"visible":116,"__hash__":3103},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2877,"toc":3082},[2878,2881,2883,2886,2888,2894,2904,2906,2939,2941,2943,2987,2989,2995,2997,2999,3020,3022,3025,3031,3039,3041,3055,3057,3073,3075,3077,3080],[10,2879,2880],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2882,16],{"id":16},[10,2884,2885],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2887,22],{"id":22},[10,2889,2890],{},[26,2891],{"alt":2892,"src":2893},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2895,2896,2897,1119,2900,2903],{},"比较表达式先产生 ",[34,2898,2899],{},"True",[34,2901,2902],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2905,44],{"id":44},[46,2907,2908,2922,2936],{},[49,2909,2910,2913,2914,2917,2918,2921],{},[34,2911,2912],{},"=="," 判断是否相等，",[34,2915,2916],{},"!="," 判断是否不等；单个 ",[34,2919,2920],{},"="," 是赋值。",[49,2923,2924,2927,2928,2931,2932,2935],{},[34,2925,2926],{},"and"," 要求两侧都为真，",[34,2929,2930],{},"or"," 只需一侧为真，",[34,2933,2934],{},"not"," 取反。",[49,2937,2938],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2940,66],{"id":66},[10,2942,69],{},[71,2944,2946],{"className":73,"code":2945,"language":75,"meta":76,"style":76},"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",[34,2947,2948,2953,2958,2962,2967,2972,2977,2982],{"__ignoreMap":76},[80,2949,2950],{"class":82,"line":83},[80,2951,2952],{},"age = 20\n",[80,2954,2955],{"class":82,"line":89},[80,2956,2957],{},"has_ticket = True\n",[80,2959,2960],{"class":82,"line":95},[80,2961,117],{"emptyLinePlaceholder":116},[80,2963,2964],{"class":82,"line":101},[80,2965,2966],{},"is_adult = age >= 18\n",[80,2968,2969],{"class":82,"line":107},[80,2970,2971],{},"can_enter = is_adult and has_ticket\n",[80,2973,2974],{"class":82,"line":113},[80,2975,2976],{},"print(is_adult)\n",[80,2978,2979],{"class":82,"line":120},[80,2980,2981],{},"print(can_enter)\n",[80,2983,2984],{"class":82,"line":126},[80,2985,2986],{},"print(not has_ticket)\n",[10,2988,168],{},[71,2990,2993],{"className":2991,"code":2992,"language":174,"meta":76},[172],"True\nTrue\nFalse\n",[34,2994,2992],{"__ignoreMap":76},[10,2996,179],{},[14,2998,182],{"id":182},[184,3000,3001,3011],{},[49,3002,3003,3006,3007,3010],{},[34,3004,3005],{},"age >= 18"," 先产生布尔值并绑定给 ",[34,3008,3009],{},"is_adult","，这一步没有任何分支跳转。",[49,3012,3013,3016,3017,3019],{},[34,3014,3015],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[34,3018,2934],{}," 只对紧随其后的值取反。",[213,3021,215],{"id":215},[10,3023,3024],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,3026,3027],{},[26,3028],{"alt":3029,"src":3030},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,3032,3033,3035,3036,3038],{},[34,3034,2926],{}," 只有“真、真”得到真；",[34,3037,2930],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,3040,270],{"id":270},[46,3042,3043,3052],{},[49,3044,3045,3046,3048,3049,3051],{},"用单个等号判断相等。",[34,3047,2920],{}," 是赋值，",[34,3050,2912],{}," 才是相等比较。",[49,3053,3054],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,3056,288],{"id":288},[184,3058,3059,3066],{},[49,3060,3061,3062,3065],{},"判断数字 ",[34,3063,3064],{},"15"," 是否同时大于 10 且小于 20。",[49,3067,3068,3069,3072],{},"分别修改年龄和票据状态，记录 ",[34,3070,3071],{},"can_enter"," 的四种组合结果。",[10,3074,313],{},[14,3076,316],{"id":316},[10,3078,3079],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,3081,323],{},{"title":76,"searchDepth":89,"depth":89,"links":3083},[3084,3085,3086,3087,3088,3091,3092,3093],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":3089},[3090],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2875,"description":2880},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[337,3101,3102],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3105,"title":3106,"body":3107,"category":337,"cover":338,"description":3111,"extension":339,"meta":3278,"navigation":116,"path":3279,"pinned":342,"publishedAt":343,"seo":3280,"slug":3281,"stem":3282,"summary":3283,"tags":3284,"updatedAt":343,"visible":116,"__hash__":3286},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3108,"toc":3268},[3109,3112,3114,3117,3119,3125,3142,3144,3157,3159,3161,3195,3197,3203,3205,3207,3229,3231,3243,3245,3259,3261,3263,3266],[10,3110,3111],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3113,16],{"id":16},[10,3115,3116],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3118,22],{"id":22},[10,3120,3121],{},[26,3122],{"alt":3123,"src":3124},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3126,3127,3130,3131,3134,3135,3138,3139,3141],{},[34,3128,3129],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[34,3132,3133],{},"18","，程序首先得到的也是 ",[34,3136,3137],{},"\"18\"","，需要 ",[34,3140,190],{}," 后才能按整数参与计算。",[14,3143,44],{"id":44},[46,3145,3146,3149,3154],{},[49,3147,3148],{},"提示文字应告诉用户需要输入什么。",[49,3150,3151,3153],{},[34,3152,190],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[49,3155,3156],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3158,66],{"id":66},[10,3160,69],{},[71,3162,3164],{"className":73,"code":3163,"language":75,"meta":76,"style":76},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[34,3165,3166,3171,3176,3181,3185,3190],{"__ignoreMap":76},[80,3167,3168],{"class":82,"line":83},[80,3169,3170],{},"name = input(\"请输入姓名：\")\n",[80,3172,3173],{"class":82,"line":89},[80,3174,3175],{},"age_text = input(\"请输入年龄：\")\n",[80,3177,3178],{"class":82,"line":95},[80,3179,3180],{},"age = int(age_text)\n",[80,3182,3183],{"class":82,"line":101},[80,3184,117],{"emptyLinePlaceholder":116},[80,3186,3187],{"class":82,"line":107},[80,3188,3189],{},"print(\"你好，\" + name)\n",[80,3191,3192],{"class":82,"line":113},[80,3193,3194],{},"print(age + 1)\n",[10,3196,168],{},[71,3198,3201],{"className":3199,"code":3200,"language":174,"meta":76},[172],"根据输入显示姓名，并输出下一年的年龄\n",[34,3202,3200],{"__ignoreMap":76},[10,3204,179],{},[14,3206,182],{"id":182},[184,3208,3209,3219],{},[49,3210,3211,3212,3214,3215,3218],{},"两次 ",[34,3213,3129],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[34,3216,3217],{},"age_text"," 用来提醒这仍是文本。",[49,3220,3221,3224,3225,3228],{},[34,3222,3223],{},"int(age_text)"," 创建整数对象，后面的 ",[34,3226,3227],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3230,270],{"id":270},[46,3232,3233,3240],{},[49,3234,3235,3236,3239],{},"直接计算 ",[34,3237,3238],{},"input(...) + 1","，忽略输入结果是字符串。",[49,3241,3242],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3244,288],{"id":288},[184,3246,3247,3250],{},[49,3248,3249],{},"接收两个整数并输出它们的和。",[49,3251,1827,3252,3255,3256,3258],{},[34,3253,3254],{},"18.5"," 给 ",[34,3257,190],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3260,313],{},[14,3262,316],{"id":316},[10,3264,3265],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,3267,323],{},{"title":76,"searchDepth":89,"depth":89,"links":3269},[3270,3271,3272,3273,3274,3275,3276,3277],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3106,"description":3111},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[337,2452,3285],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3288,"title":3289,"body":3290,"category":337,"cover":338,"description":3294,"extension":339,"meta":3454,"navigation":116,"path":3455,"pinned":342,"publishedAt":343,"seo":3456,"slug":3457,"stem":3458,"summary":3459,"tags":3460,"updatedAt":343,"visible":116,"__hash__":3463},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3291,"toc":3444},[3292,3295,3297,3300,3302,3308,3315,3317,3331,3333,3335,3374,3376,3382,3384,3386,3405,3407,3422,3424,3435,3437,3439,3442],[10,3293,3294],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3296,16],{"id":16},[10,3298,3299],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3301,22],{"id":22},[10,3303,3304],{},[26,3305],{"alt":3306,"src":3307},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3309,3310,3311,3314],{},"列表为元素维护从 0 开始的位置索引。修改 ",[34,3312,3313],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3316,44],{"id":44},[46,3318,3319,3322,3325],{},[49,3320,3321],{},"列表使用方括号，元素之间用逗号分隔。",[49,3323,3324],{},"列表可变，可以替换、追加和删除元素。",[49,3326,3327,3328,211],{},"访问不存在的索引会产生 ",[34,3329,3330],{},"IndexError",[14,3332,66],{"id":66},[10,3334,69],{},[71,3336,3338],{"className":73,"code":3337,"language":75,"meta":76,"style":76},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[34,3339,3340,3345,3350,3354,3359,3364,3369],{"__ignoreMap":76},[80,3341,3342],{"class":82,"line":83},[80,3343,3344],{},"scores = [82, 90, 76]\n",[80,3346,3347],{"class":82,"line":89},[80,3348,3349],{},"print(scores[0])\n",[80,3351,3352],{"class":82,"line":95},[80,3353,117],{"emptyLinePlaceholder":116},[80,3355,3356],{"class":82,"line":101},[80,3357,3358],{},"scores[1] = 95\n",[80,3360,3361],{"class":82,"line":107},[80,3362,3363],{},"scores.append(88)\n",[80,3365,3366],{"class":82,"line":113},[80,3367,3368],{},"print(scores)\n",[80,3370,3371],{"class":82,"line":120},[80,3372,3373],{},"print(len(scores))\n",[10,3375,168],{},[71,3377,3380],{"className":3378,"code":3379,"language":174,"meta":76},[172],"82\n[82, 95, 76, 88]\n4\n",[34,3381,3379],{"__ignoreMap":76},[10,3383,179],{},[14,3385,182],{"id":182},[184,3387,3388,3391],{},[49,3389,3390],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[49,3392,3393,3396,3397,3400,3401,3404],{},[34,3394,3395],{},"scores[1] = 95"," 替换第二个位置，",[34,3398,3399],{},"append(88)"," 在末尾增加新位置，",[34,3402,3403],{},"len()"," 因而从 3 变为 4。",[14,3406,270],{"id":270},[46,3408,3409,3419],{},[49,3410,3411,3412,3415,3416,211],{},"访问 ",[34,3413,3414],{},"scores[len(scores)]","。最后一个合法正索引是 ",[34,3417,3418],{},"len(scores) - 1",[49,3420,3421],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3423,288],{"id":288},[184,3425,3426,3429],{},[49,3427,3428],{},"建立三项学习任务列表，再追加第四项。",[49,3430,3431,3432,3434],{},"修改第二项，并用 ",[34,3433,3403],{}," 检查元素数量。",[10,3436,313],{},[14,3438,316],{"id":316},[10,3440,3441],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,3443,323],{},{"title":76,"searchDepth":89,"depth":89,"links":3445},[3446,3447,3448,3449,3450,3451,3452,3453],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3289,"description":3294},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[337,3461,3462],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3465,"title":3466,"body":3467,"category":337,"cover":338,"description":3471,"extension":339,"meta":3612,"navigation":116,"path":3613,"pinned":342,"publishedAt":343,"seo":3614,"slug":3615,"stem":3616,"summary":3617,"tags":3618,"updatedAt":343,"visible":116,"__hash__":3620},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3468,"toc":3602},[3469,3472,3474,3477,3479,3485,3488,3490,3501,3503,3505,3539,3541,3547,3549,3551,3565,3567,3579,3581,3593,3595,3597,3600],[10,3470,3471],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3473,16],{"id":16},[10,3475,3476],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3478,22],{"id":22},[10,3480,3481],{},[26,3482],{"alt":3483,"src":3484},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3486,3487],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3489,44],{"id":44},[46,3491,3492,3495,3498],{},[49,3493,3494],{},"元组常用来表达固定数量、固定含义的一组值。",[49,3496,3497],{},"只有一个元素的元组必须保留尾随逗号。",[49,3499,3500],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3502,66],{"id":66},[10,3504,69],{},[71,3506,3508],{"className":73,"code":3507,"language":75,"meta":76,"style":76},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[34,3509,3510,3515,3520,3525,3529,3534],{"__ignoreMap":76},[80,3511,3512],{"class":82,"line":83},[80,3513,3514],{},"point = (120, 80)\n",[80,3516,3517],{"class":82,"line":89},[80,3518,3519],{},"print(point[0])\n",[80,3521,3522],{"class":82,"line":95},[80,3523,3524],{},"print(point[1])\n",[80,3526,3527],{"class":82,"line":101},[80,3528,117],{"emptyLinePlaceholder":116},[80,3530,3531],{"class":82,"line":107},[80,3532,3533],{},"single = (5,)\n",[80,3535,3536],{"class":82,"line":113},[80,3537,3538],{},"print(single)\n",[10,3540,168],{},[71,3542,3545],{"className":3543,"code":3544,"language":174,"meta":76},[172],"120\n80\n(5,)\n",[34,3546,3544],{"__ignoreMap":76},[10,3548,179],{},[14,3550,182],{"id":182},[184,3552,3553,3559],{},[49,3554,3555,3558],{},[34,3556,3557],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[49,3560,3561,3564],{},[34,3562,3563],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3566,270],{"id":270},[46,3568,3569,3576],{},[49,3570,3571,3572,3575],{},"把 ",[34,3573,3574],{},"(5)"," 当作元组，实际它仍是整数。",[49,3577,3578],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3580,288],{"id":288},[184,3582,3583,3586],{},[49,3584,3585],{},"用元组表示宽度和高度。",[49,3587,2280,3588,2283,3590,3592],{},[34,3589,3574],{},[34,3591,3563],{}," 的类型。",[10,3594,313],{},[14,3596,316],{"id":316},[10,3598,3599],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,3601,323],{},{"title":76,"searchDepth":89,"depth":89,"links":3603},[3604,3605,3606,3607,3608,3609,3610,3611],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3466,"description":3471},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[337,3619,3462],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3622,"title":3623,"body":3624,"category":337,"cover":338,"description":3628,"extension":339,"meta":3783,"navigation":116,"path":3784,"pinned":342,"publishedAt":343,"seo":3785,"slug":3786,"stem":3787,"summary":3788,"tags":3789,"updatedAt":343,"visible":116,"__hash__":3791},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3625,"toc":3773},[3626,3629,3631,3634,3636,3642,3652,3654,3668,3670,3672,3706,3708,3714,3716,3718,3733,3735,3754,3756,3764,3766,3768,3771],[10,3627,3628],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3630,16],{"id":16},[10,3632,3633],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3635,22],{"id":22},[10,3637,3638],{},[26,3639],{"alt":3640,"src":3641},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3643,3644,3645,3648,3649,3651],{},"字典通过键定位值，不使用连续位置表达含义。",[34,3646,3647],{},"student[\"score\"]"," 读取的是键 ",[34,3650,2353],{}," 对应的值，而不是“第几个元素”。",[14,3653,44],{"id":44},[46,3655,3656,3659,3665],{},[49,3657,3658],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[49,3660,2445,3661,3664],{},[34,3662,3663],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[49,3666,3667],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3669,66],{"id":66},[10,3671,69],{},[71,3673,3675],{"className":73,"code":3674,"language":75,"meta":76,"style":76},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[34,3676,3677,3682,3687,3691,3696,3701],{"__ignoreMap":76},[80,3678,3679],{"class":82,"line":83},[80,3680,3681],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[80,3683,3684],{"class":82,"line":89},[80,3685,3686],{},"print(student[\"name\"])\n",[80,3688,3689],{"class":82,"line":95},[80,3690,117],{"emptyLinePlaceholder":116},[80,3692,3693],{"class":82,"line":101},[80,3694,3695],{},"student[\"score\"] = 95\n",[80,3697,3698],{"class":82,"line":107},[80,3699,3700],{},"student[\"city\"] = \"郑州\"\n",[80,3702,3703],{"class":82,"line":113},[80,3704,3705],{},"print(student)\n",[10,3707,168],{},[71,3709,3712],{"className":3710,"code":3711,"language":174,"meta":76},[172],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[34,3713,3711],{"__ignoreMap":76},[10,3715,179],{},[14,3717,182],{"id":182},[184,3719,3720,3723],{},[49,3721,3722],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[49,3724,3725,3726,3728,3729,3732],{},"给已有键 ",[34,3727,2353],{}," 赋值会更新映射，给新键 ",[34,3730,3731],{},"city"," 赋值会增加映射。",[14,3734,270],{"id":270},[46,3736,3737,3744],{},[49,3738,3739,3740,3743],{},"按位置理解字典并尝试 ",[34,3741,3742],{},"student[0]","，而实际键是字符串。",[49,3745,3746,3747,3750,3751,211],{},"直接读取不确定存在的键并忽略 ",[34,3748,3749],{},"KeyError","；后续可根据场景使用成员检查或 ",[34,3752,3753],{},"get()",[14,3755,288],{"id":288},[184,3757,3758,3761],{},[49,3759,3760],{},"建立一本书的标题、作者和页数字典。",[49,3762,3763],{},"添加分类键，再修改页数。",[10,3765,313],{},[14,3767,316],{"id":316},[10,3769,3770],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,3772,323],{},{"title":76,"searchDepth":89,"depth":89,"links":3774},[3775,3776,3777,3778,3779,3780,3781,3782],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3623,"description":3628},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[337,3790,3462],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3793,"title":3794,"body":3795,"category":337,"cover":338,"description":3799,"extension":339,"meta":3948,"navigation":116,"path":3949,"pinned":342,"publishedAt":343,"seo":3950,"slug":3951,"stem":3952,"summary":3953,"tags":3954,"updatedAt":343,"visible":116,"__hash__":3956},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3796,"toc":3938},[3797,3800,3802,3805,3807,3813,3816,3818,3837,3839,3841,3875,3877,3883,3885,3887,3902,3904,3916,3918,3929,3931,3933,3936],[10,3798,3799],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3801,16],{"id":16},[10,3803,3804],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3806,22],{"id":22},[10,3808,3809],{},[26,3810],{"alt":3811,"src":3812},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3814,3815],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3817,44],{"id":44},[46,3819,3820,3823,3826],{},[49,3821,3822],{},"集合中的元素不重复。",[49,3824,3825],{},"集合是无序容器，不要依赖打印顺序或索引。",[49,3827,3828,3829,3832,3833,3836],{},"创建空集合必须写 ",[34,3830,3831],{},"set()","；",[34,3834,3835],{},"{}"," 创建的是空字典。",[14,3838,66],{"id":66},[10,3840,69],{},[71,3842,3844],{"className":73,"code":3843,"language":75,"meta":76,"style":76},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[34,3845,3846,3851,3856,3860,3865,3870],{"__ignoreMap":76},[80,3847,3848],{"class":82,"line":83},[80,3849,3850],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[80,3852,3853],{"class":82,"line":89},[80,3854,3855],{},"right = {\"Python\", \"Docker\"}\n",[80,3857,3858],{"class":82,"line":95},[80,3859,117],{"emptyLinePlaceholder":116},[80,3861,3862],{"class":82,"line":101},[80,3863,3864],{},"print(left & right)\n",[80,3866,3867],{"class":82,"line":107},[80,3868,3869],{},"print(left | right)\n",[80,3871,3872],{"class":82,"line":113},[80,3873,3874],{},"print(\"Git\" in left)\n",[10,3876,168],{},[71,3878,3881],{"className":3879,"code":3880,"language":174,"meta":76},[172],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[34,3882,3880],{"__ignoreMap":76},[10,3884,179],{},[14,3886,182],{"id":182},[184,3888,3889,3892],{},[49,3890,3891],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[49,3893,3894,3897,3898,3901],{},[34,3895,3896],{},"&"," 计算交集，",[34,3899,3900],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3903,270],{"id":270},[46,3905,3906,3913],{},[49,3907,2445,3908,3910,3911,211],{},[34,3909,3835],{}," 创建空集合，实际得到空字典；空集合应写 ",[34,3912,3831],{},[49,3914,3915],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3917,288],{"id":288},[184,3919,3920,3926],{},[49,3921,3922,3923,3925],{},"把包含重复标签的列表交给 ",[34,3924,3831],{}," 去重。",[49,3927,3928],{},"计算两组课程标签的交集和差集。",[10,3930,313],{},[14,3932,316],{"id":316},[10,3934,3935],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,3937,323],{},{"title":76,"searchDepth":89,"depth":89,"links":3939},[3940,3941,3942,3943,3944,3945,3946,3947],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3794,"description":3799},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[337,3955,3462],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3958,"title":3959,"body":3960,"category":337,"cover":338,"description":3964,"extension":339,"meta":4161,"navigation":116,"path":4162,"pinned":342,"publishedAt":343,"seo":4163,"slug":4164,"stem":4165,"summary":4166,"tags":4167,"updatedAt":343,"visible":116,"__hash__":4170},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3961,"toc":4149},[3962,3965,3967,3970,3972,3978,3988,3990,4007,4009,4011,4060,4062,4068,4070,4072,4094,4096,4099,4105,4108,4110,4123,4125,4140,4142,4144,4147],[10,3963,3964],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3966,16],{"id":16},[10,3968,3969],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3971,22],{"id":22},[10,3973,3974],{},[26,3975],{"alt":3976,"src":3977},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3979,3980,3983,3984,3987],{},[34,3981,3982],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[34,3985,3986],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3989,44],{"id":44},[46,3991,3992,4001,4004],{},[49,3993,3994,3996,3997,4000],{},[34,3995,2912],{}," 比较内容是否相等，",[34,3998,3999],{},"is"," 比较是否为同一个对象。",[49,4002,4003],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[49,4005,4006],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,4008,66],{"id":66},[10,4010,69],{},[71,4012,4014],{"className":73,"code":4013,"language":75,"meta":76,"style":76},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[34,4015,4016,4021,4026,4031,4035,4040,4045,4050,4055],{"__ignoreMap":76},[80,4017,4018],{"class":82,"line":83},[80,4019,4020],{},"tasks = [\"变量\", \"字符串\"]\n",[80,4022,4023],{"class":82,"line":89},[80,4024,4025],{},"shared = tasks\n",[80,4027,4028],{"class":82,"line":95},[80,4029,4030],{},"backup = tasks.copy()\n",[80,4032,4033],{"class":82,"line":101},[80,4034,117],{"emptyLinePlaceholder":116},[80,4036,4037],{"class":82,"line":107},[80,4038,4039],{},"tasks.append(\"列表\")\n",[80,4041,4042],{"class":82,"line":113},[80,4043,4044],{},"print(shared)\n",[80,4046,4047],{"class":82,"line":120},[80,4048,4049],{},"print(backup)\n",[80,4051,4052],{"class":82,"line":126},[80,4053,4054],{},"print(tasks is shared)\n",[80,4056,4057],{"class":82,"line":132},[80,4058,4059],{},"print(tasks is backup)\n",[10,4061,168],{},[71,4063,4066],{"className":4064,"code":4065,"language":174,"meta":76},[172],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[34,4067,4065],{"__ignoreMap":76},[10,4069,179],{},[14,4071,182],{"id":182},[184,4073,4074,4080],{},[49,4075,4076,4079],{},[34,4077,4078],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[49,4081,4082,4085,4086,4089,4090,4093],{},[34,4083,4084],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[34,4087,4088],{},"shared"," 能观察到变化，",[34,4091,4092],{},"backup"," 不会。",[213,4095,215],{"id":215},[10,4097,4098],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4100,4101],{},[26,4102],{"alt":4103,"src":4104},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4106,4107],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4109,270],{"id":270},[46,4111,4112,4120],{},[49,4113,4114,4115,4117,4118,211],{},"用 ",[34,4116,2912],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[34,4119,3999],{},[49,4121,4122],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4124,288],{"id":288},[184,4126,4127,4130],{},[49,4128,4129],{},"让两个变量引用同一个字典并修改其中一个。",[49,4131,2445,4132,4135,4136,223,4138,211],{},[34,4133,4134],{},"copy()"," 创建外层副本，再比较 ",[34,4137,3999],{},[34,4139,2912],{},[10,4141,313],{},[14,4143,316],{"id":316},[10,4145,4146],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,4148,323],{},{"title":76,"searchDepth":89,"depth":89,"links":4150},[4151,4152,4153,4154,4155,4158,4159,4160],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":4156},[4157],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3959,"description":3964},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[337,4168,4169],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4172,"title":4173,"body":4174,"category":337,"cover":338,"description":4178,"extension":339,"meta":4389,"navigation":116,"path":4390,"pinned":342,"publishedAt":343,"seo":4391,"slug":4392,"stem":4393,"summary":4394,"tags":4395,"updatedAt":343,"visible":116,"__hash__":4397},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4175,"toc":4376},[4176,4179,4181,4184,4186,4192,4202,4204,4215,4217,4219,4271,4273,4279,4281,4283,4301,4303,4306,4312,4320,4322,4325,4331,4337,4339,4357,4359,4367,4369,4371,4374],[10,4177,4178],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4180,16],{"id":16},[10,4182,4183],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4185,22],{"id":22},[10,4187,4188],{},[26,4189],{"alt":4190,"src":4191},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4193,4194,220,4196,220,4199,4201],{},[34,4195,1265],{},[34,4197,4198],{},"elif",[34,4200,207],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4203,44],{"id":44},[46,4205,4206,4209,4212],{},[49,4207,4208],{},"冒号表示接下来开始一个代码块。",[49,4210,4211],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[49,4213,4214],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4216,66],{"id":66},[10,4218,69],{},[71,4220,4222],{"className":73,"code":4221,"language":75,"meta":76,"style":76},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[34,4223,4224,4229,4233,4238,4243,4248,4253,4257,4262,4266],{"__ignoreMap":76},[80,4225,4226],{"class":82,"line":83},[80,4227,4228],{},"score = int(input(\"请输入分数：\"))\n",[80,4230,4231],{"class":82,"line":89},[80,4232,117],{"emptyLinePlaceholder":116},[80,4234,4235],{"class":82,"line":95},[80,4236,4237],{},"if score >= 90:\n",[80,4239,4240],{"class":82,"line":101},[80,4241,4242],{},"    level = \"优秀\"\n",[80,4244,4245],{"class":82,"line":107},[80,4246,4247],{},"elif score >= 60:\n",[80,4249,4250],{"class":82,"line":113},[80,4251,4252],{},"    level = \"合格\"\n",[80,4254,4255],{"class":82,"line":120},[80,4256,147],{},[80,4258,4259],{"class":82,"line":126},[80,4260,4261],{},"    level = \"需要继续学习\"\n",[80,4263,4264],{"class":82,"line":132},[80,4265,117],{"emptyLinePlaceholder":116},[80,4267,4268],{"class":82,"line":138},[80,4269,4270],{},"print(level)\n",[10,4272,168],{},[71,4274,4277],{"className":4275,"code":4276,"language":174,"meta":76},[172],"输入 85 时输出：合格\n",[34,4278,4276],{"__ignoreMap":76},[10,4280,179],{},[14,4282,182],{"id":182},[184,4284,4285,4292],{},[49,4286,4287,4288,4291],{},"输入先转换为整数，程序从 ",[34,4289,4290],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[49,4293,4294,4297,4298,4300],{},[34,4295,4296],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[34,4299,207],{}," 被跳过；最终三个分支只会选择一个。",[213,4302,215],{"id":215},[10,4304,4305],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4307,4308],{},[26,4309],{"alt":4310,"src":4311},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4313,4314,4316,4317,4319],{},[34,4315,4290],{}," 必须放在 ",[34,4318,4296],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[213,4321,215],{"id":246},[10,4323,4324],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4326,4327],{},[26,4328],{"alt":4329,"src":4330},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4332,4333,4334,4336],{},"同一缩进层级属于同一个代码块；回到 ",[34,4335,1265],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4338,270],{"id":270},[46,4340,4341,4347],{},[49,4342,4343,4344,4346],{},"先写 ",[34,4345,4296],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[49,4348,4349,4350,4352,4353,4356],{},"混用多个独立 ",[34,4351,1265],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[34,4354,4355],{},"if\u002Felif\u002Felse"," 链。",[14,4358,288],{"id":288},[184,4360,4361,4364],{},[49,4362,4363],{},"根据温度输出“冷、适中、热”三个等级。",[49,4365,4366],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4368,313],{},[14,4370,316],{"id":316},[10,4372,4373],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,4375,323],{},{"title":76,"searchDepth":89,"depth":89,"links":4377},[4378,4379,4380,4381,4382,4386,4387,4388],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":4383},[4384,4385],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4173,"description":4178},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[337,1265,4396],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4399,"title":4400,"body":4401,"category":337,"cover":338,"description":4405,"extension":339,"meta":4571,"navigation":116,"path":4572,"pinned":342,"publishedAt":343,"seo":4573,"slug":4574,"stem":4575,"summary":4576,"tags":4577,"updatedAt":343,"visible":116,"__hash__":4579},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4402,"toc":4559},[4403,4406,4408,4411,4413,4419,4425,4427,4442,4444,4446,4484,4486,4492,4494,4496,4511,4513,4516,4522,4528,4530,4538,4540,4550,4552,4554,4557],[10,4404,4405],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4407,16],{"id":16},[10,4409,4410],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4412,22],{"id":22},[10,4414,4415],{},[26,4416],{"alt":4417,"src":4418},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4420,4421,4424],{},[34,4422,4423],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4426,44],{"id":44},[46,4428,4429,4432,4435],{},[49,4430,4431],{},"进入循环前先准备参与条件判断的状态。",[49,4433,4434],{},"循环体中必须有机会让条件变为假。",[49,4436,4437,4438,4441],{},"能够预先确定遍历对象时，后续介绍的 ",[34,4439,4440],{},"for"," 通常更直接。",[14,4443,66],{"id":66},[10,4445,69],{},[71,4447,4449],{"className":73,"code":4448,"language":75,"meta":76,"style":76},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[34,4450,4451,4456,4460,4465,4470,4475,4479],{"__ignoreMap":76},[80,4452,4453],{"class":82,"line":83},[80,4454,4455],{},"count = 1\n",[80,4457,4458],{"class":82,"line":89},[80,4459,117],{"emptyLinePlaceholder":116},[80,4461,4462],{"class":82,"line":95},[80,4463,4464],{},"while count \u003C= 3:\n",[80,4466,4467],{"class":82,"line":101},[80,4468,4469],{},"    print(\"第\", count, \"次练习\")\n",[80,4471,4472],{"class":82,"line":107},[80,4473,4474],{},"    count = count + 1\n",[80,4476,4477],{"class":82,"line":113},[80,4478,117],{"emptyLinePlaceholder":116},[80,4480,4481],{"class":82,"line":120},[80,4482,4483],{},"print(\"练习结束\")\n",[10,4485,168],{},[71,4487,4490],{"className":4488,"code":4489,"language":174,"meta":76},[172],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[34,4491,4489],{"__ignoreMap":76},[10,4493,179],{},[14,4495,182],{"id":182},[184,4497,4498,4505],{},[49,4499,4500,4501,4504],{},"进入循环前 ",[34,4502,4503],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[49,4506,4507,4508,4510],{},"循环体末尾把 ",[34,4509,4503],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[213,4512,215],{"id":215},[10,4514,4515],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4517,4518],{},[26,4519],{"alt":4520,"src":4521},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4523,4524,4525,4527],{},"第4次检查时 ",[34,4526,4503],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4529,270],{"id":270},[46,4531,4532,4535],{},[49,4533,4534],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[49,4536,4537],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4539,288],{"id":288},[184,4541,4542,4547],{},[49,4543,2445,4544,4546],{},[34,4545,4423],{}," 输出 1 到 5。",[49,4548,4549],{},"计算 1 到 10 的累加和。",[10,4551,313],{},[14,4553,316],{"id":316},[10,4555,4556],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,4558,323],{},{"title":76,"searchDepth":89,"depth":89,"links":4560},[4561,4562,4563,4564,4565,4568,4569,4570],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":4566},[4567],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4400,"description":4405},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[337,4423,4578],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4581,"title":4582,"body":4583,"category":337,"cover":338,"description":4587,"extension":339,"meta":4735,"navigation":116,"path":4736,"pinned":342,"publishedAt":343,"seo":4737,"slug":4738,"stem":4739,"summary":4740,"tags":4741,"updatedAt":343,"visible":116,"__hash__":4743},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4584,"toc":4725},[4585,4588,4590,4593,4595,4601,4606,4608,4622,4624,4626,4664,4666,4672,4674,4676,4693,4695,4703,4705,4716,4718,4720,4723],[10,4586,4587],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4589,16],{"id":16},[10,4591,4592],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4594,22],{"id":22},[10,4596,4597],{},[26,4598],{"alt":4599,"src":4600},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4602,4603,4605],{},[34,4604,4440],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4607,44],{"id":44},[46,4609,4610,4616,4619],{},[49,4611,4612,4615],{},[34,4613,4614],{},"range(1, 4)"," 包含 1，不包含 4。",[49,4617,4618],{},"只需要元素时直接遍历元素，不必手工维护索引。",[49,4620,4621],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4623,66],{"id":66},[10,4625,69],{},[71,4627,4629],{"className":73,"code":4628,"language":75,"meta":76,"style":76},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[34,4630,4631,4636,4640,4645,4650,4654,4659],{"__ignoreMap":76},[80,4632,4633],{"class":82,"line":83},[80,4634,4635],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[80,4637,4638],{"class":82,"line":89},[80,4639,117],{"emptyLinePlaceholder":116},[80,4641,4642],{"class":82,"line":95},[80,4643,4644],{},"for course in courses:\n",[80,4646,4647],{"class":82,"line":101},[80,4648,4649],{},"    print(course)\n",[80,4651,4652],{"class":82,"line":107},[80,4653,117],{"emptyLinePlaceholder":116},[80,4655,4656],{"class":82,"line":113},[80,4657,4658],{},"for number in range(1, 4):\n",[80,4660,4661],{"class":82,"line":120},[80,4662,4663],{},"    print(number)\n",[10,4665,168],{},[71,4667,4670],{"className":4668,"code":4669,"language":174,"meta":76},[172],"变量\n字符串\n列表\n1\n2\n3\n",[34,4671,4669],{"__ignoreMap":76},[10,4673,179],{},[14,4675,182],{"id":182},[184,4677,4678,4688],{},[49,4679,4680,4681,4683,4684,4687],{},"第一个 ",[34,4682,4440],{}," 依次从列表取得字符串，循环变量 ",[34,4685,4686],{},"course"," 每轮重新绑定。",[49,4689,4690,4692],{},[34,4691,4614],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4694,270],{"id":270},[46,4696,4697,4700],{},[49,4698,4699],{},"只需要元素却手工维护索引，增加越界风险。",[49,4701,4702],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4704,288],{"id":288},[184,4706,4707,4710],{},[49,4708,4709],{},"逐项输出一个字符串中的字符。",[49,4711,2445,4712,4715],{},[34,4713,4714],{},"range()"," 输出 2、4、6、8。",[10,4717,313],{},[14,4719,316],{"id":316},[10,4721,4722],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,4724,323],{},{"title":76,"searchDepth":89,"depth":89,"links":4726},[4727,4728,4729,4730,4731,4732,4733,4734],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4582,"description":4587},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[337,4440,4742],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4745,"title":4746,"body":4747,"category":337,"cover":338,"description":4751,"extension":339,"meta":4925,"navigation":116,"path":4926,"pinned":342,"publishedAt":343,"seo":4927,"slug":4928,"stem":4929,"summary":4930,"tags":4931,"updatedAt":343,"visible":116,"__hash__":4932},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4748,"toc":4915},[4749,4752,4754,4757,4759,4765,4775,4777,4796,4798,4800,4852,4854,4860,4862,4864,4878,4880,4896,4898,4906,4908,4910,4913],[10,4750,4751],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4753,16],{"id":16},[10,4755,4756],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4758,22],{"id":22},[10,4760,4761],{},[26,4762],{"alt":4763,"src":4764},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4766,4767,4770,4771,4774],{},[34,4768,4769],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[34,4772,4773],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4776,44],{"id":44},[46,4778,4779,4782,4790],{},[49,4780,4781],{},"先写普通循环，再在确有需要时加入流程控制语句。",[49,4783,4784,4786,4787,4789],{},[34,4785,4769],{}," 前要确认不会跳过 ",[34,4788,4423],{}," 循环中的状态更新。",[49,4791,4792,4793,4795],{},"多层嵌套中 ",[34,4794,4773],{}," 只结束它所在的最内层循环。",[14,4797,66],{"id":66},[10,4799,69],{},[71,4801,4803],{"className":73,"code":4802,"language":75,"meta":76,"style":76},"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",[34,4804,4805,4810,4814,4819,4824,4829,4834,4839,4843,4847],{"__ignoreMap":76},[80,4806,4807],{"class":82,"line":83},[80,4808,4809],{},"numbers = [3, -1, 0, 8, 12]\n",[80,4811,4812],{"class":82,"line":89},[80,4813,117],{"emptyLinePlaceholder":116},[80,4815,4816],{"class":82,"line":95},[80,4817,4818],{},"for number in numbers:\n",[80,4820,4821],{"class":82,"line":101},[80,4822,4823],{},"    if number \u003C 0:\n",[80,4825,4826],{"class":82,"line":107},[80,4827,4828],{},"        continue\n",[80,4830,4831],{"class":82,"line":113},[80,4832,4833],{},"    if number == 0:\n",[80,4835,4836],{"class":82,"line":120},[80,4837,4838],{},"        break\n",[80,4840,4841],{"class":82,"line":126},[80,4842,4663],{},[80,4844,4845],{"class":82,"line":132},[80,4846,117],{"emptyLinePlaceholder":116},[80,4848,4849],{"class":82,"line":138},[80,4850,4851],{},"print(\"循环结束\")\n",[10,4853,168],{},[71,4855,4858],{"className":4856,"code":4857,"language":174,"meta":76},[172],"3\n循环结束\n",[34,4859,4857],{"__ignoreMap":76},[10,4861,179],{},[14,4863,182],{"id":182},[184,4865,4866,4872],{},[49,4867,4868,4869,4871],{},"遇到 -1 时 ",[34,4870,4769],{}," 立即结束本轮，后面的判断和输出都不执行。",[49,4873,4874,4875,4877],{},"遇到 0 时 ",[34,4876,4773],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4879,270],{"id":270},[46,4881,4882,4887],{},[49,4883,3571,4884,4886],{},[34,4885,4769],{}," 当作结束循环，实际它只跳到下一轮。",[49,4888,4889,4890,4892,4893,4895],{},"在 ",[34,4891,4423],{}," 中把状态更新放在可能被 ",[34,4894,4769],{}," 跳过的位置，造成无限循环。",[14,4897,288],{"id":288},[184,4899,4900,4903],{},[49,4901,4902],{},"跳过列表中的空字符串并输出其他内容。",[49,4904,4905],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4907,313],{},[14,4909,316],{"id":316},[10,4911,4912],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,4914,323],{},{"title":76,"searchDepth":89,"depth":89,"links":4916},[4917,4918,4919,4920,4921,4922,4923,4924],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4746,"description":4751},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[337,4773,4769],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4934,"title":4935,"body":4936,"category":337,"cover":338,"description":4940,"extension":339,"meta":5111,"navigation":116,"path":5112,"pinned":342,"publishedAt":343,"seo":5113,"slug":5114,"stem":5115,"summary":5116,"tags":5117,"updatedAt":343,"visible":116,"__hash__":5120},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4937,"toc":5099},[4938,4941,4943,4946,4948,4954,4957,4959,4983,4985,4987,5021,5023,5029,5031,5033,5050,5052,5055,5061,5064,5066,5080,5082,5090,5092,5094,5097],[10,4939,4940],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4942,16],{"id":16},[10,4944,4945],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4947,22],{"id":22},[10,4949,4950],{},[26,4951],{"alt":4952,"src":4953},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4955,4956],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4958,44],{"id":44},[46,4960,4961,4964,4967],{},[49,4962,4963],{},"每增加一层嵌套，阅读成本都会上升。",[49,4965,4966],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[49,4968,4969,4970,220,4973,4976,4977,220,4980,211],{},"变量名使用 ",[34,4971,4972],{},"row",[34,4974,4975],{},"cell"," 等层级含义，避免全部写成 ",[34,4978,4979],{},"i",[34,4981,4982],{},"j",[14,4984,66],{"id":66},[10,4986,69],{},[71,4988,4990],{"className":73,"code":4989,"language":75,"meta":76,"style":76},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[34,4991,4992,4997,5001,5006,5011,5016],{"__ignoreMap":76},[80,4993,4994],{"class":82,"line":83},[80,4995,4996],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[80,4998,4999],{"class":82,"line":89},[80,5000,117],{"emptyLinePlaceholder":116},[80,5002,5003],{"class":82,"line":95},[80,5004,5005],{},"for row in table:\n",[80,5007,5008],{"class":82,"line":101},[80,5009,5010],{},"    for cell in row:\n",[80,5012,5013],{"class":82,"line":107},[80,5014,5015],{},"        print(cell)\n",[80,5017,5018],{"class":82,"line":113},[80,5019,5020],{},"    print(\"一行结束\")\n",[10,5022,168],{},[71,5024,5027],{"className":5025,"code":5026,"language":174,"meta":76},[172],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[34,5028,5026],{"__ignoreMap":76},[10,5030,179],{},[14,5032,182],{"id":182},[184,5034,5035,5047],{},[49,5036,5037,5038,5040,5041,223,5044,211],{},"外层变量 ",[34,5039,4972],{}," 先引用第一行列表，内层才依次处理 ",[34,5042,5043],{},"A1",[34,5045,5046],{},"A2",[49,5048,5049],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[213,5051,215],{"id":215},[10,5053,5054],{},"二维列表的输出顺序可以展开成一条时间线。",[10,5056,5057],{},[26,5058],{"alt":5059,"src":5060},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,5062,5063],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,5065,270],{"id":270},[46,5067,5068,5077],{},[49,5069,5070,5071,1119,5074,5076],{},"把两层循环变量都叫 ",[34,5072,5073],{},"item",[34,5075,4979],{},"，难以确认当前层级。",[49,5078,5079],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,5081,288],{"id":288},[184,5083,5084,5087],{},[49,5085,5086],{},"打印一个 2×3 数字表。",[49,5088,5089],{},"在内层增加条件，只输出大于 3 的元素。",[10,5091,313],{},[14,5093,316],{"id":316},[10,5095,5096],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,5098,323],{},{"title":76,"searchDepth":89,"depth":89,"links":5100},[5101,5102,5103,5104,5105,5108,5109,5110],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":5106},[5107],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4935,"description":4940},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[337,5118,5119],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5122,"title":5123,"body":5124,"category":337,"cover":338,"description":5128,"extension":339,"meta":5266,"navigation":116,"path":5267,"pinned":342,"publishedAt":343,"seo":5268,"slug":5269,"stem":5270,"summary":5271,"tags":5272,"updatedAt":343,"visible":116,"__hash__":5275},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5125,"toc":5256},[5126,5129,5131,5134,5136,5142,5145,5147,5158,5160,5162,5200,5202,5208,5210,5212,5224,5226,5237,5239,5247,5249,5251,5254],[10,5127,5128],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5130,16],{"id":16},[10,5132,5133],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5135,22],{"id":22},[10,5137,5138],{},[26,5139],{"alt":5140,"src":5141},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5143,5144],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5146,44],{"id":44},[46,5148,5149,5152,5155],{},[49,5150,5151],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[49,5153,5154],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[49,5156,5157],{},"推导式创建新列表，不修改输入列表。",[14,5159,66],{"id":66},[10,5161,69],{},[71,5163,5165],{"className":73,"code":5164,"language":75,"meta":76,"style":76},"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",[34,5166,5167,5172,5176,5181,5186,5190,5195],{"__ignoreMap":76},[80,5168,5169],{"class":82,"line":83},[80,5170,5171],{},"numbers = [1, 2, 3, 4, 5]\n",[80,5173,5174],{"class":82,"line":89},[80,5175,117],{"emptyLinePlaceholder":116},[80,5177,5178],{"class":82,"line":95},[80,5179,5180],{},"squares = [number * number for number in numbers]\n",[80,5182,5183],{"class":82,"line":101},[80,5184,5185],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[80,5187,5188],{"class":82,"line":107},[80,5189,117],{"emptyLinePlaceholder":116},[80,5191,5192],{"class":82,"line":113},[80,5193,5194],{},"print(squares)\n",[80,5196,5197],{"class":82,"line":120},[80,5198,5199],{},"print(even_squares)\n",[10,5201,168],{},[71,5203,5206],{"className":5204,"code":5205,"language":174,"meta":76},[172],"[1, 4, 9, 16, 25]\n[4, 16]\n",[34,5207,5205],{"__ignoreMap":76},[10,5209,179],{},[14,5211,182],{"id":182},[184,5213,5214,5217],{},[49,5215,5216],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[49,5218,5219,5220,5223],{},"第二条先用 ",[34,5221,5222],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5225,270],{"id":270},[46,5227,5228,5234],{},[49,5229,5230,5231,5233],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[34,5232,4440],{}," 开始找输入。",[49,5235,5236],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5238,288],{"id":288},[184,5240,5241,5244],{},[49,5242,5243],{},"把字符串列表转换为长度列表。",[49,5245,5246],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5248,313],{},[14,5250,316],{"id":316},[10,5252,5253],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,5255,323],{},{"title":76,"searchDepth":89,"depth":89,"links":5257},[5258,5259,5260,5261,5262,5263,5264,5265],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5123,"description":5128},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[337,5273,5274],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5277,"title":5278,"body":5279,"category":337,"cover":338,"description":5283,"extension":339,"meta":5426,"navigation":116,"path":5427,"pinned":342,"publishedAt":343,"seo":5428,"slug":5429,"stem":5430,"summary":5431,"tags":5432,"updatedAt":343,"visible":116,"__hash__":5435},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5280,"toc":5416},[5281,5284,5286,5289,5291,5297,5300,5302,5313,5315,5317,5356,5358,5364,5366,5368,5383,5385,5393,5395,5407,5409,5411,5414],[10,5282,5283],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5285,16],{"id":16},[10,5287,5288],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5290,22],{"id":22},[10,5292,5293],{},[26,5294],{"alt":5295,"src":5296},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5298,5299],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5301,44],{"id":44},[46,5303,5304,5307,5310],{},[49,5305,5306],{},"函数名描述动作，使用小写字母和下划线。",[49,5308,5309],{},"函数定义要先执行，之后才能调用。",[49,5311,5312],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5314,66],{"id":66},[10,5316,69],{},[71,5318,5320],{"className":73,"code":5319,"language":75,"meta":76,"style":76},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[34,5321,5322,5327,5332,5337,5341,5346,5351],{"__ignoreMap":76},[80,5323,5324],{"class":82,"line":83},[80,5325,5326],{},"def show_progress():\n",[80,5328,5329],{"class":82,"line":89},[80,5330,5331],{},"    print(\"正在学习函数\")\n",[80,5333,5334],{"class":82,"line":95},[80,5335,5336],{},"    print(\"本节完成 50%\")\n",[80,5338,5339],{"class":82,"line":101},[80,5340,117],{"emptyLinePlaceholder":116},[80,5342,5343],{"class":82,"line":107},[80,5344,5345],{},"print(\"调用前\")\n",[80,5347,5348],{"class":82,"line":113},[80,5349,5350],{},"show_progress()\n",[80,5352,5353],{"class":82,"line":120},[80,5354,5355],{},"print(\"调用后\")\n",[10,5357,168],{},[71,5359,5362],{"className":5360,"code":5361,"language":174,"meta":76},[172],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[34,5363,5361],{"__ignoreMap":76},[10,5365,179],{},[14,5367,182],{"id":182},[184,5369,5370,5376],{},[49,5371,1048,5372,5375],{},[34,5373,5374],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[49,5377,5378,5379,5382],{},"运行到 ",[34,5380,5381],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5384,270],{"id":270},[46,5386,5387,5390],{},[49,5388,5389],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[49,5391,5392],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5394,288],{"id":288},[184,5396,5397,5404],{},[49,5398,5399,5400,5403],{},"定义 ",[34,5401,5402],{},"show_plan()"," 输出两行学习计划。",[49,5405,5406],{},"连续调用同一个函数两次，观察执行顺序。",[10,5408,313],{},[14,5410,316],{"id":316},[10,5412,5413],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,5415,323],{},{"title":76,"searchDepth":89,"depth":89,"links":5417},[5418,5419,5420,5421,5422,5423,5424,5425],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5278,"description":5283},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[337,5433,5434],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5437,"title":5438,"body":5439,"category":337,"cover":338,"description":5443,"extension":339,"meta":5623,"navigation":116,"path":5624,"pinned":342,"publishedAt":343,"seo":5625,"slug":5626,"stem":5627,"summary":5628,"tags":5629,"updatedAt":343,"visible":116,"__hash__":5632},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5440,"toc":5611},[5441,5444,5446,5449,5451,5457,5464,5466,5483,5485,5487,5521,5523,5529,5531,5533,5554,5556,5559,5565,5575,5577,5592,5594,5602,5604,5606,5609],[10,5442,5443],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5445,16],{"id":16},[10,5447,5448],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5450,22],{"id":22},[10,5452,5453],{},[26,5454],{"alt":5455,"src":5456},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5458,5459,5460,5463],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[34,5461,5462],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5465,44],{"id":44},[46,5467,5468,5471,5474],{},[49,5469,5470],{},"形参出现在函数定义中，实参出现在函数调用中。",[49,5472,5473],{},"局部变量默认只在函数内部可见。",[49,5475,5476,5477,5479,5480,211],{},"没有显式 ",[34,5478,5462],{}," 的函数会返回 ",[34,5481,5482],{},"None",[14,5484,66],{"id":66},[10,5486,69],{},[71,5488,5490],{"className":73,"code":5489,"language":75,"meta":76,"style":76},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[34,5491,5492,5497,5502,5507,5511,5516],{"__ignoreMap":76},[80,5493,5494],{"class":82,"line":83},[80,5495,5496],{},"def calculate_total(price, count):\n",[80,5498,5499],{"class":82,"line":89},[80,5500,5501],{},"    total = price * count\n",[80,5503,5504],{"class":82,"line":95},[80,5505,5506],{},"    return total\n",[80,5508,5509],{"class":82,"line":101},[80,5510,117],{"emptyLinePlaceholder":116},[80,5512,5513],{"class":82,"line":107},[80,5514,5515],{},"result = calculate_total(25, 4)\n",[80,5517,5518],{"class":82,"line":113},[80,5519,5520],{},"print(result)\n",[10,5522,168],{},[71,5524,5527],{"className":5525,"code":5526,"language":174,"meta":76},[172],"100\n",[34,5528,5526],{"__ignoreMap":76},[10,5530,179],{},[14,5532,182],{"id":182},[184,5534,5535,5544],{},[49,5536,5537,5538,220,5541,5543],{},"调用时 25 和 4 分别绑定到 ",[34,5539,5540],{},"price",[34,5542,4503],{},"，它们只在本次函数调用的局部范围中使用。",[49,5545,5546,5549,5550,5553],{},[34,5547,5548],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[34,5551,5552],{},"result"," 并输出。",[213,5555,215],{"id":215},[10,5557,5558],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5560,5561],{},[26,5562],{"alt":5563,"src":5564},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5566,5567,220,5569,223,5571,5574],{},[34,5568,5540],{},[34,5570,4503],{},[34,5572,5573],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5576,270],{"id":270},[46,5578,5579,5586],{},[49,5580,5581,5582,5585],{},"在函数内部只 ",[34,5583,5584],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[49,5587,5588,5589,5591],{},"试图在函数外直接访问局部变量 ",[34,5590,5573],{},"，它的名字只在调用期间的局部作用域存在。",[14,5593,288],{"id":288},[184,5595,5596,5599],{},[49,5597,5598],{},"编写计算长方形面积的函数。",[49,5600,5601],{},"让函数返回结果后在调用方加上单位再输出。",[10,5603,313],{},[14,5605,316],{"id":316},[10,5607,5608],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,5610,323],{},{"title":76,"searchDepth":89,"depth":89,"links":5612},[5613,5614,5615,5616,5617,5620,5621,5622],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":5618},[5619],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5438,"description":5443},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[337,5630,5631],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5634,"title":5635,"body":5636,"category":337,"cover":338,"description":5640,"extension":339,"meta":5820,"navigation":116,"path":5821,"pinned":342,"publishedAt":343,"seo":5822,"slug":5823,"stem":5824,"summary":5825,"tags":5826,"updatedAt":343,"visible":116,"__hash__":5829},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5637,"toc":5808},[5638,5641,5643,5646,5648,5654,5657,5659,5676,5678,5680,5732,5734,5740,5742,5744,5762,5764,5767,5773,5776,5778,5789,5791,5799,5801,5803,5806],[10,5639,5640],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5642,16],{"id":16},[10,5644,5645],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5647,22],{"id":22},[10,5649,5650],{},[26,5651],{"alt":5652,"src":5653},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5655,5656],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5658,44],{"id":44},[46,5660,5661,5664,5670],{},[49,5662,5663],{},"必需参数应放在有默认值的参数之前。",[49,5665,5666,5669],{},[34,5667,5668],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[49,5671,5672,5675],{},[34,5673,5674],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5677,66],{"id":66},[10,5679,69],{},[71,5681,5683],{"className":73,"code":5682,"language":75,"meta":76,"style":76},"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",[34,5684,5685,5690,5695,5699,5704,5709,5713,5718,5723,5727],{"__ignoreMap":76},[80,5686,5687],{"class":82,"line":83},[80,5688,5689],{},"def build_title(name, level=\"基础\"):\n",[80,5691,5692],{"class":82,"line":89},[80,5693,5694],{},"    return name + \"｜\" + level\n",[80,5696,5697],{"class":82,"line":95},[80,5698,117],{"emptyLinePlaceholder":116},[80,5700,5701],{"class":82,"line":101},[80,5702,5703],{},"print(build_title(\"Python\"))\n",[80,5705,5706],{"class":82,"line":107},[80,5707,5708],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[80,5710,5711],{"class":82,"line":113},[80,5712,117],{"emptyLinePlaceholder":116},[80,5714,5715],{"class":82,"line":120},[80,5716,5717],{},"def total(*numbers):\n",[80,5719,5720],{"class":82,"line":126},[80,5721,5722],{},"    return sum(numbers)\n",[80,5724,5725],{"class":82,"line":132},[80,5726,117],{"emptyLinePlaceholder":116},[80,5728,5729],{"class":82,"line":138},[80,5730,5731],{},"print(total(10, 20, 30))\n",[10,5733,168],{},[71,5735,5738],{"className":5736,"code":5737,"language":174,"meta":76},[172],"Python｜基础\n异常处理｜进阶\n60\n",[34,5739,5737],{"__ignoreMap":76},[10,5741,179],{},[14,5743,182],{"id":182},[184,5745,5746,5753],{},[49,5747,5748,5749,5752],{},"第一次调用只提供必需参数，",[34,5750,5751],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[49,5754,5755,5758,5759,211],{},[34,5756,5757],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[34,5760,5761],{},"sum()",[213,5763,215],{"id":215},[10,5765,5766],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5768,5769],{},[26,5770],{"alt":5771,"src":5772},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5774,5775],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5777,270],{"id":270},[46,5779,5780,5786],{},[49,5781,5782,5783,5785],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[34,5784,5482],{}," 再在函数内创建。",[49,5787,5788],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5790,288],{"id":288},[184,5792,5793,5796],{},[49,5794,5795],{},"给问候函数增加默认称呼。",[49,5797,5798],{},"编写接收任意数量分数并返回总分的函数。",[10,5800,313],{},[14,5802,316],{"id":316},[10,5804,5805],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,5807,323],{},{"title":76,"searchDepth":89,"depth":89,"links":5809},[5810,5811,5812,5813,5814,5817,5818,5819],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":5815},[5816],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5635,"description":5640},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[337,5827,5828],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5831,"title":5832,"body":5833,"category":337,"cover":338,"description":5837,"extension":339,"meta":6032,"navigation":116,"path":6033,"pinned":342,"publishedAt":343,"seo":6034,"slug":6035,"stem":6036,"summary":6037,"tags":6038,"updatedAt":343,"visible":116,"__hash__":6041},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5834,"toc":6020},[5835,5838,5840,5843,5845,5851,5854,5856,5873,5875,5877,5938,5940,5946,5948,5950,5977,5979,5982,5988,5991,5993,6001,6003,6011,6013,6015,6018],[10,5836,5837],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5839,16],{"id":16},[10,5841,5842],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5844,22],{"id":22},[10,5846,5847],{},[26,5848],{"alt":5849,"src":5850},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5852,5853],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5855,44],{"id":44},[46,5857,5858,5861,5864],{},[49,5859,5860],{},"函数内部赋值默认创建局部变量。",[49,5862,5863],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[49,5865,5866,2283,5869,5872],{},[34,5867,5868],{},"global",[34,5870,5871],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5874,66],{"id":66},[10,5876,69],{},[71,5878,5880],{"className":73,"code":5879,"language":75,"meta":76,"style":76},"course = \"Python\"\n\ndef outer():\n    level = \"基础\"\n\n    def show():\n        lesson = \"作用域\"\n        print(course, level, lesson)\n\n    show()\n\nouter()\n",[34,5881,5882,5887,5891,5896,5901,5905,5910,5915,5920,5924,5929,5933],{"__ignoreMap":76},[80,5883,5884],{"class":82,"line":83},[80,5885,5886],{},"course = \"Python\"\n",[80,5888,5889],{"class":82,"line":89},[80,5890,117],{"emptyLinePlaceholder":116},[80,5892,5893],{"class":82,"line":95},[80,5894,5895],{},"def outer():\n",[80,5897,5898],{"class":82,"line":101},[80,5899,5900],{},"    level = \"基础\"\n",[80,5902,5903],{"class":82,"line":107},[80,5904,117],{"emptyLinePlaceholder":116},[80,5906,5907],{"class":82,"line":113},[80,5908,5909],{},"    def show():\n",[80,5911,5912],{"class":82,"line":120},[80,5913,5914],{},"        lesson = \"作用域\"\n",[80,5916,5917],{"class":82,"line":126},[80,5918,5919],{},"        print(course, level, lesson)\n",[80,5921,5922],{"class":82,"line":132},[80,5923,117],{"emptyLinePlaceholder":116},[80,5925,5926],{"class":82,"line":138},[80,5927,5928],{},"    show()\n",[80,5930,5931],{"class":82,"line":144},[80,5932,117],{"emptyLinePlaceholder":116},[80,5934,5935],{"class":82,"line":150},[80,5936,5937],{},"outer()\n",[10,5939,168],{},[71,5941,5944],{"className":5942,"code":5943,"language":174,"meta":76},[172],"Python 基础 作用域\n",[34,5945,5943],{"__ignoreMap":76},[10,5947,179],{},[14,5949,182],{"id":182},[184,5951,5952,5969],{},[49,5953,5954,5957,5958,5961,5962,5964,5965,5968],{},[34,5955,5956],{},"show()"," 中查找 ",[34,5959,5960],{},"lesson"," 时先在局部找到，查找 ",[34,5963,5751],{}," 时到外层 ",[34,5966,5967],{},"outer()"," 找到。",[49,5970,5971,5973,5974,5976],{},[34,5972,4686],{}," 在局部和外层都不存在，继续到模块全局找到；",[34,5975,2315],{}," 最后在内置作用域找到。",[213,5978,215],{"id":215},[10,5980,5981],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5983,5984],{},[26,5985],{"alt":5986,"src":5987},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5989,5990],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5992,270],{"id":270},[46,5994,5995,5998],{},[49,5996,5997],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[49,5999,6000],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,6002,288],{"id":288},[184,6004,6005,6008],{},[49,6006,6007],{},"在内外层定义同名变量，观察最近作用域优先。",[49,6009,6010],{},"尝试在函数外访问局部变量，记录异常类型。",[10,6012,313],{},[14,6014,316],{"id":316},[10,6016,6017],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,6019,323],{},{"title":76,"searchDepth":89,"depth":89,"links":6021},[6022,6023,6024,6025,6026,6029,6030,6031],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":6027},[6028],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5832,"description":5837},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[337,6039,6040],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":6043,"title":6044,"body":6045,"category":337,"cover":338,"description":6049,"extension":339,"meta":6199,"navigation":116,"path":6200,"pinned":342,"publishedAt":343,"seo":6201,"slug":6202,"stem":6203,"summary":6204,"tags":6205,"updatedAt":343,"visible":116,"__hash__":6208},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":6046,"toc":6189},[6047,6050,6052,6055,6057,6063,6066,6068,6087,6089,6091,6125,6127,6133,6135,6137,6152,6154,6166,6168,6180,6182,6184,6187],[10,6048,6049],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,6051,16],{"id":16},[10,6053,6054],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6056,22],{"id":22},[10,6058,6059],{},[26,6060],{"alt":6061,"src":6062},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,6064,6065],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,6067,44],{"id":44},[46,6069,6070,6073,6076],{},[49,6071,6072],{},"文档字符串紧跟在函数定义后的第一条语句。",[49,6074,6075],{},"注解表达接口意图，不代替输入校验和测试。",[49,6077,6078,6079,220,6081,220,6083,6086],{},"基础注解优先使用 ",[34,6080,2366],{},[34,6082,2532],{},[34,6084,6085],{},"list[str]"," 等直接写法。",[14,6088,66],{"id":66},[10,6090,69],{},[71,6092,6094],{"className":73,"code":6093,"language":75,"meta":76,"style":76},"def format_score(name: str, score: int) -> str:\n    \"\"\"返回带姓名的分数文本。\"\"\"\n    return name + \"：\" + str(score)\n\nprint(format_score(\"小郑\", 95))\nprint(format_score.__doc__)\n",[34,6095,6096,6101,6106,6111,6115,6120],{"__ignoreMap":76},[80,6097,6098],{"class":82,"line":83},[80,6099,6100],{},"def format_score(name: str, score: int) -> str:\n",[80,6102,6103],{"class":82,"line":89},[80,6104,6105],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[80,6107,6108],{"class":82,"line":95},[80,6109,6110],{},"    return name + \"：\" + str(score)\n",[80,6112,6113],{"class":82,"line":101},[80,6114,117],{"emptyLinePlaceholder":116},[80,6116,6117],{"class":82,"line":107},[80,6118,6119],{},"print(format_score(\"小郑\", 95))\n",[80,6121,6122],{"class":82,"line":113},[80,6123,6124],{},"print(format_score.__doc__)\n",[10,6126,168],{},[71,6128,6131],{"className":6129,"code":6130,"language":174,"meta":76},[172],"小郑：95\n返回带姓名的分数文本。\n",[34,6132,6130],{"__ignoreMap":76},[10,6134,179],{},[14,6136,182],{"id":182},[184,6138,6139,6149],{},[49,6140,6141,6142,6145,6146,6148],{},"函数签名说明 ",[34,6143,6144],{},"name"," 预期为字符串、",[34,6147,2353],{}," 预期为整数，返回值预期为字符串。",[49,6150,6151],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6153,270],{"id":270},[46,6155,6156,6163],{},[49,6157,6158,6159,6162],{},"认为加了 ",[34,6160,6161],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[49,6164,6165],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6167,288],{"id":288},[184,6169,6170,6173],{},[49,6171,6172],{},"为面积函数补充参数和返回值注解。",[49,6174,6175,6176,6179],{},"通过 ",[34,6177,6178],{},"函数名.__doc__"," 查看文档字符串。",[10,6181,313],{},[14,6183,316],{"id":316},[10,6185,6186],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,6188,323],{},{"title":76,"searchDepth":89,"depth":89,"links":6190},[6191,6192,6193,6194,6195,6196,6197,6198],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":6044,"description":6049},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[337,6206,6207],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6210,"title":6211,"body":6212,"category":337,"cover":338,"description":6216,"extension":339,"meta":6443,"navigation":116,"path":6444,"pinned":342,"publishedAt":343,"seo":6445,"slug":6446,"stem":6447,"summary":6448,"tags":6449,"updatedAt":343,"visible":116,"__hash__":6452},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6213,"toc":6431},[6214,6217,6219,6225,6227,6233,6244,6246,6264,6266,6273,6302,6309,6328,6337,6339,6345,6347,6349,6372,6374,6377,6383,6389,6391,6407,6409,6422,6424,6426,6429],[10,6215,6216],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6218,16],{"id":16},[10,6220,6221,6222,6224],{},"本篇只处理“模块、import 与 ",[406,6223,6144],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6226,22],{"id":22},[10,6228,6229],{},[26,6230],{"alt":6231,"src":6232},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6234,6235,6236,6239,6240,6243],{},"同一个文件直接运行时 ",[34,6237,6238],{},"__name__"," 等于 ",[34,6241,6242],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6245,44],{"id":44},[46,6247,6248,6254,6257],{},[49,6249,6250,6251,6253],{},"一个 ",[34,6252,1278],{}," 文件就是一个模块。",[49,6255,6256],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[49,6258,6259,6260,6263],{},"避免使用 ",[34,6261,6262],{},"from module import *","，它会让名字来源不清楚。",[14,6265,66],{"id":66},[10,6267,6268,6269,6272],{},"先在同一个目录中创建两个文件。把函数放进 ",[34,6270,6271],{},"calculator.py","：",[71,6274,6276],{"className":73,"code":6275,"language":75,"meta":76,"style":76},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[34,6277,6278,6283,6288,6292,6297],{"__ignoreMap":76},[80,6279,6280],{"class":82,"line":83},[80,6281,6282],{},"def add(left, right):\n",[80,6284,6285],{"class":82,"line":89},[80,6286,6287],{},"    return left + right\n",[80,6289,6290],{"class":82,"line":95},[80,6291,117],{"emptyLinePlaceholder":116},[80,6293,6294],{"class":82,"line":101},[80,6295,6296],{},"if __name__ == \"__main__\":\n",[80,6298,6299],{"class":82,"line":107},[80,6300,6301],{},"    print(add(2, 3))\n",[10,6303,6304,6305,6308],{},"再创建 ",[34,6306,6307],{},"app.py","，从模块中导入函数：",[71,6310,6312],{"className":73,"code":6311,"language":75,"meta":76,"style":76},"from calculator import add\n\nprint(add(10, 20))\n",[34,6313,6314,6319,6323],{"__ignoreMap":76},[80,6315,6316],{"class":82,"line":83},[80,6317,6318],{},"from calculator import add\n",[80,6320,6321],{"class":82,"line":89},[80,6322,117],{"emptyLinePlaceholder":116},[80,6324,6325],{"class":82,"line":95},[80,6326,6327],{},"print(add(10, 20))\n",[10,6329,6330,6331,223,6334,211],{},"分别执行 ",[34,6332,6333],{},"python3 calculator.py",[34,6335,6336],{},"python3 app.py",[10,6338,168],{},[71,6340,6343],{"className":6341,"code":6342,"language":174,"meta":76},[172],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[34,6344,6342],{"__ignoreMap":76},[10,6346,179],{},[14,6348,182],{"id":182},[184,6350,6351,6361],{},[49,6352,6353,6354,6356,6357,6360],{},"直接运行 ",[34,6355,6271],{}," 时，模块名是 ",[34,6358,6359],{},"__main__","，入口代码输出 5。",[49,6362,6363,6365,6366,6368,6369,6371],{},[34,6364,6307],{}," 导入模块时，",[34,6367,6271],{}," 的函数定义会执行，但入口判断为假；随后 ",[34,6370,6307],{}," 调用函数输出 30。",[213,6373,215],{"id":215},[10,6375,6376],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6378,6379],{},[26,6380],{"alt":6381,"src":6382},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6384,6385,6386,6388],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[34,6387,6359],{}," 保护下的演示代码。",[14,6390,270],{"id":270},[46,6392,6393,6400],{},[49,6394,6395,6396,223,6398,211],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[34,6397,6271],{},[34,6399,6307],{},[49,6401,6402,6403,6406],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[34,6404,6405],{},"json.py","，导致导入目标被遮蔽。",[14,6408,288],{"id":288},[184,6410,6411,6417],{},[49,6412,2460,6413,6416],{},[34,6414,6415],{},"text_tools.py"," 并导出一个格式化函数。",[49,6418,6419,6420,211],{},"分别直接运行模块和从另一个脚本导入，输出 ",[34,6421,6238],{},[10,6423,313],{},[14,6425,316],{"id":316},[10,6427,6428],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,6430,323],{},{"title":76,"searchDepth":89,"depth":89,"links":6432},[6433,6434,6435,6436,6437,6440,6441,6442],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":6438},[6439],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6211,"description":6216},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[337,6450,6451],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6454,"title":6455,"body":6456,"category":337,"cover":338,"description":6460,"extension":339,"meta":6625,"navigation":116,"path":6626,"pinned":342,"publishedAt":343,"seo":6627,"slug":6628,"stem":6629,"summary":6630,"tags":6631,"updatedAt":343,"visible":116,"__hash__":6633},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6457,"toc":6615},[6458,6461,6463,6466,6468,6474,6477,6479,6493,6495,6497,6543,6545,6551,6553,6555,6581,6583,6593,6595,6606,6608,6610,6613],[10,6459,6460],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6462,16],{"id":16},[10,6464,6465],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6467,22],{"id":22},[10,6469,6470],{},[26,6471],{"alt":6472,"src":6473},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6475,6476],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6478,44],{"id":44},[46,6480,6481,6487,6490],{},[49,6482,6483,6486],{},[34,6484,6485],{},".venv"," 是常见目录名，不应提交到 Git。",[49,6488,6489],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[49,6491,6492],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6494,66],{"id":66},[10,6496,1681],{},[71,6498,6500],{"className":701,"code":6499,"language":703,"meta":76,"style":76},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[34,6501,6502,6514,6522,6528,6538],{"__ignoreMap":76},[80,6503,6504,6506,6508,6511],{"class":82,"line":83},[80,6505,801],{"class":710},[80,6507,743],{"class":713},[80,6509,6510],{"class":746}," venv",[80,6512,6513],{"class":746}," .venv\n",[80,6515,6516,6519],{"class":82,"line":89},[80,6517,6518],{"class":713},"source",[80,6520,6521],{"class":746}," .venv\u002Fbin\u002Factivate\n",[80,6523,6524,6526],{"class":82,"line":95},[80,6525,75],{"class":710},[80,6527,714],{"class":713},[80,6529,6530,6532,6534,6536],{"class":82,"line":101},[80,6531,75],{"class":710},[80,6533,743],{"class":713},[80,6535,747],{"class":746},[80,6537,714],{"class":713},[80,6539,6540],{"class":82,"line":107},[80,6541,6542],{"class":710},"deactivate\n",[10,6544,168],{},[71,6546,6549],{"className":6547,"code":6548,"language":174,"meta":76},[172],"Python 和 pip 的路径应指向当前项目的 .venv\n",[34,6550,6548],{"__ignoreMap":76},[10,6552,179],{},[14,6554,182],{"id":182},[184,6556,6557,6566],{},[49,6558,6559,6562,6563,6565],{},[34,6560,6561],{},"venv"," 根据当前 ",[34,6564,801],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[49,6567,6568,6569,2283,6571,6574,6575,3832,6577,6580],{},"激活后 ",[34,6570,75],{},[34,6572,6573],{},"python -m pip"," 优先指向 ",[34,6576,6485],{},[34,6578,6579],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6582,270],{"id":270},[46,6584,6585,6588],{},[49,6586,6587],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[49,6589,3571,6590,6592],{},[34,6591,6485],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6594,288],{"id":288},[184,6596,6597,6603],{},[49,6598,6599,6600,211],{},"创建虚拟环境并记录激活前后的 ",[34,6601,6602],{},"which python",[49,6604,6605],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6607,313],{},[14,6609,316],{"id":316},[10,6611,6612],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,6614,1765],{},{"title":76,"searchDepth":89,"depth":89,"links":6616},[6617,6618,6619,6620,6621,6622,6623,6624],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6455,"description":6460},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[337,6632,372],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6635,"title":6636,"body":6637,"category":337,"cover":338,"description":6641,"extension":339,"meta":6829,"navigation":116,"path":6830,"pinned":342,"publishedAt":343,"seo":6831,"slug":6832,"stem":6833,"summary":6834,"tags":6835,"updatedAt":343,"visible":116,"__hash__":6838},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6638,"toc":6819},[6639,6642,6644,6647,6649,6655,6664,6666,6690,6692,6694,6747,6749,6755,6757,6759,6775,6777,6796,6798,6810,6812,6814,6817],[10,6640,6641],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6643,16],{"id":16},[10,6645,6646],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6648,22],{"id":22},[10,6650,6651],{},[26,6652],{"alt":6653,"src":6654},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6656,6657,6660,6661,6663],{},[34,6658,6659],{},"Path"," 使用 ",[34,6662,2542],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6665,44],{"id":44},[46,6667,6668,6671,6683],{},[49,6669,6670],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[49,6672,6673,220,6676,220,6679,6682],{},[34,6674,6675],{},"exists()",[34,6677,6678],{},"is_file()",[34,6680,6681],{},"is_dir()"," 检查真实文件系统状态。",[49,6684,6685,6686,6689],{},"创建目录前明确目标；",[34,6687,6688],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6691,66],{"id":66},[10,6693,69],{},[71,6695,6697],{"className":73,"code":6696,"language":75,"meta":76,"style":76},"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",[34,6698,6699,6704,6708,6713,6718,6723,6727,6732,6737,6742],{"__ignoreMap":76},[80,6700,6701],{"class":82,"line":83},[80,6702,6703],{},"from pathlib import Path\n",[80,6705,6706],{"class":82,"line":89},[80,6707,117],{"emptyLinePlaceholder":116},[80,6709,6710],{"class":82,"line":95},[80,6711,6712],{},"project = Path.cwd()\n",[80,6714,6715],{"class":82,"line":101},[80,6716,6717],{},"data_dir = project \u002F \"data\"\n",[80,6719,6720],{"class":82,"line":107},[80,6721,6722],{},"file_path = data_dir \u002F \"records.json\"\n",[80,6724,6725],{"class":82,"line":113},[80,6726,117],{"emptyLinePlaceholder":116},[80,6728,6729],{"class":82,"line":120},[80,6730,6731],{},"print(project)\n",[80,6733,6734],{"class":82,"line":126},[80,6735,6736],{},"print(file_path.name)\n",[80,6738,6739],{"class":82,"line":132},[80,6740,6741],{},"print(file_path.suffix)\n",[80,6743,6744],{"class":82,"line":138},[80,6745,6746],{},"print(file_path.exists())\n",[10,6748,168],{},[71,6750,6753],{"className":6751,"code":6752,"language":174,"meta":76},[172],"显示当前项目路径、records.json、.json 和存在状态\n",[34,6754,6752],{"__ignoreMap":76},[10,6756,179],{},[14,6758,182],{"id":182},[184,6760,6761,6767],{},[49,6762,6763,6766],{},[34,6764,6765],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[49,6768,2445,6769,6771,6772,6774],{},[34,6770,2542],{}," 组合路径片段只创建新的 ",[34,6773,6659],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6776,270],{"id":270},[46,6778,6779,6787],{},[49,6780,3571,6781,6783,6784,6786],{},[34,6782,6659],{}," 对象存在当成真实文件存在，仍需调用 ",[34,6785,6675],{}," 等方法确认。",[49,6788,6789,6790,1119,6792,6795],{},"手工拼接 ",[34,6791,2542],{},[34,6793,6794],{},"\\"," 分隔符，降低跨平台可读性。",[14,6797,288],{"id":288},[184,6799,6800,6807],{},[49,6801,6802,6803,6806],{},"组合 ",[34,6804,6805],{},"output\u002Freport.txt"," 路径但先不创建文件。",[49,6808,6809],{},"输出路径的父目录、文件名和扩展名。",[10,6811,313],{},[14,6813,316],{"id":316},[10,6815,6816],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,6818,323],{},{"title":76,"searchDepth":89,"depth":89,"links":6820},[6821,6822,6823,6824,6825,6826,6827,6828],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6636,"description":6641},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[337,6836,6837],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6840,"title":6841,"body":6842,"category":337,"cover":338,"description":6846,"extension":339,"meta":7023,"navigation":116,"path":7024,"pinned":342,"publishedAt":343,"seo":7025,"slug":7026,"stem":7027,"summary":7028,"tags":7029,"updatedAt":343,"visible":116,"__hash__":7032},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6843,"toc":7013},[6844,6847,6849,6852,6854,6860,6863,6865,6892,6894,6896,6953,6955,6961,6963,6965,6976,6978,6991,6993,7004,7006,7008,7011],[10,6845,6846],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6848,16],{"id":16},[10,6850,6851],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6853,22],{"id":22},[10,6855,6856],{},[26,6857],{"alt":6858,"src":6859},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6861,6862],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6864,44],{"id":44},[46,6866,6867,6873,6881],{},[49,6868,6869,6872],{},[34,6870,6871],{},"w"," 模式会截断原文件，写入前必须确认目标。",[49,6874,6875,6878,6879,211],{},[34,6876,6877],{},"r"," 模式读取不存在文件会产生 ",[34,6880,309],{},[49,6882,6883,6884,6887,6888,6891],{},"本篇显式调用 ",[34,6885,6886],{},"close()","；第 34 篇会用 ",[34,6889,6890],{},"with"," 更可靠地管理关闭动作。",[14,6893,66],{"id":66},[10,6895,69],{},[71,6897,6899],{"className":73,"code":6898,"language":75,"meta":76,"style":76},"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",[34,6900,6901,6905,6909,6914,6919,6924,6929,6933,6938,6943,6948],{"__ignoreMap":76},[80,6902,6903],{"class":82,"line":83},[80,6904,6703],{},[80,6906,6907],{"class":82,"line":89},[80,6908,117],{"emptyLinePlaceholder":116},[80,6910,6911],{"class":82,"line":95},[80,6912,6913],{},"file_path = Path(\"notes.txt\")\n",[80,6915,6916],{"class":82,"line":101},[80,6917,6918],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[80,6920,6921],{"class":82,"line":107},[80,6922,6923],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[80,6925,6926],{"class":82,"line":113},[80,6927,6928],{},"writer.close()\n",[80,6930,6931],{"class":82,"line":120},[80,6932,117],{"emptyLinePlaceholder":116},[80,6934,6935],{"class":82,"line":126},[80,6936,6937],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[80,6939,6940],{"class":82,"line":132},[80,6941,6942],{},"content = reader.read()\n",[80,6944,6945],{"class":82,"line":138},[80,6946,6947],{},"reader.close()\n",[80,6949,6950],{"class":82,"line":144},[80,6951,6952],{},"print(content)\n",[10,6954,168],{},[71,6956,6959],{"className":6957,"code":6958,"language":174,"meta":76},[172],"变量\n循环\n函数\n",[34,6960,6958],{"__ignoreMap":76},[10,6962,179],{},[14,6964,182],{"id":182},[184,6966,6967,6973],{},[49,6968,6969,6970,6972],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[34,6971,6886],{}," 确保缓冲内容交给文件系统。",[49,6974,6975],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6977,270],{"id":270},[46,6979,6980,6985],{},[49,6981,2445,6982,6984],{},[34,6983,6871],{}," 模式打开重要文件却未确认覆盖风险。",[49,6986,6987,6988,211],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[34,6989,6990],{},"encoding=\"utf-8\"",[14,6992,288],{"id":288},[184,6994,6995,6998],{},[49,6996,6997],{},"写入三行学习记录并读取。",[49,6999,7000,7001,7003],{},"改用 ",[34,7002,447],{}," 模式追加一行，确认原内容仍保留。",[10,7005,313],{},[14,7007,316],{"id":316},[10,7009,7010],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,7012,323],{},{"title":76,"searchDepth":89,"depth":89,"links":7014},[7015,7016,7017,7018,7019,7020,7021,7022],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6841,"description":6846},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[337,7030,7031],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":7034,"title":7035,"body":7036,"category":337,"cover":338,"description":7040,"extension":339,"meta":7207,"navigation":116,"path":7208,"pinned":342,"publishedAt":343,"seo":7209,"slug":7210,"stem":7211,"summary":7212,"tags":7213,"updatedAt":343,"visible":116,"__hash__":7216},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":7037,"toc":7197},[7038,7041,7043,7046,7048,7054,7064,7066,7080,7082,7084,7144,7146,7152,7154,7156,7168,7170,7178,7180,7188,7190,7192,7195],[10,7039,7040],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,7042,16],{"id":16},[10,7044,7045],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7047,22],{"id":22},[10,7049,7050],{},[26,7051],{"alt":7052,"src":7053},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,7055,7056,7059,7060,7063],{},[34,7057,7058],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[34,7061,7062],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,7065,44],{"id":44},[46,7067,7068,7071,7077],{},[49,7069,7070],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[49,7072,7073,7076],{},[34,7074,7075],{},"ensure_ascii=False"," 让中文以可读字符写入。",[49,7078,7079],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,7081,66],{"id":66},[10,7083,69],{},[71,7085,7087],{"className":73,"code":7086,"language":75,"meta":76,"style":76},"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",[34,7088,7089,7094,7098,7103,7107,7112,7117,7121,7125,7130,7135,7139],{"__ignoreMap":76},[80,7090,7091],{"class":82,"line":83},[80,7092,7093],{},"import json\n",[80,7095,7096],{"class":82,"line":89},[80,7097,117],{"emptyLinePlaceholder":116},[80,7099,7100],{"class":82,"line":95},[80,7101,7102],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[80,7104,7105],{"class":82,"line":101},[80,7106,117],{"emptyLinePlaceholder":116},[80,7108,7109],{"class":82,"line":107},[80,7110,7111],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[80,7113,7114],{"class":82,"line":113},[80,7115,7116],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[80,7118,7119],{"class":82,"line":120},[80,7120,6928],{},[80,7122,7123],{"class":82,"line":126},[80,7124,117],{"emptyLinePlaceholder":116},[80,7126,7127],{"class":82,"line":132},[80,7128,7129],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[80,7131,7132],{"class":82,"line":138},[80,7133,7134],{},"loaded = json.load(reader)\n",[80,7136,7137],{"class":82,"line":144},[80,7138,6947],{},[80,7140,7141],{"class":82,"line":150},[80,7142,7143],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7145,168],{},[71,7147,7150],{"className":7148,"code":7149,"language":174,"meta":76},[172],"Python 60\n",[34,7151,7149],{"__ignoreMap":76},[10,7153,179],{},[14,7155,182],{"id":182},[184,7157,7158,7163],{},[49,7159,7160,7162],{},[34,7161,7058],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[49,7164,7165,7167],{},[34,7166,7062],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7169,270],{"id":270},[46,7171,7172,7175],{},[49,7173,7174],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[49,7176,7177],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7179,288],{"id":288},[184,7181,7182,7185],{},[49,7183,7184],{},"保存包含两条学习记录的列表。",[49,7186,7187],{},"读取后修改进度，再重新写回文件。",[10,7189,313],{},[14,7191,316],{"id":316},[10,7193,7194],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,7196,323],{},{"title":76,"searchDepth":89,"depth":89,"links":7198},[7199,7200,7201,7202,7203,7204,7205,7206],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":7035,"description":7040},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[337,7214,7215],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7218,"title":7219,"body":7220,"category":337,"cover":338,"description":7224,"extension":339,"meta":7408,"navigation":116,"path":7409,"pinned":342,"publishedAt":343,"seo":7410,"slug":7411,"stem":7412,"summary":7413,"tags":7414,"updatedAt":343,"visible":116,"__hash__":7417},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7221,"toc":7398},[7222,7225,7227,7230,7232,7238,7244,7246,7268,7270,7272,7335,7337,7343,7345,7347,7363,7365,7379,7381,7389,7391,7393,7396],[10,7223,7224],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7226,16],{"id":16},[10,7228,7229],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7231,22],{"id":22},[10,7233,7234],{},[26,7235],{"alt":7236,"src":7237},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7239,7240,7243],{},[34,7241,7242],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7245,44],{"id":44},[46,7247,7248,7258,7265],{},[49,7249,2445,7250,7253,7254,7257],{},[34,7251,7252],{},"newline=\"\""," 让 ",[34,7255,7256],{},"csv"," 模块正确处理换行。",[49,7259,7260,7261,7264],{},"字段顺序由 ",[34,7262,7263],{},"fieldnames"," 决定，字典键需要与字段名一致。",[49,7266,7267],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7269,66],{"id":66},[10,7271,69],{},[71,7273,7275],{"className":73,"code":7274,"language":75,"meta":76,"style":76},"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",[34,7276,7277,7282,7286,7291,7296,7301,7306,7311,7315,7320,7325,7330],{"__ignoreMap":76},[80,7278,7279],{"class":82,"line":83},[80,7280,7281],{},"import csv\n",[80,7283,7284],{"class":82,"line":89},[80,7285,117],{"emptyLinePlaceholder":116},[80,7287,7288],{"class":82,"line":95},[80,7289,7290],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[80,7292,7293],{"class":82,"line":101},[80,7294,7295],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[80,7297,7298],{"class":82,"line":107},[80,7299,7300],{},"writer.writeheader()\n",[80,7302,7303],{"class":82,"line":113},[80,7304,7305],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[80,7307,7308],{"class":82,"line":120},[80,7309,7310],{},"writer_file.close()\n",[80,7312,7313],{"class":82,"line":126},[80,7314,117],{"emptyLinePlaceholder":116},[80,7316,7317],{"class":82,"line":132},[80,7318,7319],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[80,7321,7322],{"class":82,"line":138},[80,7323,7324],{},"for row in csv.DictReader(reader_file):\n",[80,7326,7327],{"class":82,"line":144},[80,7328,7329],{},"    print(row[\"name\"], row[\"score\"])\n",[80,7331,7332],{"class":82,"line":150},[80,7333,7334],{},"reader_file.close()\n",[10,7336,168],{},[71,7338,7341],{"className":7339,"code":7340,"language":174,"meta":76},[172],"小郑 95\n",[34,7342,7340],{"__ignoreMap":76},[10,7344,179],{},[14,7346,182],{"id":182},[184,7348,7349,7358],{},[49,7350,7351,7354,7355,7357],{},[34,7352,7353],{},"DictWriter"," 按 ",[34,7356,7263],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[49,7359,7360,7362],{},[34,7361,7242],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7364,270],{"id":270},[46,7366,7367,7370],{},[49,7368,7369],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[49,7371,7372,7373,7375,7376,7378],{},"在 macOS 以外环境忽略 ",[34,7374,7252],{}," 可能出现额外空行；统一交给 ",[34,7377,7256],{}," 模块管理换行。",[14,7380,288],{"id":288},[184,7382,7383,7386],{},[49,7384,7385],{},"写入三名学习者的课程和分数。",[49,7387,7388],{},"读取 CSV 后把分数字符串转换为整数。",[10,7390,313],{},[14,7392,316],{"id":316},[10,7394,7395],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,7397,323],{},{"title":76,"searchDepth":89,"depth":89,"links":7399},[7400,7401,7402,7403,7404,7405,7406,7407],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7219,"description":7224},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[337,7415,7416],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":4,"title":5,"body":7419,"category":337,"cover":338,"description":12,"extension":339,"meta":7633,"navigation":116,"path":341,"pinned":342,"publishedAt":343,"seo":7634,"slug":345,"stem":346,"summary":347,"tags":7635,"updatedAt":343,"visible":116,"__hash__":351},{"type":7,"value":7420,"toc":7620},[7421,7423,7425,7427,7429,7433,7439,7441,7453,7455,7457,7517,7519,7524,7526,7528,7546,7548,7556,7560,7568,7570,7574,7578,7584,7586,7596,7598,7612,7614,7616,7618],[10,7422,12],{},[14,7424,16],{"id":16},[10,7426,19],{},[14,7428,22],{"id":22},[10,7430,7431],{},[26,7432],{"alt":28,"src":29},[10,7434,32,7435,37,7437,41],{},[34,7436,36],{},[34,7438,40],{},[14,7440,44],{"id":44},[46,7442,7443,7447,7451],{},[49,7444,51,7445,54],{},[34,7446,36],{},[49,7448,7449,60],{},[34,7450,59],{},[49,7452,63],{},[14,7454,66],{"id":66},[10,7456,69],{},[71,7458,7459],{"className":73,"code":74,"language":75,"meta":76,"style":76},[34,7460,7461,7465,7469,7473,7477,7481,7485,7489,7493,7497,7501,7505,7509,7513],{"__ignoreMap":76},[80,7462,7463],{"class":82,"line":83},[80,7464,86],{},[80,7466,7467],{"class":82,"line":89},[80,7468,92],{},[80,7470,7471],{"class":82,"line":95},[80,7472,98],{},[80,7474,7475],{"class":82,"line":101},[80,7476,104],{},[80,7478,7479],{"class":82,"line":107},[80,7480,110],{},[80,7482,7483],{"class":82,"line":113},[80,7484,117],{"emptyLinePlaceholder":116},[80,7486,7487],{"class":82,"line":120},[80,7488,123],{},[80,7490,7491],{"class":82,"line":126},[80,7492,129],{},[80,7494,7495],{"class":82,"line":132},[80,7496,135],{},[80,7498,7499],{"class":82,"line":138},[80,7500,141],{},[80,7502,7503],{"class":82,"line":144},[80,7504,147],{},[80,7506,7507],{"class":82,"line":150},[80,7508,153],{},[80,7510,7511],{"class":82,"line":156},[80,7512,159],{},[80,7514,7515],{"class":82,"line":162},[80,7516,165],{},[10,7518,168],{},[71,7520,7522],{"className":7521,"code":173,"language":174,"meta":76},[172],[34,7523,173],{"__ignoreMap":76},[10,7525,179],{},[14,7527,182],{"id":182},[184,7529,7530,7538],{},[49,7531,7532,191,7534,194,7536,198],{},[34,7533,190],{},[34,7535,59],{},[34,7537,197],{},[49,7539,201,7540,204,7542,208,7544,211],{},[34,7541,36],{},[34,7543,207],{},[34,7545,40],{},[213,7547,215],{"id":215},[10,7549,7550,220,7552,223,7554,226],{},[34,7551,36],{},[34,7553,207],{},[34,7555,40],{},[10,7557,7558],{},[26,7559],{"alt":231,"src":232},[10,7561,7562,237,7564,240,7566,243],{},[34,7563,36],{},[34,7565,207],{},[34,7567,40],{},[213,7569,215],{"id":246},[10,7571,7572,252],{},[34,7573,251],{},[10,7575,7576],{},[26,7577],{"alt":257,"src":258},[10,7579,261,7580,264,7582,267],{},[34,7581,251],{},[34,7583,207],{},[14,7585,270],{"id":270},[46,7587,7588,7592],{},[49,7589,275,7590,279],{},[34,7591,278],{},[49,7593,282,7594,285],{},[34,7595,251],{},[14,7597,288],{"id":288},[184,7599,7600,7608],{},[49,7601,293,7602,297,7604,223,7606,211],{},[34,7603,296],{},[34,7605,300],{},[34,7607,303],{},[49,7609,306,7610,310],{},[34,7611,309],{},[10,7613,313],{},[14,7615,316],{"id":316},[10,7617,319],{},[321,7619,323],{},{"title":76,"searchDepth":89,"depth":89,"links":7621},[7622,7623,7624,7625,7626,7630,7631,7632],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":7627},[7628,7629],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5,"description":12},[337,349,350],{"id":7637,"title":7638,"body":7639,"category":337,"cover":338,"description":7643,"extension":339,"meta":7819,"navigation":116,"path":7820,"pinned":342,"publishedAt":343,"seo":7821,"slug":7822,"stem":7823,"summary":7824,"tags":7825,"updatedAt":343,"visible":116,"__hash__":7827},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7640,"toc":7809},[7641,7644,7646,7649,7651,7657,7663,7665,7681,7683,7685,7739,7741,7747,7749,7751,7764,7766,7779,7781,7800,7802,7804,7807],[10,7642,7643],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7645,16],{"id":16},[10,7647,7648],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7650,22],{"id":22},[10,7652,7653],{},[26,7654],{"alt":7655,"src":7656},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7658,7659,7660,7662],{},"进入 ",[34,7661,6890],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7664,44],{"id":44},[46,7666,7667,7672,7678],{},[49,7668,7669,7671],{},[34,7670,6890],{}," 把资源获取和释放配成一个清晰边界。",[49,7673,7674,7677],{},[34,7675,7676],{},"as file"," 得到的是上下文返回的资源对象。",[49,7679,7680],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7682,66],{"id":66},[10,7684,69],{},[71,7686,7688],{"className":73,"code":7687,"language":75,"meta":76,"style":76},"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",[34,7689,7690,7694,7698,7702,7706,7711,7716,7720,7725,7730,7734],{"__ignoreMap":76},[80,7691,7692],{"class":82,"line":83},[80,7693,6703],{},[80,7695,7696],{"class":82,"line":89},[80,7697,117],{"emptyLinePlaceholder":116},[80,7699,7700],{"class":82,"line":95},[80,7701,6913],{},[80,7703,7704],{"class":82,"line":101},[80,7705,117],{"emptyLinePlaceholder":116},[80,7707,7708],{"class":82,"line":107},[80,7709,7710],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[80,7712,7713],{"class":82,"line":113},[80,7714,7715],{},"    file.write(\"上下文管理器\\n\")\n",[80,7717,7718],{"class":82,"line":120},[80,7719,117],{"emptyLinePlaceholder":116},[80,7721,7722],{"class":82,"line":126},[80,7723,7724],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[80,7726,7727],{"class":82,"line":132},[80,7728,7729],{},"    print(file.read())\n",[80,7731,7732],{"class":82,"line":138},[80,7733,117],{"emptyLinePlaceholder":116},[80,7735,7736],{"class":82,"line":144},[80,7737,7738],{},"print(file.closed)\n",[10,7740,168],{},[71,7742,7745],{"className":7743,"code":7744,"language":174,"meta":76},[172],"上下文管理器\n\nTrue\n",[34,7746,7744],{"__ignoreMap":76},[10,7748,179],{},[14,7750,182],{"id":182},[184,7752,7753,7761],{},[49,7754,7659,7755,7757,7758,211],{},[34,7756,6890],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[34,7759,7760],{},"file",[49,7762,7763],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7765,270],{"id":270},[46,7767,7768,7773],{},[49,7769,4889,7770,7772],{},[34,7771,6890],{}," 代码块外继续读写已经关闭的文件对象。",[49,7774,7775,7776,7778],{},"误以为 ",[34,7777,6890],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7780,288],{"id":288},[184,7782,7783,7792],{},[49,7784,7785,7786,7789,7790,211],{},"把第 30 篇的手动 ",[34,7787,7788],{},"open\u002Fclose"," 改写为 ",[34,7791,6890],{},[49,7793,4889,7794,7796,7797,211],{},[34,7795,6890],{}," 块后检查 ",[34,7798,7799],{},"file.closed",[10,7801,313],{},[14,7803,316],{"id":316},[10,7805,7806],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,7808,323],{},{"title":76,"searchDepth":89,"depth":89,"links":7810},[7811,7812,7813,7814,7815,7816,7817,7818],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7638,"description":7643},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[337,6890,7826],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7829,"title":7830,"body":7831,"category":337,"cover":338,"description":7835,"extension":339,"meta":8047,"navigation":116,"path":8048,"pinned":342,"publishedAt":343,"seo":8049,"slug":8050,"stem":8051,"summary":8052,"tags":8053,"updatedAt":343,"visible":116,"__hash__":8056},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7832,"toc":8035},[7833,7836,7838,7841,7843,7849,7852,7854,7871,7873,7875,7943,7945,7951,7953,7955,7980,7982,7985,7991,8000,8002,8013,8015,8026,8028,8030,8033],[10,7834,7835],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7837,16],{"id":16},[10,7839,7840],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7842,22],{"id":22},[10,7844,7845],{},[26,7846],{"alt":7847,"src":7848},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7850,7851],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7853,44],{"id":44},[46,7855,7856,7862,7868],{},[49,7857,7858,7861],{},[34,7859,7860],{},"self"," 表示当前实例，由方法调用自动传入。",[49,7863,7864,7867],{},[34,7865,7866],{},"__init__"," 在实例创建过程中初始化属性。",[49,7869,7870],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7872,66],{"id":66},[10,7874,69],{},[71,7876,7878],{"className":73,"code":7877,"language":75,"meta":76,"style":76},"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",[34,7879,7880,7885,7890,7895,7900,7904,7909,7914,7919,7924,7928,7933,7938],{"__ignoreMap":76},[80,7881,7882],{"class":82,"line":83},[80,7883,7884],{},"class LearningRecord:\n",[80,7886,7887],{"class":82,"line":89},[80,7888,7889],{},"    def __init__(self, course, progress=0):\n",[80,7891,7892],{"class":82,"line":95},[80,7893,7894],{},"        self.course = course\n",[80,7896,7897],{"class":82,"line":101},[80,7898,7899],{},"        self.progress = progress\n",[80,7901,7902],{"class":82,"line":107},[80,7903,117],{"emptyLinePlaceholder":116},[80,7905,7906],{"class":82,"line":113},[80,7907,7908],{},"    def advance(self, amount):\n",[80,7910,7911],{"class":82,"line":120},[80,7912,7913],{},"        self.progress = self.progress + amount\n",[80,7915,7916],{"class":82,"line":126},[80,7917,7918],{},"        if self.progress > 100:\n",[80,7920,7921],{"class":82,"line":132},[80,7922,7923],{},"            self.progress = 100\n",[80,7925,7926],{"class":82,"line":138},[80,7927,117],{"emptyLinePlaceholder":116},[80,7929,7930],{"class":82,"line":144},[80,7931,7932],{},"record = LearningRecord(\"Python\", 40)\n",[80,7934,7935],{"class":82,"line":150},[80,7936,7937],{},"record.advance(15)\n",[80,7939,7940],{"class":82,"line":156},[80,7941,7942],{},"print(record.course, record.progress)\n",[10,7944,168],{},[71,7946,7949],{"className":7947,"code":7948,"language":174,"meta":76},[172],"Python 55\n",[34,7950,7948],{"__ignoreMap":76},[10,7952,179],{},[14,7954,182],{"id":182},[184,7956,7957,7967],{},[49,7958,7959,7960,7963,7964,7966],{},"调用 ",[34,7961,7962],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[34,7965,7866],{}," 把课程和进度保存在该实例属性中。",[49,7968,7969,7972,7973,7976,7977,7979],{},[34,7970,7971],{},"record.advance(15)"," 自动把 ",[34,7974,7975],{},"record"," 作为 ",[34,7978,7860],{},"，方法更新同一实例的进度并限制上限。",[213,7981,215],{"id":215},[10,7983,7984],{},"类是共同定义，实例则各自保存状态。",[10,7986,7987],{},[26,7988],{"alt":7989,"src":7990},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7992,7993,7994,223,7996,7999],{},"两个实例共享同一套方法定义，但 ",[34,7995,4686],{},[34,7997,7998],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,8001,270],{"id":270},[46,8003,8004,8010],{},[49,8005,8006,8007,8009],{},"调用实例方法时手工再传一次 ",[34,8008,7860],{},"。通过实例调用时 Python 会自动绑定。",[49,8011,8012],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,8014,288],{"id":288},[184,8016,8017,8023],{},[49,8018,5399,8019,8022],{},[34,8020,8021],{},"Book"," 类，保存标题和阅读页数。",[49,8024,8025],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,8027,313],{},[14,8029,316],{"id":316},[10,8031,8032],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,8034,323],{},{"title":76,"searchDepth":89,"depth":89,"links":8036},[8037,8038,8039,8040,8041,8044,8045,8046],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":8042},[8043],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7830,"description":7835},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[337,8054,8055],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":8058,"title":8059,"body":8060,"category":337,"cover":338,"description":8064,"extension":339,"meta":8242,"navigation":116,"path":8243,"pinned":342,"publishedAt":343,"seo":8244,"slug":8245,"stem":8246,"summary":8247,"tags":8248,"updatedAt":343,"visible":116,"__hash__":8251},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8061,"toc":8232},[8062,8065,8067,8070,8072,8078,8081,8083,8094,8096,8098,8165,8167,8173,8175,8177,8196,8198,8206,8208,8223,8225,8227,8230],[10,8063,8064],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,8066,16],{"id":16},[10,8068,8069],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8071,22],{"id":22},[10,8073,8074],{},[26,8075],{"alt":8076,"src":8077},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8079,8080],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8082,44],{"id":44},[46,8084,8085,8088,8091],{},[49,8086,8087],{},"封装让对象通过方法维护自己的有效状态。",[49,8089,8090],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[49,8092,8093],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8095,66],{"id":66},[10,8097,69],{},[71,8099,8101],{"className":73,"code":8100,"language":75,"meta":76,"style":76},"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",[34,8102,8103,8108,8113,8118,8122,8127,8132,8137,8141,8146,8151,8155,8160],{"__ignoreMap":76},[80,8104,8105],{"class":82,"line":83},[80,8106,8107],{},"class Storage:\n",[80,8109,8110],{"class":82,"line":89},[80,8111,8112],{},"    def save(self, text):\n",[80,8114,8115],{"class":82,"line":95},[80,8116,8117],{},"        print(\"保存：\", text)\n",[80,8119,8120],{"class":82,"line":101},[80,8121,117],{"emptyLinePlaceholder":116},[80,8123,8124],{"class":82,"line":107},[80,8125,8126],{},"class LearningService:\n",[80,8128,8129],{"class":82,"line":113},[80,8130,8131],{},"    def __init__(self, storage):\n",[80,8133,8134],{"class":82,"line":120},[80,8135,8136],{},"        self.storage = storage\n",[80,8138,8139],{"class":82,"line":126},[80,8140,117],{"emptyLinePlaceholder":116},[80,8142,8143],{"class":82,"line":132},[80,8144,8145],{},"    def finish_lesson(self, title):\n",[80,8147,8148],{"class":82,"line":138},[80,8149,8150],{},"        self.storage.save(title)\n",[80,8152,8153],{"class":82,"line":144},[80,8154,117],{"emptyLinePlaceholder":116},[80,8156,8157],{"class":82,"line":150},[80,8158,8159],{},"service = LearningService(Storage())\n",[80,8161,8162],{"class":82,"line":156},[80,8163,8164],{},"service.finish_lesson(\"异常处理\")\n",[10,8166,168],{},[71,8168,8171],{"className":8169,"code":8170,"language":174,"meta":76},[172],"保存： 异常处理\n",[34,8172,8170],{"__ignoreMap":76},[10,8174,179],{},[14,8176,182],{"id":182},[184,8178,8179,8189],{},[49,8180,8181,8184,8185,8188],{},[34,8182,8183],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[34,8186,8187],{},"save()"," 的协作对象。",[49,8190,8191,8192,8195],{},"调用业务方法时，服务把保存动作委托给 ",[34,8193,8194],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8197,270],{"id":270},[46,8199,8200,8203],{},[49,8201,8202],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[49,8204,8205],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8207,288],{"id":288},[184,8209,8210,8220],{},[49,8211,8212,8213,8216,8217,211],{},"用组合让 ",[34,8214,8215],{},"OrderService"," 使用一个 ",[34,8218,8219],{},"Notifier",[49,8221,8222],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8224,313],{},[14,8226,316],{"id":316},[10,8228,8229],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,8231,323],{},{"title":76,"searchDepth":89,"depth":89,"links":8233},[8234,8235,8236,8237,8238,8239,8240,8241],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":8059,"description":8064},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[337,8249,8250],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8253,"title":8254,"body":8255,"category":337,"cover":338,"description":8259,"extension":339,"meta":8462,"navigation":116,"path":8463,"pinned":342,"publishedAt":343,"seo":8464,"slug":8465,"stem":8466,"summary":8467,"tags":8468,"updatedAt":343,"visible":116,"__hash__":8471},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8256,"toc":8450},[8257,8260,8262,8265,8267,8273,8280,8282,8307,8309,8311,8363,8365,8371,8373,8375,8396,8398,8404,8410,8416,8418,8426,8428,8441,8443,8445,8448],[10,8258,8259],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8261,16],{"id":16},[10,8263,8264],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8266,22],{"id":22},[10,8268,8269],{},[26,8270],{"alt":8271,"src":8272},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8274,8275,8276,8279],{},"生成器运行到 ",[34,8277,8278],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8281,44],{"id":44},[46,8283,8284,8294,8304],{},[49,8285,8286,8289,8290,8293],{},[34,8287,8288],{},"iter()"," 从可迭代对象取得迭代器，",[34,8291,8292],{},"next()"," 请求下一个值。",[49,8295,8296,8297,8300,8301,8303],{},"没有更多值时迭代器抛出 ",[34,8298,8299],{},"StopIteration","，",[34,8302,4440],{}," 会自动处理。",[49,8305,8306],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8308,66],{"id":66},[10,8310,69],{},[71,8312,8314],{"className":73,"code":8313,"language":75,"meta":76,"style":76},"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",[34,8315,8316,8321,8326,8331,8336,8341,8345,8350,8355,8359],{"__ignoreMap":76},[80,8317,8318],{"class":82,"line":83},[80,8319,8320],{},"def countdown(start):\n",[80,8322,8323],{"class":82,"line":89},[80,8324,8325],{},"    current = start\n",[80,8327,8328],{"class":82,"line":95},[80,8329,8330],{},"    while current > 0:\n",[80,8332,8333],{"class":82,"line":101},[80,8334,8335],{},"        yield current\n",[80,8337,8338],{"class":82,"line":107},[80,8339,8340],{},"        current = current - 1\n",[80,8342,8343],{"class":82,"line":113},[80,8344,117],{"emptyLinePlaceholder":116},[80,8346,8347],{"class":82,"line":120},[80,8348,8349],{},"iterator = countdown(3)\n",[80,8351,8352],{"class":82,"line":126},[80,8353,8354],{},"print(next(iterator))\n",[80,8356,8357],{"class":82,"line":132},[80,8358,8354],{},[80,8360,8361],{"class":82,"line":138},[80,8362,8354],{},[10,8364,168],{},[71,8366,8369],{"className":8367,"code":8368,"language":174,"meta":76},[172],"3\n2\n1\n",[34,8370,8368],{"__ignoreMap":76},[10,8372,179],{},[14,8374,182],{"id":182},[184,8376,8377,8383],{},[49,8378,7959,8379,8382],{},[34,8380,8381],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[49,8384,8385,8386,8388,8389,8391,8392,8395],{},"每次 ",[34,8387,8292],{}," 运行到下一个 ",[34,8390,8278],{}," 并暂停，局部变量 ",[34,8393,8394],{},"current"," 和执行位置被保留。",[213,8397,215],{"id":215},[10,8399,8400,8401,8403],{},"生成器的暂停位置可以展开成多次 ",[34,8402,8292],{}," 的时间线。",[10,8405,8406],{},[26,8407],{"alt":8408,"src":8409},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8411,8412,8413,8415],{},"每次请求只推进到下一个 ",[34,8414,8278],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8417,270],{"id":270},[46,8419,8420,8423],{},[49,8421,8422],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[49,8424,8425],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8427,288],{"id":288},[184,8429,8430,8433],{},[49,8431,8432],{},"编写产生 1 到指定上限偶数的生成器。",[49,8434,4114,8435,8437,8438,8440],{},[34,8436,4440],{}," 遍历生成器，比较手动 ",[34,8439,8292],{}," 的差异。",[10,8442,313],{},[14,8444,316],{"id":316},[10,8446,8447],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,8449,323],{},{"title":76,"searchDepth":89,"depth":89,"links":8451},[8452,8453,8454,8455,8456,8459,8460,8461],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":8457},[8458],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8254,"description":8259},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[337,8469,8470],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8473,"title":8474,"body":8475,"category":337,"cover":338,"description":8479,"extension":339,"meta":8703,"navigation":116,"path":8704,"pinned":342,"publishedAt":343,"seo":8705,"slug":8706,"stem":8707,"summary":8708,"tags":8709,"updatedAt":343,"visible":116,"__hash__":8711},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8476,"toc":8691},[8477,8480,8482,8485,8487,8493,8496,8498,8518,8520,8522,8604,8606,8612,8614,8616,8638,8640,8643,8649,8656,8658,8668,8670,8682,8684,8686,8689],[10,8478,8479],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8481,16],{"id":16},[10,8483,8484],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8486,22],{"id":22},[10,8488,8489],{},[26,8490],{"alt":8491,"src":8492},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8494,8495],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8497,44],{"id":44},[46,8499,8500,8509,8512],{},[49,8501,8502,8505,8506,211],{},[34,8503,8504],{},"@trace"," 等价于 ",[34,8507,8508],{},"add = trace(add)",[49,8510,8511],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[49,8513,8514,8517],{},[34,8515,8516],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8519,66],{"id":66},[10,8521,69],{},[71,8523,8525],{"className":73,"code":8524,"language":75,"meta":76,"style":76},"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",[34,8526,8527,8532,8536,8541,8546,8551,8556,8561,8566,8571,8576,8580,8585,8589,8593,8598],{"__ignoreMap":76},[80,8528,8529],{"class":82,"line":83},[80,8530,8531],{},"from functools import wraps\n",[80,8533,8534],{"class":82,"line":89},[80,8535,117],{"emptyLinePlaceholder":116},[80,8537,8538],{"class":82,"line":95},[80,8539,8540],{},"def trace(function):\n",[80,8542,8543],{"class":82,"line":101},[80,8544,8545],{},"    @wraps(function)\n",[80,8547,8548],{"class":82,"line":107},[80,8549,8550],{},"    def wrapper(*args, **kwargs):\n",[80,8552,8553],{"class":82,"line":113},[80,8554,8555],{},"        print(\"开始：\", function.__name__)\n",[80,8557,8558],{"class":82,"line":120},[80,8559,8560],{},"        result = function(*args, **kwargs)\n",[80,8562,8563],{"class":82,"line":126},[80,8564,8565],{},"        print(\"结束：\", function.__name__)\n",[80,8567,8568],{"class":82,"line":132},[80,8569,8570],{},"        return result\n",[80,8572,8573],{"class":82,"line":138},[80,8574,8575],{},"    return wrapper\n",[80,8577,8578],{"class":82,"line":144},[80,8579,117],{"emptyLinePlaceholder":116},[80,8581,8582],{"class":82,"line":150},[80,8583,8584],{},"@trace\n",[80,8586,8587],{"class":82,"line":156},[80,8588,6282],{},[80,8590,8591],{"class":82,"line":162},[80,8592,6287],{},[80,8594,8596],{"class":82,"line":8595},15,[80,8597,117],{"emptyLinePlaceholder":116},[80,8599,8601],{"class":82,"line":8600},16,[80,8602,8603],{},"print(add(2, 3))\n",[10,8605,168],{},[71,8607,8610],{"className":8608,"code":8609,"language":174,"meta":76},[172],"开始： add\n结束： add\n5\n",[34,8611,8609],{"__ignoreMap":76},[10,8613,179],{},[14,8615,182],{"id":182},[184,8617,8618,8635],{},[49,8619,8620,8621,8624,8625,8628,8629,8632,8633,211],{},"解释器执行定义时，把原 ",[34,8622,8623],{},"add"," 函数交给 ",[34,8626,8627],{},"trace","，返回的 ",[34,8630,8631],{},"wrapper"," 重新绑定到名字 ",[34,8634,8623],{},[49,8636,8637],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[213,8639,215],{"id":215},[10,8641,8642],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8644,8645],{},[26,8646],{"alt":8647,"src":8648},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8650,8651,8653,8654,211],{},[34,8652,8504],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[34,8655,8508],{},[14,8657,270],{"id":270},[46,8659,8660,8665],{},[49,8661,8662,8663,211],{},"包装函数忘记返回原函数结果，调用方得到 ",[34,8664,5482],{},[49,8666,8667],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8669,288],{"id":288},[184,8671,8672,8675],{},[49,8673,8674],{},"编写只记录调用次数的简单装饰器。",[49,8676,8677,8678,8681],{},"删除包装函数的 ",[34,8679,8680],{},"return result","，观察调用方得到什么。",[10,8683,313],{},[14,8685,316],{"id":316},[10,8687,8688],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,8690,323],{},{"title":76,"searchDepth":89,"depth":89,"links":8692},[8693,8694,8695,8696,8697,8700,8701,8702],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":8698},[8699],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8474,"description":8479},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[337,8710,5433],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8713,"title":8714,"body":8715,"category":337,"cover":338,"description":8719,"extension":339,"meta":8906,"navigation":116,"path":8907,"pinned":342,"publishedAt":343,"seo":8908,"slug":8909,"stem":8910,"summary":8911,"tags":8912,"updatedAt":343,"visible":116,"__hash__":8915},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8716,"toc":8894},[8717,8720,8722,8725,8727,8733,8736,8738,8749,8751,8753,8828,8830,8836,8838,8840,8851,8853,8856,8862,8865,8867,8875,8877,8885,8887,8889,8892],[10,8718,8719],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8721,16],{"id":16},[10,8723,8724],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8726,22],{"id":22},[10,8728,8729],{},[26,8730],{"alt":8731,"src":8732},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8734,8735],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8737,44],{"id":44},[46,8739,8740,8743,8746],{},[49,8741,8742],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[49,8744,8745],{},"日志记录运行状态，测试判断结果是否符合约定。",[49,8747,8748],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8750,66],{"id":66},[10,8752,69],{},[71,8754,8756],{"className":73,"code":8755,"language":75,"meta":76,"style":76},"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",[34,8757,8758,8763,8768,8772,8777,8781,8786,8791,8796,8800,8805,8810,8815,8819,8823],{"__ignoreMap":76},[80,8759,8760],{"class":82,"line":83},[80,8761,8762],{},"import logging\n",[80,8764,8765],{"class":82,"line":89},[80,8766,8767],{},"import unittest\n",[80,8769,8770],{"class":82,"line":95},[80,8771,117],{"emptyLinePlaceholder":116},[80,8773,8774],{"class":82,"line":101},[80,8775,8776],{},"logging.basicConfig(level=logging.INFO)\n",[80,8778,8779],{"class":82,"line":107},[80,8780,117],{"emptyLinePlaceholder":116},[80,8782,8783],{"class":82,"line":113},[80,8784,8785],{},"def clamp_progress(value):\n",[80,8787,8788],{"class":82,"line":120},[80,8789,8790],{},"    logging.info(\"检查进度：%s\", value)\n",[80,8792,8793],{"class":82,"line":126},[80,8794,8795],{},"    return max(0, min(100, value))\n",[80,8797,8798],{"class":82,"line":132},[80,8799,117],{"emptyLinePlaceholder":116},[80,8801,8802],{"class":82,"line":138},[80,8803,8804],{},"class ProgressTest(unittest.TestCase):\n",[80,8806,8807],{"class":82,"line":144},[80,8808,8809],{},"    def test_upper_limit(self):\n",[80,8811,8812],{"class":82,"line":150},[80,8813,8814],{},"        self.assertEqual(clamp_progress(120), 100)\n",[80,8816,8817],{"class":82,"line":156},[80,8818,117],{"emptyLinePlaceholder":116},[80,8820,8821],{"class":82,"line":162},[80,8822,6296],{},[80,8824,8825],{"class":82,"line":8595},[80,8826,8827],{},"    unittest.main()\n",[10,8829,168],{},[71,8831,8834],{"className":8832,"code":8833,"language":174,"meta":76},[172],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[34,8835,8833],{"__ignoreMap":76},[10,8837,179],{},[14,8839,182],{"id":182},[184,8841,8842,8848],{},[49,8843,8844,8847],{},[34,8845,8846],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[49,8849,8850],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[213,8852,215],{"id":215},[10,8854,8855],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8857,8858],{},[26,8859],{"alt":8860,"src":8861},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8863,8864],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8866,270],{"id":270},[46,8868,8869,8872],{},[49,8870,8871],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[49,8873,8874],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8876,288],{"id":288},[184,8878,8879,8882],{},[49,8880,8881],{},"为负数进度增加测试。",[49,8883,8884],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8886,313],{},[14,8888,316],{"id":316},[10,8890,8891],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,8893,323],{},{"title":76,"searchDepth":89,"depth":89,"links":8895},[8896,8897,8898,8899,8900,8903,8904,8905],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":8901},[8902],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8714,"description":8719},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[337,8913,8914],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8917,"title":8918,"body":8919,"category":337,"cover":338,"description":8923,"extension":339,"meta":9223,"navigation":116,"path":9224,"pinned":342,"publishedAt":343,"seo":9225,"slug":9226,"stem":9227,"summary":9228,"tags":9229,"updatedAt":343,"visible":116,"__hash__":9232},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8920,"toc":9210},[8921,8924,8926,8929,8931,8937,8940,8942,8957,8959,8961,9108,9110,9116,9118,9120,9133,9135,9138,9144,9147,9149,9152,9158,9165,9167,9178,9180,9201,9203,9205,9208],[10,8922,8923],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8925,16],{"id":16},[10,8927,8928],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8930,22],{"id":22},[10,8932,8933],{},[26,8934],{"alt":8935,"src":8936},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8938,8939],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8941,44],{"id":44},[46,8943,8944,8947,8950],{},[49,8945,8946],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[49,8948,8949],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[49,8951,8952,8953,8956],{},"实际扩展前先为 ",[34,8954,8955],{},"add()"," 和存储边界补充测试。",[14,8958,66],{"id":66},[10,8960,69],{},[71,8962,8964],{"className":73,"code":8963,"language":75,"meta":76,"style":76},"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",[34,8965,8966,8970,8974,8978,8983,8988,8993,8998,9002,9007,9012,9017,9022,9027,9031,9036,9041,9047,9052,9058,9063,9068,9074,9080,9086,9091,9097,9102],{"__ignoreMap":76},[80,8967,8968],{"class":82,"line":83},[80,8969,7093],{},[80,8971,8972],{"class":82,"line":89},[80,8973,6703],{},[80,8975,8976],{"class":82,"line":95},[80,8977,117],{"emptyLinePlaceholder":116},[80,8979,8980],{"class":82,"line":101},[80,8981,8982],{},"class LearningRecords:\n",[80,8984,8985],{"class":82,"line":107},[80,8986,8987],{},"    def __init__(self, file_path):\n",[80,8989,8990],{"class":82,"line":113},[80,8991,8992],{},"        self.file_path = Path(file_path)\n",[80,8994,8995],{"class":82,"line":120},[80,8996,8997],{},"        self.items = []\n",[80,8999,9000],{"class":82,"line":126},[80,9001,117],{"emptyLinePlaceholder":116},[80,9003,9004],{"class":82,"line":132},[80,9005,9006],{},"    def add(self, title):\n",[80,9008,9009],{"class":82,"line":138},[80,9010,9011],{},"        title = title.strip()\n",[80,9013,9014],{"class":82,"line":144},[80,9015,9016],{},"        if not title:\n",[80,9018,9019],{"class":82,"line":150},[80,9020,9021],{},"            raise ValueError(\"课程名称不能为空\")\n",[80,9023,9024],{"class":82,"line":156},[80,9025,9026],{},"        self.items.append({\"title\": title, \"done\": False})\n",[80,9028,9029],{"class":82,"line":162},[80,9030,117],{"emptyLinePlaceholder":116},[80,9032,9033],{"class":82,"line":8595},[80,9034,9035],{},"    def save(self):\n",[80,9037,9038],{"class":82,"line":8600},[80,9039,9040],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[80,9042,9044],{"class":82,"line":9043},17,[80,9045,9046],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[80,9048,9050],{"class":82,"line":9049},18,[80,9051,117],{"emptyLinePlaceholder":116},[80,9053,9055],{"class":82,"line":9054},19,[80,9056,9057],{},"records = LearningRecords(\"learning-records.json\")\n",[80,9059,9061],{"class":82,"line":9060},20,[80,9062,117],{"emptyLinePlaceholder":116},[80,9064,9066],{"class":82,"line":9065},21,[80,9067,123],{},[80,9069,9071],{"class":82,"line":9070},22,[80,9072,9073],{},"    title = input(\"输入已学习课程：\")\n",[80,9075,9077],{"class":82,"line":9076},23,[80,9078,9079],{},"    records.add(title)\n",[80,9081,9083],{"class":82,"line":9082},24,[80,9084,9085],{},"    records.save()\n",[80,9087,9089],{"class":82,"line":9088},25,[80,9090,135],{},[80,9092,9094],{"class":82,"line":9093},26,[80,9095,9096],{},"    print(\"无法保存：\", error)\n",[80,9098,9100],{"class":82,"line":9099},27,[80,9101,147],{},[80,9103,9105],{"class":82,"line":9104},28,[80,9106,9107],{},"    print(\"已保存 1 条学习记录\")\n",[10,9109,168],{},[71,9111,9114],{"className":9112,"code":9113,"language":174,"meta":76},[172],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[34,9115,9113],{"__ignoreMap":76},[10,9117,179],{},[14,9119,182],{"id":182},[184,9121,9122,9128],{},[49,9123,9124,9125,9127],{},"输入层取得课程名后，",[34,9126,8955],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[49,9129,9130,9132],{},[34,9131,8187],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[213,9134,215],{"id":215},[10,9136,9137],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9139,9140],{},[26,9141],{"alt":9142,"src":9143},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9145,9146],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[213,9148,215],{"id":246},[10,9150,9151],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9153,9154],{},[26,9155],{"alt":9156,"src":9157},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9159,9160,9161,9164],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[34,9162,9163],{},"load()"," 把文件状态恢复到内存。",[14,9166,270],{"id":270},[46,9168,9169,9172],{},[49,9170,9171],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[49,9173,9174,9175,9177],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[34,9176,9163],{}," 是下一项必要扩展。",[14,9179,288],{"id":288},[184,9181,9182,9188,9191],{},[49,9183,9184,9185,9187],{},"增加 ",[34,9186,9163],{},"，文件不存在时从空列表开始。",[49,9189,9190],{},"增加按序号标记完成的功能，并校验序号范围。",[49,9192,9193,9194,9197,9198,9200],{},"把输入循环放进 ",[34,9195,9196],{},"main()","，通过 ",[34,9199,6238],{}," 控制程序入口。",[10,9202,313],{},[14,9204,316],{"id":316},[10,9206,9207],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[321,9209,323],{},{"title":76,"searchDepth":89,"depth":89,"links":9211},[9212,9213,9214,9215,9216,9220,9221,9222],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":9217},[9218,9219],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8918,"description":8923},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[337,9230,9231],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9234,9337,9456,9587,9730,9855,9992,10129,10270,10439,10576,10709,10832,10961,11088,11251,11427,11568,11697,11846,11989,12110,12233,12382,12535,12700,12827,13008,13151,13308,13459,13606,13761,13979,14134,14309,14460,14627,14814,14977,15219,15459],{"id":1500,"title":1501,"body":9235,"category":337,"cover":338,"description":1506,"extension":339,"meta":9334,"navigation":116,"path":1625,"pinned":342,"publishedAt":343,"seo":9335,"slug":1627,"stem":1628,"summary":1629,"tags":9336,"updatedAt":343,"visible":116,"__hash__":1632},{"type":7,"value":9236,"toc":9324},[9237,9239,9241,9243,9245,9249,9253,9255,9265,9267,9269,9277,9279,9284,9286,9288,9298,9300,9308,9310,9316,9318,9320,9322],[10,9238,1506],{},[14,9240,16],{"id":16},[10,9242,1511],{},[14,9244,22],{"id":22},[10,9246,9247],{},[26,9248],{"alt":1518,"src":1519},[10,9250,9251,1524],{},[34,9252,1278],{},[14,9254,44],{"id":44},[46,9256,9257,9261,9263],{},[49,9258,1531,9259,1534],{},[34,9260,1278],{},[49,9262,1537],{},[49,9264,1540],{},[14,9266,66],{"id":66},[10,9268,69],{},[71,9270,9271],{"className":73,"code":1547,"language":75,"meta":76,"style":76},[34,9272,9273],{"__ignoreMap":76},[80,9274,9275],{"class":82,"line":83},[80,9276,1547],{},[10,9278,168],{},[71,9280,9282],{"className":9281,"code":1559,"language":174,"meta":76},[172],[34,9283,1559],{"__ignoreMap":76},[10,9285,179],{},[14,9287,182],{"id":182},[184,9289,9290,9294],{},[49,9291,1570,9292,1574],{},[34,9293,1573],{},[49,9295,1577,9296,1581],{},[34,9297,1580],{},[14,9299,270],{"id":270},[46,9301,9302,9304],{},[49,9303,1588],{},[49,9305,1591,9306,1594],{},[34,9307,1278],{},[14,9309,288],{"id":288},[184,9311,9312,9314],{},[49,9313,1601],{},[49,9315,1604],{},[10,9317,313],{},[14,9319,316],{"id":316},[10,9321,1611],{},[321,9323,323],{},{"title":76,"searchDepth":89,"depth":89,"links":9325},[9326,9327,9328,9329,9330,9331,9332,9333],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":1501,"description":1506},[337,1496,1631],{"id":1634,"title":1635,"body":9338,"category":337,"cover":338,"description":1640,"extension":339,"meta":9453,"navigation":116,"path":1777,"pinned":342,"publishedAt":343,"seo":9454,"slug":1779,"stem":1780,"summary":1781,"tags":9455,"updatedAt":343,"visible":116,"__hash__":1784},{"type":7,"value":9339,"toc":9443},[9340,9342,9344,9346,9348,9352,9356,9358,9368,9370,9372,9392,9394,9399,9401,9403,9413,9415,9425,9427,9435,9437,9439,9441],[10,9341,1640],{},[14,9343,16],{"id":16},[10,9345,1645],{},[14,9347,22],{"id":22},[10,9349,9350],{},[26,9351],{"alt":1652,"src":1653},[10,9353,1656,9354,1659],{},[34,9355,801],{},[14,9357,44],{"id":44},[46,9359,9360,9362,9364],{},[49,9361,1666],{},[49,9363,1669],{},[49,9365,1672,9366,1676],{},[34,9367,1675],{},[14,9369,66],{"id":66},[10,9371,1681],{},[71,9373,9374],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,9375,9376,9382],{"__ignoreMap":76},[80,9377,9378,9380],{"class":82,"line":83},[80,9379,801],{"class":710},[80,9381,714],{"class":713},[80,9383,9384,9386,9388,9390],{"class":82,"line":89},[80,9385,801],{"class":710},[80,9387,743],{"class":713},[80,9389,747],{"class":746},[80,9391,714],{"class":713},[10,9393,168],{},[71,9395,9397],{"className":9396,"code":1707,"language":174,"meta":76},[172],[34,9398,1707],{"__ignoreMap":76},[10,9400,179],{},[14,9402,182],{"id":182},[184,9404,9405,9409],{},[49,9406,9407,1721],{},[34,9408,1720],{},[49,9410,9411,1726],{},[34,9412,809],{},[14,9414,270],{"id":270},[46,9416,9417,9421],{},[49,9418,1733,9419,1736],{},[34,9420,801],{},[49,9422,1739,9423,1742],{},[34,9424,801],{},[14,9426,288],{"id":288},[184,9428,9429,9433],{},[49,9430,1048,9431,1752],{},[34,9432,1751],{},[49,9434,1755],{},[10,9436,313],{},[14,9438,316],{"id":316},[10,9440,1762],{},[321,9442,1765],{},{"title":76,"searchDepth":89,"depth":89,"links":9444},[9445,9446,9447,9448,9449,9450,9451,9452],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":1635,"description":1640},[337,1783,1162],{"id":1786,"title":1787,"body":9457,"category":337,"cover":338,"description":1953,"extension":339,"meta":9584,"navigation":116,"path":1955,"pinned":342,"publishedAt":343,"seo":9585,"slug":1957,"stem":1958,"summary":1959,"tags":9586,"updatedAt":343,"visible":116,"__hash__":1963},{"type":7,"value":9458,"toc":9574},[9459,9463,9465,9467,9469,9473,9475,9477,9493,9495,9497,9517,9519,9524,9526,9528,9540,9542,9552,9554,9564,9566,9568,9572],[10,9460,1792,9461,1795],{},[34,9462,1278],{},[14,9464,16],{"id":16},[10,9466,1800],{},[14,9468,22],{"id":22},[10,9470,9471],{},[26,9472],{"alt":1807,"src":1808},[10,9474,1811],{},[14,9476,44],{"id":44},[46,9478,9479,9485,9489],{},[49,9480,1818,9481,1821,9483,211],{},[34,9482,801],{},[34,9484,1824],{},[49,9486,1827,9487,1831],{},[34,9488,1830],{},[49,9490,1834,9491,1837],{},[34,9492,1278],{},[14,9494,66],{"id":66},[10,9496,69],{},[71,9498,9499],{"className":1844,"code":1845,"language":1846,"meta":76,"style":76},[34,9500,9501,9505,9509,9513],{"__ignoreMap":76},[80,9502,9503],{"class":82,"line":83},[80,9504,1853],{},[80,9506,9507],{"class":82,"line":89},[80,9508,1858],{},[80,9510,9511],{"class":82,"line":95},[80,9512,1863],{},[80,9514,9515],{"class":82,"line":101},[80,9516,1868],{},[10,9518,168],{},[71,9520,9522],{"className":9521,"code":1874,"language":174,"meta":76},[172],[34,9523,1874],{"__ignoreMap":76},[10,9525,179],{},[14,9527,182],{"id":182},[184,9529,9530,9536],{},[49,9531,1885,9532,1889,9534,211],{},[34,9533,1888],{},[34,9535,1892],{},[49,9537,1895,9538,1898],{},[34,9539,1580],{},[14,9541,270],{"id":270},[46,9543,9544,9550],{},[49,9545,1905,9546,1908,9548,1911],{},[34,9547,1824],{},[34,9549,1278],{},[49,9551,1914],{},[14,9553,288],{"id":288},[184,9555,9556,9560],{},[49,9557,1921,9558,211],{},[34,9559,1924],{},[49,9561,1927,9562,1930],{},[34,9563,1580],{},[10,9565,313],{},[14,9567,316],{"id":316},[10,9569,1937,9570,1940],{},[34,9571,1278],{},[321,9573,323],{},{"title":76,"searchDepth":89,"depth":89,"links":9575},[9576,9577,9578,9579,9580,9581,9582,9583],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":1787,"description":1953},[337,1961,1962],{"id":1965,"title":1966,"body":9588,"category":337,"cover":338,"description":1971,"extension":339,"meta":9727,"navigation":116,"path":2143,"pinned":342,"publishedAt":343,"seo":9728,"slug":2145,"stem":2146,"summary":2147,"tags":9729,"updatedAt":343,"visible":116,"__hash__":2151},{"type":7,"value":9589,"toc":9717},[9590,9592,9594,9596,9598,9602,9606,9608,9620,9622,9624,9660,9662,9667,9669,9671,9687,9689,9699,9701,9709,9711,9713,9715],[10,9591,1971],{},[14,9593,16],{"id":16},[10,9595,1976],{},[14,9597,22],{"id":22},[10,9599,9600],{},[26,9601],{"alt":1983,"src":1984},[10,9603,9604,1990],{},[34,9605,1989],{},[14,9607,44],{"id":44},[46,9609,9610,9612,9618],{},[49,9611,1997],{},[49,9613,9614,2003,9616,2007],{},[34,9615,2002],{},[34,9617,2006],{},[49,9619,2010],{},[14,9621,66],{"id":66},[10,9623,1681],{},[71,9625,9626],{"className":701,"code":2017,"language":703,"meta":76,"style":76},[34,9627,9628,9634,9640,9644,9654],{"__ignoreMap":76},[80,9629,9630,9632],{"class":82,"line":83},[80,9631,2024],{"class":710},[80,9633,2027],{"class":746},[80,9635,9636,9638],{"class":82,"line":89},[80,9637,2032],{"class":713},[80,9639,2027],{"class":746},[80,9641,9642],{"class":82,"line":95},[80,9643,2039],{"class":713},[80,9645,9646,9648,9650,9652],{"class":82,"line":101},[80,9647,2044],{"class":713},[80,9649,2047],{"class":746},[80,9651,2051],{"class":2050},[80,9653,1322],{"class":746},[80,9655,9656,9658],{"class":82,"line":107},[80,9657,801],{"class":710},[80,9659,1322],{"class":746},[10,9661,168],{},[71,9663,9665],{"className":9664,"code":2065,"language":174,"meta":76},[172],[34,9666,2065],{"__ignoreMap":76},[10,9668,179],{},[14,9670,182],{"id":182},[184,9672,9673,9681],{},[49,9674,9675,2078,9677,2081,9679,2084],{},[34,9676,2024],{},[34,9678,2032],{},[34,9680,2002],{},[49,9682,9683,2089,9685,2093],{},[34,9684,1989],{},[34,9686,2092],{},[14,9688,270],{"id":270},[46,9690,9691,9697],{},[49,9692,2100,9693,223,9695,211],{},[34,9694,2002],{},[34,9696,2006],{},[49,9698,2107],{},[14,9700,288],{"id":288},[184,9702,9703,9707],{},[49,9704,2114,9705,2118],{},[34,9706,2117],{},[49,9708,2121],{},[10,9710,313],{},[14,9712,316],{"id":316},[10,9714,2128],{},[321,9716,2131],{},{"title":76,"searchDepth":89,"depth":89,"links":9718},[9719,9720,9721,9722,9723,9724,9725,9726],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":1966,"description":1971},[337,2149,2150],{"id":2153,"title":2154,"body":9731,"category":337,"cover":338,"description":2159,"extension":339,"meta":9852,"navigation":116,"path":2308,"pinned":342,"publishedAt":343,"seo":9853,"slug":2310,"stem":2311,"summary":2312,"tags":9854,"updatedAt":343,"visible":116,"__hash__":2316},{"type":7,"value":9732,"toc":9842},[9733,9735,9737,9739,9741,9745,9753,9755,9769,9771,9773,9789,9791,9796,9798,9800,9814,9816,9822,9824,9834,9836,9838,9840],[10,9734,2159],{},[14,9736,16],{"id":16},[10,9738,2164],{},[14,9740,22],{"id":22},[10,9742,9743],{},[26,9744],{"alt":2171,"src":2172},[10,9746,2175,9747,211,9749,2181,9751,211],{},[34,9748,1580],{},[34,9750,2180],{},[34,9752,1888],{},[14,9754,44],{"id":44},[46,9756,9757,9761,9767],{},[49,9758,9759,2193],{},[34,9760,2192],{},[49,9762,9763,2199,9765,211],{},[34,9764,2198],{},[34,9766,2202],{},[49,9768,2205],{},[14,9770,66],{"id":66},[10,9772,69],{},[71,9774,9775],{"className":73,"code":2212,"language":75,"meta":76,"style":76},[34,9776,9777,9781,9785],{"__ignoreMap":76},[80,9778,9779],{"class":82,"line":83},[80,9780,2219],{},[80,9782,9783],{"class":82,"line":89},[80,9784,2224],{},[80,9786,9787],{"class":82,"line":95},[80,9788,2229],{},[10,9790,168],{},[71,9792,9794],{"className":9793,"code":2235,"language":174,"meta":76},[172],[34,9795,2235],{"__ignoreMap":76},[10,9797,179],{},[14,9799,182],{"id":182},[184,9801,9802,9808],{},[49,9803,9804,2249,9806,211],{},[34,9805,2248],{},[34,9807,2202],{},[49,9809,9810,2256,9812,2260],{},[34,9811,1580],{},[34,9813,2259],{},[14,9815,270],{"id":270},[46,9817,9818,9820],{},[49,9819,2267],{},[49,9821,2270],{},[14,9823,288],{"id":288},[184,9825,9826,9828],{},[49,9827,2277],{},[49,9829,2280,9830,2283,9832,2287],{},[34,9831,2180],{},[34,9833,2286],{},[10,9835,313],{},[14,9837,316],{"id":316},[10,9839,2294],{},[321,9841,323],{},{"title":76,"searchDepth":89,"depth":89,"links":9843},[9844,9845,9846,9847,9848,9849,9850,9851],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":2154,"description":2159},[337,2314,2315],{"id":2318,"title":2319,"body":9856,"category":337,"cover":338,"description":2324,"extension":339,"meta":9989,"navigation":116,"path":2491,"pinned":342,"publishedAt":343,"seo":9990,"slug":2493,"stem":2494,"summary":2495,"tags":9991,"updatedAt":343,"visible":116,"__hash__":2499},{"type":7,"value":9857,"toc":9979},[9858,9860,9862,9864,9866,9870,9872,9874,9890,9892,9894,9918,9920,9925,9927,9929,9945,9947,9959,9961,9971,9973,9975,9977],[10,9859,2324],{},[14,9861,16],{"id":16},[10,9863,2329],{},[14,9865,22],{"id":22},[10,9867,9868],{},[26,9869],{"alt":2336,"src":2337},[10,9871,2340],{},[14,9873,44],{"id":44},[46,9875,9876,9878,9884],{},[49,9877,2347],{},[49,9879,2350,9880,2283,9882,2357],{},[34,9881,2353],{},[34,9883,2356],{},[49,9885,2360,9886,220,9888,2367],{},[34,9887,2363],{},[34,9889,2366],{},[14,9891,66],{"id":66},[10,9893,69],{},[71,9895,9896],{"className":73,"code":2374,"language":75,"meta":76,"style":76},[34,9897,9898,9902,9906,9910,9914],{"__ignoreMap":76},[80,9899,9900],{"class":82,"line":83},[80,9901,2381],{},[80,9903,9904],{"class":82,"line":89},[80,9905,2386],{},[80,9907,9908],{"class":82,"line":95},[80,9909,117],{"emptyLinePlaceholder":116},[80,9911,9912],{"class":82,"line":101},[80,9913,2395],{},[80,9915,9916],{"class":82,"line":107},[80,9917,2386],{},[10,9919,168],{},[71,9921,9923],{"className":9922,"code":2405,"language":174,"meta":76},[172],[34,9924,2405],{"__ignoreMap":76},[10,9926,179],{},[14,9928,182],{"id":182},[184,9930,9931,9937],{},[49,9932,1048,9933,2419,9935,2422],{},[34,9934,2418],{},[34,9936,2353],{},[49,9938,1048,9939,2428,9941,2432,9943,211],{},[34,9940,2427],{},[34,9942,2431],{},[34,9944,2435],{},[14,9946,270],{"id":270},[46,9948,9949,9951],{},[49,9950,2442],{},[49,9952,2445,9953,220,9955,220,9957,2453],{},[34,9954,2363],{},[34,9956,2366],{},[34,9958,2452],{},[14,9960,288],{"id":288},[184,9962,9963,9969],{},[49,9964,2460,9965,223,9967,2467],{},[34,9966,2463],{},[34,9968,2466],{},[49,9970,2470],{},[10,9972,313],{},[14,9974,316],{"id":316},[10,9976,2477],{},[321,9978,323],{},{"title":76,"searchDepth":89,"depth":89,"links":9980},[9981,9982,9983,9984,9985,9986,9987,9988],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":2319,"description":2324},[337,2497,2498],{"id":2501,"title":2502,"body":9993,"category":337,"cover":338,"description":2507,"extension":339,"meta":10126,"navigation":116,"path":2672,"pinned":342,"publishedAt":343,"seo":10127,"slug":2674,"stem":2675,"summary":2676,"tags":10128,"updatedAt":343,"visible":116,"__hash__":2680},{"type":7,"value":9994,"toc":10116},[9995,9997,9999,10001,10003,10007,10009,10011,10029,10031,10033,10069,10071,10076,10078,10080,10090,10092,10100,10102,10108,10110,10112,10114],[10,9996,2507],{},[14,9998,16],{"id":16},[10,10000,2512],{},[14,10002,22],{"id":22},[10,10004,10005],{},[26,10006],{"alt":2519,"src":2520},[10,10008,2523],{},[14,10010,44],{"id":44},[46,10012,10013,10019,10027],{},[49,10014,10015,2533,10017,2537],{},[34,10016,2532],{},[34,10018,2536],{},[49,10020,10021,2543,10023,2547,10025,2551],{},[34,10022,2542],{},[34,10024,2546],{},[34,10026,2550],{},[49,10028,2554],{},[14,10030,66],{"id":66},[10,10032,69],{},[71,10034,10035],{"className":73,"code":2561,"language":75,"meta":76,"style":76},[34,10036,10037,10041,10045,10049,10053,10057,10061,10065],{"__ignoreMap":76},[80,10038,10039],{"class":82,"line":83},[80,10040,2568],{},[80,10042,10043],{"class":82,"line":89},[80,10044,2573],{},[80,10046,10047],{"class":82,"line":95},[80,10048,2578],{},[80,10050,10051],{"class":82,"line":101},[80,10052,117],{"emptyLinePlaceholder":116},[80,10054,10055],{"class":82,"line":107},[80,10056,2587],{},[80,10058,10059],{"class":82,"line":113},[80,10060,2592],{},[80,10062,10063],{"class":82,"line":120},[80,10064,2597],{},[80,10066,10067],{"class":82,"line":126},[80,10068,2602],{},[10,10070,168],{},[71,10072,10074],{"className":10073,"code":2608,"language":174,"meta":76},[172],[34,10075,2608],{"__ignoreMap":76},[10,10077,179],{},[14,10079,182],{"id":182},[184,10081,10082,10086],{},[49,10083,10084,2622],{},[34,10085,2621],{},[49,10087,10088,2628],{},[34,10089,2627],{},[14,10091,270],{"id":270},[46,10093,10094,10098],{},[49,10095,2635,10096,211],{},[34,10097,2638],{},[49,10099,2641],{},[14,10101,288],{"id":288},[184,10103,10104,10106],{},[49,10105,2648],{},[49,10107,2651],{},[10,10109,313],{},[14,10111,316],{"id":316},[10,10113,2658],{},[321,10115,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10117},[10118,10119,10120,10121,10122,10123,10124,10125],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":2502,"description":2507},[337,2678,2679],{"id":2682,"title":2683,"body":10130,"category":337,"cover":338,"description":2688,"extension":339,"meta":10267,"navigation":116,"path":2864,"pinned":342,"publishedAt":343,"seo":10268,"slug":2866,"stem":2867,"summary":2868,"tags":10269,"updatedAt":343,"visible":116,"__hash__":2872},{"type":7,"value":10131,"toc":10255},[10132,10134,10136,10138,10140,10144,10150,10152,10160,10162,10164,10188,10190,10195,10197,10199,10217,10219,10221,10225,10227,10229,10235,10237,10247,10249,10251,10253],[10,10133,2688],{},[14,10135,16],{"id":16},[10,10137,2693],{},[14,10139,22],{"id":22},[10,10141,10142],{},[26,10143],{"alt":2700,"src":2701},[10,10145,2704,10146,2708,10148,211],{},[34,10147,2707],{},[34,10149,2711],{},[14,10151,44],{"id":44},[46,10153,10154,10156,10158],{},[49,10155,2718],{},[49,10157,2721],{},[49,10159,2724],{},[14,10161,66],{"id":66},[10,10163,69],{},[71,10165,10166],{"className":73,"code":2731,"language":75,"meta":76,"style":76},[34,10167,10168,10172,10176,10180,10184],{"__ignoreMap":76},[80,10169,10170],{"class":82,"line":83},[80,10171,2738],{},[80,10173,10174],{"class":82,"line":89},[80,10175,2743],{},[80,10177,10178],{"class":82,"line":95},[80,10179,2748],{},[80,10181,10182],{"class":82,"line":101},[80,10183,2753],{},[80,10185,10186],{"class":82,"line":107},[80,10187,2758],{},[10,10189,168],{},[71,10191,10193],{"className":10192,"code":2764,"language":174,"meta":76},[172],[34,10194,2764],{"__ignoreMap":76},[10,10196,179],{},[14,10198,182],{"id":182},[184,10200,10201,10209],{},[49,10202,2775,10203,2778,10205,2782,10207,2786],{},[34,10204,337],{},[34,10206,2781],{},[34,10208,2785],{},[49,10210,10211,2792,10213,2796,10215,2800],{},[34,10212,2791],{},[34,10214,2795],{},[34,10216,2799],{},[213,10218,215],{"id":215},[10,10220,2805],{},[10,10222,10223],{},[26,10224],{"alt":2810,"src":2811},[10,10226,2814],{},[14,10228,270],{"id":270},[46,10230,10231,10233],{},[49,10232,2821],{},[49,10234,2824],{},[14,10236,288],{"id":288},[184,10238,10239,10245],{},[49,10240,2831,10241,2835,10243,211],{},[34,10242,2834],{},[34,10244,2838],{},[49,10246,2841],{},[10,10248,313],{},[14,10250,316],{"id":316},[10,10252,2848],{},[321,10254,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10256},[10257,10258,10259,10260,10261,10264,10265,10266],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":10262},[10263],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":2683,"description":2688},[337,2870,2871],{"id":2874,"title":2875,"body":10271,"category":337,"cover":338,"description":2880,"extension":339,"meta":10436,"navigation":116,"path":3095,"pinned":342,"publishedAt":343,"seo":10437,"slug":3097,"stem":3098,"summary":3099,"tags":10438,"updatedAt":343,"visible":116,"__hash__":3103},{"type":7,"value":10272,"toc":10424},[10273,10275,10277,10279,10281,10285,10291,10293,10313,10315,10317,10353,10355,10360,10362,10364,10378,10380,10382,10386,10392,10394,10404,10406,10416,10418,10420,10422],[10,10274,2880],{},[14,10276,16],{"id":16},[10,10278,2885],{},[14,10280,22],{"id":22},[10,10282,10283],{},[26,10284],{"alt":2892,"src":2893},[10,10286,2896,10287,1119,10289,2903],{},[34,10288,2899],{},[34,10290,2902],{},[14,10292,44],{"id":44},[46,10294,10295,10303,10311],{},[49,10296,10297,2913,10299,2917,10301,2921],{},[34,10298,2912],{},[34,10300,2916],{},[34,10302,2920],{},[49,10304,10305,2927,10307,2931,10309,2935],{},[34,10306,2926],{},[34,10308,2930],{},[34,10310,2934],{},[49,10312,2938],{},[14,10314,66],{"id":66},[10,10316,69],{},[71,10318,10319],{"className":73,"code":2945,"language":75,"meta":76,"style":76},[34,10320,10321,10325,10329,10333,10337,10341,10345,10349],{"__ignoreMap":76},[80,10322,10323],{"class":82,"line":83},[80,10324,2952],{},[80,10326,10327],{"class":82,"line":89},[80,10328,2957],{},[80,10330,10331],{"class":82,"line":95},[80,10332,117],{"emptyLinePlaceholder":116},[80,10334,10335],{"class":82,"line":101},[80,10336,2966],{},[80,10338,10339],{"class":82,"line":107},[80,10340,2971],{},[80,10342,10343],{"class":82,"line":113},[80,10344,2976],{},[80,10346,10347],{"class":82,"line":120},[80,10348,2981],{},[80,10350,10351],{"class":82,"line":126},[80,10352,2986],{},[10,10354,168],{},[71,10356,10358],{"className":10357,"code":2992,"language":174,"meta":76},[172],[34,10359,2992],{"__ignoreMap":76},[10,10361,179],{},[14,10363,182],{"id":182},[184,10365,10366,10372],{},[49,10367,10368,3006,10370,3010],{},[34,10369,3005],{},[34,10371,3009],{},[49,10373,10374,3016,10376,3019],{},[34,10375,3015],{},[34,10377,2934],{},[213,10379,215],{"id":215},[10,10381,3024],{},[10,10383,10384],{},[26,10385],{"alt":3029,"src":3030},[10,10387,10388,3035,10390,3038],{},[34,10389,2926],{},[34,10391,2930],{},[14,10393,270],{"id":270},[46,10395,10396,10402],{},[49,10397,3045,10398,3048,10400,3051],{},[34,10399,2920],{},[34,10401,2912],{},[49,10403,3054],{},[14,10405,288],{"id":288},[184,10407,10408,10412],{},[49,10409,3061,10410,3065],{},[34,10411,3064],{},[49,10413,3068,10414,3072],{},[34,10415,3071],{},[10,10417,313],{},[14,10419,316],{"id":316},[10,10421,3079],{},[321,10423,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10425},[10426,10427,10428,10429,10430,10433,10434,10435],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":10431},[10432],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":2875,"description":2880},[337,3101,3102],{"id":3105,"title":3106,"body":10440,"category":337,"cover":338,"description":3111,"extension":339,"meta":10573,"navigation":116,"path":3279,"pinned":342,"publishedAt":343,"seo":10574,"slug":3281,"stem":3282,"summary":3283,"tags":10575,"updatedAt":343,"visible":116,"__hash__":3286},{"type":7,"value":10441,"toc":10563},[10442,10444,10446,10448,10450,10454,10464,10466,10476,10478,10480,10508,10510,10515,10517,10519,10533,10535,10543,10545,10555,10557,10559,10561],[10,10443,3111],{},[14,10445,16],{"id":16},[10,10447,3116],{},[14,10449,22],{"id":22},[10,10451,10452],{},[26,10453],{"alt":3123,"src":3124},[10,10455,10456,3130,10458,3134,10460,3138,10462,3141],{},[34,10457,3129],{},[34,10459,3133],{},[34,10461,3137],{},[34,10463,190],{},[14,10465,44],{"id":44},[46,10467,10468,10470,10474],{},[49,10469,3148],{},[49,10471,10472,3153],{},[34,10473,190],{},[49,10475,3156],{},[14,10477,66],{"id":66},[10,10479,69],{},[71,10481,10482],{"className":73,"code":3163,"language":75,"meta":76,"style":76},[34,10483,10484,10488,10492,10496,10500,10504],{"__ignoreMap":76},[80,10485,10486],{"class":82,"line":83},[80,10487,3170],{},[80,10489,10490],{"class":82,"line":89},[80,10491,3175],{},[80,10493,10494],{"class":82,"line":95},[80,10495,3180],{},[80,10497,10498],{"class":82,"line":101},[80,10499,117],{"emptyLinePlaceholder":116},[80,10501,10502],{"class":82,"line":107},[80,10503,3189],{},[80,10505,10506],{"class":82,"line":113},[80,10507,3194],{},[10,10509,168],{},[71,10511,10513],{"className":10512,"code":3200,"language":174,"meta":76},[172],[34,10514,3200],{"__ignoreMap":76},[10,10516,179],{},[14,10518,182],{"id":182},[184,10520,10521,10527],{},[49,10522,3211,10523,3214,10525,3218],{},[34,10524,3129],{},[34,10526,3217],{},[49,10528,10529,3224,10531,3228],{},[34,10530,3223],{},[34,10532,3227],{},[14,10534,270],{"id":270},[46,10536,10537,10541],{},[49,10538,3235,10539,3239],{},[34,10540,3238],{},[49,10542,3242],{},[14,10544,288],{"id":288},[184,10546,10547,10549],{},[49,10548,3249],{},[49,10550,1827,10551,3255,10553,3258],{},[34,10552,3254],{},[34,10554,190],{},[10,10556,313],{},[14,10558,316],{"id":316},[10,10560,3265],{},[321,10562,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10564},[10565,10566,10567,10568,10569,10570,10571,10572],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":3106,"description":3111},[337,2452,3285],{"id":3288,"title":3289,"body":10577,"category":337,"cover":338,"description":3294,"extension":339,"meta":10706,"navigation":116,"path":3455,"pinned":342,"publishedAt":343,"seo":10707,"slug":3457,"stem":3458,"summary":3459,"tags":10708,"updatedAt":343,"visible":116,"__hash__":3463},{"type":7,"value":10578,"toc":10696},[10579,10581,10583,10585,10587,10591,10595,10597,10607,10609,10611,10643,10645,10650,10652,10654,10666,10668,10678,10680,10688,10690,10692,10694],[10,10580,3294],{},[14,10582,16],{"id":16},[10,10584,3299],{},[14,10586,22],{"id":22},[10,10588,10589],{},[26,10590],{"alt":3306,"src":3307},[10,10592,3310,10593,3314],{},[34,10594,3313],{},[14,10596,44],{"id":44},[46,10598,10599,10601,10603],{},[49,10600,3321],{},[49,10602,3324],{},[49,10604,3327,10605,211],{},[34,10606,3330],{},[14,10608,66],{"id":66},[10,10610,69],{},[71,10612,10613],{"className":73,"code":3337,"language":75,"meta":76,"style":76},[34,10614,10615,10619,10623,10627,10631,10635,10639],{"__ignoreMap":76},[80,10616,10617],{"class":82,"line":83},[80,10618,3344],{},[80,10620,10621],{"class":82,"line":89},[80,10622,3349],{},[80,10624,10625],{"class":82,"line":95},[80,10626,117],{"emptyLinePlaceholder":116},[80,10628,10629],{"class":82,"line":101},[80,10630,3358],{},[80,10632,10633],{"class":82,"line":107},[80,10634,3363],{},[80,10636,10637],{"class":82,"line":113},[80,10638,3368],{},[80,10640,10641],{"class":82,"line":120},[80,10642,3373],{},[10,10644,168],{},[71,10646,10648],{"className":10647,"code":3379,"language":174,"meta":76},[172],[34,10649,3379],{"__ignoreMap":76},[10,10651,179],{},[14,10653,182],{"id":182},[184,10655,10656,10658],{},[49,10657,3390],{},[49,10659,10660,3396,10662,3400,10664,3404],{},[34,10661,3395],{},[34,10663,3399],{},[34,10665,3403],{},[14,10667,270],{"id":270},[46,10669,10670,10676],{},[49,10671,3411,10672,3415,10674,211],{},[34,10673,3414],{},[34,10675,3418],{},[49,10677,3421],{},[14,10679,288],{"id":288},[184,10681,10682,10684],{},[49,10683,3428],{},[49,10685,3431,10686,3434],{},[34,10687,3403],{},[10,10689,313],{},[14,10691,316],{"id":316},[10,10693,3441],{},[321,10695,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10697},[10698,10699,10700,10701,10702,10703,10704,10705],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":3289,"description":3294},[337,3461,3462],{"id":3465,"title":3466,"body":10710,"category":337,"cover":338,"description":3471,"extension":339,"meta":10829,"navigation":116,"path":3613,"pinned":342,"publishedAt":343,"seo":10830,"slug":3615,"stem":3616,"summary":3617,"tags":10831,"updatedAt":343,"visible":116,"__hash__":3620},{"type":7,"value":10711,"toc":10819},[10712,10714,10716,10718,10720,10724,10726,10728,10736,10738,10740,10768,10770,10775,10777,10779,10789,10791,10799,10801,10811,10813,10815,10817],[10,10713,3471],{},[14,10715,16],{"id":16},[10,10717,3476],{},[14,10719,22],{"id":22},[10,10721,10722],{},[26,10723],{"alt":3483,"src":3484},[10,10725,3487],{},[14,10727,44],{"id":44},[46,10729,10730,10732,10734],{},[49,10731,3494],{},[49,10733,3497],{},[49,10735,3500],{},[14,10737,66],{"id":66},[10,10739,69],{},[71,10741,10742],{"className":73,"code":3507,"language":75,"meta":76,"style":76},[34,10743,10744,10748,10752,10756,10760,10764],{"__ignoreMap":76},[80,10745,10746],{"class":82,"line":83},[80,10747,3514],{},[80,10749,10750],{"class":82,"line":89},[80,10751,3519],{},[80,10753,10754],{"class":82,"line":95},[80,10755,3524],{},[80,10757,10758],{"class":82,"line":101},[80,10759,117],{"emptyLinePlaceholder":116},[80,10761,10762],{"class":82,"line":107},[80,10763,3533],{},[80,10765,10766],{"class":82,"line":113},[80,10767,3538],{},[10,10769,168],{},[71,10771,10773],{"className":10772,"code":3544,"language":174,"meta":76},[172],[34,10774,3544],{"__ignoreMap":76},[10,10776,179],{},[14,10778,182],{"id":182},[184,10780,10781,10785],{},[49,10782,10783,3558],{},[34,10784,3557],{},[49,10786,10787,3564],{},[34,10788,3563],{},[14,10790,270],{"id":270},[46,10792,10793,10797],{},[49,10794,3571,10795,3575],{},[34,10796,3574],{},[49,10798,3578],{},[14,10800,288],{"id":288},[184,10802,10803,10805],{},[49,10804,3585],{},[49,10806,2280,10807,2283,10809,3592],{},[34,10808,3574],{},[34,10810,3563],{},[10,10812,313],{},[14,10814,316],{"id":316},[10,10816,3599],{},[321,10818,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10820},[10821,10822,10823,10824,10825,10826,10827,10828],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":3466,"description":3471},[337,3619,3462],{"id":3622,"title":3623,"body":10833,"category":337,"cover":338,"description":3628,"extension":339,"meta":10958,"navigation":116,"path":3784,"pinned":342,"publishedAt":343,"seo":10959,"slug":3786,"stem":3787,"summary":3788,"tags":10960,"updatedAt":343,"visible":116,"__hash__":3791},{"type":7,"value":10834,"toc":10948},[10835,10837,10839,10841,10843,10847,10853,10855,10865,10867,10869,10897,10899,10904,10906,10908,10918,10920,10932,10934,10940,10942,10944,10946],[10,10836,3628],{},[14,10838,16],{"id":16},[10,10840,3633],{},[14,10842,22],{"id":22},[10,10844,10845],{},[26,10846],{"alt":3640,"src":3641},[10,10848,3644,10849,3648,10851,3651],{},[34,10850,3647],{},[34,10852,2353],{},[14,10854,44],{"id":44},[46,10856,10857,10859,10863],{},[49,10858,3658],{},[49,10860,2445,10861,3664],{},[34,10862,3663],{},[49,10864,3667],{},[14,10866,66],{"id":66},[10,10868,69],{},[71,10870,10871],{"className":73,"code":3674,"language":75,"meta":76,"style":76},[34,10872,10873,10877,10881,10885,10889,10893],{"__ignoreMap":76},[80,10874,10875],{"class":82,"line":83},[80,10876,3681],{},[80,10878,10879],{"class":82,"line":89},[80,10880,3686],{},[80,10882,10883],{"class":82,"line":95},[80,10884,117],{"emptyLinePlaceholder":116},[80,10886,10887],{"class":82,"line":101},[80,10888,3695],{},[80,10890,10891],{"class":82,"line":107},[80,10892,3700],{},[80,10894,10895],{"class":82,"line":113},[80,10896,3705],{},[10,10898,168],{},[71,10900,10902],{"className":10901,"code":3711,"language":174,"meta":76},[172],[34,10903,3711],{"__ignoreMap":76},[10,10905,179],{},[14,10907,182],{"id":182},[184,10909,10910,10912],{},[49,10911,3722],{},[49,10913,3725,10914,3728,10916,3732],{},[34,10915,2353],{},[34,10917,3731],{},[14,10919,270],{"id":270},[46,10921,10922,10926],{},[49,10923,3739,10924,3743],{},[34,10925,3742],{},[49,10927,3746,10928,3750,10930,211],{},[34,10929,3749],{},[34,10931,3753],{},[14,10933,288],{"id":288},[184,10935,10936,10938],{},[49,10937,3760],{},[49,10939,3763],{},[10,10941,313],{},[14,10943,316],{"id":316},[10,10945,3770],{},[321,10947,323],{},{"title":76,"searchDepth":89,"depth":89,"links":10949},[10950,10951,10952,10953,10954,10955,10956,10957],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":3623,"description":3628},[337,3790,3462],{"id":3793,"title":3794,"body":10962,"category":337,"cover":338,"description":3799,"extension":339,"meta":11085,"navigation":116,"path":3949,"pinned":342,"publishedAt":343,"seo":11086,"slug":3951,"stem":3952,"summary":3953,"tags":11087,"updatedAt":343,"visible":116,"__hash__":3956},{"type":7,"value":10963,"toc":11075},[10964,10966,10968,10970,10972,10976,10978,10980,10992,10994,10996,11024,11026,11031,11033,11035,11045,11047,11057,11059,11067,11069,11071,11073],[10,10965,3799],{},[14,10967,16],{"id":16},[10,10969,3804],{},[14,10971,22],{"id":22},[10,10973,10974],{},[26,10975],{"alt":3811,"src":3812},[10,10977,3815],{},[14,10979,44],{"id":44},[46,10981,10982,10984,10986],{},[49,10983,3822],{},[49,10985,3825],{},[49,10987,3828,10988,3832,10990,3836],{},[34,10989,3831],{},[34,10991,3835],{},[14,10993,66],{"id":66},[10,10995,69],{},[71,10997,10998],{"className":73,"code":3843,"language":75,"meta":76,"style":76},[34,10999,11000,11004,11008,11012,11016,11020],{"__ignoreMap":76},[80,11001,11002],{"class":82,"line":83},[80,11003,3850],{},[80,11005,11006],{"class":82,"line":89},[80,11007,3855],{},[80,11009,11010],{"class":82,"line":95},[80,11011,117],{"emptyLinePlaceholder":116},[80,11013,11014],{"class":82,"line":101},[80,11015,3864],{},[80,11017,11018],{"class":82,"line":107},[80,11019,3869],{},[80,11021,11022],{"class":82,"line":113},[80,11023,3874],{},[10,11025,168],{},[71,11027,11029],{"className":11028,"code":3880,"language":174,"meta":76},[172],[34,11030,3880],{"__ignoreMap":76},[10,11032,179],{},[14,11034,182],{"id":182},[184,11036,11037,11039],{},[49,11038,3891],{},[49,11040,11041,3897,11043,3901],{},[34,11042,3896],{},[34,11044,3900],{},[14,11046,270],{"id":270},[46,11048,11049,11055],{},[49,11050,2445,11051,3910,11053,211],{},[34,11052,3835],{},[34,11054,3831],{},[49,11056,3915],{},[14,11058,288],{"id":288},[184,11060,11061,11065],{},[49,11062,3922,11063,3925],{},[34,11064,3831],{},[49,11066,3928],{},[10,11068,313],{},[14,11070,316],{"id":316},[10,11072,3935],{},[321,11074,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11076},[11077,11078,11079,11080,11081,11082,11083,11084],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":3794,"description":3799},[337,3955,3462],{"id":3958,"title":3959,"body":11089,"category":337,"cover":338,"description":3964,"extension":339,"meta":11248,"navigation":116,"path":4162,"pinned":342,"publishedAt":343,"seo":11249,"slug":4164,"stem":4165,"summary":4166,"tags":11250,"updatedAt":343,"visible":116,"__hash__":4170},{"type":7,"value":11090,"toc":11236},[11091,11093,11095,11097,11099,11103,11109,11111,11123,11125,11127,11167,11169,11174,11176,11178,11192,11194,11196,11200,11202,11204,11214,11216,11228,11230,11232,11234],[10,11092,3964],{},[14,11094,16],{"id":16},[10,11096,3969],{},[14,11098,22],{"id":22},[10,11100,11101],{},[26,11102],{"alt":3976,"src":3977},[10,11104,11105,3983,11107,3987],{},[34,11106,3982],{},[34,11108,3986],{},[14,11110,44],{"id":44},[46,11112,11113,11119,11121],{},[49,11114,11115,3996,11117,4000],{},[34,11116,2912],{},[34,11118,3999],{},[49,11120,4003],{},[49,11122,4006],{},[14,11124,66],{"id":66},[10,11126,69],{},[71,11128,11129],{"className":73,"code":4013,"language":75,"meta":76,"style":76},[34,11130,11131,11135,11139,11143,11147,11151,11155,11159,11163],{"__ignoreMap":76},[80,11132,11133],{"class":82,"line":83},[80,11134,4020],{},[80,11136,11137],{"class":82,"line":89},[80,11138,4025],{},[80,11140,11141],{"class":82,"line":95},[80,11142,4030],{},[80,11144,11145],{"class":82,"line":101},[80,11146,117],{"emptyLinePlaceholder":116},[80,11148,11149],{"class":82,"line":107},[80,11150,4039],{},[80,11152,11153],{"class":82,"line":113},[80,11154,4044],{},[80,11156,11157],{"class":82,"line":120},[80,11158,4049],{},[80,11160,11161],{"class":82,"line":126},[80,11162,4054],{},[80,11164,11165],{"class":82,"line":132},[80,11166,4059],{},[10,11168,168],{},[71,11170,11172],{"className":11171,"code":4065,"language":174,"meta":76},[172],[34,11173,4065],{"__ignoreMap":76},[10,11175,179],{},[14,11177,182],{"id":182},[184,11179,11180,11184],{},[49,11181,11182,4079],{},[34,11183,4078],{},[49,11185,11186,4085,11188,4089,11190,4093],{},[34,11187,4084],{},[34,11189,4088],{},[34,11191,4092],{},[213,11193,215],{"id":215},[10,11195,4098],{},[10,11197,11198],{},[26,11199],{"alt":4103,"src":4104},[10,11201,4107],{},[14,11203,270],{"id":270},[46,11205,11206,11212],{},[49,11207,4114,11208,4117,11210,211],{},[34,11209,2912],{},[34,11211,3999],{},[49,11213,4122],{},[14,11215,288],{"id":288},[184,11217,11218,11220],{},[49,11219,4129],{},[49,11221,2445,11222,4135,11224,223,11226,211],{},[34,11223,4134],{},[34,11225,3999],{},[34,11227,2912],{},[10,11229,313],{},[14,11231,316],{"id":316},[10,11233,4146],{},[321,11235,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11237},[11238,11239,11240,11241,11242,11245,11246,11247],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":11243},[11244],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":3959,"description":3964},[337,4168,4169],{"id":4172,"title":4173,"body":11252,"category":337,"cover":338,"description":4178,"extension":339,"meta":11424,"navigation":116,"path":4390,"pinned":342,"publishedAt":343,"seo":11425,"slug":4392,"stem":4393,"summary":4394,"tags":11426,"updatedAt":343,"visible":116,"__hash__":4397},{"type":7,"value":11253,"toc":11411},[11254,11256,11258,11260,11262,11266,11274,11276,11284,11286,11288,11332,11334,11339,11341,11343,11355,11357,11359,11363,11369,11371,11373,11377,11381,11383,11395,11397,11403,11405,11407,11409],[10,11255,4178],{},[14,11257,16],{"id":16},[10,11259,4183],{},[14,11261,22],{"id":22},[10,11263,11264],{},[26,11265],{"alt":4190,"src":4191},[10,11267,11268,220,11270,220,11272,4201],{},[34,11269,1265],{},[34,11271,4198],{},[34,11273,207],{},[14,11275,44],{"id":44},[46,11277,11278,11280,11282],{},[49,11279,4208],{},[49,11281,4211],{},[49,11283,4214],{},[14,11285,66],{"id":66},[10,11287,69],{},[71,11289,11290],{"className":73,"code":4221,"language":75,"meta":76,"style":76},[34,11291,11292,11296,11300,11304,11308,11312,11316,11320,11324,11328],{"__ignoreMap":76},[80,11293,11294],{"class":82,"line":83},[80,11295,4228],{},[80,11297,11298],{"class":82,"line":89},[80,11299,117],{"emptyLinePlaceholder":116},[80,11301,11302],{"class":82,"line":95},[80,11303,4237],{},[80,11305,11306],{"class":82,"line":101},[80,11307,4242],{},[80,11309,11310],{"class":82,"line":107},[80,11311,4247],{},[80,11313,11314],{"class":82,"line":113},[80,11315,4252],{},[80,11317,11318],{"class":82,"line":120},[80,11319,147],{},[80,11321,11322],{"class":82,"line":126},[80,11323,4261],{},[80,11325,11326],{"class":82,"line":132},[80,11327,117],{"emptyLinePlaceholder":116},[80,11329,11330],{"class":82,"line":138},[80,11331,4270],{},[10,11333,168],{},[71,11335,11337],{"className":11336,"code":4276,"language":174,"meta":76},[172],[34,11338,4276],{"__ignoreMap":76},[10,11340,179],{},[14,11342,182],{"id":182},[184,11344,11345,11349],{},[49,11346,4287,11347,4291],{},[34,11348,4290],{},[49,11350,11351,4297,11353,4300],{},[34,11352,4296],{},[34,11354,207],{},[213,11356,215],{"id":215},[10,11358,4305],{},[10,11360,11361],{},[26,11362],{"alt":4310,"src":4311},[10,11364,11365,4316,11367,4319],{},[34,11366,4290],{},[34,11368,4296],{},[213,11370,215],{"id":246},[10,11372,4324],{},[10,11374,11375],{},[26,11376],{"alt":4329,"src":4330},[10,11378,4333,11379,4336],{},[34,11380,1265],{},[14,11382,270],{"id":270},[46,11384,11385,11389],{},[49,11386,4343,11387,4346],{},[34,11388,4296],{},[49,11390,4349,11391,4352,11393,4356],{},[34,11392,1265],{},[34,11394,4355],{},[14,11396,288],{"id":288},[184,11398,11399,11401],{},[49,11400,4363],{},[49,11402,4366],{},[10,11404,313],{},[14,11406,316],{"id":316},[10,11408,4373],{},[321,11410,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11412},[11413,11414,11415,11416,11417,11421,11422,11423],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":11418},[11419,11420],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":4173,"description":4178},[337,1265,4396],{"id":4399,"title":4400,"body":11428,"category":337,"cover":338,"description":4405,"extension":339,"meta":11565,"navigation":116,"path":4572,"pinned":342,"publishedAt":343,"seo":11566,"slug":4574,"stem":4575,"summary":4576,"tags":11567,"updatedAt":343,"visible":116,"__hash__":4579},{"type":7,"value":11429,"toc":11553},[11430,11432,11434,11436,11438,11442,11446,11448,11458,11460,11462,11494,11496,11501,11503,11505,11515,11517,11519,11523,11527,11529,11535,11537,11545,11547,11549,11551],[10,11431,4405],{},[14,11433,16],{"id":16},[10,11435,4410],{},[14,11437,22],{"id":22},[10,11439,11440],{},[26,11441],{"alt":4417,"src":4418},[10,11443,11444,4424],{},[34,11445,4423],{},[14,11447,44],{"id":44},[46,11449,11450,11452,11454],{},[49,11451,4431],{},[49,11453,4434],{},[49,11455,4437,11456,4441],{},[34,11457,4440],{},[14,11459,66],{"id":66},[10,11461,69],{},[71,11463,11464],{"className":73,"code":4448,"language":75,"meta":76,"style":76},[34,11465,11466,11470,11474,11478,11482,11486,11490],{"__ignoreMap":76},[80,11467,11468],{"class":82,"line":83},[80,11469,4455],{},[80,11471,11472],{"class":82,"line":89},[80,11473,117],{"emptyLinePlaceholder":116},[80,11475,11476],{"class":82,"line":95},[80,11477,4464],{},[80,11479,11480],{"class":82,"line":101},[80,11481,4469],{},[80,11483,11484],{"class":82,"line":107},[80,11485,4474],{},[80,11487,11488],{"class":82,"line":113},[80,11489,117],{"emptyLinePlaceholder":116},[80,11491,11492],{"class":82,"line":120},[80,11493,4483],{},[10,11495,168],{},[71,11497,11499],{"className":11498,"code":4489,"language":174,"meta":76},[172],[34,11500,4489],{"__ignoreMap":76},[10,11502,179],{},[14,11504,182],{"id":182},[184,11506,11507,11511],{},[49,11508,4500,11509,4504],{},[34,11510,4503],{},[49,11512,4507,11513,4510],{},[34,11514,4503],{},[213,11516,215],{"id":215},[10,11518,4515],{},[10,11520,11521],{},[26,11522],{"alt":4520,"src":4521},[10,11524,4524,11525,4527],{},[34,11526,4503],{},[14,11528,270],{"id":270},[46,11530,11531,11533],{},[49,11532,4534],{},[49,11534,4537],{},[14,11536,288],{"id":288},[184,11538,11539,11543],{},[49,11540,2445,11541,4546],{},[34,11542,4423],{},[49,11544,4549],{},[10,11546,313],{},[14,11548,316],{"id":316},[10,11550,4556],{},[321,11552,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11554},[11555,11556,11557,11558,11559,11562,11563,11564],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":11560},[11561],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":4400,"description":4405},[337,4423,4578],{"id":4581,"title":4582,"body":11569,"category":337,"cover":338,"description":4587,"extension":339,"meta":11694,"navigation":116,"path":4736,"pinned":342,"publishedAt":343,"seo":11695,"slug":4738,"stem":4739,"summary":4740,"tags":11696,"updatedAt":343,"visible":116,"__hash__":4743},{"type":7,"value":11570,"toc":11684},[11571,11573,11575,11577,11579,11583,11587,11589,11599,11601,11603,11635,11637,11642,11644,11646,11658,11660,11666,11668,11676,11678,11680,11682],[10,11572,4587],{},[14,11574,16],{"id":16},[10,11576,4592],{},[14,11578,22],{"id":22},[10,11580,11581],{},[26,11582],{"alt":4599,"src":4600},[10,11584,11585,4605],{},[34,11586,4440],{},[14,11588,44],{"id":44},[46,11590,11591,11595,11597],{},[49,11592,11593,4615],{},[34,11594,4614],{},[49,11596,4618],{},[49,11598,4621],{},[14,11600,66],{"id":66},[10,11602,69],{},[71,11604,11605],{"className":73,"code":4628,"language":75,"meta":76,"style":76},[34,11606,11607,11611,11615,11619,11623,11627,11631],{"__ignoreMap":76},[80,11608,11609],{"class":82,"line":83},[80,11610,4635],{},[80,11612,11613],{"class":82,"line":89},[80,11614,117],{"emptyLinePlaceholder":116},[80,11616,11617],{"class":82,"line":95},[80,11618,4644],{},[80,11620,11621],{"class":82,"line":101},[80,11622,4649],{},[80,11624,11625],{"class":82,"line":107},[80,11626,117],{"emptyLinePlaceholder":116},[80,11628,11629],{"class":82,"line":113},[80,11630,4658],{},[80,11632,11633],{"class":82,"line":120},[80,11634,4663],{},[10,11636,168],{},[71,11638,11640],{"className":11639,"code":4669,"language":174,"meta":76},[172],[34,11641,4669],{"__ignoreMap":76},[10,11643,179],{},[14,11645,182],{"id":182},[184,11647,11648,11654],{},[49,11649,4680,11650,4683,11652,4687],{},[34,11651,4440],{},[34,11653,4686],{},[49,11655,11656,4692],{},[34,11657,4614],{},[14,11659,270],{"id":270},[46,11661,11662,11664],{},[49,11663,4699],{},[49,11665,4702],{},[14,11667,288],{"id":288},[184,11669,11670,11672],{},[49,11671,4709],{},[49,11673,2445,11674,4715],{},[34,11675,4714],{},[10,11677,313],{},[14,11679,316],{"id":316},[10,11681,4722],{},[321,11683,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11685},[11686,11687,11688,11689,11690,11691,11692,11693],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":4582,"description":4587},[337,4440,4742],{"id":4745,"title":4746,"body":11698,"category":337,"cover":338,"description":4751,"extension":339,"meta":11843,"navigation":116,"path":4926,"pinned":342,"publishedAt":343,"seo":11844,"slug":4928,"stem":4929,"summary":4930,"tags":11845,"updatedAt":343,"visible":116,"__hash__":4932},{"type":7,"value":11699,"toc":11833},[11700,11702,11704,11706,11708,11712,11718,11720,11734,11736,11738,11782,11784,11789,11791,11793,11803,11805,11817,11819,11825,11827,11829,11831],[10,11701,4751],{},[14,11703,16],{"id":16},[10,11705,4756],{},[14,11707,22],{"id":22},[10,11709,11710],{},[26,11711],{"alt":4763,"src":4764},[10,11713,11714,4770,11716,4774],{},[34,11715,4769],{},[34,11717,4773],{},[14,11719,44],{"id":44},[46,11721,11722,11724,11730],{},[49,11723,4781],{},[49,11725,11726,4786,11728,4789],{},[34,11727,4769],{},[34,11729,4423],{},[49,11731,4792,11732,4795],{},[34,11733,4773],{},[14,11735,66],{"id":66},[10,11737,69],{},[71,11739,11740],{"className":73,"code":4802,"language":75,"meta":76,"style":76},[34,11741,11742,11746,11750,11754,11758,11762,11766,11770,11774,11778],{"__ignoreMap":76},[80,11743,11744],{"class":82,"line":83},[80,11745,4809],{},[80,11747,11748],{"class":82,"line":89},[80,11749,117],{"emptyLinePlaceholder":116},[80,11751,11752],{"class":82,"line":95},[80,11753,4818],{},[80,11755,11756],{"class":82,"line":101},[80,11757,4823],{},[80,11759,11760],{"class":82,"line":107},[80,11761,4828],{},[80,11763,11764],{"class":82,"line":113},[80,11765,4833],{},[80,11767,11768],{"class":82,"line":120},[80,11769,4838],{},[80,11771,11772],{"class":82,"line":126},[80,11773,4663],{},[80,11775,11776],{"class":82,"line":132},[80,11777,117],{"emptyLinePlaceholder":116},[80,11779,11780],{"class":82,"line":138},[80,11781,4851],{},[10,11783,168],{},[71,11785,11787],{"className":11786,"code":4857,"language":174,"meta":76},[172],[34,11788,4857],{"__ignoreMap":76},[10,11790,179],{},[14,11792,182],{"id":182},[184,11794,11795,11799],{},[49,11796,4868,11797,4871],{},[34,11798,4769],{},[49,11800,4874,11801,4877],{},[34,11802,4773],{},[14,11804,270],{"id":270},[46,11806,11807,11811],{},[49,11808,3571,11809,4886],{},[34,11810,4769],{},[49,11812,4889,11813,4892,11815,4895],{},[34,11814,4423],{},[34,11816,4769],{},[14,11818,288],{"id":288},[184,11820,11821,11823],{},[49,11822,4902],{},[49,11824,4905],{},[10,11826,313],{},[14,11828,316],{"id":316},[10,11830,4912],{},[321,11832,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11834},[11835,11836,11837,11838,11839,11840,11841,11842],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":4746,"description":4751},[337,4773,4769],{"id":4934,"title":4935,"body":11847,"category":337,"cover":338,"description":4940,"extension":339,"meta":11986,"navigation":116,"path":5112,"pinned":342,"publishedAt":343,"seo":11987,"slug":5114,"stem":5115,"summary":5116,"tags":11988,"updatedAt":343,"visible":116,"__hash__":5120},{"type":7,"value":11848,"toc":11974},[11849,11851,11853,11855,11857,11861,11863,11865,11881,11883,11885,11913,11915,11920,11922,11924,11936,11938,11940,11944,11946,11948,11958,11960,11966,11968,11970,11972],[10,11850,4940],{},[14,11852,16],{"id":16},[10,11854,4945],{},[14,11856,22],{"id":22},[10,11858,11859],{},[26,11860],{"alt":4952,"src":4953},[10,11862,4956],{},[14,11864,44],{"id":44},[46,11866,11867,11869,11871],{},[49,11868,4963],{},[49,11870,4966],{},[49,11872,4969,11873,220,11875,4976,11877,220,11879,211],{},[34,11874,4972],{},[34,11876,4975],{},[34,11878,4979],{},[34,11880,4982],{},[14,11882,66],{"id":66},[10,11884,69],{},[71,11886,11887],{"className":73,"code":4989,"language":75,"meta":76,"style":76},[34,11888,11889,11893,11897,11901,11905,11909],{"__ignoreMap":76},[80,11890,11891],{"class":82,"line":83},[80,11892,4996],{},[80,11894,11895],{"class":82,"line":89},[80,11896,117],{"emptyLinePlaceholder":116},[80,11898,11899],{"class":82,"line":95},[80,11900,5005],{},[80,11902,11903],{"class":82,"line":101},[80,11904,5010],{},[80,11906,11907],{"class":82,"line":107},[80,11908,5015],{},[80,11910,11911],{"class":82,"line":113},[80,11912,5020],{},[10,11914,168],{},[71,11916,11918],{"className":11917,"code":5026,"language":174,"meta":76},[172],[34,11919,5026],{"__ignoreMap":76},[10,11921,179],{},[14,11923,182],{"id":182},[184,11925,11926,11934],{},[49,11927,5037,11928,5040,11930,223,11932,211],{},[34,11929,4972],{},[34,11931,5043],{},[34,11933,5046],{},[49,11935,5049],{},[213,11937,215],{"id":215},[10,11939,5054],{},[10,11941,11942],{},[26,11943],{"alt":5059,"src":5060},[10,11945,5063],{},[14,11947,270],{"id":270},[46,11949,11950,11956],{},[49,11951,5070,11952,1119,11954,5076],{},[34,11953,5073],{},[34,11955,4979],{},[49,11957,5079],{},[14,11959,288],{"id":288},[184,11961,11962,11964],{},[49,11963,5086],{},[49,11965,5089],{},[10,11967,313],{},[14,11969,316],{"id":316},[10,11971,5096],{},[321,11973,323],{},{"title":76,"searchDepth":89,"depth":89,"links":11975},[11976,11977,11978,11979,11980,11983,11984,11985],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":11981},[11982],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":4935,"description":4940},[337,5118,5119],{"id":5122,"title":5123,"body":11990,"category":337,"cover":338,"description":5128,"extension":339,"meta":12107,"navigation":116,"path":5267,"pinned":342,"publishedAt":343,"seo":12108,"slug":5269,"stem":5270,"summary":5271,"tags":12109,"updatedAt":343,"visible":116,"__hash__":5275},{"type":7,"value":11991,"toc":12097},[11992,11994,11996,11998,12000,12004,12006,12008,12016,12018,12020,12052,12054,12059,12061,12063,12071,12073,12081,12083,12089,12091,12093,12095],[10,11993,5128],{},[14,11995,16],{"id":16},[10,11997,5133],{},[14,11999,22],{"id":22},[10,12001,12002],{},[26,12003],{"alt":5140,"src":5141},[10,12005,5144],{},[14,12007,44],{"id":44},[46,12009,12010,12012,12014],{},[49,12011,5151],{},[49,12013,5154],{},[49,12015,5157],{},[14,12017,66],{"id":66},[10,12019,69],{},[71,12021,12022],{"className":73,"code":5164,"language":75,"meta":76,"style":76},[34,12023,12024,12028,12032,12036,12040,12044,12048],{"__ignoreMap":76},[80,12025,12026],{"class":82,"line":83},[80,12027,5171],{},[80,12029,12030],{"class":82,"line":89},[80,12031,117],{"emptyLinePlaceholder":116},[80,12033,12034],{"class":82,"line":95},[80,12035,5180],{},[80,12037,12038],{"class":82,"line":101},[80,12039,5185],{},[80,12041,12042],{"class":82,"line":107},[80,12043,117],{"emptyLinePlaceholder":116},[80,12045,12046],{"class":82,"line":113},[80,12047,5194],{},[80,12049,12050],{"class":82,"line":120},[80,12051,5199],{},[10,12053,168],{},[71,12055,12057],{"className":12056,"code":5205,"language":174,"meta":76},[172],[34,12058,5205],{"__ignoreMap":76},[10,12060,179],{},[14,12062,182],{"id":182},[184,12064,12065,12067],{},[49,12066,5216],{},[49,12068,5219,12069,5223],{},[34,12070,5222],{},[14,12072,270],{"id":270},[46,12074,12075,12079],{},[49,12076,5230,12077,5233],{},[34,12078,4440],{},[49,12080,5236],{},[14,12082,288],{"id":288},[184,12084,12085,12087],{},[49,12086,5243],{},[49,12088,5246],{},[10,12090,313],{},[14,12092,316],{"id":316},[10,12094,5253],{},[321,12096,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12098},[12099,12100,12101,12102,12103,12104,12105,12106],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5123,"description":5128},[337,5273,5274],{"id":5277,"title":5278,"body":12111,"category":337,"cover":338,"description":5283,"extension":339,"meta":12230,"navigation":116,"path":5427,"pinned":342,"publishedAt":343,"seo":12231,"slug":5429,"stem":5430,"summary":5431,"tags":12232,"updatedAt":343,"visible":116,"__hash__":5435},{"type":7,"value":12112,"toc":12220},[12113,12115,12117,12119,12121,12125,12127,12129,12137,12139,12141,12173,12175,12180,12182,12184,12194,12196,12202,12204,12212,12214,12216,12218],[10,12114,5283],{},[14,12116,16],{"id":16},[10,12118,5288],{},[14,12120,22],{"id":22},[10,12122,12123],{},[26,12124],{"alt":5295,"src":5296},[10,12126,5299],{},[14,12128,44],{"id":44},[46,12130,12131,12133,12135],{},[49,12132,5306],{},[49,12134,5309],{},[49,12136,5312],{},[14,12138,66],{"id":66},[10,12140,69],{},[71,12142,12143],{"className":73,"code":5319,"language":75,"meta":76,"style":76},[34,12144,12145,12149,12153,12157,12161,12165,12169],{"__ignoreMap":76},[80,12146,12147],{"class":82,"line":83},[80,12148,5326],{},[80,12150,12151],{"class":82,"line":89},[80,12152,5331],{},[80,12154,12155],{"class":82,"line":95},[80,12156,5336],{},[80,12158,12159],{"class":82,"line":101},[80,12160,117],{"emptyLinePlaceholder":116},[80,12162,12163],{"class":82,"line":107},[80,12164,5345],{},[80,12166,12167],{"class":82,"line":113},[80,12168,5350],{},[80,12170,12171],{"class":82,"line":120},[80,12172,5355],{},[10,12174,168],{},[71,12176,12178],{"className":12177,"code":5361,"language":174,"meta":76},[172],[34,12179,5361],{"__ignoreMap":76},[10,12181,179],{},[14,12183,182],{"id":182},[184,12185,12186,12190],{},[49,12187,1048,12188,5375],{},[34,12189,5374],{},[49,12191,5378,12192,5382],{},[34,12193,5381],{},[14,12195,270],{"id":270},[46,12197,12198,12200],{},[49,12199,5389],{},[49,12201,5392],{},[14,12203,288],{"id":288},[184,12205,12206,12210],{},[49,12207,5399,12208,5403],{},[34,12209,5402],{},[49,12211,5406],{},[10,12213,313],{},[14,12215,316],{"id":316},[10,12217,5413],{},[321,12219,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12221},[12222,12223,12224,12225,12226,12227,12228,12229],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5278,"description":5283},[337,5433,5434],{"id":5437,"title":5438,"body":12234,"category":337,"cover":338,"description":5443,"extension":339,"meta":12379,"navigation":116,"path":5624,"pinned":342,"publishedAt":343,"seo":12380,"slug":5626,"stem":5627,"summary":5628,"tags":12381,"updatedAt":343,"visible":116,"__hash__":5632},{"type":7,"value":12235,"toc":12367},[12236,12238,12240,12242,12244,12248,12252,12254,12266,12268,12270,12298,12300,12305,12307,12309,12323,12325,12327,12331,12339,12341,12351,12353,12359,12361,12363,12365],[10,12237,5443],{},[14,12239,16],{"id":16},[10,12241,5448],{},[14,12243,22],{"id":22},[10,12245,12246],{},[26,12247],{"alt":5455,"src":5456},[10,12249,5459,12250,5463],{},[34,12251,5462],{},[14,12253,44],{"id":44},[46,12255,12256,12258,12260],{},[49,12257,5470],{},[49,12259,5473],{},[49,12261,5476,12262,5479,12264,211],{},[34,12263,5462],{},[34,12265,5482],{},[14,12267,66],{"id":66},[10,12269,69],{},[71,12271,12272],{"className":73,"code":5489,"language":75,"meta":76,"style":76},[34,12273,12274,12278,12282,12286,12290,12294],{"__ignoreMap":76},[80,12275,12276],{"class":82,"line":83},[80,12277,5496],{},[80,12279,12280],{"class":82,"line":89},[80,12281,5501],{},[80,12283,12284],{"class":82,"line":95},[80,12285,5506],{},[80,12287,12288],{"class":82,"line":101},[80,12289,117],{"emptyLinePlaceholder":116},[80,12291,12292],{"class":82,"line":107},[80,12293,5515],{},[80,12295,12296],{"class":82,"line":113},[80,12297,5520],{},[10,12299,168],{},[71,12301,12303],{"className":12302,"code":5526,"language":174,"meta":76},[172],[34,12304,5526],{"__ignoreMap":76},[10,12306,179],{},[14,12308,182],{"id":182},[184,12310,12311,12317],{},[49,12312,5537,12313,220,12315,5543],{},[34,12314,5540],{},[34,12316,4503],{},[49,12318,12319,5549,12321,5553],{},[34,12320,5548],{},[34,12322,5552],{},[213,12324,215],{"id":215},[10,12326,5558],{},[10,12328,12329],{},[26,12330],{"alt":5563,"src":5564},[10,12332,12333,220,12335,223,12337,5574],{},[34,12334,5540],{},[34,12336,4503],{},[34,12338,5573],{},[14,12340,270],{"id":270},[46,12342,12343,12347],{},[49,12344,5581,12345,5585],{},[34,12346,5584],{},[49,12348,5588,12349,5591],{},[34,12350,5573],{},[14,12352,288],{"id":288},[184,12354,12355,12357],{},[49,12356,5598],{},[49,12358,5601],{},[10,12360,313],{},[14,12362,316],{"id":316},[10,12364,5608],{},[321,12366,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12368},[12369,12370,12371,12372,12373,12376,12377,12378],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":12374},[12375],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5438,"description":5443},[337,5630,5631],{"id":5634,"title":5635,"body":12383,"category":337,"cover":338,"description":5640,"extension":339,"meta":12532,"navigation":116,"path":5821,"pinned":342,"publishedAt":343,"seo":12533,"slug":5823,"stem":5824,"summary":5825,"tags":12534,"updatedAt":343,"visible":116,"__hash__":5829},{"type":7,"value":12384,"toc":12520},[12385,12387,12389,12391,12393,12397,12399,12401,12413,12415,12417,12461,12463,12468,12470,12472,12484,12486,12488,12492,12494,12496,12504,12506,12512,12514,12516,12518],[10,12386,5640],{},[14,12388,16],{"id":16},[10,12390,5645],{},[14,12392,22],{"id":22},[10,12394,12395],{},[26,12396],{"alt":5652,"src":5653},[10,12398,5656],{},[14,12400,44],{"id":44},[46,12402,12403,12405,12409],{},[49,12404,5663],{},[49,12406,12407,5669],{},[34,12408,5668],{},[49,12410,12411,5675],{},[34,12412,5674],{},[14,12414,66],{"id":66},[10,12416,69],{},[71,12418,12419],{"className":73,"code":5682,"language":75,"meta":76,"style":76},[34,12420,12421,12425,12429,12433,12437,12441,12445,12449,12453,12457],{"__ignoreMap":76},[80,12422,12423],{"class":82,"line":83},[80,12424,5689],{},[80,12426,12427],{"class":82,"line":89},[80,12428,5694],{},[80,12430,12431],{"class":82,"line":95},[80,12432,117],{"emptyLinePlaceholder":116},[80,12434,12435],{"class":82,"line":101},[80,12436,5703],{},[80,12438,12439],{"class":82,"line":107},[80,12440,5708],{},[80,12442,12443],{"class":82,"line":113},[80,12444,117],{"emptyLinePlaceholder":116},[80,12446,12447],{"class":82,"line":120},[80,12448,5717],{},[80,12450,12451],{"class":82,"line":126},[80,12452,5722],{},[80,12454,12455],{"class":82,"line":132},[80,12456,117],{"emptyLinePlaceholder":116},[80,12458,12459],{"class":82,"line":138},[80,12460,5731],{},[10,12462,168],{},[71,12464,12466],{"className":12465,"code":5737,"language":174,"meta":76},[172],[34,12467,5737],{"__ignoreMap":76},[10,12469,179],{},[14,12471,182],{"id":182},[184,12473,12474,12478],{},[49,12475,5748,12476,5752],{},[34,12477,5751],{},[49,12479,12480,5758,12482,211],{},[34,12481,5757],{},[34,12483,5761],{},[213,12485,215],{"id":215},[10,12487,5766],{},[10,12489,12490],{},[26,12491],{"alt":5771,"src":5772},[10,12493,5775],{},[14,12495,270],{"id":270},[46,12497,12498,12502],{},[49,12499,5782,12500,5785],{},[34,12501,5482],{},[49,12503,5788],{},[14,12505,288],{"id":288},[184,12507,12508,12510],{},[49,12509,5795],{},[49,12511,5798],{},[10,12513,313],{},[14,12515,316],{"id":316},[10,12517,5805],{},[321,12519,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12521},[12522,12523,12524,12525,12526,12529,12530,12531],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":12527},[12528],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5635,"description":5640},[337,5827,5828],{"id":5831,"title":5832,"body":12536,"category":337,"cover":338,"description":5837,"extension":339,"meta":12697,"navigation":116,"path":6033,"pinned":342,"publishedAt":343,"seo":12698,"slug":6035,"stem":6036,"summary":6037,"tags":12699,"updatedAt":343,"visible":116,"__hash__":6041},{"type":7,"value":12537,"toc":12685},[12538,12540,12542,12544,12546,12550,12552,12554,12566,12568,12570,12622,12624,12629,12631,12633,12651,12653,12655,12659,12661,12663,12669,12671,12677,12679,12681,12683],[10,12539,5837],{},[14,12541,16],{"id":16},[10,12543,5842],{},[14,12545,22],{"id":22},[10,12547,12548],{},[26,12549],{"alt":5849,"src":5850},[10,12551,5853],{},[14,12553,44],{"id":44},[46,12555,12556,12558,12560],{},[49,12557,5860],{},[49,12559,5863],{},[49,12561,12562,2283,12564,5872],{},[34,12563,5868],{},[34,12565,5871],{},[14,12567,66],{"id":66},[10,12569,69],{},[71,12571,12572],{"className":73,"code":5879,"language":75,"meta":76,"style":76},[34,12573,12574,12578,12582,12586,12590,12594,12598,12602,12606,12610,12614,12618],{"__ignoreMap":76},[80,12575,12576],{"class":82,"line":83},[80,12577,5886],{},[80,12579,12580],{"class":82,"line":89},[80,12581,117],{"emptyLinePlaceholder":116},[80,12583,12584],{"class":82,"line":95},[80,12585,5895],{},[80,12587,12588],{"class":82,"line":101},[80,12589,5900],{},[80,12591,12592],{"class":82,"line":107},[80,12593,117],{"emptyLinePlaceholder":116},[80,12595,12596],{"class":82,"line":113},[80,12597,5909],{},[80,12599,12600],{"class":82,"line":120},[80,12601,5914],{},[80,12603,12604],{"class":82,"line":126},[80,12605,5919],{},[80,12607,12608],{"class":82,"line":132},[80,12609,117],{"emptyLinePlaceholder":116},[80,12611,12612],{"class":82,"line":138},[80,12613,5928],{},[80,12615,12616],{"class":82,"line":144},[80,12617,117],{"emptyLinePlaceholder":116},[80,12619,12620],{"class":82,"line":150},[80,12621,5937],{},[10,12623,168],{},[71,12625,12627],{"className":12626,"code":5943,"language":174,"meta":76},[172],[34,12628,5943],{"__ignoreMap":76},[10,12630,179],{},[14,12632,182],{"id":182},[184,12634,12635,12645],{},[49,12636,12637,5957,12639,5961,12641,5964,12643,5968],{},[34,12638,5956],{},[34,12640,5960],{},[34,12642,5751],{},[34,12644,5967],{},[49,12646,12647,5973,12649,5976],{},[34,12648,4686],{},[34,12650,2315],{},[213,12652,215],{"id":215},[10,12654,5981],{},[10,12656,12657],{},[26,12658],{"alt":5986,"src":5987},[10,12660,5990],{},[14,12662,270],{"id":270},[46,12664,12665,12667],{},[49,12666,5997],{},[49,12668,6000],{},[14,12670,288],{"id":288},[184,12672,12673,12675],{},[49,12674,6007],{},[49,12676,6010],{},[10,12678,313],{},[14,12680,316],{"id":316},[10,12682,6017],{},[321,12684,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12686},[12687,12688,12689,12690,12691,12694,12695,12696],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":12692},[12693],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5832,"description":5837},[337,6039,6040],{"id":6043,"title":6044,"body":12701,"category":337,"cover":338,"description":6049,"extension":339,"meta":12824,"navigation":116,"path":6200,"pinned":342,"publishedAt":343,"seo":12825,"slug":6202,"stem":6203,"summary":6204,"tags":12826,"updatedAt":343,"visible":116,"__hash__":6208},{"type":7,"value":12702,"toc":12814},[12703,12705,12707,12709,12711,12715,12717,12719,12733,12735,12737,12765,12767,12772,12774,12776,12786,12788,12796,12798,12806,12808,12810,12812],[10,12704,6049],{},[14,12706,16],{"id":16},[10,12708,6054],{},[14,12710,22],{"id":22},[10,12712,12713],{},[26,12714],{"alt":6061,"src":6062},[10,12716,6065],{},[14,12718,44],{"id":44},[46,12720,12721,12723,12725],{},[49,12722,6072],{},[49,12724,6075],{},[49,12726,6078,12727,220,12729,220,12731,6086],{},[34,12728,2366],{},[34,12730,2532],{},[34,12732,6085],{},[14,12734,66],{"id":66},[10,12736,69],{},[71,12738,12739],{"className":73,"code":6093,"language":75,"meta":76,"style":76},[34,12740,12741,12745,12749,12753,12757,12761],{"__ignoreMap":76},[80,12742,12743],{"class":82,"line":83},[80,12744,6100],{},[80,12746,12747],{"class":82,"line":89},[80,12748,6105],{},[80,12750,12751],{"class":82,"line":95},[80,12752,6110],{},[80,12754,12755],{"class":82,"line":101},[80,12756,117],{"emptyLinePlaceholder":116},[80,12758,12759],{"class":82,"line":107},[80,12760,6119],{},[80,12762,12763],{"class":82,"line":113},[80,12764,6124],{},[10,12766,168],{},[71,12768,12770],{"className":12769,"code":6130,"language":174,"meta":76},[172],[34,12771,6130],{"__ignoreMap":76},[10,12773,179],{},[14,12775,182],{"id":182},[184,12777,12778,12784],{},[49,12779,6141,12780,6145,12782,6148],{},[34,12781,6144],{},[34,12783,2353],{},[49,12785,6151],{},[14,12787,270],{"id":270},[46,12789,12790,12794],{},[49,12791,6158,12792,6162],{},[34,12793,6161],{},[49,12795,6165],{},[14,12797,288],{"id":288},[184,12799,12800,12802],{},[49,12801,6172],{},[49,12803,6175,12804,6179],{},[34,12805,6178],{},[10,12807,313],{},[14,12809,316],{"id":316},[10,12811,6186],{},[321,12813,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12815},[12816,12817,12818,12819,12820,12821,12822,12823],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":6044,"description":6049},[337,6206,6207],{"id":6210,"title":6211,"body":12828,"category":337,"cover":338,"description":6216,"extension":339,"meta":13005,"navigation":116,"path":6444,"pinned":342,"publishedAt":343,"seo":13006,"slug":6446,"stem":6447,"summary":6448,"tags":13007,"updatedAt":343,"visible":116,"__hash__":6452},{"type":7,"value":12829,"toc":12993},[12830,12832,12834,12838,12840,12844,12850,12852,12864,12866,12870,12894,12898,12914,12920,12922,12927,12929,12931,12947,12949,12951,12955,12959,12961,12973,12975,12985,12987,12989,12991],[10,12831,6216],{},[14,12833,16],{"id":16},[10,12835,6221,12836,6224],{},[406,12837,6144],{},[14,12839,22],{"id":22},[10,12841,12842],{},[26,12843],{"alt":6231,"src":6232},[10,12845,6235,12846,6239,12848,6243],{},[34,12847,6238],{},[34,12849,6242],{},[14,12851,44],{"id":44},[46,12853,12854,12858,12860],{},[49,12855,6250,12856,6253],{},[34,12857,1278],{},[49,12859,6256],{},[49,12861,6259,12862,6263],{},[34,12863,6262],{},[14,12865,66],{"id":66},[10,12867,6268,12868,6272],{},[34,12869,6271],{},[71,12871,12872],{"className":73,"code":6275,"language":75,"meta":76,"style":76},[34,12873,12874,12878,12882,12886,12890],{"__ignoreMap":76},[80,12875,12876],{"class":82,"line":83},[80,12877,6282],{},[80,12879,12880],{"class":82,"line":89},[80,12881,6287],{},[80,12883,12884],{"class":82,"line":95},[80,12885,117],{"emptyLinePlaceholder":116},[80,12887,12888],{"class":82,"line":101},[80,12889,6296],{},[80,12891,12892],{"class":82,"line":107},[80,12893,6301],{},[10,12895,6304,12896,6308],{},[34,12897,6307],{},[71,12899,12900],{"className":73,"code":6311,"language":75,"meta":76,"style":76},[34,12901,12902,12906,12910],{"__ignoreMap":76},[80,12903,12904],{"class":82,"line":83},[80,12905,6318],{},[80,12907,12908],{"class":82,"line":89},[80,12909,117],{"emptyLinePlaceholder":116},[80,12911,12912],{"class":82,"line":95},[80,12913,6327],{},[10,12915,6330,12916,223,12918,211],{},[34,12917,6333],{},[34,12919,6336],{},[10,12921,168],{},[71,12923,12925],{"className":12924,"code":6342,"language":174,"meta":76},[172],[34,12926,6342],{"__ignoreMap":76},[10,12928,179],{},[14,12930,182],{"id":182},[184,12932,12933,12939],{},[49,12934,6353,12935,6356,12937,6360],{},[34,12936,6271],{},[34,12938,6359],{},[49,12940,12941,6365,12943,6368,12945,6371],{},[34,12942,6307],{},[34,12944,6271],{},[34,12946,6307],{},[213,12948,215],{"id":215},[10,12950,6376],{},[10,12952,12953],{},[26,12954],{"alt":6381,"src":6382},[10,12956,6385,12957,6388],{},[34,12958,6359],{},[14,12960,270],{"id":270},[46,12962,12963,12969],{},[49,12964,6395,12965,223,12967,211],{},[34,12966,6271],{},[34,12968,6307],{},[49,12970,6402,12971,6406],{},[34,12972,6405],{},[14,12974,288],{"id":288},[184,12976,12977,12981],{},[49,12978,2460,12979,6416],{},[34,12980,6415],{},[49,12982,6419,12983,211],{},[34,12984,6238],{},[10,12986,313],{},[14,12988,316],{"id":316},[10,12990,6428],{},[321,12992,323],{},{"title":76,"searchDepth":89,"depth":89,"links":12994},[12995,12996,12997,12998,12999,13002,13003,13004],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":13000},[13001],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":6211,"description":6216},[337,6450,6451],{"id":6454,"title":6455,"body":13009,"category":337,"cover":338,"description":6460,"extension":339,"meta":13148,"navigation":116,"path":6626,"pinned":342,"publishedAt":343,"seo":13149,"slug":6628,"stem":6629,"summary":6630,"tags":13150,"updatedAt":343,"visible":116,"__hash__":6633},{"type":7,"value":13010,"toc":13138},[13011,13013,13015,13017,13019,13023,13025,13027,13037,13039,13041,13081,13083,13088,13090,13092,13110,13112,13120,13122,13130,13132,13134,13136],[10,13012,6460],{},[14,13014,16],{"id":16},[10,13016,6465],{},[14,13018,22],{"id":22},[10,13020,13021],{},[26,13022],{"alt":6472,"src":6473},[10,13024,6476],{},[14,13026,44],{"id":44},[46,13028,13029,13033,13035],{},[49,13030,13031,6486],{},[34,13032,6485],{},[49,13034,6489],{},[49,13036,6492],{},[14,13038,66],{"id":66},[10,13040,1681],{},[71,13042,13043],{"className":701,"code":6499,"language":703,"meta":76,"style":76},[34,13044,13045,13055,13061,13067,13077],{"__ignoreMap":76},[80,13046,13047,13049,13051,13053],{"class":82,"line":83},[80,13048,801],{"class":710},[80,13050,743],{"class":713},[80,13052,6510],{"class":746},[80,13054,6513],{"class":746},[80,13056,13057,13059],{"class":82,"line":89},[80,13058,6518],{"class":713},[80,13060,6521],{"class":746},[80,13062,13063,13065],{"class":82,"line":95},[80,13064,75],{"class":710},[80,13066,714],{"class":713},[80,13068,13069,13071,13073,13075],{"class":82,"line":101},[80,13070,75],{"class":710},[80,13072,743],{"class":713},[80,13074,747],{"class":746},[80,13076,714],{"class":713},[80,13078,13079],{"class":82,"line":107},[80,13080,6542],{"class":710},[10,13082,168],{},[71,13084,13086],{"className":13085,"code":6548,"language":174,"meta":76},[172],[34,13087,6548],{"__ignoreMap":76},[10,13089,179],{},[14,13091,182],{"id":182},[184,13093,13094,13100],{},[49,13095,13096,6562,13098,6565],{},[34,13097,6561],{},[34,13099,801],{},[49,13101,6568,13102,2283,13104,6574,13106,3832,13108,6580],{},[34,13103,75],{},[34,13105,6573],{},[34,13107,6485],{},[34,13109,6579],{},[14,13111,270],{"id":270},[46,13113,13114,13116],{},[49,13115,6587],{},[49,13117,3571,13118,6592],{},[34,13119,6485],{},[14,13121,288],{"id":288},[184,13123,13124,13128],{},[49,13125,6599,13126,211],{},[34,13127,6602],{},[49,13129,6605],{},[10,13131,313],{},[14,13133,316],{"id":316},[10,13135,6612],{},[321,13137,1765],{},{"title":76,"searchDepth":89,"depth":89,"links":13139},[13140,13141,13142,13143,13144,13145,13146,13147],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":6455,"description":6460},[337,6632,372],{"id":6635,"title":6636,"body":13152,"category":337,"cover":338,"description":6641,"extension":339,"meta":13305,"navigation":116,"path":6830,"pinned":342,"publishedAt":343,"seo":13306,"slug":6832,"stem":6833,"summary":6834,"tags":13307,"updatedAt":343,"visible":116,"__hash__":6838},{"type":7,"value":13153,"toc":13295},[13154,13156,13158,13160,13162,13166,13172,13174,13190,13192,13194,13238,13240,13245,13247,13249,13261,13263,13277,13279,13287,13289,13291,13293],[10,13155,6641],{},[14,13157,16],{"id":16},[10,13159,6646],{},[14,13161,22],{"id":22},[10,13163,13164],{},[26,13165],{"alt":6653,"src":6654},[10,13167,13168,6660,13170,6663],{},[34,13169,6659],{},[34,13171,2542],{},[14,13173,44],{"id":44},[46,13175,13176,13178,13186],{},[49,13177,6670],{},[49,13179,13180,220,13182,220,13184,6682],{},[34,13181,6675],{},[34,13183,6678],{},[34,13185,6681],{},[49,13187,6685,13188,6689],{},[34,13189,6688],{},[14,13191,66],{"id":66},[10,13193,69],{},[71,13195,13196],{"className":73,"code":6696,"language":75,"meta":76,"style":76},[34,13197,13198,13202,13206,13210,13214,13218,13222,13226,13230,13234],{"__ignoreMap":76},[80,13199,13200],{"class":82,"line":83},[80,13201,6703],{},[80,13203,13204],{"class":82,"line":89},[80,13205,117],{"emptyLinePlaceholder":116},[80,13207,13208],{"class":82,"line":95},[80,13209,6712],{},[80,13211,13212],{"class":82,"line":101},[80,13213,6717],{},[80,13215,13216],{"class":82,"line":107},[80,13217,6722],{},[80,13219,13220],{"class":82,"line":113},[80,13221,117],{"emptyLinePlaceholder":116},[80,13223,13224],{"class":82,"line":120},[80,13225,6731],{},[80,13227,13228],{"class":82,"line":126},[80,13229,6736],{},[80,13231,13232],{"class":82,"line":132},[80,13233,6741],{},[80,13235,13236],{"class":82,"line":138},[80,13237,6746],{},[10,13239,168],{},[71,13241,13243],{"className":13242,"code":6752,"language":174,"meta":76},[172],[34,13244,6752],{"__ignoreMap":76},[10,13246,179],{},[14,13248,182],{"id":182},[184,13250,13251,13255],{},[49,13252,13253,6766],{},[34,13254,6765],{},[49,13256,2445,13257,6771,13259,6774],{},[34,13258,2542],{},[34,13260,6659],{},[14,13262,270],{"id":270},[46,13264,13265,13271],{},[49,13266,3571,13267,6783,13269,6786],{},[34,13268,6659],{},[34,13270,6675],{},[49,13272,6789,13273,1119,13275,6795],{},[34,13274,2542],{},[34,13276,6794],{},[14,13278,288],{"id":288},[184,13280,13281,13285],{},[49,13282,6802,13283,6806],{},[34,13284,6805],{},[49,13286,6809],{},[10,13288,313],{},[14,13290,316],{"id":316},[10,13292,6816],{},[321,13294,323],{},{"title":76,"searchDepth":89,"depth":89,"links":13296},[13297,13298,13299,13300,13301,13302,13303,13304],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":6636,"description":6641},[337,6836,6837],{"id":6840,"title":6841,"body":13309,"category":337,"cover":338,"description":6846,"extension":339,"meta":13456,"navigation":116,"path":7024,"pinned":342,"publishedAt":343,"seo":13457,"slug":7026,"stem":7027,"summary":7028,"tags":13458,"updatedAt":343,"visible":116,"__hash__":7032},{"type":7,"value":13310,"toc":13446},[13311,13313,13315,13317,13319,13323,13325,13327,13345,13347,13349,13397,13399,13404,13406,13408,13416,13418,13428,13430,13438,13440,13442,13444],[10,13312,6846],{},[14,13314,16],{"id":16},[10,13316,6851],{},[14,13318,22],{"id":22},[10,13320,13321],{},[26,13322],{"alt":6858,"src":6859},[10,13324,6862],{},[14,13326,44],{"id":44},[46,13328,13329,13333,13339],{},[49,13330,13331,6872],{},[34,13332,6871],{},[49,13334,13335,6878,13337,211],{},[34,13336,6877],{},[34,13338,309],{},[49,13340,6883,13341,6887,13343,6891],{},[34,13342,6886],{},[34,13344,6890],{},[14,13346,66],{"id":66},[10,13348,69],{},[71,13350,13351],{"className":73,"code":6898,"language":75,"meta":76,"style":76},[34,13352,13353,13357,13361,13365,13369,13373,13377,13381,13385,13389,13393],{"__ignoreMap":76},[80,13354,13355],{"class":82,"line":83},[80,13356,6703],{},[80,13358,13359],{"class":82,"line":89},[80,13360,117],{"emptyLinePlaceholder":116},[80,13362,13363],{"class":82,"line":95},[80,13364,6913],{},[80,13366,13367],{"class":82,"line":101},[80,13368,6918],{},[80,13370,13371],{"class":82,"line":107},[80,13372,6923],{},[80,13374,13375],{"class":82,"line":113},[80,13376,6928],{},[80,13378,13379],{"class":82,"line":120},[80,13380,117],{"emptyLinePlaceholder":116},[80,13382,13383],{"class":82,"line":126},[80,13384,6937],{},[80,13386,13387],{"class":82,"line":132},[80,13388,6942],{},[80,13390,13391],{"class":82,"line":138},[80,13392,6947],{},[80,13394,13395],{"class":82,"line":144},[80,13396,6952],{},[10,13398,168],{},[71,13400,13402],{"className":13401,"code":6958,"language":174,"meta":76},[172],[34,13403,6958],{"__ignoreMap":76},[10,13405,179],{},[14,13407,182],{"id":182},[184,13409,13410,13414],{},[49,13411,6969,13412,6972],{},[34,13413,6886],{},[49,13415,6975],{},[14,13417,270],{"id":270},[46,13419,13420,13424],{},[49,13421,2445,13422,6984],{},[34,13423,6871],{},[49,13425,6987,13426,211],{},[34,13427,6990],{},[14,13429,288],{"id":288},[184,13431,13432,13434],{},[49,13433,6997],{},[49,13435,7000,13436,7003],{},[34,13437,447],{},[10,13439,313],{},[14,13441,316],{"id":316},[10,13443,7010],{},[321,13445,323],{},{"title":76,"searchDepth":89,"depth":89,"links":13447},[13448,13449,13450,13451,13452,13453,13454,13455],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":6841,"description":6846},[337,7030,7031],{"id":7034,"title":7035,"body":13460,"category":337,"cover":338,"description":7040,"extension":339,"meta":13603,"navigation":116,"path":7208,"pinned":342,"publishedAt":343,"seo":13604,"slug":7210,"stem":7211,"summary":7212,"tags":13605,"updatedAt":343,"visible":116,"__hash__":7216},{"type":7,"value":13461,"toc":13593},[13462,13464,13466,13468,13470,13474,13480,13482,13492,13494,13496,13548,13550,13555,13557,13559,13569,13571,13577,13579,13585,13587,13589,13591],[10,13463,7040],{},[14,13465,16],{"id":16},[10,13467,7045],{},[14,13469,22],{"id":22},[10,13471,13472],{},[26,13473],{"alt":7052,"src":7053},[10,13475,13476,7059,13478,7063],{},[34,13477,7058],{},[34,13479,7062],{},[14,13481,44],{"id":44},[46,13483,13484,13486,13490],{},[49,13485,7070],{},[49,13487,13488,7076],{},[34,13489,7075],{},[49,13491,7079],{},[14,13493,66],{"id":66},[10,13495,69],{},[71,13497,13498],{"className":73,"code":7086,"language":75,"meta":76,"style":76},[34,13499,13500,13504,13508,13512,13516,13520,13524,13528,13532,13536,13540,13544],{"__ignoreMap":76},[80,13501,13502],{"class":82,"line":83},[80,13503,7093],{},[80,13505,13506],{"class":82,"line":89},[80,13507,117],{"emptyLinePlaceholder":116},[80,13509,13510],{"class":82,"line":95},[80,13511,7102],{},[80,13513,13514],{"class":82,"line":101},[80,13515,117],{"emptyLinePlaceholder":116},[80,13517,13518],{"class":82,"line":107},[80,13519,7111],{},[80,13521,13522],{"class":82,"line":113},[80,13523,7116],{},[80,13525,13526],{"class":82,"line":120},[80,13527,6928],{},[80,13529,13530],{"class":82,"line":126},[80,13531,117],{"emptyLinePlaceholder":116},[80,13533,13534],{"class":82,"line":132},[80,13535,7129],{},[80,13537,13538],{"class":82,"line":138},[80,13539,7134],{},[80,13541,13542],{"class":82,"line":144},[80,13543,6947],{},[80,13545,13546],{"class":82,"line":150},[80,13547,7143],{},[10,13549,168],{},[71,13551,13553],{"className":13552,"code":7149,"language":174,"meta":76},[172],[34,13554,7149],{"__ignoreMap":76},[10,13556,179],{},[14,13558,182],{"id":182},[184,13560,13561,13565],{},[49,13562,13563,7162],{},[34,13564,7058],{},[49,13566,13567,7167],{},[34,13568,7062],{},[14,13570,270],{"id":270},[46,13572,13573,13575],{},[49,13574,7174],{},[49,13576,7177],{},[14,13578,288],{"id":288},[184,13580,13581,13583],{},[49,13582,7184],{},[49,13584,7187],{},[10,13586,313],{},[14,13588,316],{"id":316},[10,13590,7194],{},[321,13592,323],{},{"title":76,"searchDepth":89,"depth":89,"links":13594},[13595,13596,13597,13598,13599,13600,13601,13602],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":7035,"description":7040},[337,7214,7215],{"id":7218,"title":7219,"body":13607,"category":337,"cover":338,"description":7224,"extension":339,"meta":13758,"navigation":116,"path":7409,"pinned":342,"publishedAt":343,"seo":13759,"slug":7411,"stem":7412,"summary":7413,"tags":13760,"updatedAt":343,"visible":116,"__hash__":7417},{"type":7,"value":13608,"toc":13748},[13609,13611,13613,13615,13617,13621,13625,13627,13641,13643,13645,13697,13699,13704,13706,13708,13720,13722,13732,13734,13740,13742,13744,13746],[10,13610,7224],{},[14,13612,16],{"id":16},[10,13614,7229],{},[14,13616,22],{"id":22},[10,13618,13619],{},[26,13620],{"alt":7236,"src":7237},[10,13622,13623,7243],{},[34,13624,7242],{},[14,13626,44],{"id":44},[46,13628,13629,13635,13639],{},[49,13630,2445,13631,7253,13633,7257],{},[34,13632,7252],{},[34,13634,7256],{},[49,13636,7260,13637,7264],{},[34,13638,7263],{},[49,13640,7267],{},[14,13642,66],{"id":66},[10,13644,69],{},[71,13646,13647],{"className":73,"code":7274,"language":75,"meta":76,"style":76},[34,13648,13649,13653,13657,13661,13665,13669,13673,13677,13681,13685,13689,13693],{"__ignoreMap":76},[80,13650,13651],{"class":82,"line":83},[80,13652,7281],{},[80,13654,13655],{"class":82,"line":89},[80,13656,117],{"emptyLinePlaceholder":116},[80,13658,13659],{"class":82,"line":95},[80,13660,7290],{},[80,13662,13663],{"class":82,"line":101},[80,13664,7295],{},[80,13666,13667],{"class":82,"line":107},[80,13668,7300],{},[80,13670,13671],{"class":82,"line":113},[80,13672,7305],{},[80,13674,13675],{"class":82,"line":120},[80,13676,7310],{},[80,13678,13679],{"class":82,"line":126},[80,13680,117],{"emptyLinePlaceholder":116},[80,13682,13683],{"class":82,"line":132},[80,13684,7319],{},[80,13686,13687],{"class":82,"line":138},[80,13688,7324],{},[80,13690,13691],{"class":82,"line":144},[80,13692,7329],{},[80,13694,13695],{"class":82,"line":150},[80,13696,7334],{},[10,13698,168],{},[71,13700,13702],{"className":13701,"code":7340,"language":174,"meta":76},[172],[34,13703,7340],{"__ignoreMap":76},[10,13705,179],{},[14,13707,182],{"id":182},[184,13709,13710,13716],{},[49,13711,13712,7354,13714,7357],{},[34,13713,7353],{},[34,13715,7263],{},[49,13717,13718,7362],{},[34,13719,7242],{},[14,13721,270],{"id":270},[46,13723,13724,13726],{},[49,13725,7369],{},[49,13727,7372,13728,7375,13730,7378],{},[34,13729,7252],{},[34,13731,7256],{},[14,13733,288],{"id":288},[184,13735,13736,13738],{},[49,13737,7385],{},[49,13739,7388],{},[10,13741,313],{},[14,13743,316],{"id":316},[10,13745,7395],{},[321,13747,323],{},{"title":76,"searchDepth":89,"depth":89,"links":13749},[13750,13751,13752,13753,13754,13755,13756,13757],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":7219,"description":7224},[337,7415,7416],{"id":4,"title":5,"body":13762,"category":337,"cover":338,"description":12,"extension":339,"meta":13976,"navigation":116,"path":341,"pinned":342,"publishedAt":343,"seo":13977,"slug":345,"stem":346,"summary":347,"tags":13978,"updatedAt":343,"visible":116,"__hash__":351},{"type":7,"value":13763,"toc":13963},[13764,13766,13768,13770,13772,13776,13782,13784,13796,13798,13800,13860,13862,13867,13869,13871,13889,13891,13899,13903,13911,13913,13917,13921,13927,13929,13939,13941,13955,13957,13959,13961],[10,13765,12],{},[14,13767,16],{"id":16},[10,13769,19],{},[14,13771,22],{"id":22},[10,13773,13774],{},[26,13775],{"alt":28,"src":29},[10,13777,32,13778,37,13780,41],{},[34,13779,36],{},[34,13781,40],{},[14,13783,44],{"id":44},[46,13785,13786,13790,13794],{},[49,13787,51,13788,54],{},[34,13789,36],{},[49,13791,13792,60],{},[34,13793,59],{},[49,13795,63],{},[14,13797,66],{"id":66},[10,13799,69],{},[71,13801,13802],{"className":73,"code":74,"language":75,"meta":76,"style":76},[34,13803,13804,13808,13812,13816,13820,13824,13828,13832,13836,13840,13844,13848,13852,13856],{"__ignoreMap":76},[80,13805,13806],{"class":82,"line":83},[80,13807,86],{},[80,13809,13810],{"class":82,"line":89},[80,13811,92],{},[80,13813,13814],{"class":82,"line":95},[80,13815,98],{},[80,13817,13818],{"class":82,"line":101},[80,13819,104],{},[80,13821,13822],{"class":82,"line":107},[80,13823,110],{},[80,13825,13826],{"class":82,"line":113},[80,13827,117],{"emptyLinePlaceholder":116},[80,13829,13830],{"class":82,"line":120},[80,13831,123],{},[80,13833,13834],{"class":82,"line":126},[80,13835,129],{},[80,13837,13838],{"class":82,"line":132},[80,13839,135],{},[80,13841,13842],{"class":82,"line":138},[80,13843,141],{},[80,13845,13846],{"class":82,"line":144},[80,13847,147],{},[80,13849,13850],{"class":82,"line":150},[80,13851,153],{},[80,13853,13854],{"class":82,"line":156},[80,13855,159],{},[80,13857,13858],{"class":82,"line":162},[80,13859,165],{},[10,13861,168],{},[71,13863,13865],{"className":13864,"code":173,"language":174,"meta":76},[172],[34,13866,173],{"__ignoreMap":76},[10,13868,179],{},[14,13870,182],{"id":182},[184,13872,13873,13881],{},[49,13874,13875,191,13877,194,13879,198],{},[34,13876,190],{},[34,13878,59],{},[34,13880,197],{},[49,13882,201,13883,204,13885,208,13887,211],{},[34,13884,36],{},[34,13886,207],{},[34,13888,40],{},[213,13890,215],{"id":215},[10,13892,13893,220,13895,223,13897,226],{},[34,13894,36],{},[34,13896,207],{},[34,13898,40],{},[10,13900,13901],{},[26,13902],{"alt":231,"src":232},[10,13904,13905,237,13907,240,13909,243],{},[34,13906,36],{},[34,13908,207],{},[34,13910,40],{},[213,13912,215],{"id":246},[10,13914,13915,252],{},[34,13916,251],{},[10,13918,13919],{},[26,13920],{"alt":257,"src":258},[10,13922,261,13923,264,13925,267],{},[34,13924,251],{},[34,13926,207],{},[14,13928,270],{"id":270},[46,13930,13931,13935],{},[49,13932,275,13933,279],{},[34,13934,278],{},[49,13936,282,13937,285],{},[34,13938,251],{},[14,13940,288],{"id":288},[184,13942,13943,13951],{},[49,13944,293,13945,297,13947,223,13949,211],{},[34,13946,296],{},[34,13948,300],{},[34,13950,303],{},[49,13952,306,13953,310],{},[34,13954,309],{},[10,13956,313],{},[14,13958,316],{"id":316},[10,13960,319],{},[321,13962,323],{},{"title":76,"searchDepth":89,"depth":89,"links":13964},[13965,13966,13967,13968,13969,13973,13974,13975],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":13970},[13971,13972],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":5,"description":12},[337,349,350],{"id":7637,"title":7638,"body":13980,"category":337,"cover":338,"description":7643,"extension":339,"meta":14131,"navigation":116,"path":7820,"pinned":342,"publishedAt":343,"seo":14132,"slug":7822,"stem":7823,"summary":7824,"tags":14133,"updatedAt":343,"visible":116,"__hash__":7827},{"type":7,"value":13981,"toc":14121},[13982,13984,13986,13988,13990,13994,13998,14000,14012,14014,14016,14064,14066,14071,14073,14075,14085,14087,14097,14099,14113,14115,14117,14119],[10,13983,7643],{},[14,13985,16],{"id":16},[10,13987,7648],{},[14,13989,22],{"id":22},[10,13991,13992],{},[26,13993],{"alt":7655,"src":7656},[10,13995,7659,13996,7662],{},[34,13997,6890],{},[14,13999,44],{"id":44},[46,14001,14002,14006,14010],{},[49,14003,14004,7671],{},[34,14005,6890],{},[49,14007,14008,7677],{},[34,14009,7676],{},[49,14011,7680],{},[14,14013,66],{"id":66},[10,14015,69],{},[71,14017,14018],{"className":73,"code":7687,"language":75,"meta":76,"style":76},[34,14019,14020,14024,14028,14032,14036,14040,14044,14048,14052,14056,14060],{"__ignoreMap":76},[80,14021,14022],{"class":82,"line":83},[80,14023,6703],{},[80,14025,14026],{"class":82,"line":89},[80,14027,117],{"emptyLinePlaceholder":116},[80,14029,14030],{"class":82,"line":95},[80,14031,6913],{},[80,14033,14034],{"class":82,"line":101},[80,14035,117],{"emptyLinePlaceholder":116},[80,14037,14038],{"class":82,"line":107},[80,14039,7710],{},[80,14041,14042],{"class":82,"line":113},[80,14043,7715],{},[80,14045,14046],{"class":82,"line":120},[80,14047,117],{"emptyLinePlaceholder":116},[80,14049,14050],{"class":82,"line":126},[80,14051,7724],{},[80,14053,14054],{"class":82,"line":132},[80,14055,7729],{},[80,14057,14058],{"class":82,"line":138},[80,14059,117],{"emptyLinePlaceholder":116},[80,14061,14062],{"class":82,"line":144},[80,14063,7738],{},[10,14065,168],{},[71,14067,14069],{"className":14068,"code":7744,"language":174,"meta":76},[172],[34,14070,7744],{"__ignoreMap":76},[10,14072,179],{},[14,14074,182],{"id":182},[184,14076,14077,14083],{},[49,14078,7659,14079,7757,14081,211],{},[34,14080,6890],{},[34,14082,7760],{},[49,14084,7763],{},[14,14086,270],{"id":270},[46,14088,14089,14093],{},[49,14090,4889,14091,7772],{},[34,14092,6890],{},[49,14094,7775,14095,7778],{},[34,14096,6890],{},[14,14098,288],{"id":288},[184,14100,14101,14107],{},[49,14102,7785,14103,7789,14105,211],{},[34,14104,7788],{},[34,14106,6890],{},[49,14108,4889,14109,7796,14111,211],{},[34,14110,6890],{},[34,14112,7799],{},[10,14114,313],{},[14,14116,316],{"id":316},[10,14118,7806],{},[321,14120,323],{},{"title":76,"searchDepth":89,"depth":89,"links":14122},[14123,14124,14125,14126,14127,14128,14129,14130],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":7638,"description":7643},[337,6890,7826],{"id":7829,"title":7830,"body":14135,"category":337,"cover":338,"description":7835,"extension":339,"meta":14306,"navigation":116,"path":8048,"pinned":342,"publishedAt":343,"seo":14307,"slug":8050,"stem":8051,"summary":8052,"tags":14308,"updatedAt":343,"visible":116,"__hash__":8056},{"type":7,"value":14136,"toc":14294},[14137,14139,14141,14143,14145,14149,14151,14153,14165,14167,14169,14225,14227,14232,14234,14236,14252,14254,14256,14260,14266,14268,14276,14278,14286,14288,14290,14292],[10,14138,7835],{},[14,14140,16],{"id":16},[10,14142,7840],{},[14,14144,22],{"id":22},[10,14146,14147],{},[26,14148],{"alt":7847,"src":7848},[10,14150,7851],{},[14,14152,44],{"id":44},[46,14154,14155,14159,14163],{},[49,14156,14157,7861],{},[34,14158,7860],{},[49,14160,14161,7867],{},[34,14162,7866],{},[49,14164,7870],{},[14,14166,66],{"id":66},[10,14168,69],{},[71,14170,14171],{"className":73,"code":7877,"language":75,"meta":76,"style":76},[34,14172,14173,14177,14181,14185,14189,14193,14197,14201,14205,14209,14213,14217,14221],{"__ignoreMap":76},[80,14174,14175],{"class":82,"line":83},[80,14176,7884],{},[80,14178,14179],{"class":82,"line":89},[80,14180,7889],{},[80,14182,14183],{"class":82,"line":95},[80,14184,7894],{},[80,14186,14187],{"class":82,"line":101},[80,14188,7899],{},[80,14190,14191],{"class":82,"line":107},[80,14192,117],{"emptyLinePlaceholder":116},[80,14194,14195],{"class":82,"line":113},[80,14196,7908],{},[80,14198,14199],{"class":82,"line":120},[80,14200,7913],{},[80,14202,14203],{"class":82,"line":126},[80,14204,7918],{},[80,14206,14207],{"class":82,"line":132},[80,14208,7923],{},[80,14210,14211],{"class":82,"line":138},[80,14212,117],{"emptyLinePlaceholder":116},[80,14214,14215],{"class":82,"line":144},[80,14216,7932],{},[80,14218,14219],{"class":82,"line":150},[80,14220,7937],{},[80,14222,14223],{"class":82,"line":156},[80,14224,7942],{},[10,14226,168],{},[71,14228,14230],{"className":14229,"code":7948,"language":174,"meta":76},[172],[34,14231,7948],{"__ignoreMap":76},[10,14233,179],{},[14,14235,182],{"id":182},[184,14237,14238,14244],{},[49,14239,7959,14240,7963,14242,7966],{},[34,14241,7962],{},[34,14243,7866],{},[49,14245,14246,7972,14248,7976,14250,7979],{},[34,14247,7971],{},[34,14249,7975],{},[34,14251,7860],{},[213,14253,215],{"id":215},[10,14255,7984],{},[10,14257,14258],{},[26,14259],{"alt":7989,"src":7990},[10,14261,7993,14262,223,14264,7999],{},[34,14263,4686],{},[34,14265,7998],{},[14,14267,270],{"id":270},[46,14269,14270,14274],{},[49,14271,8006,14272,8009],{},[34,14273,7860],{},[49,14275,8012],{},[14,14277,288],{"id":288},[184,14279,14280,14284],{},[49,14281,5399,14282,8022],{},[34,14283,8021],{},[49,14285,8025],{},[10,14287,313],{},[14,14289,316],{"id":316},[10,14291,8032],{},[321,14293,323],{},{"title":76,"searchDepth":89,"depth":89,"links":14295},[14296,14297,14298,14299,14300,14303,14304,14305],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":14301},[14302],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":7830,"description":7835},[337,8054,8055],{"id":8058,"title":8059,"body":14310,"category":337,"cover":338,"description":8064,"extension":339,"meta":14457,"navigation":116,"path":8243,"pinned":342,"publishedAt":343,"seo":14458,"slug":8245,"stem":8246,"summary":8247,"tags":14459,"updatedAt":343,"visible":116,"__hash__":8251},{"type":7,"value":14311,"toc":14447},[14312,14314,14316,14318,14320,14324,14326,14328,14336,14338,14340,14396,14398,14403,14405,14407,14419,14421,14427,14429,14439,14441,14443,14445],[10,14313,8064],{},[14,14315,16],{"id":16},[10,14317,8069],{},[14,14319,22],{"id":22},[10,14321,14322],{},[26,14323],{"alt":8076,"src":8077},[10,14325,8080],{},[14,14327,44],{"id":44},[46,14329,14330,14332,14334],{},[49,14331,8087],{},[49,14333,8090],{},[49,14335,8093],{},[14,14337,66],{"id":66},[10,14339,69],{},[71,14341,14342],{"className":73,"code":8100,"language":75,"meta":76,"style":76},[34,14343,14344,14348,14352,14356,14360,14364,14368,14372,14376,14380,14384,14388,14392],{"__ignoreMap":76},[80,14345,14346],{"class":82,"line":83},[80,14347,8107],{},[80,14349,14350],{"class":82,"line":89},[80,14351,8112],{},[80,14353,14354],{"class":82,"line":95},[80,14355,8117],{},[80,14357,14358],{"class":82,"line":101},[80,14359,117],{"emptyLinePlaceholder":116},[80,14361,14362],{"class":82,"line":107},[80,14363,8126],{},[80,14365,14366],{"class":82,"line":113},[80,14367,8131],{},[80,14369,14370],{"class":82,"line":120},[80,14371,8136],{},[80,14373,14374],{"class":82,"line":126},[80,14375,117],{"emptyLinePlaceholder":116},[80,14377,14378],{"class":82,"line":132},[80,14379,8145],{},[80,14381,14382],{"class":82,"line":138},[80,14383,8150],{},[80,14385,14386],{"class":82,"line":144},[80,14387,117],{"emptyLinePlaceholder":116},[80,14389,14390],{"class":82,"line":150},[80,14391,8159],{},[80,14393,14394],{"class":82,"line":156},[80,14395,8164],{},[10,14397,168],{},[71,14399,14401],{"className":14400,"code":8170,"language":174,"meta":76},[172],[34,14402,8170],{"__ignoreMap":76},[10,14404,179],{},[14,14406,182],{"id":182},[184,14408,14409,14415],{},[49,14410,14411,8184,14413,8188],{},[34,14412,8183],{},[34,14414,8187],{},[49,14416,8191,14417,8195],{},[34,14418,8194],{},[14,14420,270],{"id":270},[46,14422,14423,14425],{},[49,14424,8202],{},[49,14426,8205],{},[14,14428,288],{"id":288},[184,14430,14431,14437],{},[49,14432,8212,14433,8216,14435,211],{},[34,14434,8215],{},[34,14436,8219],{},[49,14438,8222],{},[10,14440,313],{},[14,14442,316],{"id":316},[10,14444,8229],{},[321,14446,323],{},{"title":76,"searchDepth":89,"depth":89,"links":14448},[14449,14450,14451,14452,14453,14454,14455,14456],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":8059,"description":8064},[337,8249,8250],{"id":8253,"title":8254,"body":14461,"category":337,"cover":338,"description":8259,"extension":339,"meta":14624,"navigation":116,"path":8463,"pinned":342,"publishedAt":343,"seo":14625,"slug":8465,"stem":8466,"summary":8467,"tags":14626,"updatedAt":343,"visible":116,"__hash__":8471},{"type":7,"value":14462,"toc":14612},[14463,14465,14467,14469,14471,14475,14479,14481,14497,14499,14501,14545,14547,14552,14554,14556,14570,14572,14576,14580,14584,14586,14592,14594,14604,14606,14608,14610],[10,14464,8259],{},[14,14466,16],{"id":16},[10,14468,8264],{},[14,14470,22],{"id":22},[10,14472,14473],{},[26,14474],{"alt":8271,"src":8272},[10,14476,8275,14477,8279],{},[34,14478,8278],{},[14,14480,44],{"id":44},[46,14482,14483,14489,14495],{},[49,14484,14485,8289,14487,8293],{},[34,14486,8288],{},[34,14488,8292],{},[49,14490,8296,14491,8300,14493,8303],{},[34,14492,8299],{},[34,14494,4440],{},[49,14496,8306],{},[14,14498,66],{"id":66},[10,14500,69],{},[71,14502,14503],{"className":73,"code":8313,"language":75,"meta":76,"style":76},[34,14504,14505,14509,14513,14517,14521,14525,14529,14533,14537,14541],{"__ignoreMap":76},[80,14506,14507],{"class":82,"line":83},[80,14508,8320],{},[80,14510,14511],{"class":82,"line":89},[80,14512,8325],{},[80,14514,14515],{"class":82,"line":95},[80,14516,8330],{},[80,14518,14519],{"class":82,"line":101},[80,14520,8335],{},[80,14522,14523],{"class":82,"line":107},[80,14524,8340],{},[80,14526,14527],{"class":82,"line":113},[80,14528,117],{"emptyLinePlaceholder":116},[80,14530,14531],{"class":82,"line":120},[80,14532,8349],{},[80,14534,14535],{"class":82,"line":126},[80,14536,8354],{},[80,14538,14539],{"class":82,"line":132},[80,14540,8354],{},[80,14542,14543],{"class":82,"line":138},[80,14544,8354],{},[10,14546,168],{},[71,14548,14550],{"className":14549,"code":8368,"language":174,"meta":76},[172],[34,14551,8368],{"__ignoreMap":76},[10,14553,179],{},[14,14555,182],{"id":182},[184,14557,14558,14562],{},[49,14559,7959,14560,8382],{},[34,14561,8381],{},[49,14563,8385,14564,8388,14566,8391,14568,8395],{},[34,14565,8292],{},[34,14567,8278],{},[34,14569,8394],{},[213,14571,215],{"id":215},[10,14573,8400,14574,8403],{},[34,14575,8292],{},[10,14577,14578],{},[26,14579],{"alt":8408,"src":8409},[10,14581,8412,14582,8415],{},[34,14583,8278],{},[14,14585,270],{"id":270},[46,14587,14588,14590],{},[49,14589,8422],{},[49,14591,8425],{},[14,14593,288],{"id":288},[184,14595,14596,14598],{},[49,14597,8432],{},[49,14599,4114,14600,8437,14602,8440],{},[34,14601,4440],{},[34,14603,8292],{},[10,14605,313],{},[14,14607,316],{"id":316},[10,14609,8447],{},[321,14611,323],{},{"title":76,"searchDepth":89,"depth":89,"links":14613},[14614,14615,14616,14617,14618,14621,14622,14623],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":14619},[14620],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":8254,"description":8259},[337,8469,8470],{"id":8473,"title":8474,"body":14628,"category":337,"cover":338,"description":8479,"extension":339,"meta":14811,"navigation":116,"path":8704,"pinned":342,"publishedAt":343,"seo":14812,"slug":8706,"stem":8707,"summary":8708,"tags":14813,"updatedAt":343,"visible":116,"__hash__":8711},{"type":7,"value":14629,"toc":14799},[14630,14632,14634,14636,14638,14642,14644,14646,14660,14662,14664,14732,14734,14739,14741,14743,14757,14759,14761,14765,14771,14773,14781,14783,14791,14793,14795,14797],[10,14631,8479],{},[14,14633,16],{"id":16},[10,14635,8484],{},[14,14637,22],{"id":22},[10,14639,14640],{},[26,14641],{"alt":8491,"src":8492},[10,14643,8495],{},[14,14645,44],{"id":44},[46,14647,14648,14654,14656],{},[49,14649,14650,8505,14652,211],{},[34,14651,8504],{},[34,14653,8508],{},[49,14655,8511],{},[49,14657,14658,8517],{},[34,14659,8516],{},[14,14661,66],{"id":66},[10,14663,69],{},[71,14665,14666],{"className":73,"code":8524,"language":75,"meta":76,"style":76},[34,14667,14668,14672,14676,14680,14684,14688,14692,14696,14700,14704,14708,14712,14716,14720,14724,14728],{"__ignoreMap":76},[80,14669,14670],{"class":82,"line":83},[80,14671,8531],{},[80,14673,14674],{"class":82,"line":89},[80,14675,117],{"emptyLinePlaceholder":116},[80,14677,14678],{"class":82,"line":95},[80,14679,8540],{},[80,14681,14682],{"class":82,"line":101},[80,14683,8545],{},[80,14685,14686],{"class":82,"line":107},[80,14687,8550],{},[80,14689,14690],{"class":82,"line":113},[80,14691,8555],{},[80,14693,14694],{"class":82,"line":120},[80,14695,8560],{},[80,14697,14698],{"class":82,"line":126},[80,14699,8565],{},[80,14701,14702],{"class":82,"line":132},[80,14703,8570],{},[80,14705,14706],{"class":82,"line":138},[80,14707,8575],{},[80,14709,14710],{"class":82,"line":144},[80,14711,117],{"emptyLinePlaceholder":116},[80,14713,14714],{"class":82,"line":150},[80,14715,8584],{},[80,14717,14718],{"class":82,"line":156},[80,14719,6282],{},[80,14721,14722],{"class":82,"line":162},[80,14723,6287],{},[80,14725,14726],{"class":82,"line":8595},[80,14727,117],{"emptyLinePlaceholder":116},[80,14729,14730],{"class":82,"line":8600},[80,14731,8603],{},[10,14733,168],{},[71,14735,14737],{"className":14736,"code":8609,"language":174,"meta":76},[172],[34,14738,8609],{"__ignoreMap":76},[10,14740,179],{},[14,14742,182],{"id":182},[184,14744,14745,14755],{},[49,14746,8620,14747,8624,14749,8628,14751,8632,14753,211],{},[34,14748,8623],{},[34,14750,8627],{},[34,14752,8631],{},[34,14754,8623],{},[49,14756,8637],{},[213,14758,215],{"id":215},[10,14760,8642],{},[10,14762,14763],{},[26,14764],{"alt":8647,"src":8648},[10,14766,14767,8653,14769,211],{},[34,14768,8504],{},[34,14770,8508],{},[14,14772,270],{"id":270},[46,14774,14775,14779],{},[49,14776,8662,14777,211],{},[34,14778,5482],{},[49,14780,8667],{},[14,14782,288],{"id":288},[184,14784,14785,14787],{},[49,14786,8674],{},[49,14788,8677,14789,8681],{},[34,14790,8680],{},[10,14792,313],{},[14,14794,316],{"id":316},[10,14796,8688],{},[321,14798,323],{},{"title":76,"searchDepth":89,"depth":89,"links":14800},[14801,14802,14803,14804,14805,14808,14809,14810],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":14806},[14807],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":8474,"description":8479},[337,8710,5433],{"id":8713,"title":8714,"body":14815,"category":337,"cover":338,"description":8719,"extension":339,"meta":14974,"navigation":116,"path":8907,"pinned":342,"publishedAt":343,"seo":14975,"slug":8909,"stem":8910,"summary":8911,"tags":14976,"updatedAt":343,"visible":116,"__hash__":8915},{"type":7,"value":14816,"toc":14962},[14817,14819,14821,14823,14825,14829,14831,14833,14841,14843,14845,14909,14911,14916,14918,14920,14928,14930,14932,14936,14938,14940,14946,14948,14954,14956,14958,14960],[10,14818,8719],{},[14,14820,16],{"id":16},[10,14822,8724],{},[14,14824,22],{"id":22},[10,14826,14827],{},[26,14828],{"alt":8731,"src":8732},[10,14830,8735],{},[14,14832,44],{"id":44},[46,14834,14835,14837,14839],{},[49,14836,8742],{},[49,14838,8745],{},[49,14840,8748],{},[14,14842,66],{"id":66},[10,14844,69],{},[71,14846,14847],{"className":73,"code":8755,"language":75,"meta":76,"style":76},[34,14848,14849,14853,14857,14861,14865,14869,14873,14877,14881,14885,14889,14893,14897,14901,14905],{"__ignoreMap":76},[80,14850,14851],{"class":82,"line":83},[80,14852,8762],{},[80,14854,14855],{"class":82,"line":89},[80,14856,8767],{},[80,14858,14859],{"class":82,"line":95},[80,14860,117],{"emptyLinePlaceholder":116},[80,14862,14863],{"class":82,"line":101},[80,14864,8776],{},[80,14866,14867],{"class":82,"line":107},[80,14868,117],{"emptyLinePlaceholder":116},[80,14870,14871],{"class":82,"line":113},[80,14872,8785],{},[80,14874,14875],{"class":82,"line":120},[80,14876,8790],{},[80,14878,14879],{"class":82,"line":126},[80,14880,8795],{},[80,14882,14883],{"class":82,"line":132},[80,14884,117],{"emptyLinePlaceholder":116},[80,14886,14887],{"class":82,"line":138},[80,14888,8804],{},[80,14890,14891],{"class":82,"line":144},[80,14892,8809],{},[80,14894,14895],{"class":82,"line":150},[80,14896,8814],{},[80,14898,14899],{"class":82,"line":156},[80,14900,117],{"emptyLinePlaceholder":116},[80,14902,14903],{"class":82,"line":162},[80,14904,6296],{},[80,14906,14907],{"class":82,"line":8595},[80,14908,8827],{},[10,14910,168],{},[71,14912,14914],{"className":14913,"code":8833,"language":174,"meta":76},[172],[34,14915,8833],{"__ignoreMap":76},[10,14917,179],{},[14,14919,182],{"id":182},[184,14921,14922,14926],{},[49,14923,14924,8847],{},[34,14925,8846],{},[49,14927,8850],{},[213,14929,215],{"id":215},[10,14931,8855],{},[10,14933,14934],{},[26,14935],{"alt":8860,"src":8861},[10,14937,8864],{},[14,14939,270],{"id":270},[46,14941,14942,14944],{},[49,14943,8871],{},[49,14945,8874],{},[14,14947,288],{"id":288},[184,14949,14950,14952],{},[49,14951,8881],{},[49,14953,8884],{},[10,14955,313],{},[14,14957,316],{"id":316},[10,14959,8891],{},[321,14961,323],{},{"title":76,"searchDepth":89,"depth":89,"links":14963},[14964,14965,14966,14967,14968,14971,14972,14973],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":14969},[14970],{"id":215,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":8714,"description":8719},[337,8913,8914],{"id":8917,"title":8918,"body":14978,"category":337,"cover":338,"description":8923,"extension":339,"meta":15216,"navigation":116,"path":9224,"pinned":342,"publishedAt":343,"seo":15217,"slug":9226,"stem":9227,"summary":9228,"tags":15218,"updatedAt":343,"visible":116,"__hash__":9232},{"type":7,"value":14979,"toc":15203},[14980,14982,14984,14986,14988,14992,14994,14996,15006,15008,15010,15126,15128,15133,15135,15137,15147,15149,15151,15155,15157,15159,15161,15165,15169,15171,15179,15181,15195,15197,15199,15201],[10,14981,8923],{},[14,14983,16],{"id":16},[10,14985,8928],{},[14,14987,22],{"id":22},[10,14989,14990],{},[26,14991],{"alt":8935,"src":8936},[10,14993,8939],{},[14,14995,44],{"id":44},[46,14997,14998,15000,15002],{},[49,14999,8946],{},[49,15001,8949],{},[49,15003,8952,15004,8956],{},[34,15005,8955],{},[14,15007,66],{"id":66},[10,15009,69],{},[71,15011,15012],{"className":73,"code":8963,"language":75,"meta":76,"style":76},[34,15013,15014,15018,15022,15026,15030,15034,15038,15042,15046,15050,15054,15058,15062,15066,15070,15074,15078,15082,15086,15090,15094,15098,15102,15106,15110,15114,15118,15122],{"__ignoreMap":76},[80,15015,15016],{"class":82,"line":83},[80,15017,7093],{},[80,15019,15020],{"class":82,"line":89},[80,15021,6703],{},[80,15023,15024],{"class":82,"line":95},[80,15025,117],{"emptyLinePlaceholder":116},[80,15027,15028],{"class":82,"line":101},[80,15029,8982],{},[80,15031,15032],{"class":82,"line":107},[80,15033,8987],{},[80,15035,15036],{"class":82,"line":113},[80,15037,8992],{},[80,15039,15040],{"class":82,"line":120},[80,15041,8997],{},[80,15043,15044],{"class":82,"line":126},[80,15045,117],{"emptyLinePlaceholder":116},[80,15047,15048],{"class":82,"line":132},[80,15049,9006],{},[80,15051,15052],{"class":82,"line":138},[80,15053,9011],{},[80,15055,15056],{"class":82,"line":144},[80,15057,9016],{},[80,15059,15060],{"class":82,"line":150},[80,15061,9021],{},[80,15063,15064],{"class":82,"line":156},[80,15065,9026],{},[80,15067,15068],{"class":82,"line":162},[80,15069,117],{"emptyLinePlaceholder":116},[80,15071,15072],{"class":82,"line":8595},[80,15073,9035],{},[80,15075,15076],{"class":82,"line":8600},[80,15077,9040],{},[80,15079,15080],{"class":82,"line":9043},[80,15081,9046],{},[80,15083,15084],{"class":82,"line":9049},[80,15085,117],{"emptyLinePlaceholder":116},[80,15087,15088],{"class":82,"line":9054},[80,15089,9057],{},[80,15091,15092],{"class":82,"line":9060},[80,15093,117],{"emptyLinePlaceholder":116},[80,15095,15096],{"class":82,"line":9065},[80,15097,123],{},[80,15099,15100],{"class":82,"line":9070},[80,15101,9073],{},[80,15103,15104],{"class":82,"line":9076},[80,15105,9079],{},[80,15107,15108],{"class":82,"line":9082},[80,15109,9085],{},[80,15111,15112],{"class":82,"line":9088},[80,15113,135],{},[80,15115,15116],{"class":82,"line":9093},[80,15117,9096],{},[80,15119,15120],{"class":82,"line":9099},[80,15121,147],{},[80,15123,15124],{"class":82,"line":9104},[80,15125,9107],{},[10,15127,168],{},[71,15129,15131],{"className":15130,"code":9113,"language":174,"meta":76},[172],[34,15132,9113],{"__ignoreMap":76},[10,15134,179],{},[14,15136,182],{"id":182},[184,15138,15139,15143],{},[49,15140,9124,15141,9127],{},[34,15142,8955],{},[49,15144,15145,9132],{},[34,15146,8187],{},[213,15148,215],{"id":215},[10,15150,9137],{},[10,15152,15153],{},[26,15154],{"alt":9142,"src":9143},[10,15156,9146],{},[213,15158,215],{"id":246},[10,15160,9151],{},[10,15162,15163],{},[26,15164],{"alt":9156,"src":9157},[10,15166,9160,15167,9164],{},[34,15168,9163],{},[14,15170,270],{"id":270},[46,15172,15173,15175],{},[49,15174,9171],{},[49,15176,9174,15177,9177],{},[34,15178,9163],{},[14,15180,288],{"id":288},[184,15182,15183,15187,15189],{},[49,15184,9184,15185,9187],{},[34,15186,9163],{},[49,15188,9190],{},[49,15190,9193,15191,9197,15193,9200],{},[34,15192,9196],{},[34,15194,6238],{},[10,15196,313],{},[14,15198,316],{"id":316},[10,15200,9207],{},[321,15202,323],{},{"title":76,"searchDepth":89,"depth":89,"links":15204},[15205,15206,15207,15208,15209,15213,15214,15215],{"id":16,"depth":89,"text":16},{"id":22,"depth":89,"text":22},{"id":44,"depth":89,"text":44},{"id":66,"depth":89,"text":66},{"id":182,"depth":89,"text":182,"children":15210},[15211,15212],{"id":215,"depth":95,"text":215},{"id":246,"depth":95,"text":215},{"id":270,"depth":89,"text":270},{"id":288,"depth":89,"text":288},{"id":316,"depth":89,"text":316},{},{"title":8918,"description":8923},[337,9230,9231],{"id":1166,"title":1167,"body":15220,"category":337,"cover":1175,"description":76,"extension":339,"meta":15456,"navigation":116,"path":1489,"pinned":342,"publishedAt":1490,"seo":15457,"slug":1492,"stem":1493,"summary":1494,"tags":15458,"updatedAt":1490,"visible":116,"__hash__":1498},{"type":7,"value":15221,"toc":15441},[15222,15226,15228,15230,15232,15234,15254,15256,15261,15263,15265,15293,15299,15301,15305,15307,15327,15329,15339,15341,15343,15345,15347,15349,15351,15353,15355,15357,15377,15379,15381,15385,15387,15389,15391,15393,15397,15399,15417,15419,15421,15423,15425,15427,15429,15431,15433,15435,15437,15439],[10,15223,15224],{},[26,15225],{"alt":1174,"src":1175},[10,15227,1178],{},[10,15229,1181],{},[14,15231,1185],{"id":1184},[10,15233,1188],{},[71,15235,15236],{"className":73,"code":1191,"language":75,"meta":76,"style":76},[34,15237,15238,15242,15246,15250],{"__ignoreMap":76},[80,15239,15240],{"class":82,"line":83},[80,15241,1198],{},[80,15243,15244],{"class":82,"line":89},[80,15245,1203],{},[80,15247,15248],{"class":82,"line":95},[80,15249,117],{"emptyLinePlaceholder":116},[80,15251,15252],{"class":82,"line":101},[80,15253,1212],{},[10,15255,1215],{},[71,15257,15259],{"className":15258,"code":1219,"language":174,"meta":76},[172],[34,15260,1219],{"__ignoreMap":76},[10,15262,1224],{},[10,15264,1227],{},[71,15266,15267],{"className":73,"code":1230,"language":75,"meta":76,"style":76},[34,15268,15269,15273,15277,15281,15285,15289],{"__ignoreMap":76},[80,15270,15271],{"class":82,"line":83},[80,15272,1237],{},[80,15274,15275],{"class":82,"line":89},[80,15276,117],{"emptyLinePlaceholder":116},[80,15278,15279],{"class":82,"line":95},[80,15280,1246],{},[80,15282,15283],{"class":82,"line":101},[80,15284,1251],{},[80,15286,15287],{"class":82,"line":107},[80,15288,147],{},[80,15290,15291],{"class":82,"line":113},[80,15292,1260],{},[10,15294,15295,223,15297,1268],{},[34,15296,1265],{},[34,15298,207],{},[14,15300,1272],{"id":1271},[10,15302,1275,15303,1279],{},[34,15304,1278],{},[10,15306,1282],{},[71,15308,15309],{"className":73,"code":1285,"language":75,"meta":76,"style":76},[34,15310,15311,15315,15319,15323],{"__ignoreMap":76},[80,15312,15313],{"class":82,"line":83},[80,15314,1292],{},[80,15316,15317],{"class":82,"line":89},[80,15318,1297],{},[80,15320,15321],{"class":82,"line":95},[80,15322,1302],{},[80,15324,15325],{"class":82,"line":101},[80,15326,1307],{},[10,15328,1310],{},[71,15330,15331],{"className":701,"code":1313,"language":703,"meta":76,"style":76},[34,15332,15333],{"__ignoreMap":76},[80,15334,15335,15337],{"class":82,"line":83},[80,15336,801],{"class":710},[80,15338,1322],{"class":746},[10,15340,1325],{},[14,15342,1329],{"id":1328},[213,15344,1332],{"id":1332},[10,15346,1335],{},[213,15348,1338],{"id":1338},[10,15350,1341],{},[213,15352,1344],{"id":1344},[10,15354,1347],{},[10,15356,1350],{},[71,15358,15359],{"className":73,"code":1353,"language":75,"meta":76,"style":76},[34,15360,15361,15365,15369,15373],{"__ignoreMap":76},[80,15362,15363],{"class":82,"line":83},[80,15364,1360],{},[80,15366,15367],{"class":82,"line":89},[80,15368,117],{"emptyLinePlaceholder":116},[80,15370,15371],{"class":82,"line":95},[80,15372,1369],{},[80,15374,15375],{"class":82,"line":101},[80,15376,1374],{},[10,15378,1377],{},[213,15380,1380],{"id":1380},[10,15382,1383,15383,1386],{},[34,15384,372],{},[10,15386,1389],{},[213,15388,1392],{"id":1392},[10,15390,1395],{},[14,15392,1399],{"id":1398},[10,15394,15395],{},[26,15396],{"alt":1404,"src":1405},[10,15398,1408],{},[46,15400,15401,15403,15405,15407,15409,15411,15413,15415],{},[49,15402,1413],{},[49,15404,1416],{},[49,15406,1419],{},[49,15408,1422],{},[49,15410,1425],{},[49,15412,1428],{},[49,15414,1431],{},[49,15416,1434],{},[10,15418,1437],{},[14,15420,1441],{"id":1440},[10,15422,1444],{},[10,15424,1447],{},[14,15426,1451],{"id":1450},[10,15428,1454],{},[10,15430,1457],{},[10,15432,1460],{},[14,15434,1463],{"id":1463},[10,15436,1466],{},[10,15438,1469],{},[321,15440,1472],{},{"title":76,"searchDepth":89,"depth":89,"links":15442},[15443,15444,15445,15452,15453,15454,15455],{"id":1184,"depth":89,"text":1185},{"id":1271,"depth":89,"text":1272},{"id":1328,"depth":89,"text":1329,"children":15446},[15447,15448,15449,15450,15451],{"id":1332,"depth":95,"text":1332},{"id":1338,"depth":95,"text":1338},{"id":1344,"depth":95,"text":1344},{"id":1380,"depth":95,"text":1380},{"id":1392,"depth":95,"text":1392},{"id":1398,"depth":89,"text":1399},{"id":1440,"depth":89,"text":1441},{"id":1450,"depth":89,"text":1451},{"id":1463,"depth":89,"text":1463},{},{"title":1167,"description":76},[337,1496,1497],{"id":354,"title":355,"body":15460,"category":337,"cover":338,"description":76,"extension":339,"meta":16039,"navigation":116,"path":1155,"pinned":342,"publishedAt":1156,"seo":16040,"slug":1158,"stem":1159,"summary":1160,"tags":16041,"updatedAt":1156,"visible":116,"__hash__":1164},{"type":7,"value":15461,"toc":16015},[15462,15464,15466,15468,15472,15474,15476,15500,15512,15514,15516,15521,15525,15529,15541,15545,15549,15553,15555,15589,15591,15595,15599,15601,15623,15653,15665,15675,15683,15685,15691,15701,15703,15708,15712,15714,15728,15734,15754,15756,15758,15760,15770,15774,15776,15785,15789,15791,15793,15813,15817,15819,15821,15823,15825,15845,15847,15849,15851,15877,15879,15895,15897,15913,15917,15919,15921,15941,15943,15945,15947,15951,15961,15963,15965,15967,15977,15985,15987,15989,16003,16013],[14,15463,360],{"id":360},[10,15465,363],{},[10,15467,366],{},[10,15469,369,15470,373],{},[34,15471,372],{},[14,15473,376],{"id":376},[10,15475,379],{},[381,15477,15478,15480],{},[10,15479,385],{},[381,15481,15482,15488,15490,15494,15496],{},[10,15483,390,15484,394,15486,398],{},[34,15485,393],{},[34,15487,397],{},[10,15489,401],{},[10,15491,404,15492,409],{},[406,15493,408],{},[10,15495,412],{},[10,15497,15498],{},[26,15499],{"alt":417,"src":418},[381,15501,15502,15504],{},[10,15503,423],{},[381,15505,15506,15508],{},[10,15507,428],{},[10,15509,15510],{},[26,15511],{"alt":433,"src":434},[14,15513,438],{"id":437},[213,15515,442],{"id":441},[10,15517,445,15518,453],{},[447,15519,452],{"href":449,"rel":15520},[451],[381,15522,15523],{},[10,15524,458],{},[10,15526,15527],{},[26,15528],{"alt":463,"src":464},[46,15530,15531,15535,15539],{},[49,15532,469,15533,211],{},[406,15534,472],{},[49,15536,475,15537,211],{},[406,15538,478],{},[49,15540,481],{},[10,15542,15543],{},[26,15544],{"alt":486,"src":487},[381,15546,15547],{},[10,15548,492],{},[10,15550,15551],{},[26,15552],{"alt":497,"src":498},[213,15554,502],{"id":501},[381,15556,15557,15561,15565,15585],{},[381,15558,15559],{},[10,15560,509],{},[10,15562,512,15563,516],{},[406,15564,515],{},[71,15566,15567],{"className":73,"code":519,"language":75,"meta":76,"style":76},[34,15568,15569,15573,15577,15581],{"__ignoreMap":76},[80,15570,15571],{"class":82,"line":83},[80,15572,526],{},[80,15574,15575],{"class":82,"line":89},[80,15576,531],{},[80,15578,15579],{"class":82,"line":95},[80,15580,536],{},[80,15582,15583],{"class":82,"line":101},[80,15584,541],{},[10,15586,544,15587,548],{},[406,15588,547],{},[10,15590,551],{},[10,15592,554,15593,557],{},[34,15594,75],{},[10,15596,15597],{},[26,15598],{"alt":562,"src":563},[10,15600,566],{},[381,15602,15603,15605,15609],{},[10,15604,571],{},[10,15606,15607],{},[406,15608,576],{},[381,15610,15611,15615,15619],{},[10,15612,581,15613,584],{},[34,15614,75],{},[10,15616,587,15617,590],{},[34,15618,75],{},[10,15620,593,15621,597],{},[406,15622,596],{},[381,15624,15625,15627,15631],{},[10,15626,602],{},[10,15628,15629],{},[406,15630,607],{},[381,15632,15633,15639,15647,15649],{},[10,15634,15635,615,15637,619],{},[34,15636,614],{},[34,15638,618],{},[10,15640,622,15641,625,15643,629,15645,633],{},[34,15642,614],{},[406,15644,628],{},[406,15646,632],{},[10,15648,636],{},[10,15650,15651,642],{},[406,15652,641],{},[381,15654,15655,15657],{},[10,15656,647],{},[381,15658,15659,15663],{},[10,15660,652,15661,656],{},[406,15662,655],{},[10,15664,659],{},[381,15666,15667,15671],{},[10,15668,664,15669],{},[406,15670,667],{},[10,15672,15673],{},[26,15674],{"alt":672,"src":673},[381,15676,15677,15679],{},[10,15678,678],{},[10,15680,15681],{},[26,15682],{"alt":672,"src":683},[213,15684,687],{"id":686},[10,15686,690,15687,694,15689,698],{},[34,15688,693],{},[34,15690,697],{},[71,15692,15693],{"className":701,"code":702,"language":703,"meta":76,"style":76},[34,15694,15695],{"__ignoreMap":76},[80,15696,15697,15699],{"class":82,"line":83},[80,15698,75],{"class":710},[80,15700,714],{"class":713},[10,15702,717],{},[71,15704,15706],{"className":15705,"code":721,"language":174,"meta":76},[172],[34,15707,721],{"__ignoreMap":76},[10,15709,15710],{},[26,15711],{"alt":672,"src":728},[10,15713,731],{},[71,15715,15716],{"className":701,"code":734,"language":703,"meta":76,"style":76},[34,15717,15718],{"__ignoreMap":76},[80,15719,15720,15722,15724,15726],{"class":82,"line":83},[80,15721,75],{"class":710},[80,15723,743],{"class":713},[80,15725,747],{"class":746},[80,15727,714],{"class":713},[10,15729,752,15730,755,15732,759],{},[34,15731,75],{},[34,15733,758],{},[71,15735,15736],{"className":701,"code":762,"language":703,"meta":76,"style":76},[34,15737,15738,15744],{"__ignoreMap":76},[80,15739,15740,15742],{"class":82,"line":83},[80,15741,618],{"class":710},[80,15743,714],{"class":713},[80,15745,15746,15748,15750,15752],{"class":82,"line":89},[80,15747,618],{"class":710},[80,15749,743],{"class":713},[80,15751,747],{"class":746},[80,15753,714],{"class":713},[14,15755,784],{"id":783},[213,15757,788],{"id":787},[10,15759,791],{},[71,15761,15762],{"className":701,"code":794,"language":703,"meta":76,"style":76},[34,15763,15764],{"__ignoreMap":76},[80,15765,15766,15768],{"class":82,"line":83},[80,15767,801],{"class":710},[80,15769,714],{"class":713},[10,15771,806,15772,810],{},[34,15773,809],{},[213,15775,814],{"id":813},[10,15777,445,15778,822,15781,211,15783,829],{},[447,15779,821],{"href":819,"rel":15780},[451],[406,15782,825],{},[34,15784,828],{},[10,15786,832,15787,836],{},[34,15788,835],{},[213,15790,840],{"id":839},[10,15792,843],{},[71,15794,15795],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,15796,15797,15803],{"__ignoreMap":76},[80,15798,15799,15801],{"class":82,"line":83},[80,15800,801],{"class":710},[80,15802,714],{"class":713},[80,15804,15805,15807,15809,15811],{"class":82,"line":89},[80,15806,801],{"class":710},[80,15808,743],{"class":713},[80,15810,747],{"class":746},[80,15812,714],{"class":713},[10,15814,867,15815,870],{},[34,15816,801],{},[14,15818,874],{"id":873},[10,15820,877],{},[213,15822,881],{"id":880},[10,15824,884],{},[71,15826,15827],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,15828,15829,15835],{"__ignoreMap":76},[80,15830,15831,15833],{"class":82,"line":83},[80,15832,801],{"class":710},[80,15834,714],{"class":713},[80,15836,15837,15839,15841,15843],{"class":82,"line":89},[80,15838,801],{"class":710},[80,15840,743],{"class":713},[80,15842,747],{"class":746},[80,15844,714],{"class":713},[10,15846,907],{},[213,15848,911],{"id":910},[10,15850,914],{},[71,15852,15853],{"className":701,"code":917,"language":703,"meta":76,"style":76},[34,15854,15855,15863],{"__ignoreMap":76},[80,15856,15857,15859,15861],{"class":82,"line":83},[80,15858,924],{"class":710},[80,15860,927],{"class":746},[80,15862,930],{"class":746},[80,15864,15865,15867,15869,15871,15873,15875],{"class":82,"line":89},[80,15866,924],{"class":710},[80,15868,927],{"class":746},[80,15870,939],{"class":746},[80,15872,942],{"class":746},[80,15874,945],{"class":746},[80,15876,948],{"class":746},[10,15878,951],{},[71,15880,15881],{"className":701,"code":954,"language":703,"meta":76,"style":76},[34,15882,15883],{"__ignoreMap":76},[80,15884,15885,15887,15889,15891,15893],{"class":82,"line":83},[80,15886,924],{"class":710},[80,15888,963],{"class":746},[80,15890,939],{"class":746},[80,15892,942],{"class":746},[80,15894,970],{"class":746},[10,15896,973],{},[71,15898,15899],{"className":701,"code":976,"language":703,"meta":76,"style":76},[34,15900,15901],{"__ignoreMap":76},[80,15902,15903,15905,15907,15909,15911],{"class":82,"line":83},[80,15904,924],{"class":710},[80,15906,985],{"class":746},[80,15908,988],{"class":713},[80,15910,991],{"class":746},[80,15912,994],{"class":746},[10,15914,15915,999],{},[34,15916,924],{},[213,15918,1003],{"id":1002},[10,15920,1006],{},[71,15922,15923],{"className":701,"code":846,"language":703,"meta":76,"style":76},[34,15924,15925,15931],{"__ignoreMap":76},[80,15926,15927,15929],{"class":82,"line":83},[80,15928,801],{"class":710},[80,15930,714],{"class":713},[80,15932,15933,15935,15937,15939],{"class":82,"line":89},[80,15934,801],{"class":710},[80,15936,743],{"class":713},[80,15938,747],{"class":746},[80,15940,714],{"class":713},[10,15942,1029],{},[14,15944,1032],{"id":1032},[213,15946,1036],{"id":1035},[10,15948,1039,15949,1043],{},[34,15950,1042],{},[184,15952,15953,15957,15959],{},[49,15954,1048,15955,1051],{},[34,15956,758],{},[49,15958,1054],{},[49,15960,1057],{},[10,15962,1060],{},[213,15964,1064],{"id":1063},[10,15966,1067],{},[71,15968,15969],{"className":701,"code":794,"language":703,"meta":76,"style":76},[34,15970,15971],{"__ignoreMap":76},[80,15972,15973,15975],{"class":82,"line":83},[80,15974,801],{"class":710},[80,15976,714],{"class":713},[10,15978,1080,15979,1083,15981,1086,15983,211],{},[34,15980,801],{},[34,15982,75],{},[34,15984,801],{},[213,15986,1092],{"id":1091},[10,15988,1095],{},[71,15990,15991],{"className":701,"code":1098,"language":703,"meta":76,"style":76},[34,15992,15993],{"__ignoreMap":76},[80,15994,15995,15997,15999,16001],{"class":82,"line":83},[80,15996,801],{"class":710},[80,15998,743],{"class":713},[80,16000,747],{"class":746},[80,16002,714],{"class":713},[10,16004,1113,16005,1116,16007,1119,16009,1122,16011,1126],{},[34,16006,801],{},[34,16008,75],{},[34,16010,618],{},[34,16012,1125],{},[321,16014,1129],{},{"title":76,"searchDepth":89,"depth":89,"links":16016},[16017,16018,16019,16024,16029,16034],{"id":360,"depth":89,"text":360},{"id":376,"depth":89,"text":376},{"id":437,"depth":89,"text":438,"children":16020},[16021,16022,16023],{"id":441,"depth":95,"text":442},{"id":501,"depth":95,"text":502},{"id":686,"depth":95,"text":687},{"id":783,"depth":89,"text":784,"children":16025},[16026,16027,16028],{"id":787,"depth":95,"text":788},{"id":813,"depth":95,"text":814},{"id":839,"depth":95,"text":840},{"id":873,"depth":89,"text":874,"children":16030},[16031,16032,16033],{"id":880,"depth":95,"text":881},{"id":910,"depth":95,"text":911},{"id":1002,"depth":95,"text":1003},{"id":1032,"depth":89,"text":1032,"children":16035},[16036,16037,16038],{"id":1035,"depth":95,"text":1036},{"id":1063,"depth":95,"text":1064},{"id":1091,"depth":95,"text":1092},{},{"title":355,"description":76},[337,1162,1163],1786973366343]