[{"data":1,"prerenderedAt":15991},["ShallowReactive",2],{"post-python-iterator-generator":3,"sidebar-posts":275,"post-related-source":9182},{"id":4,"title":5,"body":6,"category":260,"cover":261,"description":12,"extension":262,"meta":263,"navigation":121,"path":264,"pinned":265,"publishedAt":266,"seo":267,"slug":268,"stem":269,"summary":270,"tags":271,"updatedAt":266,"visible":121,"__hash__":274},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8,"toc":248},"minimark",[9,13,17,20,23,30,38,41,69,72,75,145,148,156,159,162,185,189,195,201,207,210,218,221,235,238,241,244],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[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\u002F37-generator-state.svg",[10,31,32,33,37],{},"生成器运行到 ",[34,35,36],"code",{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,39,40],{"id":40},"核心概念",[42,43,44,55,66],"ul",{},[45,46,47,50,51,54],"li",{},[34,48,49],{},"iter()"," 从可迭代对象取得迭代器，",[34,52,53],{},"next()"," 请求下一个值。",[45,56,57,58,61,62,65],{},"没有更多值时迭代器抛出 ",[34,59,60],{},"StopIteration","，",[34,63,64],{},"for"," 会自动处理。",[45,67,68],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,70,71],{"id":71},"跟着示例运行",[10,73,74],{},"把下面代码保存到本课脚本并运行：",[76,77,82],"pre",{"className":78,"code":79,"language":80,"meta":81,"style":81},"language-python shiki shiki-themes github-dark","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","python","",[34,83,84,92,98,104,110,116,123,129,135,140],{"__ignoreMap":81},[85,86,89],"span",{"class":87,"line":88},"line",1,[85,90,91],{},"def countdown(start):\n",[85,93,95],{"class":87,"line":94},2,[85,96,97],{},"    current = start\n",[85,99,101],{"class":87,"line":100},3,[85,102,103],{},"    while current > 0:\n",[85,105,107],{"class":87,"line":106},4,[85,108,109],{},"        yield current\n",[85,111,113],{"class":87,"line":112},5,[85,114,115],{},"        current = current - 1\n",[85,117,119],{"class":87,"line":118},6,[85,120,122],{"emptyLinePlaceholder":121},true,"\n",[85,124,126],{"class":87,"line":125},7,[85,127,128],{},"iterator = countdown(3)\n",[85,130,132],{"class":87,"line":131},8,[85,133,134],{},"print(next(iterator))\n",[85,136,138],{"class":87,"line":137},9,[85,139,134],{},[85,141,143],{"class":87,"line":142},10,[85,144,134],{},[10,146,147],{},"预期结果：",[76,149,154],{"className":150,"code":152,"language":153,"meta":81},[151],"language-text","3\n2\n1\n","text",[34,155,152],{"__ignoreMap":81},[10,157,158],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,160,161],{"id":161},"按执行顺序拆开看",[163,164,165,172],"ol",{},[45,166,167,168,171],{},"调用 ",[34,169,170],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[45,173,174,175,177,178,180,181,184],{},"每次 ",[34,176,53],{}," 运行到下一个 ",[34,179,36],{}," 并暂停，局部变量 ",[34,182,183],{},"current"," 和执行位置被保留。",[186,187,188],"h3",{"id":188},"再看一个具体细节",[10,190,191,192,194],{},"生成器的暂停位置可以展开成多次 ",[34,193,53],{}," 的时间线。",[10,196,197],{},[26,198],{"alt":199,"src":200},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,202,203,204,206],{},"每次请求只推进到下一个 ",[34,205,36],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,208,209],{"id":209},"初学者容易混淆的地方",[42,211,212,215],{},[45,213,214],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[45,216,217],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,219,220],{"id":220},"练习",[163,222,223,226],{},[45,224,225],{},"编写产生 1 到指定上限偶数的生成器。",[45,227,228,229,231,232,234],{},"用 ",[34,230,64],{}," 遍历生成器，比较手动 ",[34,233,53],{}," 的差异。",[10,236,237],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,239,240],{"id":240},"本篇边界",[10,242,243],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,246,247],"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":81,"searchDepth":94,"depth":94,"links":249},[250,251,252,253,254,257,258,259],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":255},[256],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",false,"2026-08-17",{"title":5,"description":12},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[260,272,273],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",[276,1089,1426,1560,1712,1891,2079,2244,2428,2609,2801,3032,3216,3393,3550,3721,3886,4099,4327,4508,4672,4861,5049,5204,5364,5561,5758,5972,6139,6383,6564,6769,6964,7148,7349,7639,7831,8059,8254,8421,8661,8865],{"id":277,"title":278,"body":279,"category":260,"cover":261,"description":81,"extension":262,"meta":1078,"navigation":121,"path":1079,"pinned":265,"publishedAt":1080,"seo":1081,"slug":1082,"stem":1083,"summary":1084,"tags":1085,"updatedAt":1080,"visible":121,"__hash__":1088},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":280,"toc":1054},[281,284,287,290,297,300,303,342,358,362,366,377,382,388,406,412,417,423,427,473,476,482,488,491,522,567,584,598,608,612,623,639,642,648,653,656,674,684,705,709,713,716,728,735,739,754,761,765,768,789,795,799,802,806,809,829,832,836,839,873,876,895,898,919,924,928,931,951,954,957,961,968,982,985,989,992,1002,1013,1017,1020,1035,1051],[14,282,283],{"id":283},"引言",[10,285,286],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,288,289],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,291,292,293,296],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[34,294,295],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,298,299],{"id":299},"扫盲",[10,301,302],{},"那么这里有几个概念：",[304,305,306,309],"blockquote",{},[10,307,308],{},"为什么需要安装python解释器？",[304,310,311,322,325,333,336],{},[10,312,313,314,317,318,321],{},"我们写的代码，电脑其实看不懂，电脑只认识",[34,315,316],{},"0","和",[34,319,320],{},"1","组成的机器指令。",[10,323,324],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,326,327,328,332],{},"这样，我们就能用",[329,330,331],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,334,335],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,337,338],{},[26,339],{"alt":340,"src":341},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[304,343,344,347],{},[10,345,346],{},"pip又是什么？",[304,348,349,352],{},[10,350,351],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,353,354],{},[26,355],{"alt":356,"src":357},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,359,361],{"id":360},"windows-安装","Windows 安装",[186,363,365],{"id":364},"_1-下载官方安装程序","1. 下载官方安装程序",[10,367,368,369,376],{},"打开 ",[370,371,375],"a",{"href":372,"rel":373},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[374],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[304,378,379],{},[10,380,381],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,383,384],{},[26,385],{"alt":386,"src":387},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[42,389,390,397,403],{},[45,391,392,393,396],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[329,394,395],{},"Windows installer (64-bit)","。",[45,398,399,400,396],{},"搭载 ARM 处理器的 Windows 设备选择 ",[329,401,402],{},"Windows installer (ARM64)",[45,404,405],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,407,408],{},[26,409],{"alt":410,"src":411},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[304,413,414],{},[10,415,416],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,418,419],{},[26,420],{"alt":421,"src":422},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[186,424,426],{"id":425},"_2-安装并加入-path","2. 安装并加入 PATH",[304,428,429,434,441,466],{},[304,430,431],{},[10,432,433],{},"PATH 环境变量",[10,435,436,437,440],{},"Windows 有一个特殊的变量叫 ",[329,438,439],{},"PATH","，它里面存了一串文件夹路径，比如：",[76,442,444],{"className":78,"code":443,"language":80,"meta":81,"style":81},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[34,445,446,451,456,461],{"__ignoreMap":81},[85,447,448],{"class":87,"line":88},[85,449,450],{},"D:\\Python313\\\n",[85,452,453],{"class":87,"line":94},[85,454,455],{},"D:\\Python313\\Scripts\\\n",[85,457,458],{"class":87,"line":100},[85,459,460],{},"C:\\Windows\\System32\\\n",[85,462,463],{"class":87,"line":106},[85,464,465],{},"...\n",[10,467,468,469,472],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[329,470,471],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,474,475],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,477,478,479,481],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[34,480,80],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,483,484],{},[26,485],{"alt":486,"src":487},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,489,490],{},"对安装界面最底部的两个勾选项分别解释 :",[304,492,493,496,501],{},[10,494,495],{},"Add python.exe to PATH",[10,497,498],{},[329,499,500],{},"把 Python 添加到系统环境变量",[304,502,503,509,515],{},[10,504,505,506,508],{},"勾选后，你可以在命令行任意位置直接输入 ",[34,507,80],{}," 就能运行",[10,510,511,512,514],{},"不勾选的话，命令行输入 ",[34,513,80],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,516,517,518,521],{},"必须",[329,519,520],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[304,523,524,527,532],{},[10,525,526],{},"Use admin privileges when installing py.exe",[10,528,529],{},[329,530,531],{},"使用管理员权限安装 py.exe（Python 启动器）",[304,533,534,544,558,561],{},[10,535,536,539,540,543],{},[34,537,538],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[34,541,542],{},"py"," 来启动 Python。",[10,545,546,547,549,550,553,554,557],{},"勾选后，",[34,548,538],{}," 会安装到",[329,551,552],{},"系统级目录","，电脑上",[329,555,556],{},"所有用户账户","都能用",[10,559,560],{},"不勾选，只有当前用户能用",[10,562,563,566],{},[329,564,565],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[304,568,569,572],{},[10,570,571],{},"操作建议",[304,573,574,581],{},[10,575,576,577,580],{},"两个都勾上之后，再点 ",[329,578,579],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,582,583],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[304,585,586,592],{},[10,587,588,589],{},"Python 安装的",[329,590,591],{},"可选功能页",[10,593,594],{},[26,595],{"alt":596,"src":597},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[304,599,600,603],{},[10,601,602],{},"高级选项页",[10,604,605],{},[26,606],{"alt":596,"src":607},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[186,609,611],{"id":610},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,613,614,615,618,619,622],{},"按 ",[34,616,617],{},"Win + R","，输入 ",[34,620,621],{},"cmd"," 并回车，然后执行：",[76,624,628],{"className":625,"code":626,"language":627,"meta":81,"style":81},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[34,629,630],{"__ignoreMap":81},[85,631,632,635],{"class":87,"line":88},[85,633,80],{"class":634},"svObZ",[85,636,638],{"class":637},"sDLfK"," --version\n",[10,640,641],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[76,643,646],{"className":644,"code":645,"language":153,"meta":81},[151],"Python 3.x.x\n",[34,647,645],{"__ignoreMap":81},[10,649,650],{},[26,651],{"alt":596,"src":652},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,654,655],{},"继续检查 pip：",[76,657,659],{"className":625,"code":658,"language":627,"meta":81,"style":81},"python -m pip --version\n",[34,660,661],{"__ignoreMap":81},[85,662,663,665,668,672],{"class":87,"line":88},[85,664,80],{"class":634},[85,666,667],{"class":637}," -m",[85,669,671],{"class":670},"sU2Wk"," pip",[85,673,638],{"class":637},[10,675,676,677,679,680,683],{},"如果 ",[34,678,80],{}," 无法识别，但 ",[34,681,682],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[76,685,687],{"className":625,"code":686,"language":627,"meta":81,"style":81},"py --version\npy -m pip --version\n",[34,688,689,695],{"__ignoreMap":81},[85,690,691,693],{"class":87,"line":88},[85,692,542],{"class":634},[85,694,638],{"class":637},[85,696,697,699,701,703],{"class":87,"line":94},[85,698,542],{"class":634},[85,700,667],{"class":637},[85,702,671],{"class":670},[85,704,638],{"class":637},[14,706,708],{"id":707},"macos-安装","macOS 安装",[186,710,712],{"id":711},"_1-先检查现有环境","1. 先检查现有环境",[10,714,715],{},"打开“终端”应用，执行：",[76,717,719],{"className":625,"code":718,"language":627,"meta":81,"style":81},"python3 --version\n",[34,720,721],{"__ignoreMap":81},[85,722,723,726],{"class":87,"line":88},[85,724,725],{"class":634},"python3",[85,727,638],{"class":637},[10,729,730,731,734],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[34,732,733],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[186,736,738],{"id":737},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,740,368,741,746,747,396,750,753],{},[370,742,745],{"href":743,"rel":744},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[374],"Python macOS 下载页","，下载当前稳定版的 ",[329,748,749],{},"macOS 64-bit universal2 installer",[34,751,752],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,755,756,757,760],{},"下载完成后打开 ",[34,758,759],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[186,762,764],{"id":763},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,766,767],{},"安装完成后重新打开终端，执行：",[76,769,771],{"className":625,"code":770,"language":627,"meta":81,"style":81},"python3 --version\npython3 -m pip --version\n",[34,772,773,779],{"__ignoreMap":81},[85,774,775,777],{"class":87,"line":88},[85,776,725],{"class":634},[85,778,638],{"class":637},[85,780,781,783,785,787],{"class":87,"line":94},[85,782,725],{"class":634},[85,784,667],{"class":637},[85,786,671],{"class":670},[85,788,638],{"class":637},[10,790,791,792,794],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[34,793,725],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,796,798],{"id":797},"linux-安装","Linux 安装",[10,800,801],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[186,803,805],{"id":804},"_1-检查是否已经安装","1. 检查是否已经安装",[10,807,808],{},"打开终端，执行：",[76,810,811],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,812,813,819],{"__ignoreMap":81},[85,814,815,817],{"class":87,"line":88},[85,816,725],{"class":634},[85,818,638],{"class":637},[85,820,821,823,825,827],{"class":87,"line":94},[85,822,725],{"class":634},[85,824,667],{"class":637},[85,826,671],{"class":670},[85,828,638],{"class":637},[10,830,831],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[186,833,835],{"id":834},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,837,838],{},"Ubuntu 或 Debian：",[76,840,842],{"className":625,"code":841,"language":627,"meta":81,"style":81},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[34,843,844,855],{"__ignoreMap":81},[85,845,846,849,852],{"class":87,"line":88},[85,847,848],{"class":634},"sudo",[85,850,851],{"class":670}," apt",[85,853,854],{"class":670}," update\n",[85,856,857,859,861,864,867,870],{"class":87,"line":94},[85,858,848],{"class":634},[85,860,851],{"class":670},[85,862,863],{"class":670}," install",[85,865,866],{"class":670}," python3",[85,868,869],{"class":670}," python3-pip",[85,871,872],{"class":670}," python3-venv\n",[10,874,875],{},"Fedora：",[76,877,879],{"className":625,"code":878,"language":627,"meta":81,"style":81},"sudo dnf install python3 python3-pip\n",[34,880,881],{"__ignoreMap":81},[85,882,883,885,888,890,892],{"class":87,"line":88},[85,884,848],{"class":634},[85,886,887],{"class":670}," dnf",[85,889,863],{"class":670},[85,891,866],{"class":670},[85,893,894],{"class":670}," python3-pip\n",[10,896,897],{},"Arch Linux：",[76,899,901],{"className":625,"code":900,"language":627,"meta":81,"style":81},"sudo pacman -S python python-pip\n",[34,902,903],{"__ignoreMap":81},[85,904,905,907,910,913,916],{"class":87,"line":88},[85,906,848],{"class":634},[85,908,909],{"class":670}," pacman",[85,911,912],{"class":637}," -S",[85,914,915],{"class":670}," python",[85,917,918],{"class":670}," python-pip\n",[10,920,921,923],{},[34,922,848],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[186,925,927],{"id":926},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,929,930],{},"安装结束后执行：",[76,932,933],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,934,935,941],{"__ignoreMap":81},[85,936,937,939],{"class":87,"line":88},[85,938,725],{"class":634},[85,940,638],{"class":637},[85,942,943,945,947,949],{"class":87,"line":94},[85,944,725],{"class":634},[85,946,667],{"class":637},[85,948,671],{"class":670},[85,950,638],{"class":637},[10,952,953],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,955,956],{"id":956},"常见问题",[186,958,960],{"id":959},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,962,963,964,967],{},"先关闭当前命令提示符并重新打开，再执行 ",[34,965,966],{},"python --version","。如果仍然失败，按下面的顺序检查：",[163,969,970,976,979],{},[45,971,972,973,975],{},"执行 ",[34,974,682],{},"，确认 Python Launcher 是否可用。",[45,977,978],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[45,980,981],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,983,984],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[186,986,988],{"id":987},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,990,991],{},"先尝试：",[76,993,994],{"className":625,"code":718,"language":627,"meta":81,"style":81},[34,995,996],{"__ignoreMap":81},[85,997,998,1000],{"class":87,"line":88},[85,999,725],{"class":634},[85,1001,638],{"class":637},[10,1003,1004,1005,1007,1008,1010,1011,396],{},"在这两个系统中，只有 ",[34,1006,725],{}," 命令而没有 ",[34,1009,80],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[34,1012,725],{},[186,1014,1016],{"id":1015},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,1018,1019],{},"先使用模块方式检查：",[76,1021,1023],{"className":625,"code":1022,"language":627,"meta":81,"style":81},"python3 -m pip --version\n",[34,1024,1025],{"__ignoreMap":81},[85,1026,1027,1029,1031,1033],{"class":87,"line":88},[85,1028,725],{"class":634},[85,1030,667],{"class":637},[85,1032,671],{"class":670},[85,1034,638],{"class":637},[10,1036,1037,1038,1040,1041,1043,1044,1046,1047,1050],{},"Windows 用户将命令中的 ",[34,1039,725],{}," 换成 ",[34,1042,80],{}," 或 ",[34,1045,542],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[34,1048,1049],{},"python3-pip","；不要直接使用其他系统的安装命令。",[245,1052,1053],{},"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":81,"searchDepth":94,"depth":94,"links":1055},[1056,1057,1058,1063,1068,1073],{"id":283,"depth":94,"text":283},{"id":299,"depth":94,"text":299},{"id":360,"depth":94,"text":361,"children":1059},[1060,1061,1062],{"id":364,"depth":100,"text":365},{"id":425,"depth":100,"text":426},{"id":610,"depth":100,"text":611},{"id":707,"depth":94,"text":708,"children":1064},[1065,1066,1067],{"id":711,"depth":100,"text":712},{"id":737,"depth":100,"text":738},{"id":763,"depth":100,"text":764},{"id":797,"depth":94,"text":798,"children":1069},[1070,1071,1072],{"id":804,"depth":100,"text":805},{"id":834,"depth":100,"text":835},{"id":926,"depth":100,"text":927},{"id":956,"depth":94,"text":956,"children":1074},[1075,1076,1077],{"id":959,"depth":100,"text":960},{"id":987,"depth":100,"text":988},{"id":1015,"depth":100,"text":1016},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":278,"description":81},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[260,1086,1087],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1090,"title":1091,"body":1092,"category":260,"cover":1099,"description":81,"extension":262,"meta":1415,"navigation":121,"path":1416,"pinned":265,"publishedAt":1417,"seo":1418,"slug":1419,"stem":1420,"summary":1421,"tags":1422,"updatedAt":1417,"visible":121,"__hash__":1425},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1093,"toc":1400},[1094,1100,1103,1106,1110,1113,1137,1140,1146,1149,1152,1186,1196,1200,1207,1210,1235,1238,1250,1253,1257,1260,1263,1266,1269,1272,1275,1278,1302,1305,1308,1314,1317,1320,1323,1327,1333,1336,1362,1365,1369,1372,1375,1379,1382,1385,1388,1391,1394,1397],[10,1095,1096],{},[26,1097],{"alt":1098,"src":1099},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1101,1102],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1104,1105],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1107,1109],{"id":1108},"python-代码是什么样的","Python 代码是什么样的",[10,1111,1112],{},"下面是一段简单的 Python 代码：",[76,1114,1116],{"className":78,"code":1115,"language":80,"meta":81,"style":81},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[34,1117,1118,1123,1128,1132],{"__ignoreMap":81},[85,1119,1120],{"class":87,"line":88},[85,1121,1122],{},"name = \"Python\"\n",[85,1124,1125],{"class":87,"line":94},[85,1126,1127],{},"year = 2026\n",[85,1129,1130],{"class":87,"line":100},[85,1131,122],{"emptyLinePlaceholder":121},[85,1133,1134],{"class":87,"line":106},[85,1135,1136],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1138,1139],{},"运行结果：",[76,1141,1144],{"className":1142,"code":1143,"language":153,"meta":81},[151],"正在学习 Python，当前年份是 2026\n",[34,1145,1143],{"__ignoreMap":81},[10,1147,1148],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1150,1151],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[76,1153,1155],{"className":78,"code":1154,"language":80,"meta":81,"style":81},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[34,1156,1157,1162,1166,1171,1176,1181],{"__ignoreMap":81},[85,1158,1159],{"class":87,"line":88},[85,1160,1161],{},"score = 85\n",[85,1163,1164],{"class":87,"line":94},[85,1165,122],{"emptyLinePlaceholder":121},[85,1167,1168],{"class":87,"line":100},[85,1169,1170],{},"if score >= 60:\n",[85,1172,1173],{"class":87,"line":106},[85,1174,1175],{},"    print(\"成绩合格\")\n",[85,1177,1178],{"class":87,"line":112},[85,1179,1180],{},"else:\n",[85,1182,1183],{"class":87,"line":118},[85,1184,1185],{},"    print(\"需要继续学习\")\n",[10,1187,1188,1191,1192,1195],{},[34,1189,1190],{},"if"," 和 ",[34,1193,1194],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1197,1199],{"id":1198},"python-如何运行代码","Python 如何运行代码",[10,1201,1202,1203,1206],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[34,1204,1205],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1208,1209],{},"交互式环境适合快速验证一个表达式：",[76,1211,1213],{"className":78,"code":1212,"language":80,"meta":81,"style":81},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[34,1214,1215,1220,1225,1230],{"__ignoreMap":81},[85,1216,1217],{"class":87,"line":88},[85,1218,1219],{},">>> 10 + 20\n",[85,1221,1222],{"class":87,"line":94},[85,1223,1224],{},"30\n",[85,1226,1227],{"class":87,"line":100},[85,1228,1229],{},">>> \"Python\".lower()\n",[85,1231,1232],{"class":87,"line":106},[85,1233,1234],{},"'python'\n",[10,1236,1237],{},"需要保存和重复运行的程序，则可以写入文件：",[76,1239,1241],{"className":625,"code":1240,"language":627,"meta":81,"style":81},"python3 hello.py\n",[34,1242,1243],{"__ignoreMap":81},[85,1244,1245,1247],{"class":87,"line":88},[85,1246,725],{"class":634},[85,1248,1249],{"class":670}," hello.py\n",[10,1251,1252],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1254,1256],{"id":1255},"python-的特点","Python 的特点",[186,1258,1259],{"id":1259},"语法相对简洁",[10,1261,1262],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[186,1264,1265],{"id":1265},"支持多种编程方式",[10,1267,1268],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[186,1270,1271],{"id":1271},"标准库比较完整",[10,1273,1274],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1276,1277],{},"例如，获取当前时间：",[76,1279,1281],{"className":78,"code":1280,"language":80,"meta":81,"style":81},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[34,1282,1283,1288,1292,1297],{"__ignoreMap":81},[85,1284,1285],{"class":87,"line":88},[85,1286,1287],{},"from datetime import datetime\n",[85,1289,1290],{"class":87,"line":94},[85,1291,122],{"emptyLinePlaceholder":121},[85,1293,1294],{"class":87,"line":100},[85,1295,1296],{},"now = datetime.now()\n",[85,1298,1299],{"class":87,"line":106},[85,1300,1301],{},"print(now)\n",[10,1303,1304],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[186,1306,1307],{"id":1307},"第三方工具丰富",[10,1309,1310,1311,1313],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[34,1312,295],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1315,1316],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[186,1318,1319],{"id":1319},"支持多个操作系统",[10,1321,1322],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1324,1326],{"id":1325},"python-可以做什么","Python 可以做什么",[10,1328,1329],{},[26,1330],{"alt":1331,"src":1332},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1334,1335],{},"Python 的应用范围比较广，常见方向包括：",[42,1337,1338,1341,1344,1347,1350,1353,1356,1359],{},[45,1339,1340],{},"编写自动化脚本，批量处理文件和重复任务；",[45,1342,1343],{},"开发网站后端和 API 服务；",[45,1345,1346],{},"进行数据清洗、统计分析和图表展示；",[45,1348,1349],{},"编写网络爬虫和信息采集工具；",[45,1351,1352],{},"开发自动化测试程序；",[45,1354,1355],{},"进行机器学习和人工智能开发；",[45,1357,1358],{},"编写运维、监控和辅助开发工具；",[45,1360,1361],{},"开发部分桌面应用和插件。",[10,1363,1364],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1366,1368],{"id":1367},"python-的发展","Python 的发展",[10,1370,1371],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1373,1374],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1376,1378],{"id":1377},"python-也有局限","Python 也有局限",[10,1380,1381],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1383,1384],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1386,1387],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1389,1390],{"id":1390},"写在最后",[10,1392,1393],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1395,1396],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[245,1398,1399],{},"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":81,"searchDepth":94,"depth":94,"links":1401},[1402,1403,1404,1411,1412,1413,1414],{"id":1108,"depth":94,"text":1109},{"id":1198,"depth":94,"text":1199},{"id":1255,"depth":94,"text":1256,"children":1405},[1406,1407,1408,1409,1410],{"id":1259,"depth":100,"text":1259},{"id":1265,"depth":100,"text":1265},{"id":1271,"depth":100,"text":1271},{"id":1307,"depth":100,"text":1307},{"id":1319,"depth":100,"text":1319},{"id":1325,"depth":94,"text":1326},{"id":1367,"depth":94,"text":1368},{"id":1377,"depth":94,"text":1378},{"id":1390,"depth":94,"text":1390},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1091,"description":81},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[260,1423,1424],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1427,"title":1428,"body":1429,"category":260,"cover":261,"description":1433,"extension":262,"meta":1551,"navigation":121,"path":1552,"pinned":265,"publishedAt":266,"seo":1553,"slug":1554,"stem":1555,"summary":1556,"tags":1557,"updatedAt":266,"visible":121,"__hash__":1559},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1430,"toc":1541},[1431,1434,1436,1439,1441,1447,1452,1454,1468,1470,1472,1481,1483,1489,1491,1493,1509,1511,1522,1524,1532,1534,1536,1539],[10,1432,1433],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1435,16],{"id":16},[10,1437,1438],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1440,22],{"id":22},[10,1442,1443],{},[26,1444],{"alt":1445,"src":1446},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1448,1449,1451],{},[34,1450,1205],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1453,40],{"id":40},[42,1455,1456,1462,1465],{},[45,1457,1458,1459,1461],{},"源代码是人编写的文本，通常保存在 ",[34,1460,1205],{}," 文件中。",[45,1463,1464],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[45,1466,1467],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1469,71],{"id":71},[10,1471,74],{},[76,1473,1475],{"className":78,"code":1474,"language":80,"meta":81,"style":81},"print(\"你好，Python\")\n",[34,1476,1477],{"__ignoreMap":81},[85,1478,1479],{"class":87,"line":88},[85,1480,1474],{},[10,1482,147],{},[76,1484,1487],{"className":1485,"code":1486,"language":153,"meta":81},[151],"你好，Python\n",[34,1488,1486],{"__ignoreMap":81},[10,1490,158],{},[14,1492,161],{"id":161},[163,1494,1495,1502],{},[45,1496,1497,1498,1501],{},"终端启动解释器后，解释器读取 ",[34,1499,1500],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[45,1503,1504,1505,1508],{},"字符串对象先准备好，再交给 ",[34,1506,1507],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1510,209],{"id":209},[42,1512,1513,1516],{},[45,1514,1515],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[45,1517,1518,1519,1521],{},"认为 ",[34,1520,1205],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1523,220],{"id":220},[163,1525,1526,1529],{},[45,1527,1528],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[45,1530,1531],{},"把示例文字改成自己的学习目标并重新运行。",[10,1533,237],{},[14,1535,240],{"id":240},[10,1537,1538],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,1540,247],{},{"title":81,"searchDepth":94,"depth":94,"links":1542},[1543,1544,1545,1546,1547,1548,1549,1550],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1428,"description":1433},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[260,1423,1558],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1561,"title":1562,"body":1563,"category":260,"cover":261,"description":1567,"extension":262,"meta":1703,"navigation":121,"path":1704,"pinned":265,"publishedAt":266,"seo":1705,"slug":1706,"stem":1707,"summary":1708,"tags":1709,"updatedAt":266,"visible":121,"__hash__":1711},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1564,"toc":1693},[1565,1568,1570,1573,1575,1581,1587,1589,1604,1606,1609,1629,1631,1637,1639,1641,1654,1656,1670,1672,1683,1685,1687,1690],[10,1566,1567],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1569,16],{"id":16},[10,1571,1572],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1574,22],{"id":22},[10,1576,1577],{},[26,1578],{"alt":1579,"src":1580},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1582,1583,1584,1586],{},"终端收到 ",[34,1585,725],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1588,40],{"id":40},[42,1590,1591,1594,1597],{},[45,1592,1593],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[45,1595,1596],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[45,1598,1599,1600,1603],{},"检查 pip 时使用 ",[34,1601,1602],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1605,71],{"id":71},[10,1607,1608],{},"在 macOS 终端执行：",[76,1610,1611],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,1612,1613,1619],{"__ignoreMap":81},[85,1614,1615,1617],{"class":87,"line":88},[85,1616,725],{"class":634},[85,1618,638],{"class":637},[85,1620,1621,1623,1625,1627],{"class":87,"line":94},[85,1622,725],{"class":634},[85,1624,667],{"class":637},[85,1626,671],{"class":670},[85,1628,638],{"class":637},[10,1630,147],{},[76,1632,1635],{"className":1633,"code":1634,"language":153,"meta":81},[151],"Python 3.14.x\npip 版本信息与安装路径\n",[34,1636,1634],{"__ignoreMap":81},[10,1638,158],{},[14,1640,161],{"id":161},[163,1642,1643,1649],{},[45,1644,1645,1648],{},[34,1646,1647],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[45,1650,1651,1653],{},[34,1652,733],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1655,209],{"id":209},[42,1657,1658,1664],{},[45,1659,1660,1661,1663],{},"看到系统已有 ",[34,1662,725],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[45,1665,1666,1667,1669],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[34,1668,725],{},"，不修改系统自带工具。",[14,1671,220],{"id":220},[163,1673,1674,1680],{},[45,1675,972,1676,1679],{},[34,1677,1678],{},"which python3","，记录当前解释器路径。",[45,1681,1682],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1684,237],{},[14,1686,240],{"id":240},[10,1688,1689],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,1691,1692],{},"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":81,"searchDepth":94,"depth":94,"links":1694},[1695,1696,1697,1698,1699,1700,1701,1702],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1562,"description":1567},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[260,1710,1086],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1713,"title":1714,"body":1715,"category":260,"cover":261,"description":1880,"extension":262,"meta":1881,"navigation":121,"path":1882,"pinned":265,"publishedAt":266,"seo":1883,"slug":1884,"stem":1885,"summary":1886,"tags":1887,"updatedAt":266,"visible":121,"__hash__":1890},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1716,"toc":1870},[1717,1723,1725,1728,1730,1736,1739,1741,1765,1767,1769,1796,1798,1804,1806,1808,1826,1828,1842,1844,1858,1860,1862,1868],[10,1718,1719,1720,1722],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[34,1721,1205],{}," 脚本。",[14,1724,16],{"id":16},[10,1726,1727],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1729,22],{"id":22},[10,1731,1732],{},[26,1733],{"alt":1734,"src":1735},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1737,1738],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1740,40],{"id":40},[42,1742,1743,1752,1759],{},[45,1744,1745,1746,1748,1749,396],{},"在终端输入 ",[34,1747,725],{}," 进入 REPL，提示符通常是 ",[34,1750,1751],{},">>>",[45,1753,1754,1755,1758],{},"输入 ",[34,1756,1757],{},"exit()"," 或按 Control-D 退出 REPL。",[45,1760,1761,1762,1764],{},"需要保存、复查或多次运行的代码应写入 ",[34,1763,1205],{}," 文件。",[14,1766,71],{"id":71},[10,1768,74],{},[76,1770,1774],{"className":1771,"code":1772,"language":1773,"meta":81,"style":81},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[34,1775,1776,1781,1786,1791],{"__ignoreMap":81},[85,1777,1778],{"class":87,"line":88},[85,1779,1780],{},">>> 2 + 3\n",[85,1782,1783],{"class":87,"line":94},[85,1784,1785],{},"5\n",[85,1787,1788],{"class":87,"line":100},[85,1789,1790],{},">>> \"python\".upper()\n",[85,1792,1793],{"class":87,"line":106},[85,1794,1795],{},"'PYTHON'\n",[10,1797,147],{},[76,1799,1802],{"className":1800,"code":1801,"language":153,"meta":81},[151],"REPL 会直接显示表达式结果\n",[34,1803,1801],{"__ignoreMap":81},[10,1805,158],{},[14,1807,161],{"id":161},[163,1809,1810,1820],{},[45,1811,1812,1813,1816,1817,396],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[34,1814,1815],{},"2 + 3"," 能直接看到 ",[34,1818,1819],{},"5",[45,1821,1822,1823,1825],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[34,1824,1507],{}," 才会写到标准输出。",[14,1827,209],{"id":209},[42,1829,1830,1839],{},[45,1831,1832,1833,1835,1836,1838],{},"把提示符 ",[34,1834,1751],{}," 复制进 ",[34,1837,1205],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[45,1840,1841],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1843,220],{"id":220},[163,1845,1846,1852],{},[45,1847,1848,1849,396],{},"在 REPL 计算 ",[34,1850,1851],{},"12 * 8",[45,1853,1854,1855,1857],{},"把同一表达式写入脚本；观察脚本中不调用 ",[34,1856,1507],{}," 时是否显示结果。",[10,1859,237],{},[14,1861,240],{"id":240},[10,1863,1864,1865,1867],{},"本篇目标是根据任务选择 REPL 或 ",[34,1866,1205],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,1869,247],{},{"title":81,"searchDepth":94,"depth":94,"links":1871},[1872,1873,1874,1875,1876,1877,1878,1879],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1714,"description":1880},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[260,1888,1889],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1892,"title":1893,"body":1894,"category":260,"cover":261,"description":1898,"extension":262,"meta":2069,"navigation":121,"path":2070,"pinned":265,"publishedAt":266,"seo":2071,"slug":2072,"stem":2073,"summary":2074,"tags":2075,"updatedAt":266,"visible":121,"__hash__":2078},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1895,"toc":2059},[1896,1899,1901,1904,1906,1912,1918,1920,1938,1940,1942,1987,1989,1995,1997,1999,2021,2023,2035,2037,2049,2051,2053,2056],[10,1897,1898],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1900,16],{"id":16},[10,1902,1903],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1905,22],{"id":22},[10,1907,1908],{},[26,1909],{"alt":1910,"src":1911},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1913,1914,1917],{},[34,1915,1916],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1919,40],{"id":40},[42,1921,1922,1925,1935],{},[45,1923,1924],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[45,1926,1927,1930,1931,1934],{},[34,1928,1929],{},"pwd"," 显示当前目录，",[34,1932,1933],{},"ls"," 显示目录里的文件。",[45,1936,1937],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1939,71],{"id":71},[10,1941,1608],{},[76,1943,1945],{"className":625,"code":1944,"language":627,"meta":81,"style":81},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[34,1946,1947,1955,1962,1967,1981],{"__ignoreMap":81},[85,1948,1949,1952],{"class":87,"line":88},[85,1950,1951],{"class":634},"mkdir",[85,1953,1954],{"class":670}," python-study\n",[85,1956,1957,1960],{"class":87,"line":94},[85,1958,1959],{"class":637},"cd",[85,1961,1954],{"class":670},[85,1963,1964],{"class":87,"line":100},[85,1965,1966],{"class":637},"pwd\n",[85,1968,1969,1972,1975,1979],{"class":87,"line":106},[85,1970,1971],{"class":637},"printf",[85,1973,1974],{"class":670}," 'print(\"项目已经运行\")\\n'",[85,1976,1978],{"class":1977},"snl16"," >",[85,1980,1249],{"class":670},[85,1982,1983,1985],{"class":87,"line":112},[85,1984,725],{"class":634},[85,1986,1249],{"class":670},[10,1988,147],{},[76,1990,1993],{"className":1991,"code":1992,"language":153,"meta":81},[151],"项目已经运行\n",[34,1994,1992],{"__ignoreMap":81},[10,1996,158],{},[14,1998,161],{"id":161},[163,2000,2001,2012],{},[45,2002,2003,2005,2006,2008,2009,2011],{},[34,2004,1951],{}," 创建目录，",[34,2007,1959],{}," 改变终端当前目录，",[34,2010,1929],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[45,2013,2014,2016,2017,2020],{},[34,2015,1916],{}," 会在当前目录寻找 ",[34,2018,2019],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,2022,209],{"id":209},[42,2024,2025,2032],{},[45,2026,2027,2028,1191,2030,396],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[34,2029,1929],{},[34,2031,1933],{},[45,2033,2034],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2036,220],{"id":220},[163,2038,2039,2046],{},[45,2040,2041,2042,2045],{},"新建 ",[34,2043,2044],{},"lesson01.py"," 并输出课程编号。",[45,2047,2048],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2050,237],{},[14,2052,240],{"id":240},[10,2054,2055],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,2057,2058],{},"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":81,"searchDepth":94,"depth":94,"links":2060},[2061,2062,2063,2064,2065,2066,2067,2068],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1893,"description":1898},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[260,2076,2077],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2080,"title":2081,"body":2082,"category":260,"cover":261,"description":2086,"extension":262,"meta":2234,"navigation":121,"path":2235,"pinned":265,"publishedAt":266,"seo":2236,"slug":2237,"stem":2238,"summary":2239,"tags":2240,"updatedAt":266,"visible":121,"__hash__":2243},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2083,"toc":2224},[2084,2087,2089,2092,2094,2100,2111,2113,2133,2135,2137,2157,2159,2165,2167,2169,2188,2190,2198,2200,2215,2217,2219,2222],[10,2085,2086],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2088,16],{"id":16},[10,2090,2091],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2093,22],{"id":22},[10,2095,2096],{},[26,2097],{"alt":2098,"src":2099},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2101,2102,2103,396,2105,2108,2109,396],{},"Python 先计算表达式，再把得到的对象交给 ",[34,2104,1507],{},[34,2106,2107],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[34,2110,1815],{},[14,2112,40],{"id":40},[42,2114,2115,2121,2130],{},[45,2116,2117,2120],{},[34,2118,2119],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[45,2122,2123,2126,2127,396],{},[34,2124,2125],{},"7 + 5"," 是表达式，运行时先求值得到 ",[34,2128,2129],{},"12",[45,2131,2132],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2134,71],{"id":71},[10,2136,74],{},[76,2138,2140],{"className":78,"code":2139,"language":80,"meta":81,"style":81},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[34,2141,2142,2147,2152],{"__ignoreMap":81},[85,2143,2144],{"class":87,"line":88},[85,2145,2146],{},"print(42)\n",[85,2148,2149],{"class":87,"line":94},[85,2150,2151],{},"print(7 + 5)\n",[85,2153,2154],{"class":87,"line":100},[85,2155,2156],{},"print(\"Python 基础课\")\n",[10,2158,147],{},[76,2160,2163],{"className":2161,"code":2162,"language":153,"meta":81},[151],"42\n12\nPython 基础课\n",[34,2164,2162],{"__ignoreMap":81},[10,2166,158],{},[14,2168,161],{"id":161},[163,2170,2171,2179],{},[45,2172,2173,2176,2177,396],{},[34,2174,2175],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[34,2178,2129],{},[45,2180,2181,2183,2184,2187],{},[34,2182,1507],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[34,2185,2186],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2189,209],{"id":209},[42,2191,2192,2195],{},[45,2193,2194],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[45,2196,2197],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2199,220],{"id":220},[163,2201,2202,2205],{},[45,2203,2204],{},"分别输出一个整数、一个小数和一段文本。",[45,2206,2207,2208,2210,2211,2214],{},"比较 ",[34,2209,2107],{}," 与 ",[34,2212,2213],{},"print(\"2 + 3\")"," 的结果。",[10,2216,237],{},[14,2218,240],{"id":240},[10,2220,2221],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,2223,247],{},{"title":81,"searchDepth":94,"depth":94,"links":2225},[2226,2227,2228,2229,2230,2231,2232,2233],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2081,"description":2086},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[260,2241,2242],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2245,"title":2246,"body":2247,"category":260,"cover":261,"description":2251,"extension":262,"meta":2418,"navigation":121,"path":2419,"pinned":265,"publishedAt":266,"seo":2420,"slug":2421,"stem":2422,"summary":2423,"tags":2424,"updatedAt":266,"visible":121,"__hash__":2427},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2248,"toc":2408},[2249,2252,2254,2257,2259,2265,2268,2270,2296,2298,2300,2328,2330,2336,2338,2340,2364,2366,2382,2384,2399,2401,2403,2406],[10,2250,2251],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2253,16],{"id":16},[10,2255,2256],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2258,22],{"id":22},[10,2260,2261],{},[26,2262],{"alt":2263,"src":2264},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2266,2267],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2269,40],{"id":40},[42,2271,2272,2275,2285],{},[45,2273,2274],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[45,2276,2277,2278,2210,2281,2284],{},"变量名区分大小写，",[34,2279,2280],{},"score",[34,2282,2283],{},"Score"," 是两个名字。",[45,2286,2287,2288,2291,2292,2295],{},"使用能表达含义的名称；不要用 ",[34,2289,2290],{},"list","、",[34,2293,2294],{},"str"," 等内置名称作为普通变量名。",[14,2297,71],{"id":71},[10,2299,74],{},[76,2301,2303],{"className":78,"code":2302,"language":80,"meta":81,"style":81},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[34,2304,2305,2310,2315,2319,2324],{"__ignoreMap":81},[85,2306,2307],{"class":87,"line":88},[85,2308,2309],{},"score = 90\n",[85,2311,2312],{"class":87,"line":94},[85,2313,2314],{},"print(score)\n",[85,2316,2317],{"class":87,"line":100},[85,2318,122],{"emptyLinePlaceholder":121},[85,2320,2321],{"class":87,"line":106},[85,2322,2323],{},"score = 95\n",[85,2325,2326],{"class":87,"line":112},[85,2327,2314],{},[10,2329,147],{},[76,2331,2334],{"className":2332,"code":2333,"language":153,"meta":81},[151],"90\n95\n",[34,2335,2333],{"__ignoreMap":81},[10,2337,158],{},[14,2339,161],{"id":161},[163,2341,2342,2351],{},[45,2343,972,2344,2347,2348,2350],{},[34,2345,2346],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[34,2349,2280],{}," 再绑定到它。",[45,2352,972,2353,2356,2357,2360,2361,396],{},[34,2354,2355],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[34,2358,2359],{},"90"," 没有被改造成 ",[34,2362,2363],{},"95",[14,2365,209],{"id":209},[42,2367,2368,2371],{},[45,2369,2370],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[45,2372,2373,2374,2291,2376,2291,2378,2381],{},"使用 ",[34,2375,2290],{},[34,2377,2294],{},[34,2379,2380],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2383,220],{"id":220},[163,2385,2386,2396],{},[45,2387,2388,2389,1191,2392,2395],{},"创建 ",[34,2390,2391],{},"course_name",[34,2393,2394],{},"lesson_count"," 两个变量并输出。",[45,2397,2398],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2400,237],{},[14,2402,240],{"id":240},[10,2404,2405],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,2407,247],{},{"title":81,"searchDepth":94,"depth":94,"links":2409},[2410,2411,2412,2413,2414,2415,2416,2417],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2246,"description":2251},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[260,2425,2426],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2429,"title":2430,"body":2431,"category":260,"cover":261,"description":2435,"extension":262,"meta":2599,"navigation":121,"path":2600,"pinned":265,"publishedAt":266,"seo":2601,"slug":2602,"stem":2603,"summary":2604,"tags":2605,"updatedAt":266,"visible":121,"__hash__":2608},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2432,"toc":2589},[2433,2436,2438,2441,2443,2449,2452,2454,2483,2485,2487,2531,2533,2539,2541,2543,2557,2559,2570,2572,2580,2582,2584,2587],[10,2434,2435],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2437,16],{"id":16},[10,2439,2440],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2442,22],{"id":22},[10,2444,2445],{},[26,2446],{"alt":2447,"src":2448},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2450,2451],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2453,40],{"id":40},[42,2455,2456,2466,2480],{},[45,2457,2458,2461,2462,2465],{},[34,2459,2460],{},"int"," 表示整数，",[34,2463,2464],{},"float"," 表示浮点数。",[45,2467,2468,2471,2472,2475,2476,2479],{},[34,2469,2470],{},"\u002F"," 总是进行真除法；",[34,2473,2474],{},"\u002F\u002F"," 是向下取整除法，",[34,2477,2478],{},"%"," 得到余数。",[45,2481,2482],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2484,71],{"id":71},[10,2486,74],{},[76,2488,2490],{"className":78,"code":2489,"language":80,"meta":81,"style":81},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[34,2491,2492,2497,2502,2507,2511,2516,2521,2526],{"__ignoreMap":81},[85,2493,2494],{"class":87,"line":88},[85,2495,2496],{},"price = 25\n",[85,2498,2499],{"class":87,"line":94},[85,2500,2501],{},"count = 4\n",[85,2503,2504],{"class":87,"line":100},[85,2505,2506],{},"discount = 0.9\n",[85,2508,2509],{"class":87,"line":106},[85,2510,122],{"emptyLinePlaceholder":121},[85,2512,2513],{"class":87,"line":112},[85,2514,2515],{},"total = price * count * discount\n",[85,2517,2518],{"class":87,"line":118},[85,2519,2520],{},"average = total \u002F count\n",[85,2522,2523],{"class":87,"line":125},[85,2524,2525],{},"print(total)\n",[85,2527,2528],{"class":87,"line":131},[85,2529,2530],{},"print(average)\n",[10,2532,147],{},[76,2534,2537],{"className":2535,"code":2536,"language":153,"meta":81},[151],"90.0\n22.5\n",[34,2538,2536],{"__ignoreMap":81},[10,2540,158],{},[14,2542,161],{"id":161},[163,2544,2545,2551],{},[45,2546,2547,2550],{},[34,2548,2549],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[45,2552,2553,2556],{},[34,2554,2555],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2558,209],{"id":209},[42,2560,2561,2567],{},[45,2562,2563,2564,396],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[34,2565,2566],{},"decimal.Decimal",[45,2568,2569],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2571,220],{"id":220},[163,2573,2574,2577],{},[45,2575,2576],{},"计算 137 除以 10 的商和余数。",[45,2578,2579],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2581,237],{},[14,2583,240],{"id":240},[10,2585,2586],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,2588,247],{},{"title":81,"searchDepth":94,"depth":94,"links":2590},[2591,2592,2593,2594,2595,2596,2597,2598],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2430,"description":2435},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[260,2606,2607],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2610,"title":2611,"body":2612,"category":260,"cover":261,"description":2616,"extension":262,"meta":2791,"navigation":121,"path":2792,"pinned":265,"publishedAt":266,"seo":2793,"slug":2794,"stem":2795,"summary":2796,"tags":2797,"updatedAt":266,"visible":121,"__hash__":2800},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2613,"toc":2779},[2614,2617,2619,2622,2624,2630,2640,2642,2653,2655,2657,2687,2689,2695,2697,2699,2729,2731,2734,2740,2743,2745,2753,2755,2770,2772,2774,2777],[10,2615,2616],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2618,16],{"id":16},[10,2620,2621],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2623,22],{"id":22},[10,2625,2626],{},[26,2627],{"alt":2628,"src":2629},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2631,2632,2633,2636,2637,396],{},"切片 ",[34,2634,2635],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[34,2638,2639],{},"stop - start",[14,2641,40],{"id":40},[42,2643,2644,2647,2650],{},[45,2645,2646],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[45,2648,2649],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[45,2651,2652],{},"切片会创建新的字符串，不会修改原字符串。",[14,2654,71],{"id":71},[10,2656,74],{},[76,2658,2660],{"className":78,"code":2659,"language":80,"meta":81,"style":81},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[34,2661,2662,2667,2672,2677,2682],{"__ignoreMap":81},[85,2663,2664],{"class":87,"line":88},[85,2665,2666],{},"language = \"Python\"\n",[85,2668,2669],{"class":87,"line":94},[85,2670,2671],{},"print(language[0])\n",[85,2673,2674],{"class":87,"line":100},[85,2675,2676],{},"print(language[-1])\n",[85,2678,2679],{"class":87,"line":106},[85,2680,2681],{},"print(language[0:3])\n",[85,2683,2684],{"class":87,"line":112},[85,2685,2686],{},"print(language + \" 3.14\")\n",[10,2688,147],{},[76,2690,2693],{"className":2691,"code":2692,"language":153,"meta":81},[151],"P\nn\nPyt\nPython 3.14\n",[34,2694,2692],{"__ignoreMap":81},[10,2696,158],{},[14,2698,161],{"id":161},[163,2700,2701,2715],{},[45,2702,2703,2704,2706,2707,2710,2711,2714],{},"字符串 ",[34,2705,260],{}," 的正索引从 ",[34,2708,2709],{},"P"," 的 0 开始，负索引从末尾 ",[34,2712,2713],{},"n"," 的 -1 开始。",[45,2716,2717,2720,2721,2724,2725,2728],{},[34,2718,2719],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[34,2722,2723],{},"Pyt","；索引 3 的 ",[34,2726,2727],{},"h"," 不在结果中。",[186,2730,188],{"id":188},[10,2732,2733],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2735,2736],{},[26,2737],{"alt":2738,"src":2739},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2741,2742],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2744,209],{"id":209},[42,2746,2747,2750],{},[45,2748,2749],{},"把第一个字符写成索引 1，造成整体偏移一位。",[45,2751,2752],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2754,220],{"id":220},[163,2756,2757,2767],{},[45,2758,2759,2760,2763,2764,396],{},"从 ",[34,2761,2762],{},"\"programming\""," 中切出 ",[34,2765,2766],{},"\"gram\"",[45,2768,2769],{},"使用负索引取得字符串倒数第二个字符。",[10,2771,237],{},[14,2773,240],{"id":240},[10,2775,2776],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,2778,247],{},{"title":81,"searchDepth":94,"depth":94,"links":2780},[2781,2782,2783,2784,2785,2788,2789,2790],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":2786},[2787],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2611,"description":2616},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[260,2798,2799],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2802,"title":2803,"body":2804,"category":260,"cover":261,"description":2808,"extension":262,"meta":3022,"navigation":121,"path":3023,"pinned":265,"publishedAt":266,"seo":3024,"slug":3025,"stem":3026,"summary":3027,"tags":3028,"updatedAt":266,"visible":121,"__hash__":3031},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2805,"toc":3010},[2806,2809,2811,2814,2816,2822,2832,2834,2867,2869,2871,2915,2917,2923,2925,2927,2948,2950,2953,2959,2967,2969,2983,2985,3001,3003,3005,3008],[10,2807,2808],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2810,16],{"id":16},[10,2812,2813],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2815,22],{"id":22},[10,2817,2818],{},[26,2819],{"alt":2820,"src":2821},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2823,2824,2825,1043,2828,2831],{},"比较表达式先产生 ",[34,2826,2827],{},"True",[34,2829,2830],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2833,40],{"id":40},[42,2835,2836,2850,2864],{},[45,2837,2838,2841,2842,2845,2846,2849],{},[34,2839,2840],{},"=="," 判断是否相等，",[34,2843,2844],{},"!="," 判断是否不等；单个 ",[34,2847,2848],{},"="," 是赋值。",[45,2851,2852,2855,2856,2859,2860,2863],{},[34,2853,2854],{},"and"," 要求两侧都为真，",[34,2857,2858],{},"or"," 只需一侧为真，",[34,2861,2862],{},"not"," 取反。",[45,2865,2866],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2868,71],{"id":71},[10,2870,74],{},[76,2872,2874],{"className":78,"code":2873,"language":80,"meta":81,"style":81},"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,2875,2876,2881,2886,2890,2895,2900,2905,2910],{"__ignoreMap":81},[85,2877,2878],{"class":87,"line":88},[85,2879,2880],{},"age = 20\n",[85,2882,2883],{"class":87,"line":94},[85,2884,2885],{},"has_ticket = True\n",[85,2887,2888],{"class":87,"line":100},[85,2889,122],{"emptyLinePlaceholder":121},[85,2891,2892],{"class":87,"line":106},[85,2893,2894],{},"is_adult = age >= 18\n",[85,2896,2897],{"class":87,"line":112},[85,2898,2899],{},"can_enter = is_adult and has_ticket\n",[85,2901,2902],{"class":87,"line":118},[85,2903,2904],{},"print(is_adult)\n",[85,2906,2907],{"class":87,"line":125},[85,2908,2909],{},"print(can_enter)\n",[85,2911,2912],{"class":87,"line":131},[85,2913,2914],{},"print(not has_ticket)\n",[10,2916,147],{},[76,2918,2921],{"className":2919,"code":2920,"language":153,"meta":81},[151],"True\nTrue\nFalse\n",[34,2922,2920],{"__ignoreMap":81},[10,2924,158],{},[14,2926,161],{"id":161},[163,2928,2929,2939],{},[45,2930,2931,2934,2935,2938],{},[34,2932,2933],{},"age >= 18"," 先产生布尔值并绑定给 ",[34,2936,2937],{},"is_adult","，这一步没有任何分支跳转。",[45,2940,2941,2944,2945,2947],{},[34,2942,2943],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[34,2946,2862],{}," 只对紧随其后的值取反。",[186,2949,188],{"id":188},[10,2951,2952],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2954,2955],{},[26,2956],{"alt":2957,"src":2958},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2960,2961,2963,2964,2966],{},[34,2962,2854],{}," 只有“真、真”得到真；",[34,2965,2858],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2968,209],{"id":209},[42,2970,2971,2980],{},[45,2972,2973,2974,2976,2977,2979],{},"用单个等号判断相等。",[34,2975,2848],{}," 是赋值，",[34,2978,2840],{}," 才是相等比较。",[45,2981,2982],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,2984,220],{"id":220},[163,2986,2987,2994],{},[45,2988,2989,2990,2993],{},"判断数字 ",[34,2991,2992],{},"15"," 是否同时大于 10 且小于 20。",[45,2995,2996,2997,3000],{},"分别修改年龄和票据状态，记录 ",[34,2998,2999],{},"can_enter"," 的四种组合结果。",[10,3002,237],{},[14,3004,240],{"id":240},[10,3006,3007],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,3009,247],{},{"title":81,"searchDepth":94,"depth":94,"links":3011},[3012,3013,3014,3015,3016,3019,3020,3021],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":3017},[3018],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2803,"description":2808},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[260,3029,3030],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3033,"title":3034,"body":3035,"category":260,"cover":261,"description":3039,"extension":262,"meta":3207,"navigation":121,"path":3208,"pinned":265,"publishedAt":266,"seo":3209,"slug":3210,"stem":3211,"summary":3212,"tags":3213,"updatedAt":266,"visible":121,"__hash__":3215},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3036,"toc":3197},[3037,3040,3042,3045,3047,3053,3071,3073,3086,3088,3090,3124,3126,3132,3134,3136,3158,3160,3172,3174,3188,3190,3192,3195],[10,3038,3039],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3041,16],{"id":16},[10,3043,3044],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3046,22],{"id":22},[10,3048,3049],{},[26,3050],{"alt":3051,"src":3052},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3054,3055,3058,3059,3062,3063,3066,3067,3070],{},[34,3056,3057],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[34,3060,3061],{},"18","，程序首先得到的也是 ",[34,3064,3065],{},"\"18\"","，需要 ",[34,3068,3069],{},"int()"," 后才能按整数参与计算。",[14,3072,40],{"id":40},[42,3074,3075,3078,3083],{},[45,3076,3077],{},"提示文字应告诉用户需要输入什么。",[45,3079,3080,3082],{},[34,3081,3069],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[45,3084,3085],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3087,71],{"id":71},[10,3089,74],{},[76,3091,3093],{"className":78,"code":3092,"language":80,"meta":81,"style":81},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[34,3094,3095,3100,3105,3110,3114,3119],{"__ignoreMap":81},[85,3096,3097],{"class":87,"line":88},[85,3098,3099],{},"name = input(\"请输入姓名：\")\n",[85,3101,3102],{"class":87,"line":94},[85,3103,3104],{},"age_text = input(\"请输入年龄：\")\n",[85,3106,3107],{"class":87,"line":100},[85,3108,3109],{},"age = int(age_text)\n",[85,3111,3112],{"class":87,"line":106},[85,3113,122],{"emptyLinePlaceholder":121},[85,3115,3116],{"class":87,"line":112},[85,3117,3118],{},"print(\"你好，\" + name)\n",[85,3120,3121],{"class":87,"line":118},[85,3122,3123],{},"print(age + 1)\n",[10,3125,147],{},[76,3127,3130],{"className":3128,"code":3129,"language":153,"meta":81},[151],"根据输入显示姓名，并输出下一年的年龄\n",[34,3131,3129],{"__ignoreMap":81},[10,3133,158],{},[14,3135,161],{"id":161},[163,3137,3138,3148],{},[45,3139,3140,3141,3143,3144,3147],{},"两次 ",[34,3142,3057],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[34,3145,3146],{},"age_text"," 用来提醒这仍是文本。",[45,3149,3150,3153,3154,3157],{},[34,3151,3152],{},"int(age_text)"," 创建整数对象，后面的 ",[34,3155,3156],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3159,209],{"id":209},[42,3161,3162,3169],{},[45,3163,3164,3165,3168],{},"直接计算 ",[34,3166,3167],{},"input(...) + 1","，忽略输入结果是字符串。",[45,3170,3171],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3173,220],{"id":220},[163,3175,3176,3179],{},[45,3177,3178],{},"接收两个整数并输出它们的和。",[45,3180,1754,3181,3184,3185,3187],{},[34,3182,3183],{},"18.5"," 给 ",[34,3186,3069],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3189,237],{},[14,3191,240],{"id":240},[10,3193,3194],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,3196,247],{},{"title":81,"searchDepth":94,"depth":94,"links":3198},[3199,3200,3201,3202,3203,3204,3205,3206],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3034,"description":3039},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[260,2380,3214],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3217,"title":3218,"body":3219,"category":260,"cover":261,"description":3223,"extension":262,"meta":3383,"navigation":121,"path":3384,"pinned":265,"publishedAt":266,"seo":3385,"slug":3386,"stem":3387,"summary":3388,"tags":3389,"updatedAt":266,"visible":121,"__hash__":3392},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3220,"toc":3373},[3221,3224,3226,3229,3231,3237,3244,3246,3260,3262,3264,3303,3305,3311,3313,3315,3334,3336,3351,3353,3364,3366,3368,3371],[10,3222,3223],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3225,16],{"id":16},[10,3227,3228],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3230,22],{"id":22},[10,3232,3233],{},[26,3234],{"alt":3235,"src":3236},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3238,3239,3240,3243],{},"列表为元素维护从 0 开始的位置索引。修改 ",[34,3241,3242],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3245,40],{"id":40},[42,3247,3248,3251,3254],{},[45,3249,3250],{},"列表使用方括号，元素之间用逗号分隔。",[45,3252,3253],{},"列表可变，可以替换、追加和删除元素。",[45,3255,3256,3257,396],{},"访问不存在的索引会产生 ",[34,3258,3259],{},"IndexError",[14,3261,71],{"id":71},[10,3263,74],{},[76,3265,3267],{"className":78,"code":3266,"language":80,"meta":81,"style":81},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[34,3268,3269,3274,3279,3283,3288,3293,3298],{"__ignoreMap":81},[85,3270,3271],{"class":87,"line":88},[85,3272,3273],{},"scores = [82, 90, 76]\n",[85,3275,3276],{"class":87,"line":94},[85,3277,3278],{},"print(scores[0])\n",[85,3280,3281],{"class":87,"line":100},[85,3282,122],{"emptyLinePlaceholder":121},[85,3284,3285],{"class":87,"line":106},[85,3286,3287],{},"scores[1] = 95\n",[85,3289,3290],{"class":87,"line":112},[85,3291,3292],{},"scores.append(88)\n",[85,3294,3295],{"class":87,"line":118},[85,3296,3297],{},"print(scores)\n",[85,3299,3300],{"class":87,"line":125},[85,3301,3302],{},"print(len(scores))\n",[10,3304,147],{},[76,3306,3309],{"className":3307,"code":3308,"language":153,"meta":81},[151],"82\n[82, 95, 76, 88]\n4\n",[34,3310,3308],{"__ignoreMap":81},[10,3312,158],{},[14,3314,161],{"id":161},[163,3316,3317,3320],{},[45,3318,3319],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[45,3321,3322,3325,3326,3329,3330,3333],{},[34,3323,3324],{},"scores[1] = 95"," 替换第二个位置，",[34,3327,3328],{},"append(88)"," 在末尾增加新位置，",[34,3331,3332],{},"len()"," 因而从 3 变为 4。",[14,3335,209],{"id":209},[42,3337,3338,3348],{},[45,3339,3340,3341,3344,3345,396],{},"访问 ",[34,3342,3343],{},"scores[len(scores)]","。最后一个合法正索引是 ",[34,3346,3347],{},"len(scores) - 1",[45,3349,3350],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3352,220],{"id":220},[163,3354,3355,3358],{},[45,3356,3357],{},"建立三项学习任务列表，再追加第四项。",[45,3359,3360,3361,3363],{},"修改第二项，并用 ",[34,3362,3332],{}," 检查元素数量。",[10,3365,237],{},[14,3367,240],{"id":240},[10,3369,3370],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,3372,247],{},{"title":81,"searchDepth":94,"depth":94,"links":3374},[3375,3376,3377,3378,3379,3380,3381,3382],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3218,"description":3223},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[260,3390,3391],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3394,"title":3395,"body":3396,"category":260,"cover":261,"description":3400,"extension":262,"meta":3541,"navigation":121,"path":3542,"pinned":265,"publishedAt":266,"seo":3543,"slug":3544,"stem":3545,"summary":3546,"tags":3547,"updatedAt":266,"visible":121,"__hash__":3549},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3397,"toc":3531},[3398,3401,3403,3406,3408,3414,3417,3419,3430,3432,3434,3468,3470,3476,3478,3480,3494,3496,3508,3510,3522,3524,3526,3529],[10,3399,3400],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3402,16],{"id":16},[10,3404,3405],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3407,22],{"id":22},[10,3409,3410],{},[26,3411],{"alt":3412,"src":3413},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3415,3416],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3418,40],{"id":40},[42,3420,3421,3424,3427],{},[45,3422,3423],{},"元组常用来表达固定数量、固定含义的一组值。",[45,3425,3426],{},"只有一个元素的元组必须保留尾随逗号。",[45,3428,3429],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3431,71],{"id":71},[10,3433,74],{},[76,3435,3437],{"className":78,"code":3436,"language":80,"meta":81,"style":81},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[34,3438,3439,3444,3449,3454,3458,3463],{"__ignoreMap":81},[85,3440,3441],{"class":87,"line":88},[85,3442,3443],{},"point = (120, 80)\n",[85,3445,3446],{"class":87,"line":94},[85,3447,3448],{},"print(point[0])\n",[85,3450,3451],{"class":87,"line":100},[85,3452,3453],{},"print(point[1])\n",[85,3455,3456],{"class":87,"line":106},[85,3457,122],{"emptyLinePlaceholder":121},[85,3459,3460],{"class":87,"line":112},[85,3461,3462],{},"single = (5,)\n",[85,3464,3465],{"class":87,"line":118},[85,3466,3467],{},"print(single)\n",[10,3469,147],{},[76,3471,3474],{"className":3472,"code":3473,"language":153,"meta":81},[151],"120\n80\n(5,)\n",[34,3475,3473],{"__ignoreMap":81},[10,3477,158],{},[14,3479,161],{"id":161},[163,3481,3482,3488],{},[45,3483,3484,3487],{},[34,3485,3486],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[45,3489,3490,3493],{},[34,3491,3492],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3495,209],{"id":209},[42,3497,3498,3505],{},[45,3499,3500,3501,3504],{},"把 ",[34,3502,3503],{},"(5)"," 当作元组，实际它仍是整数。",[45,3506,3507],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3509,220],{"id":220},[163,3511,3512,3515],{},[45,3513,3514],{},"用元组表示宽度和高度。",[45,3516,2207,3517,2210,3519,3521],{},[34,3518,3503],{},[34,3520,3492],{}," 的类型。",[10,3523,237],{},[14,3525,240],{"id":240},[10,3527,3528],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,3530,247],{},{"title":81,"searchDepth":94,"depth":94,"links":3532},[3533,3534,3535,3536,3537,3538,3539,3540],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3395,"description":3400},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[260,3548,3391],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3551,"title":3552,"body":3553,"category":260,"cover":261,"description":3557,"extension":262,"meta":3712,"navigation":121,"path":3713,"pinned":265,"publishedAt":266,"seo":3714,"slug":3715,"stem":3716,"summary":3717,"tags":3718,"updatedAt":266,"visible":121,"__hash__":3720},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3554,"toc":3702},[3555,3558,3560,3563,3565,3571,3581,3583,3597,3599,3601,3635,3637,3643,3645,3647,3662,3664,3683,3685,3693,3695,3697,3700],[10,3556,3557],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3559,16],{"id":16},[10,3561,3562],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3564,22],{"id":22},[10,3566,3567],{},[26,3568],{"alt":3569,"src":3570},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3572,3573,3574,3577,3578,3580],{},"字典通过键定位值，不使用连续位置表达含义。",[34,3575,3576],{},"student[\"score\"]"," 读取的是键 ",[34,3579,2280],{}," 对应的值，而不是“第几个元素”。",[14,3582,40],{"id":40},[42,3584,3585,3588,3594],{},[45,3586,3587],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[45,3589,2373,3590,3593],{},[34,3591,3592],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[45,3595,3596],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3598,71],{"id":71},[10,3600,74],{},[76,3602,3604],{"className":78,"code":3603,"language":80,"meta":81,"style":81},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[34,3605,3606,3611,3616,3620,3625,3630],{"__ignoreMap":81},[85,3607,3608],{"class":87,"line":88},[85,3609,3610],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[85,3612,3613],{"class":87,"line":94},[85,3614,3615],{},"print(student[\"name\"])\n",[85,3617,3618],{"class":87,"line":100},[85,3619,122],{"emptyLinePlaceholder":121},[85,3621,3622],{"class":87,"line":106},[85,3623,3624],{},"student[\"score\"] = 95\n",[85,3626,3627],{"class":87,"line":112},[85,3628,3629],{},"student[\"city\"] = \"郑州\"\n",[85,3631,3632],{"class":87,"line":118},[85,3633,3634],{},"print(student)\n",[10,3636,147],{},[76,3638,3641],{"className":3639,"code":3640,"language":153,"meta":81},[151],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[34,3642,3640],{"__ignoreMap":81},[10,3644,158],{},[14,3646,161],{"id":161},[163,3648,3649,3652],{},[45,3650,3651],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[45,3653,3654,3655,3657,3658,3661],{},"给已有键 ",[34,3656,2280],{}," 赋值会更新映射，给新键 ",[34,3659,3660],{},"city"," 赋值会增加映射。",[14,3663,209],{"id":209},[42,3665,3666,3673],{},[45,3667,3668,3669,3672],{},"按位置理解字典并尝试 ",[34,3670,3671],{},"student[0]","，而实际键是字符串。",[45,3674,3675,3676,3679,3680,396],{},"直接读取不确定存在的键并忽略 ",[34,3677,3678],{},"KeyError","；后续可根据场景使用成员检查或 ",[34,3681,3682],{},"get()",[14,3684,220],{"id":220},[163,3686,3687,3690],{},[45,3688,3689],{},"建立一本书的标题、作者和页数字典。",[45,3691,3692],{},"添加分类键，再修改页数。",[10,3694,237],{},[14,3696,240],{"id":240},[10,3698,3699],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,3701,247],{},{"title":81,"searchDepth":94,"depth":94,"links":3703},[3704,3705,3706,3707,3708,3709,3710,3711],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3552,"description":3557},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[260,3719,3391],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3722,"title":3723,"body":3724,"category":260,"cover":261,"description":3728,"extension":262,"meta":3877,"navigation":121,"path":3878,"pinned":265,"publishedAt":266,"seo":3879,"slug":3880,"stem":3881,"summary":3882,"tags":3883,"updatedAt":266,"visible":121,"__hash__":3885},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3725,"toc":3867},[3726,3729,3731,3734,3736,3742,3745,3747,3766,3768,3770,3804,3806,3812,3814,3816,3831,3833,3845,3847,3858,3860,3862,3865],[10,3727,3728],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3730,16],{"id":16},[10,3732,3733],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3735,22],{"id":22},[10,3737,3738],{},[26,3739],{"alt":3740,"src":3741},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3743,3744],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3746,40],{"id":40},[42,3748,3749,3752,3755],{},[45,3750,3751],{},"集合中的元素不重复。",[45,3753,3754],{},"集合是无序容器，不要依赖打印顺序或索引。",[45,3756,3757,3758,3761,3762,3765],{},"创建空集合必须写 ",[34,3759,3760],{},"set()","；",[34,3763,3764],{},"{}"," 创建的是空字典。",[14,3767,71],{"id":71},[10,3769,74],{},[76,3771,3773],{"className":78,"code":3772,"language":80,"meta":81,"style":81},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[34,3774,3775,3780,3785,3789,3794,3799],{"__ignoreMap":81},[85,3776,3777],{"class":87,"line":88},[85,3778,3779],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[85,3781,3782],{"class":87,"line":94},[85,3783,3784],{},"right = {\"Python\", \"Docker\"}\n",[85,3786,3787],{"class":87,"line":100},[85,3788,122],{"emptyLinePlaceholder":121},[85,3790,3791],{"class":87,"line":106},[85,3792,3793],{},"print(left & right)\n",[85,3795,3796],{"class":87,"line":112},[85,3797,3798],{},"print(left | right)\n",[85,3800,3801],{"class":87,"line":118},[85,3802,3803],{},"print(\"Git\" in left)\n",[10,3805,147],{},[76,3807,3810],{"className":3808,"code":3809,"language":153,"meta":81},[151],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[34,3811,3809],{"__ignoreMap":81},[10,3813,158],{},[14,3815,161],{"id":161},[163,3817,3818,3821],{},[45,3819,3820],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[45,3822,3823,3826,3827,3830],{},[34,3824,3825],{},"&"," 计算交集，",[34,3828,3829],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3832,209],{"id":209},[42,3834,3835,3842],{},[45,3836,2373,3837,3839,3840,396],{},[34,3838,3764],{}," 创建空集合，实际得到空字典；空集合应写 ",[34,3841,3760],{},[45,3843,3844],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3846,220],{"id":220},[163,3848,3849,3855],{},[45,3850,3851,3852,3854],{},"把包含重复标签的列表交给 ",[34,3853,3760],{}," 去重。",[45,3856,3857],{},"计算两组课程标签的交集和差集。",[10,3859,237],{},[14,3861,240],{"id":240},[10,3863,3864],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,3866,247],{},{"title":81,"searchDepth":94,"depth":94,"links":3868},[3869,3870,3871,3872,3873,3874,3875,3876],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3723,"description":3728},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[260,3884,3391],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3887,"title":3888,"body":3889,"category":260,"cover":261,"description":3893,"extension":262,"meta":4089,"navigation":121,"path":4090,"pinned":265,"publishedAt":266,"seo":4091,"slug":4092,"stem":4093,"summary":4094,"tags":4095,"updatedAt":266,"visible":121,"__hash__":4098},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3890,"toc":4077},[3891,3894,3896,3899,3901,3907,3917,3919,3936,3938,3940,3989,3991,3997,3999,4001,4023,4025,4028,4034,4037,4039,4051,4053,4068,4070,4072,4075],[10,3892,3893],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3895,16],{"id":16},[10,3897,3898],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3900,22],{"id":22},[10,3902,3903],{},[26,3904],{"alt":3905,"src":3906},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3908,3909,3912,3913,3916],{},[34,3910,3911],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[34,3914,3915],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3918,40],{"id":40},[42,3920,3921,3930,3933],{},[45,3922,3923,3925,3926,3929],{},[34,3924,2840],{}," 比较内容是否相等，",[34,3927,3928],{},"is"," 比较是否为同一个对象。",[45,3931,3932],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[45,3934,3935],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3937,71],{"id":71},[10,3939,74],{},[76,3941,3943],{"className":78,"code":3942,"language":80,"meta":81,"style":81},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[34,3944,3945,3950,3955,3960,3964,3969,3974,3979,3984],{"__ignoreMap":81},[85,3946,3947],{"class":87,"line":88},[85,3948,3949],{},"tasks = [\"变量\", \"字符串\"]\n",[85,3951,3952],{"class":87,"line":94},[85,3953,3954],{},"shared = tasks\n",[85,3956,3957],{"class":87,"line":100},[85,3958,3959],{},"backup = tasks.copy()\n",[85,3961,3962],{"class":87,"line":106},[85,3963,122],{"emptyLinePlaceholder":121},[85,3965,3966],{"class":87,"line":112},[85,3967,3968],{},"tasks.append(\"列表\")\n",[85,3970,3971],{"class":87,"line":118},[85,3972,3973],{},"print(shared)\n",[85,3975,3976],{"class":87,"line":125},[85,3977,3978],{},"print(backup)\n",[85,3980,3981],{"class":87,"line":131},[85,3982,3983],{},"print(tasks is shared)\n",[85,3985,3986],{"class":87,"line":137},[85,3987,3988],{},"print(tasks is backup)\n",[10,3990,147],{},[76,3992,3995],{"className":3993,"code":3994,"language":153,"meta":81},[151],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[34,3996,3994],{"__ignoreMap":81},[10,3998,158],{},[14,4000,161],{"id":161},[163,4002,4003,4009],{},[45,4004,4005,4008],{},[34,4006,4007],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[45,4010,4011,4014,4015,4018,4019,4022],{},[34,4012,4013],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[34,4016,4017],{},"shared"," 能观察到变化，",[34,4020,4021],{},"backup"," 不会。",[186,4024,188],{"id":188},[10,4026,4027],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4029,4030],{},[26,4031],{"alt":4032,"src":4033},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4035,4036],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4038,209],{"id":209},[42,4040,4041,4048],{},[45,4042,228,4043,4045,4046,396],{},[34,4044,2840],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[34,4047,3928],{},[45,4049,4050],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4052,220],{"id":220},[163,4054,4055,4058],{},[45,4056,4057],{},"让两个变量引用同一个字典并修改其中一个。",[45,4059,2373,4060,4063,4064,1191,4066,396],{},[34,4061,4062],{},"copy()"," 创建外层副本，再比较 ",[34,4065,3928],{},[34,4067,2840],{},[10,4069,237],{},[14,4071,240],{"id":240},[10,4073,4074],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,4076,247],{},{"title":81,"searchDepth":94,"depth":94,"links":4078},[4079,4080,4081,4082,4083,4086,4087,4088],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":4084},[4085],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3888,"description":3893},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[260,4096,4097],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4100,"title":4101,"body":4102,"category":260,"cover":261,"description":4106,"extension":262,"meta":4318,"navigation":121,"path":4319,"pinned":265,"publishedAt":266,"seo":4320,"slug":4321,"stem":4322,"summary":4323,"tags":4324,"updatedAt":266,"visible":121,"__hash__":4326},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4103,"toc":4305},[4104,4107,4109,4112,4114,4120,4130,4132,4143,4145,4147,4199,4201,4207,4209,4211,4229,4231,4234,4240,4248,4251,4254,4260,4266,4268,4286,4288,4296,4298,4300,4303],[10,4105,4106],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4108,16],{"id":16},[10,4110,4111],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4113,22],{"id":22},[10,4115,4116],{},[26,4117],{"alt":4118,"src":4119},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4121,4122,2291,4124,2291,4127,4129],{},[34,4123,1190],{},[34,4125,4126],{},"elif",[34,4128,1194],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4131,40],{"id":40},[42,4133,4134,4137,4140],{},[45,4135,4136],{},"冒号表示接下来开始一个代码块。",[45,4138,4139],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[45,4141,4142],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4144,71],{"id":71},[10,4146,74],{},[76,4148,4150],{"className":78,"code":4149,"language":80,"meta":81,"style":81},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[34,4151,4152,4157,4161,4166,4171,4176,4181,4185,4190,4194],{"__ignoreMap":81},[85,4153,4154],{"class":87,"line":88},[85,4155,4156],{},"score = int(input(\"请输入分数：\"))\n",[85,4158,4159],{"class":87,"line":94},[85,4160,122],{"emptyLinePlaceholder":121},[85,4162,4163],{"class":87,"line":100},[85,4164,4165],{},"if score >= 90:\n",[85,4167,4168],{"class":87,"line":106},[85,4169,4170],{},"    level = \"优秀\"\n",[85,4172,4173],{"class":87,"line":112},[85,4174,4175],{},"elif score >= 60:\n",[85,4177,4178],{"class":87,"line":118},[85,4179,4180],{},"    level = \"合格\"\n",[85,4182,4183],{"class":87,"line":125},[85,4184,1180],{},[85,4186,4187],{"class":87,"line":131},[85,4188,4189],{},"    level = \"需要继续学习\"\n",[85,4191,4192],{"class":87,"line":137},[85,4193,122],{"emptyLinePlaceholder":121},[85,4195,4196],{"class":87,"line":142},[85,4197,4198],{},"print(level)\n",[10,4200,147],{},[76,4202,4205],{"className":4203,"code":4204,"language":153,"meta":81},[151],"输入 85 时输出：合格\n",[34,4206,4204],{"__ignoreMap":81},[10,4208,158],{},[14,4210,161],{"id":161},[163,4212,4213,4220],{},[45,4214,4215,4216,4219],{},"输入先转换为整数，程序从 ",[34,4217,4218],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[45,4221,4222,4225,4226,4228],{},[34,4223,4224],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[34,4227,1194],{}," 被跳过；最终三个分支只会选择一个。",[186,4230,188],{"id":188},[10,4232,4233],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4235,4236],{},[26,4237],{"alt":4238,"src":4239},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4241,4242,4244,4245,4247],{},[34,4243,4218],{}," 必须放在 ",[34,4246,4224],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[186,4249,188],{"id":4250},"再看一个具体细节-1",[10,4252,4253],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4255,4256],{},[26,4257],{"alt":4258,"src":4259},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4261,4262,4263,4265],{},"同一缩进层级属于同一个代码块；回到 ",[34,4264,1190],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4267,209],{"id":209},[42,4269,4270,4276],{},[45,4271,4272,4273,4275],{},"先写 ",[34,4274,4224],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[45,4277,4278,4279,4281,4282,4285],{},"混用多个独立 ",[34,4280,1190],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[34,4283,4284],{},"if\u002Felif\u002Felse"," 链。",[14,4287,220],{"id":220},[163,4289,4290,4293],{},[45,4291,4292],{},"根据温度输出“冷、适中、热”三个等级。",[45,4294,4295],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4297,237],{},[14,4299,240],{"id":240},[10,4301,4302],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,4304,247],{},{"title":81,"searchDepth":94,"depth":94,"links":4306},[4307,4308,4309,4310,4311,4315,4316,4317],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":4312},[4313,4314],{"id":188,"depth":100,"text":188},{"id":4250,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4101,"description":4106},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[260,1190,4325],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4328,"title":4329,"body":4330,"category":260,"cover":261,"description":4334,"extension":262,"meta":4499,"navigation":121,"path":4500,"pinned":265,"publishedAt":266,"seo":4501,"slug":4502,"stem":4503,"summary":4504,"tags":4505,"updatedAt":266,"visible":121,"__hash__":4507},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4331,"toc":4487},[4332,4335,4337,4340,4342,4348,4354,4356,4370,4372,4374,4412,4414,4420,4422,4424,4439,4441,4444,4450,4456,4458,4466,4468,4478,4480,4482,4485],[10,4333,4334],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4336,16],{"id":16},[10,4338,4339],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4341,22],{"id":22},[10,4343,4344],{},[26,4345],{"alt":4346,"src":4347},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4349,4350,4353],{},[34,4351,4352],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4355,40],{"id":40},[42,4357,4358,4361,4364],{},[45,4359,4360],{},"进入循环前先准备参与条件判断的状态。",[45,4362,4363],{},"循环体中必须有机会让条件变为假。",[45,4365,4366,4367,4369],{},"能够预先确定遍历对象时，后续介绍的 ",[34,4368,64],{}," 通常更直接。",[14,4371,71],{"id":71},[10,4373,74],{},[76,4375,4377],{"className":78,"code":4376,"language":80,"meta":81,"style":81},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[34,4378,4379,4384,4388,4393,4398,4403,4407],{"__ignoreMap":81},[85,4380,4381],{"class":87,"line":88},[85,4382,4383],{},"count = 1\n",[85,4385,4386],{"class":87,"line":94},[85,4387,122],{"emptyLinePlaceholder":121},[85,4389,4390],{"class":87,"line":100},[85,4391,4392],{},"while count \u003C= 3:\n",[85,4394,4395],{"class":87,"line":106},[85,4396,4397],{},"    print(\"第\", count, \"次练习\")\n",[85,4399,4400],{"class":87,"line":112},[85,4401,4402],{},"    count = count + 1\n",[85,4404,4405],{"class":87,"line":118},[85,4406,122],{"emptyLinePlaceholder":121},[85,4408,4409],{"class":87,"line":125},[85,4410,4411],{},"print(\"练习结束\")\n",[10,4413,147],{},[76,4415,4418],{"className":4416,"code":4417,"language":153,"meta":81},[151],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[34,4419,4417],{"__ignoreMap":81},[10,4421,158],{},[14,4423,161],{"id":161},[163,4425,4426,4433],{},[45,4427,4428,4429,4432],{},"进入循环前 ",[34,4430,4431],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[45,4434,4435,4436,4438],{},"循环体末尾把 ",[34,4437,4431],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[186,4440,188],{"id":188},[10,4442,4443],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4445,4446],{},[26,4447],{"alt":4448,"src":4449},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4451,4452,4453,4455],{},"第4次检查时 ",[34,4454,4431],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4457,209],{"id":209},[42,4459,4460,4463],{},[45,4461,4462],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[45,4464,4465],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4467,220],{"id":220},[163,4469,4470,4475],{},[45,4471,2373,4472,4474],{},[34,4473,4352],{}," 输出 1 到 5。",[45,4476,4477],{},"计算 1 到 10 的累加和。",[10,4479,237],{},[14,4481,240],{"id":240},[10,4483,4484],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,4486,247],{},{"title":81,"searchDepth":94,"depth":94,"links":4488},[4489,4490,4491,4492,4493,4496,4497,4498],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":4494},[4495],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4329,"description":4334},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[260,4352,4506],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4509,"title":4510,"body":4511,"category":260,"cover":261,"description":4515,"extension":262,"meta":4663,"navigation":121,"path":4664,"pinned":265,"publishedAt":266,"seo":4665,"slug":4666,"stem":4667,"summary":4668,"tags":4669,"updatedAt":266,"visible":121,"__hash__":4671},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4512,"toc":4653},[4513,4516,4518,4521,4523,4529,4534,4536,4550,4552,4554,4592,4594,4600,4602,4604,4621,4623,4631,4633,4644,4646,4648,4651],[10,4514,4515],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4517,16],{"id":16},[10,4519,4520],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4522,22],{"id":22},[10,4524,4525],{},[26,4526],{"alt":4527,"src":4528},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4530,4531,4533],{},[34,4532,64],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4535,40],{"id":40},[42,4537,4538,4544,4547],{},[45,4539,4540,4543],{},[34,4541,4542],{},"range(1, 4)"," 包含 1，不包含 4。",[45,4545,4546],{},"只需要元素时直接遍历元素，不必手工维护索引。",[45,4548,4549],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4551,71],{"id":71},[10,4553,74],{},[76,4555,4557],{"className":78,"code":4556,"language":80,"meta":81,"style":81},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[34,4558,4559,4564,4568,4573,4578,4582,4587],{"__ignoreMap":81},[85,4560,4561],{"class":87,"line":88},[85,4562,4563],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[85,4565,4566],{"class":87,"line":94},[85,4567,122],{"emptyLinePlaceholder":121},[85,4569,4570],{"class":87,"line":100},[85,4571,4572],{},"for course in courses:\n",[85,4574,4575],{"class":87,"line":106},[85,4576,4577],{},"    print(course)\n",[85,4579,4580],{"class":87,"line":112},[85,4581,122],{"emptyLinePlaceholder":121},[85,4583,4584],{"class":87,"line":118},[85,4585,4586],{},"for number in range(1, 4):\n",[85,4588,4589],{"class":87,"line":125},[85,4590,4591],{},"    print(number)\n",[10,4593,147],{},[76,4595,4598],{"className":4596,"code":4597,"language":153,"meta":81},[151],"变量\n字符串\n列表\n1\n2\n3\n",[34,4599,4597],{"__ignoreMap":81},[10,4601,158],{},[14,4603,161],{"id":161},[163,4605,4606,4616],{},[45,4607,4608,4609,4611,4612,4615],{},"第一个 ",[34,4610,64],{}," 依次从列表取得字符串，循环变量 ",[34,4613,4614],{},"course"," 每轮重新绑定。",[45,4617,4618,4620],{},[34,4619,4542],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4622,209],{"id":209},[42,4624,4625,4628],{},[45,4626,4627],{},"只需要元素却手工维护索引，增加越界风险。",[45,4629,4630],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4632,220],{"id":220},[163,4634,4635,4638],{},[45,4636,4637],{},"逐项输出一个字符串中的字符。",[45,4639,2373,4640,4643],{},[34,4641,4642],{},"range()"," 输出 2、4、6、8。",[10,4645,237],{},[14,4647,240],{"id":240},[10,4649,4650],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,4652,247],{},{"title":81,"searchDepth":94,"depth":94,"links":4654},[4655,4656,4657,4658,4659,4660,4661,4662],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4510,"description":4515},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[260,64,4670],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4673,"title":4674,"body":4675,"category":260,"cover":261,"description":4679,"extension":262,"meta":4853,"navigation":121,"path":4854,"pinned":265,"publishedAt":266,"seo":4855,"slug":4856,"stem":4857,"summary":4858,"tags":4859,"updatedAt":266,"visible":121,"__hash__":4860},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4676,"toc":4843},[4677,4680,4682,4685,4687,4693,4703,4705,4724,4726,4728,4780,4782,4788,4790,4792,4806,4808,4824,4826,4834,4836,4838,4841],[10,4678,4679],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4681,16],{"id":16},[10,4683,4684],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4686,22],{"id":22},[10,4688,4689],{},[26,4690],{"alt":4691,"src":4692},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4694,4695,4698,4699,4702],{},[34,4696,4697],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[34,4700,4701],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4704,40],{"id":40},[42,4706,4707,4710,4718],{},[45,4708,4709],{},"先写普通循环，再在确有需要时加入流程控制语句。",[45,4711,4712,4714,4715,4717],{},[34,4713,4697],{}," 前要确认不会跳过 ",[34,4716,4352],{}," 循环中的状态更新。",[45,4719,4720,4721,4723],{},"多层嵌套中 ",[34,4722,4701],{}," 只结束它所在的最内层循环。",[14,4725,71],{"id":71},[10,4727,74],{},[76,4729,4731],{"className":78,"code":4730,"language":80,"meta":81,"style":81},"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,4732,4733,4738,4742,4747,4752,4757,4762,4767,4771,4775],{"__ignoreMap":81},[85,4734,4735],{"class":87,"line":88},[85,4736,4737],{},"numbers = [3, -1, 0, 8, 12]\n",[85,4739,4740],{"class":87,"line":94},[85,4741,122],{"emptyLinePlaceholder":121},[85,4743,4744],{"class":87,"line":100},[85,4745,4746],{},"for number in numbers:\n",[85,4748,4749],{"class":87,"line":106},[85,4750,4751],{},"    if number \u003C 0:\n",[85,4753,4754],{"class":87,"line":112},[85,4755,4756],{},"        continue\n",[85,4758,4759],{"class":87,"line":118},[85,4760,4761],{},"    if number == 0:\n",[85,4763,4764],{"class":87,"line":125},[85,4765,4766],{},"        break\n",[85,4768,4769],{"class":87,"line":131},[85,4770,4591],{},[85,4772,4773],{"class":87,"line":137},[85,4774,122],{"emptyLinePlaceholder":121},[85,4776,4777],{"class":87,"line":142},[85,4778,4779],{},"print(\"循环结束\")\n",[10,4781,147],{},[76,4783,4786],{"className":4784,"code":4785,"language":153,"meta":81},[151],"3\n循环结束\n",[34,4787,4785],{"__ignoreMap":81},[10,4789,158],{},[14,4791,161],{"id":161},[163,4793,4794,4800],{},[45,4795,4796,4797,4799],{},"遇到 -1 时 ",[34,4798,4697],{}," 立即结束本轮，后面的判断和输出都不执行。",[45,4801,4802,4803,4805],{},"遇到 0 时 ",[34,4804,4701],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4807,209],{"id":209},[42,4809,4810,4815],{},[45,4811,3500,4812,4814],{},[34,4813,4697],{}," 当作结束循环，实际它只跳到下一轮。",[45,4816,4817,4818,4820,4821,4823],{},"在 ",[34,4819,4352],{}," 中把状态更新放在可能被 ",[34,4822,4697],{}," 跳过的位置，造成无限循环。",[14,4825,220],{"id":220},[163,4827,4828,4831],{},[45,4829,4830],{},"跳过列表中的空字符串并输出其他内容。",[45,4832,4833],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4835,237],{},[14,4837,240],{"id":240},[10,4839,4840],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,4842,247],{},{"title":81,"searchDepth":94,"depth":94,"links":4844},[4845,4846,4847,4848,4849,4850,4851,4852],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4674,"description":4679},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[260,4701,4697],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4862,"title":4863,"body":4864,"category":260,"cover":261,"description":4868,"extension":262,"meta":5039,"navigation":121,"path":5040,"pinned":265,"publishedAt":266,"seo":5041,"slug":5042,"stem":5043,"summary":5044,"tags":5045,"updatedAt":266,"visible":121,"__hash__":5048},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4865,"toc":5027},[4866,4869,4871,4874,4876,4882,4885,4887,4911,4913,4915,4949,4951,4957,4959,4961,4978,4980,4983,4989,4992,4994,5008,5010,5018,5020,5022,5025],[10,4867,4868],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4870,16],{"id":16},[10,4872,4873],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4875,22],{"id":22},[10,4877,4878],{},[26,4879],{"alt":4880,"src":4881},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4883,4884],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4886,40],{"id":40},[42,4888,4889,4892,4895],{},[45,4890,4891],{},"每增加一层嵌套，阅读成本都会上升。",[45,4893,4894],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[45,4896,4897,4898,2291,4901,4904,4905,2291,4908,396],{},"变量名使用 ",[34,4899,4900],{},"row",[34,4902,4903],{},"cell"," 等层级含义，避免全部写成 ",[34,4906,4907],{},"i",[34,4909,4910],{},"j",[14,4912,71],{"id":71},[10,4914,74],{},[76,4916,4918],{"className":78,"code":4917,"language":80,"meta":81,"style":81},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[34,4919,4920,4925,4929,4934,4939,4944],{"__ignoreMap":81},[85,4921,4922],{"class":87,"line":88},[85,4923,4924],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[85,4926,4927],{"class":87,"line":94},[85,4928,122],{"emptyLinePlaceholder":121},[85,4930,4931],{"class":87,"line":100},[85,4932,4933],{},"for row in table:\n",[85,4935,4936],{"class":87,"line":106},[85,4937,4938],{},"    for cell in row:\n",[85,4940,4941],{"class":87,"line":112},[85,4942,4943],{},"        print(cell)\n",[85,4945,4946],{"class":87,"line":118},[85,4947,4948],{},"    print(\"一行结束\")\n",[10,4950,147],{},[76,4952,4955],{"className":4953,"code":4954,"language":153,"meta":81},[151],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[34,4956,4954],{"__ignoreMap":81},[10,4958,158],{},[14,4960,161],{"id":161},[163,4962,4963,4975],{},[45,4964,4965,4966,4968,4969,1191,4972,396],{},"外层变量 ",[34,4967,4900],{}," 先引用第一行列表，内层才依次处理 ",[34,4970,4971],{},"A1",[34,4973,4974],{},"A2",[45,4976,4977],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[186,4979,188],{"id":188},[10,4981,4982],{},"二维列表的输出顺序可以展开成一条时间线。",[10,4984,4985],{},[26,4986],{"alt":4987,"src":4988},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,4990,4991],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,4993,209],{"id":209},[42,4995,4996,5005],{},[45,4997,4998,4999,1043,5002,5004],{},"把两层循环变量都叫 ",[34,5000,5001],{},"item",[34,5003,4907],{},"，难以确认当前层级。",[45,5006,5007],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,5009,220],{"id":220},[163,5011,5012,5015],{},[45,5013,5014],{},"打印一个 2×3 数字表。",[45,5016,5017],{},"在内层增加条件，只输出大于 3 的元素。",[10,5019,237],{},[14,5021,240],{"id":240},[10,5023,5024],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,5026,247],{},{"title":81,"searchDepth":94,"depth":94,"links":5028},[5029,5030,5031,5032,5033,5036,5037,5038],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":5034},[5035],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4863,"description":4868},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[260,5046,5047],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5050,"title":5051,"body":5052,"category":260,"cover":261,"description":5056,"extension":262,"meta":5194,"navigation":121,"path":5195,"pinned":265,"publishedAt":266,"seo":5196,"slug":5197,"stem":5198,"summary":5199,"tags":5200,"updatedAt":266,"visible":121,"__hash__":5203},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5053,"toc":5184},[5054,5057,5059,5062,5064,5070,5073,5075,5086,5088,5090,5128,5130,5136,5138,5140,5152,5154,5165,5167,5175,5177,5179,5182],[10,5055,5056],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5058,16],{"id":16},[10,5060,5061],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5063,22],{"id":22},[10,5065,5066],{},[26,5067],{"alt":5068,"src":5069},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5071,5072],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5074,40],{"id":40},[42,5076,5077,5080,5083],{},[45,5078,5079],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[45,5081,5082],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[45,5084,5085],{},"推导式创建新列表，不修改输入列表。",[14,5087,71],{"id":71},[10,5089,74],{},[76,5091,5093],{"className":78,"code":5092,"language":80,"meta":81,"style":81},"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,5094,5095,5100,5104,5109,5114,5118,5123],{"__ignoreMap":81},[85,5096,5097],{"class":87,"line":88},[85,5098,5099],{},"numbers = [1, 2, 3, 4, 5]\n",[85,5101,5102],{"class":87,"line":94},[85,5103,122],{"emptyLinePlaceholder":121},[85,5105,5106],{"class":87,"line":100},[85,5107,5108],{},"squares = [number * number for number in numbers]\n",[85,5110,5111],{"class":87,"line":106},[85,5112,5113],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[85,5115,5116],{"class":87,"line":112},[85,5117,122],{"emptyLinePlaceholder":121},[85,5119,5120],{"class":87,"line":118},[85,5121,5122],{},"print(squares)\n",[85,5124,5125],{"class":87,"line":125},[85,5126,5127],{},"print(even_squares)\n",[10,5129,147],{},[76,5131,5134],{"className":5132,"code":5133,"language":153,"meta":81},[151],"[1, 4, 9, 16, 25]\n[4, 16]\n",[34,5135,5133],{"__ignoreMap":81},[10,5137,158],{},[14,5139,161],{"id":161},[163,5141,5142,5145],{},[45,5143,5144],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[45,5146,5147,5148,5151],{},"第二条先用 ",[34,5149,5150],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5153,209],{"id":209},[42,5155,5156,5162],{},[45,5157,5158,5159,5161],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[34,5160,64],{}," 开始找输入。",[45,5163,5164],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5166,220],{"id":220},[163,5168,5169,5172],{},[45,5170,5171],{},"把字符串列表转换为长度列表。",[45,5173,5174],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5176,237],{},[14,5178,240],{"id":240},[10,5180,5181],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,5183,247],{},{"title":81,"searchDepth":94,"depth":94,"links":5185},[5186,5187,5188,5189,5190,5191,5192,5193],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5051,"description":5056},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[260,5201,5202],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5205,"title":5206,"body":5207,"category":260,"cover":261,"description":5211,"extension":262,"meta":5354,"navigation":121,"path":5355,"pinned":265,"publishedAt":266,"seo":5356,"slug":5357,"stem":5358,"summary":5359,"tags":5360,"updatedAt":266,"visible":121,"__hash__":5363},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5208,"toc":5344},[5209,5212,5214,5217,5219,5225,5228,5230,5241,5243,5245,5284,5286,5292,5294,5296,5311,5313,5321,5323,5335,5337,5339,5342],[10,5210,5211],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5213,16],{"id":16},[10,5215,5216],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5218,22],{"id":22},[10,5220,5221],{},[26,5222],{"alt":5223,"src":5224},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5226,5227],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5229,40],{"id":40},[42,5231,5232,5235,5238],{},[45,5233,5234],{},"函数名描述动作，使用小写字母和下划线。",[45,5236,5237],{},"函数定义要先执行，之后才能调用。",[45,5239,5240],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5242,71],{"id":71},[10,5244,74],{},[76,5246,5248],{"className":78,"code":5247,"language":80,"meta":81,"style":81},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[34,5249,5250,5255,5260,5265,5269,5274,5279],{"__ignoreMap":81},[85,5251,5252],{"class":87,"line":88},[85,5253,5254],{},"def show_progress():\n",[85,5256,5257],{"class":87,"line":94},[85,5258,5259],{},"    print(\"正在学习函数\")\n",[85,5261,5262],{"class":87,"line":100},[85,5263,5264],{},"    print(\"本节完成 50%\")\n",[85,5266,5267],{"class":87,"line":106},[85,5268,122],{"emptyLinePlaceholder":121},[85,5270,5271],{"class":87,"line":112},[85,5272,5273],{},"print(\"调用前\")\n",[85,5275,5276],{"class":87,"line":118},[85,5277,5278],{},"show_progress()\n",[85,5280,5281],{"class":87,"line":125},[85,5282,5283],{},"print(\"调用后\")\n",[10,5285,147],{},[76,5287,5290],{"className":5288,"code":5289,"language":153,"meta":81},[151],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[34,5291,5289],{"__ignoreMap":81},[10,5293,158],{},[14,5295,161],{"id":161},[163,5297,5298,5304],{},[45,5299,972,5300,5303],{},[34,5301,5302],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[45,5305,5306,5307,5310],{},"运行到 ",[34,5308,5309],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5312,209],{"id":209},[42,5314,5315,5318],{},[45,5316,5317],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[45,5319,5320],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5322,220],{"id":220},[163,5324,5325,5332],{},[45,5326,5327,5328,5331],{},"定义 ",[34,5329,5330],{},"show_plan()"," 输出两行学习计划。",[45,5333,5334],{},"连续调用同一个函数两次，观察执行顺序。",[10,5336,237],{},[14,5338,240],{"id":240},[10,5340,5341],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,5343,247],{},{"title":81,"searchDepth":94,"depth":94,"links":5345},[5346,5347,5348,5349,5350,5351,5352,5353],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5206,"description":5211},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[260,5361,5362],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5365,"title":5366,"body":5367,"category":260,"cover":261,"description":5371,"extension":262,"meta":5551,"navigation":121,"path":5552,"pinned":265,"publishedAt":266,"seo":5553,"slug":5554,"stem":5555,"summary":5556,"tags":5557,"updatedAt":266,"visible":121,"__hash__":5560},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5368,"toc":5539},[5369,5372,5374,5377,5379,5385,5392,5394,5411,5413,5415,5449,5451,5457,5459,5461,5482,5484,5487,5493,5503,5505,5520,5522,5530,5532,5534,5537],[10,5370,5371],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5373,16],{"id":16},[10,5375,5376],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5378,22],{"id":22},[10,5380,5381],{},[26,5382],{"alt":5383,"src":5384},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5386,5387,5388,5391],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[34,5389,5390],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5393,40],{"id":40},[42,5395,5396,5399,5402],{},[45,5397,5398],{},"形参出现在函数定义中，实参出现在函数调用中。",[45,5400,5401],{},"局部变量默认只在函数内部可见。",[45,5403,5404,5405,5407,5408,396],{},"没有显式 ",[34,5406,5390],{}," 的函数会返回 ",[34,5409,5410],{},"None",[14,5412,71],{"id":71},[10,5414,74],{},[76,5416,5418],{"className":78,"code":5417,"language":80,"meta":81,"style":81},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[34,5419,5420,5425,5430,5435,5439,5444],{"__ignoreMap":81},[85,5421,5422],{"class":87,"line":88},[85,5423,5424],{},"def calculate_total(price, count):\n",[85,5426,5427],{"class":87,"line":94},[85,5428,5429],{},"    total = price * count\n",[85,5431,5432],{"class":87,"line":100},[85,5433,5434],{},"    return total\n",[85,5436,5437],{"class":87,"line":106},[85,5438,122],{"emptyLinePlaceholder":121},[85,5440,5441],{"class":87,"line":112},[85,5442,5443],{},"result = calculate_total(25, 4)\n",[85,5445,5446],{"class":87,"line":118},[85,5447,5448],{},"print(result)\n",[10,5450,147],{},[76,5452,5455],{"className":5453,"code":5454,"language":153,"meta":81},[151],"100\n",[34,5456,5454],{"__ignoreMap":81},[10,5458,158],{},[14,5460,161],{"id":161},[163,5462,5463,5472],{},[45,5464,5465,5466,2291,5469,5471],{},"调用时 25 和 4 分别绑定到 ",[34,5467,5468],{},"price",[34,5470,4431],{},"，它们只在本次函数调用的局部范围中使用。",[45,5473,5474,5477,5478,5481],{},[34,5475,5476],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[34,5479,5480],{},"result"," 并输出。",[186,5483,188],{"id":188},[10,5485,5486],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5488,5489],{},[26,5490],{"alt":5491,"src":5492},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5494,5495,2291,5497,1191,5499,5502],{},[34,5496,5468],{},[34,5498,4431],{},[34,5500,5501],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5504,209],{"id":209},[42,5506,5507,5514],{},[45,5508,5509,5510,5513],{},"在函数内部只 ",[34,5511,5512],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[45,5515,5516,5517,5519],{},"试图在函数外直接访问局部变量 ",[34,5518,5501],{},"，它的名字只在调用期间的局部作用域存在。",[14,5521,220],{"id":220},[163,5523,5524,5527],{},[45,5525,5526],{},"编写计算长方形面积的函数。",[45,5528,5529],{},"让函数返回结果后在调用方加上单位再输出。",[10,5531,237],{},[14,5533,240],{"id":240},[10,5535,5536],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,5538,247],{},{"title":81,"searchDepth":94,"depth":94,"links":5540},[5541,5542,5543,5544,5545,5548,5549,5550],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":5546},[5547],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5366,"description":5371},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[260,5558,5559],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5562,"title":5563,"body":5564,"category":260,"cover":261,"description":5568,"extension":262,"meta":5748,"navigation":121,"path":5749,"pinned":265,"publishedAt":266,"seo":5750,"slug":5751,"stem":5752,"summary":5753,"tags":5754,"updatedAt":266,"visible":121,"__hash__":5757},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5565,"toc":5736},[5566,5569,5571,5574,5576,5582,5585,5587,5604,5606,5608,5660,5662,5668,5670,5672,5690,5692,5695,5701,5704,5706,5717,5719,5727,5729,5731,5734],[10,5567,5568],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5570,16],{"id":16},[10,5572,5573],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5575,22],{"id":22},[10,5577,5578],{},[26,5579],{"alt":5580,"src":5581},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5583,5584],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5586,40],{"id":40},[42,5588,5589,5592,5598],{},[45,5590,5591],{},"必需参数应放在有默认值的参数之前。",[45,5593,5594,5597],{},[34,5595,5596],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[45,5599,5600,5603],{},[34,5601,5602],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5605,71],{"id":71},[10,5607,74],{},[76,5609,5611],{"className":78,"code":5610,"language":80,"meta":81,"style":81},"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,5612,5613,5618,5623,5627,5632,5637,5641,5646,5651,5655],{"__ignoreMap":81},[85,5614,5615],{"class":87,"line":88},[85,5616,5617],{},"def build_title(name, level=\"基础\"):\n",[85,5619,5620],{"class":87,"line":94},[85,5621,5622],{},"    return name + \"｜\" + level\n",[85,5624,5625],{"class":87,"line":100},[85,5626,122],{"emptyLinePlaceholder":121},[85,5628,5629],{"class":87,"line":106},[85,5630,5631],{},"print(build_title(\"Python\"))\n",[85,5633,5634],{"class":87,"line":112},[85,5635,5636],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[85,5638,5639],{"class":87,"line":118},[85,5640,122],{"emptyLinePlaceholder":121},[85,5642,5643],{"class":87,"line":125},[85,5644,5645],{},"def total(*numbers):\n",[85,5647,5648],{"class":87,"line":131},[85,5649,5650],{},"    return sum(numbers)\n",[85,5652,5653],{"class":87,"line":137},[85,5654,122],{"emptyLinePlaceholder":121},[85,5656,5657],{"class":87,"line":142},[85,5658,5659],{},"print(total(10, 20, 30))\n",[10,5661,147],{},[76,5663,5666],{"className":5664,"code":5665,"language":153,"meta":81},[151],"Python｜基础\n异常处理｜进阶\n60\n",[34,5667,5665],{"__ignoreMap":81},[10,5669,158],{},[14,5671,161],{"id":161},[163,5673,5674,5681],{},[45,5675,5676,5677,5680],{},"第一次调用只提供必需参数，",[34,5678,5679],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[45,5682,5683,5686,5687,396],{},[34,5684,5685],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[34,5688,5689],{},"sum()",[186,5691,188],{"id":188},[10,5693,5694],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5696,5697],{},[26,5698],{"alt":5699,"src":5700},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5702,5703],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5705,209],{"id":209},[42,5707,5708,5714],{},[45,5709,5710,5711,5713],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[34,5712,5410],{}," 再在函数内创建。",[45,5715,5716],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5718,220],{"id":220},[163,5720,5721,5724],{},[45,5722,5723],{},"给问候函数增加默认称呼。",[45,5725,5726],{},"编写接收任意数量分数并返回总分的函数。",[10,5728,237],{},[14,5730,240],{"id":240},[10,5732,5733],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,5735,247],{},{"title":81,"searchDepth":94,"depth":94,"links":5737},[5738,5739,5740,5741,5742,5745,5746,5747],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":5743},[5744],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5563,"description":5568},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[260,5755,5756],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5759,"title":5760,"body":5761,"category":260,"cover":261,"description":5765,"extension":262,"meta":5962,"navigation":121,"path":5963,"pinned":265,"publishedAt":266,"seo":5964,"slug":5965,"stem":5966,"summary":5967,"tags":5968,"updatedAt":266,"visible":121,"__hash__":5971},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5762,"toc":5950},[5763,5766,5768,5771,5773,5779,5782,5784,5801,5803,5805,5868,5870,5876,5878,5880,5907,5909,5912,5918,5921,5923,5931,5933,5941,5943,5945,5948],[10,5764,5765],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5767,16],{"id":16},[10,5769,5770],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5772,22],{"id":22},[10,5774,5775],{},[26,5776],{"alt":5777,"src":5778},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5780,5781],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5783,40],{"id":40},[42,5785,5786,5789,5792],{},[45,5787,5788],{},"函数内部赋值默认创建局部变量。",[45,5790,5791],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[45,5793,5794,2210,5797,5800],{},[34,5795,5796],{},"global",[34,5798,5799],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5802,71],{"id":71},[10,5804,74],{},[76,5806,5808],{"className":78,"code":5807,"language":80,"meta":81,"style":81},"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,5809,5810,5815,5819,5824,5829,5833,5838,5843,5848,5852,5857,5862],{"__ignoreMap":81},[85,5811,5812],{"class":87,"line":88},[85,5813,5814],{},"course = \"Python\"\n",[85,5816,5817],{"class":87,"line":94},[85,5818,122],{"emptyLinePlaceholder":121},[85,5820,5821],{"class":87,"line":100},[85,5822,5823],{},"def outer():\n",[85,5825,5826],{"class":87,"line":106},[85,5827,5828],{},"    level = \"基础\"\n",[85,5830,5831],{"class":87,"line":112},[85,5832,122],{"emptyLinePlaceholder":121},[85,5834,5835],{"class":87,"line":118},[85,5836,5837],{},"    def show():\n",[85,5839,5840],{"class":87,"line":125},[85,5841,5842],{},"        lesson = \"作用域\"\n",[85,5844,5845],{"class":87,"line":131},[85,5846,5847],{},"        print(course, level, lesson)\n",[85,5849,5850],{"class":87,"line":137},[85,5851,122],{"emptyLinePlaceholder":121},[85,5853,5854],{"class":87,"line":142},[85,5855,5856],{},"    show()\n",[85,5858,5860],{"class":87,"line":5859},11,[85,5861,122],{"emptyLinePlaceholder":121},[85,5863,5865],{"class":87,"line":5864},12,[85,5866,5867],{},"outer()\n",[10,5869,147],{},[76,5871,5874],{"className":5872,"code":5873,"language":153,"meta":81},[151],"Python 基础 作用域\n",[34,5875,5873],{"__ignoreMap":81},[10,5877,158],{},[14,5879,161],{"id":161},[163,5881,5882,5899],{},[45,5883,5884,5887,5888,5891,5892,5894,5895,5898],{},[34,5885,5886],{},"show()"," 中查找 ",[34,5889,5890],{},"lesson"," 时先在局部找到，查找 ",[34,5893,5679],{}," 时到外层 ",[34,5896,5897],{},"outer()"," 找到。",[45,5900,5901,5903,5904,5906],{},[34,5902,4614],{}," 在局部和外层都不存在，继续到模块全局找到；",[34,5905,2242],{}," 最后在内置作用域找到。",[186,5908,188],{"id":188},[10,5910,5911],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5913,5914],{},[26,5915],{"alt":5916,"src":5917},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5919,5920],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5922,209],{"id":209},[42,5924,5925,5928],{},[45,5926,5927],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[45,5929,5930],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5932,220],{"id":220},[163,5934,5935,5938],{},[45,5936,5937],{},"在内外层定义同名变量，观察最近作用域优先。",[45,5939,5940],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5942,237],{},[14,5944,240],{"id":240},[10,5946,5947],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,5949,247],{},{"title":81,"searchDepth":94,"depth":94,"links":5951},[5952,5953,5954,5955,5956,5959,5960,5961],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":5957},[5958],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5760,"description":5765},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[260,5969,5970],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5973,"title":5974,"body":5975,"category":260,"cover":261,"description":5979,"extension":262,"meta":6129,"navigation":121,"path":6130,"pinned":265,"publishedAt":266,"seo":6131,"slug":6132,"stem":6133,"summary":6134,"tags":6135,"updatedAt":266,"visible":121,"__hash__":6138},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5976,"toc":6119},[5977,5980,5982,5985,5987,5993,5996,5998,6017,6019,6021,6055,6057,6063,6065,6067,6082,6084,6096,6098,6110,6112,6114,6117],[10,5978,5979],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,5981,16],{"id":16},[10,5983,5984],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5986,22],{"id":22},[10,5988,5989],{},[26,5990],{"alt":5991,"src":5992},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,5994,5995],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,5997,40],{"id":40},[42,5999,6000,6003,6006],{},[45,6001,6002],{},"文档字符串紧跟在函数定义后的第一条语句。",[45,6004,6005],{},"注解表达接口意图，不代替输入校验和测试。",[45,6007,6008,6009,2291,6011,2291,6013,6016],{},"基础注解优先使用 ",[34,6010,2294],{},[34,6012,2460],{},[34,6014,6015],{},"list[str]"," 等直接写法。",[14,6018,71],{"id":71},[10,6020,74],{},[76,6022,6024],{"className":78,"code":6023,"language":80,"meta":81,"style":81},"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,6025,6026,6031,6036,6041,6045,6050],{"__ignoreMap":81},[85,6027,6028],{"class":87,"line":88},[85,6029,6030],{},"def format_score(name: str, score: int) -> str:\n",[85,6032,6033],{"class":87,"line":94},[85,6034,6035],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[85,6037,6038],{"class":87,"line":100},[85,6039,6040],{},"    return name + \"：\" + str(score)\n",[85,6042,6043],{"class":87,"line":106},[85,6044,122],{"emptyLinePlaceholder":121},[85,6046,6047],{"class":87,"line":112},[85,6048,6049],{},"print(format_score(\"小郑\", 95))\n",[85,6051,6052],{"class":87,"line":118},[85,6053,6054],{},"print(format_score.__doc__)\n",[10,6056,147],{},[76,6058,6061],{"className":6059,"code":6060,"language":153,"meta":81},[151],"小郑：95\n返回带姓名的分数文本。\n",[34,6062,6060],{"__ignoreMap":81},[10,6064,158],{},[14,6066,161],{"id":161},[163,6068,6069,6079],{},[45,6070,6071,6072,6075,6076,6078],{},"函数签名说明 ",[34,6073,6074],{},"name"," 预期为字符串、",[34,6077,2280],{}," 预期为整数，返回值预期为字符串。",[45,6080,6081],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6083,209],{"id":209},[42,6085,6086,6093],{},[45,6087,6088,6089,6092],{},"认为加了 ",[34,6090,6091],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[45,6094,6095],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6097,220],{"id":220},[163,6099,6100,6103],{},[45,6101,6102],{},"为面积函数补充参数和返回值注解。",[45,6104,6105,6106,6109],{},"通过 ",[34,6107,6108],{},"函数名.__doc__"," 查看文档字符串。",[10,6111,237],{},[14,6113,240],{"id":240},[10,6115,6116],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,6118,247],{},{"title":81,"searchDepth":94,"depth":94,"links":6120},[6121,6122,6123,6124,6125,6126,6127,6128],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5974,"description":5979},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[260,6136,6137],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6140,"title":6141,"body":6142,"category":260,"cover":261,"description":6146,"extension":262,"meta":6373,"navigation":121,"path":6374,"pinned":265,"publishedAt":266,"seo":6375,"slug":6376,"stem":6377,"summary":6378,"tags":6379,"updatedAt":266,"visible":121,"__hash__":6382},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6143,"toc":6361},[6144,6147,6149,6155,6157,6163,6174,6176,6194,6196,6203,6232,6239,6258,6267,6269,6275,6277,6279,6302,6304,6307,6313,6319,6321,6337,6339,6352,6354,6356,6359],[10,6145,6146],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6148,16],{"id":16},[10,6150,6151,6152,6154],{},"本篇只处理“模块、import 与 ",[329,6153,6074],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6156,22],{"id":22},[10,6158,6159],{},[26,6160],{"alt":6161,"src":6162},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6164,6165,6166,6169,6170,6173],{},"同一个文件直接运行时 ",[34,6167,6168],{},"__name__"," 等于 ",[34,6171,6172],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6175,40],{"id":40},[42,6177,6178,6184,6187],{},[45,6179,6180,6181,6183],{},"一个 ",[34,6182,1205],{}," 文件就是一个模块。",[45,6185,6186],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[45,6188,6189,6190,6193],{},"避免使用 ",[34,6191,6192],{},"from module import *","，它会让名字来源不清楚。",[14,6195,71],{"id":71},[10,6197,6198,6199,6202],{},"先在同一个目录中创建两个文件。把函数放进 ",[34,6200,6201],{},"calculator.py","：",[76,6204,6206],{"className":78,"code":6205,"language":80,"meta":81,"style":81},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[34,6207,6208,6213,6218,6222,6227],{"__ignoreMap":81},[85,6209,6210],{"class":87,"line":88},[85,6211,6212],{},"def add(left, right):\n",[85,6214,6215],{"class":87,"line":94},[85,6216,6217],{},"    return left + right\n",[85,6219,6220],{"class":87,"line":100},[85,6221,122],{"emptyLinePlaceholder":121},[85,6223,6224],{"class":87,"line":106},[85,6225,6226],{},"if __name__ == \"__main__\":\n",[85,6228,6229],{"class":87,"line":112},[85,6230,6231],{},"    print(add(2, 3))\n",[10,6233,6234,6235,6238],{},"再创建 ",[34,6236,6237],{},"app.py","，从模块中导入函数：",[76,6240,6242],{"className":78,"code":6241,"language":80,"meta":81,"style":81},"from calculator import add\n\nprint(add(10, 20))\n",[34,6243,6244,6249,6253],{"__ignoreMap":81},[85,6245,6246],{"class":87,"line":88},[85,6247,6248],{},"from calculator import add\n",[85,6250,6251],{"class":87,"line":94},[85,6252,122],{"emptyLinePlaceholder":121},[85,6254,6255],{"class":87,"line":100},[85,6256,6257],{},"print(add(10, 20))\n",[10,6259,6260,6261,1191,6264,396],{},"分别执行 ",[34,6262,6263],{},"python3 calculator.py",[34,6265,6266],{},"python3 app.py",[10,6268,147],{},[76,6270,6273],{"className":6271,"code":6272,"language":153,"meta":81},[151],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[34,6274,6272],{"__ignoreMap":81},[10,6276,158],{},[14,6278,161],{"id":161},[163,6280,6281,6291],{},[45,6282,6283,6284,6286,6287,6290],{},"直接运行 ",[34,6285,6201],{}," 时，模块名是 ",[34,6288,6289],{},"__main__","，入口代码输出 5。",[45,6292,6293,6295,6296,6298,6299,6301],{},[34,6294,6237],{}," 导入模块时，",[34,6297,6201],{}," 的函数定义会执行，但入口判断为假；随后 ",[34,6300,6237],{}," 调用函数输出 30。",[186,6303,188],{"id":188},[10,6305,6306],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6308,6309],{},[26,6310],{"alt":6311,"src":6312},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6314,6315,6316,6318],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[34,6317,6289],{}," 保护下的演示代码。",[14,6320,209],{"id":209},[42,6322,6323,6330],{},[45,6324,6325,6326,1191,6328,396],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[34,6327,6201],{},[34,6329,6237],{},[45,6331,6332,6333,6336],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[34,6334,6335],{},"json.py","，导致导入目标被遮蔽。",[14,6338,220],{"id":220},[163,6340,6341,6347],{},[45,6342,2388,6343,6346],{},[34,6344,6345],{},"text_tools.py"," 并导出一个格式化函数。",[45,6348,6349,6350,396],{},"分别直接运行模块和从另一个脚本导入，输出 ",[34,6351,6168],{},[10,6353,237],{},[14,6355,240],{"id":240},[10,6357,6358],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,6360,247],{},{"title":81,"searchDepth":94,"depth":94,"links":6362},[6363,6364,6365,6366,6367,6370,6371,6372],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":6368},[6369],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6141,"description":6146},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[260,6380,6381],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6384,"title":6385,"body":6386,"category":260,"cover":261,"description":6390,"extension":262,"meta":6555,"navigation":121,"path":6556,"pinned":265,"publishedAt":266,"seo":6557,"slug":6558,"stem":6559,"summary":6560,"tags":6561,"updatedAt":266,"visible":121,"__hash__":6563},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6387,"toc":6545},[6388,6391,6393,6396,6398,6404,6407,6409,6423,6425,6427,6473,6475,6481,6483,6485,6511,6513,6523,6525,6536,6538,6540,6543],[10,6389,6390],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6392,16],{"id":16},[10,6394,6395],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6397,22],{"id":22},[10,6399,6400],{},[26,6401],{"alt":6402,"src":6403},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6405,6406],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6408,40],{"id":40},[42,6410,6411,6417,6420],{},[45,6412,6413,6416],{},[34,6414,6415],{},".venv"," 是常见目录名，不应提交到 Git。",[45,6418,6419],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[45,6421,6422],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6424,71],{"id":71},[10,6426,1608],{},[76,6428,6430],{"className":625,"code":6429,"language":627,"meta":81,"style":81},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[34,6431,6432,6444,6452,6458,6468],{"__ignoreMap":81},[85,6433,6434,6436,6438,6441],{"class":87,"line":88},[85,6435,725],{"class":634},[85,6437,667],{"class":637},[85,6439,6440],{"class":670}," venv",[85,6442,6443],{"class":670}," .venv\n",[85,6445,6446,6449],{"class":87,"line":94},[85,6447,6448],{"class":637},"source",[85,6450,6451],{"class":670}," .venv\u002Fbin\u002Factivate\n",[85,6453,6454,6456],{"class":87,"line":100},[85,6455,80],{"class":634},[85,6457,638],{"class":637},[85,6459,6460,6462,6464,6466],{"class":87,"line":106},[85,6461,80],{"class":634},[85,6463,667],{"class":637},[85,6465,671],{"class":670},[85,6467,638],{"class":637},[85,6469,6470],{"class":87,"line":112},[85,6471,6472],{"class":634},"deactivate\n",[10,6474,147],{},[76,6476,6479],{"className":6477,"code":6478,"language":153,"meta":81},[151],"Python 和 pip 的路径应指向当前项目的 .venv\n",[34,6480,6478],{"__ignoreMap":81},[10,6482,158],{},[14,6484,161],{"id":161},[163,6486,6487,6496],{},[45,6488,6489,6492,6493,6495],{},[34,6490,6491],{},"venv"," 根据当前 ",[34,6494,725],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[45,6497,6498,6499,2210,6501,6504,6505,3761,6507,6510],{},"激活后 ",[34,6500,80],{},[34,6502,6503],{},"python -m pip"," 优先指向 ",[34,6506,6415],{},[34,6508,6509],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6512,209],{"id":209},[42,6514,6515,6518],{},[45,6516,6517],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[45,6519,3500,6520,6522],{},[34,6521,6415],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6524,220],{"id":220},[163,6526,6527,6533],{},[45,6528,6529,6530,396],{},"创建虚拟环境并记录激活前后的 ",[34,6531,6532],{},"which python",[45,6534,6535],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6537,237],{},[14,6539,240],{"id":240},[10,6541,6542],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,6544,1692],{},{"title":81,"searchDepth":94,"depth":94,"links":6546},[6547,6548,6549,6550,6551,6552,6553,6554],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6385,"description":6390},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[260,6562,295],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6565,"title":6566,"body":6567,"category":260,"cover":261,"description":6571,"extension":262,"meta":6759,"navigation":121,"path":6760,"pinned":265,"publishedAt":266,"seo":6761,"slug":6762,"stem":6763,"summary":6764,"tags":6765,"updatedAt":266,"visible":121,"__hash__":6768},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6568,"toc":6749},[6569,6572,6574,6577,6579,6585,6594,6596,6620,6622,6624,6677,6679,6685,6687,6689,6705,6707,6726,6728,6740,6742,6744,6747],[10,6570,6571],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6573,16],{"id":16},[10,6575,6576],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6578,22],{"id":22},[10,6580,6581],{},[26,6582],{"alt":6583,"src":6584},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6586,6587,6590,6591,6593],{},[34,6588,6589],{},"Path"," 使用 ",[34,6592,2470],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6595,40],{"id":40},[42,6597,6598,6601,6613],{},[45,6599,6600],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[45,6602,6603,2291,6606,2291,6609,6612],{},[34,6604,6605],{},"exists()",[34,6607,6608],{},"is_file()",[34,6610,6611],{},"is_dir()"," 检查真实文件系统状态。",[45,6614,6615,6616,6619],{},"创建目录前明确目标；",[34,6617,6618],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6621,71],{"id":71},[10,6623,74],{},[76,6625,6627],{"className":78,"code":6626,"language":80,"meta":81,"style":81},"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,6628,6629,6634,6638,6643,6648,6653,6657,6662,6667,6672],{"__ignoreMap":81},[85,6630,6631],{"class":87,"line":88},[85,6632,6633],{},"from pathlib import Path\n",[85,6635,6636],{"class":87,"line":94},[85,6637,122],{"emptyLinePlaceholder":121},[85,6639,6640],{"class":87,"line":100},[85,6641,6642],{},"project = Path.cwd()\n",[85,6644,6645],{"class":87,"line":106},[85,6646,6647],{},"data_dir = project \u002F \"data\"\n",[85,6649,6650],{"class":87,"line":112},[85,6651,6652],{},"file_path = data_dir \u002F \"records.json\"\n",[85,6654,6655],{"class":87,"line":118},[85,6656,122],{"emptyLinePlaceholder":121},[85,6658,6659],{"class":87,"line":125},[85,6660,6661],{},"print(project)\n",[85,6663,6664],{"class":87,"line":131},[85,6665,6666],{},"print(file_path.name)\n",[85,6668,6669],{"class":87,"line":137},[85,6670,6671],{},"print(file_path.suffix)\n",[85,6673,6674],{"class":87,"line":142},[85,6675,6676],{},"print(file_path.exists())\n",[10,6678,147],{},[76,6680,6683],{"className":6681,"code":6682,"language":153,"meta":81},[151],"显示当前项目路径、records.json、.json 和存在状态\n",[34,6684,6682],{"__ignoreMap":81},[10,6686,158],{},[14,6688,161],{"id":161},[163,6690,6691,6697],{},[45,6692,6693,6696],{},[34,6694,6695],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[45,6698,2373,6699,6701,6702,6704],{},[34,6700,2470],{}," 组合路径片段只创建新的 ",[34,6703,6589],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6706,209],{"id":209},[42,6708,6709,6717],{},[45,6710,3500,6711,6713,6714,6716],{},[34,6712,6589],{}," 对象存在当成真实文件存在，仍需调用 ",[34,6715,6605],{}," 等方法确认。",[45,6718,6719,6720,1043,6722,6725],{},"手工拼接 ",[34,6721,2470],{},[34,6723,6724],{},"\\"," 分隔符，降低跨平台可读性。",[14,6727,220],{"id":220},[163,6729,6730,6737],{},[45,6731,6732,6733,6736],{},"组合 ",[34,6734,6735],{},"output\u002Freport.txt"," 路径但先不创建文件。",[45,6738,6739],{},"输出路径的父目录、文件名和扩展名。",[10,6741,237],{},[14,6743,240],{"id":240},[10,6745,6746],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,6748,247],{},{"title":81,"searchDepth":94,"depth":94,"links":6750},[6751,6752,6753,6754,6755,6756,6757,6758],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6566,"description":6571},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[260,6766,6767],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6770,"title":6771,"body":6772,"category":260,"cover":261,"description":6776,"extension":262,"meta":6954,"navigation":121,"path":6955,"pinned":265,"publishedAt":266,"seo":6956,"slug":6957,"stem":6958,"summary":6959,"tags":6960,"updatedAt":266,"visible":121,"__hash__":6963},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6773,"toc":6944},[6774,6777,6779,6782,6784,6790,6793,6795,6823,6825,6827,6884,6886,6892,6894,6896,6907,6909,6922,6924,6935,6937,6939,6942],[10,6775,6776],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6778,16],{"id":16},[10,6780,6781],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6783,22],{"id":22},[10,6785,6786],{},[26,6787],{"alt":6788,"src":6789},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6791,6792],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6794,40],{"id":40},[42,6796,6797,6803,6812],{},[45,6798,6799,6802],{},[34,6800,6801],{},"w"," 模式会截断原文件，写入前必须确认目标。",[45,6804,6805,6808,6809,396],{},[34,6806,6807],{},"r"," 模式读取不存在文件会产生 ",[34,6810,6811],{},"FileNotFoundError",[45,6813,6814,6815,6818,6819,6822],{},"本篇显式调用 ",[34,6816,6817],{},"close()","；第 34 篇会用 ",[34,6820,6821],{},"with"," 更可靠地管理关闭动作。",[14,6824,71],{"id":71},[10,6826,74],{},[76,6828,6830],{"className":78,"code":6829,"language":80,"meta":81,"style":81},"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,6831,6832,6836,6840,6845,6850,6855,6860,6864,6869,6874,6879],{"__ignoreMap":81},[85,6833,6834],{"class":87,"line":88},[85,6835,6633],{},[85,6837,6838],{"class":87,"line":94},[85,6839,122],{"emptyLinePlaceholder":121},[85,6841,6842],{"class":87,"line":100},[85,6843,6844],{},"file_path = Path(\"notes.txt\")\n",[85,6846,6847],{"class":87,"line":106},[85,6848,6849],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[85,6851,6852],{"class":87,"line":112},[85,6853,6854],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[85,6856,6857],{"class":87,"line":118},[85,6858,6859],{},"writer.close()\n",[85,6861,6862],{"class":87,"line":125},[85,6863,122],{"emptyLinePlaceholder":121},[85,6865,6866],{"class":87,"line":131},[85,6867,6868],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[85,6870,6871],{"class":87,"line":137},[85,6872,6873],{},"content = reader.read()\n",[85,6875,6876],{"class":87,"line":142},[85,6877,6878],{},"reader.close()\n",[85,6880,6881],{"class":87,"line":5859},[85,6882,6883],{},"print(content)\n",[10,6885,147],{},[76,6887,6890],{"className":6888,"code":6889,"language":153,"meta":81},[151],"变量\n循环\n函数\n",[34,6891,6889],{"__ignoreMap":81},[10,6893,158],{},[14,6895,161],{"id":161},[163,6897,6898,6904],{},[45,6899,6900,6901,6903],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[34,6902,6817],{}," 确保缓冲内容交给文件系统。",[45,6905,6906],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6908,209],{"id":209},[42,6910,6911,6916],{},[45,6912,2373,6913,6915],{},[34,6914,6801],{}," 模式打开重要文件却未确认覆盖风险。",[45,6917,6918,6919,396],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[34,6920,6921],{},"encoding=\"utf-8\"",[14,6923,220],{"id":220},[163,6925,6926,6929],{},[45,6927,6928],{},"写入三行学习记录并读取。",[45,6930,6931,6932,6934],{},"改用 ",[34,6933,370],{}," 模式追加一行，确认原内容仍保留。",[10,6936,237],{},[14,6938,240],{"id":240},[10,6940,6941],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,6943,247],{},{"title":81,"searchDepth":94,"depth":94,"links":6945},[6946,6947,6948,6949,6950,6951,6952,6953],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6771,"description":6776},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[260,6961,6962],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6965,"title":6966,"body":6967,"category":260,"cover":261,"description":6971,"extension":262,"meta":7138,"navigation":121,"path":7139,"pinned":265,"publishedAt":266,"seo":7140,"slug":7141,"stem":7142,"summary":7143,"tags":7144,"updatedAt":266,"visible":121,"__hash__":7147},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6968,"toc":7128},[6969,6972,6974,6977,6979,6985,6995,6997,7011,7013,7015,7075,7077,7083,7085,7087,7099,7101,7109,7111,7119,7121,7123,7126],[10,6970,6971],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6973,16],{"id":16},[10,6975,6976],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6978,22],{"id":22},[10,6980,6981],{},[26,6982],{"alt":6983,"src":6984},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,6986,6987,6990,6991,6994],{},[34,6988,6989],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[34,6992,6993],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,6996,40],{"id":40},[42,6998,6999,7002,7008],{},[45,7000,7001],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[45,7003,7004,7007],{},[34,7005,7006],{},"ensure_ascii=False"," 让中文以可读字符写入。",[45,7009,7010],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,7012,71],{"id":71},[10,7014,74],{},[76,7016,7018],{"className":78,"code":7017,"language":80,"meta":81,"style":81},"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,7019,7020,7025,7029,7034,7038,7043,7048,7052,7056,7061,7066,7070],{"__ignoreMap":81},[85,7021,7022],{"class":87,"line":88},[85,7023,7024],{},"import json\n",[85,7026,7027],{"class":87,"line":94},[85,7028,122],{"emptyLinePlaceholder":121},[85,7030,7031],{"class":87,"line":100},[85,7032,7033],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[85,7035,7036],{"class":87,"line":106},[85,7037,122],{"emptyLinePlaceholder":121},[85,7039,7040],{"class":87,"line":112},[85,7041,7042],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[85,7044,7045],{"class":87,"line":118},[85,7046,7047],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[85,7049,7050],{"class":87,"line":125},[85,7051,6859],{},[85,7053,7054],{"class":87,"line":131},[85,7055,122],{"emptyLinePlaceholder":121},[85,7057,7058],{"class":87,"line":137},[85,7059,7060],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[85,7062,7063],{"class":87,"line":142},[85,7064,7065],{},"loaded = json.load(reader)\n",[85,7067,7068],{"class":87,"line":5859},[85,7069,6878],{},[85,7071,7072],{"class":87,"line":5864},[85,7073,7074],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7076,147],{},[76,7078,7081],{"className":7079,"code":7080,"language":153,"meta":81},[151],"Python 60\n",[34,7082,7080],{"__ignoreMap":81},[10,7084,158],{},[14,7086,161],{"id":161},[163,7088,7089,7094],{},[45,7090,7091,7093],{},[34,7092,6989],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[45,7095,7096,7098],{},[34,7097,6993],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7100,209],{"id":209},[42,7102,7103,7106],{},[45,7104,7105],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[45,7107,7108],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7110,220],{"id":220},[163,7112,7113,7116],{},[45,7114,7115],{},"保存包含两条学习记录的列表。",[45,7117,7118],{},"读取后修改进度，再重新写回文件。",[10,7120,237],{},[14,7122,240],{"id":240},[10,7124,7125],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,7127,247],{},{"title":81,"searchDepth":94,"depth":94,"links":7129},[7130,7131,7132,7133,7134,7135,7136,7137],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6966,"description":6971},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[260,7145,7146],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7149,"title":7150,"body":7151,"category":260,"cover":261,"description":7155,"extension":262,"meta":7339,"navigation":121,"path":7340,"pinned":265,"publishedAt":266,"seo":7341,"slug":7342,"stem":7343,"summary":7344,"tags":7345,"updatedAt":266,"visible":121,"__hash__":7348},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7152,"toc":7329},[7153,7156,7158,7161,7163,7169,7175,7177,7199,7201,7203,7266,7268,7274,7276,7278,7294,7296,7310,7312,7320,7322,7324,7327],[10,7154,7155],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7157,16],{"id":16},[10,7159,7160],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7162,22],{"id":22},[10,7164,7165],{},[26,7166],{"alt":7167,"src":7168},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7170,7171,7174],{},[34,7172,7173],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7176,40],{"id":40},[42,7178,7179,7189,7196],{},[45,7180,2373,7181,7184,7185,7188],{},[34,7182,7183],{},"newline=\"\""," 让 ",[34,7186,7187],{},"csv"," 模块正确处理换行。",[45,7190,7191,7192,7195],{},"字段顺序由 ",[34,7193,7194],{},"fieldnames"," 决定，字典键需要与字段名一致。",[45,7197,7198],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7200,71],{"id":71},[10,7202,74],{},[76,7204,7206],{"className":78,"code":7205,"language":80,"meta":81,"style":81},"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,7207,7208,7213,7217,7222,7227,7232,7237,7242,7246,7251,7256,7261],{"__ignoreMap":81},[85,7209,7210],{"class":87,"line":88},[85,7211,7212],{},"import csv\n",[85,7214,7215],{"class":87,"line":94},[85,7216,122],{"emptyLinePlaceholder":121},[85,7218,7219],{"class":87,"line":100},[85,7220,7221],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[85,7223,7224],{"class":87,"line":106},[85,7225,7226],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[85,7228,7229],{"class":87,"line":112},[85,7230,7231],{},"writer.writeheader()\n",[85,7233,7234],{"class":87,"line":118},[85,7235,7236],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[85,7238,7239],{"class":87,"line":125},[85,7240,7241],{},"writer_file.close()\n",[85,7243,7244],{"class":87,"line":131},[85,7245,122],{"emptyLinePlaceholder":121},[85,7247,7248],{"class":87,"line":137},[85,7249,7250],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[85,7252,7253],{"class":87,"line":142},[85,7254,7255],{},"for row in csv.DictReader(reader_file):\n",[85,7257,7258],{"class":87,"line":5859},[85,7259,7260],{},"    print(row[\"name\"], row[\"score\"])\n",[85,7262,7263],{"class":87,"line":5864},[85,7264,7265],{},"reader_file.close()\n",[10,7267,147],{},[76,7269,7272],{"className":7270,"code":7271,"language":153,"meta":81},[151],"小郑 95\n",[34,7273,7271],{"__ignoreMap":81},[10,7275,158],{},[14,7277,161],{"id":161},[163,7279,7280,7289],{},[45,7281,7282,7285,7286,7288],{},[34,7283,7284],{},"DictWriter"," 按 ",[34,7287,7194],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[45,7290,7291,7293],{},[34,7292,7173],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7295,209],{"id":209},[42,7297,7298,7301],{},[45,7299,7300],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[45,7302,7303,7304,7306,7307,7309],{},"在 macOS 以外环境忽略 ",[34,7305,7183],{}," 可能出现额外空行；统一交给 ",[34,7308,7187],{}," 模块管理换行。",[14,7311,220],{"id":220},[163,7313,7314,7317],{},[45,7315,7316],{},"写入三名学习者的课程和分数。",[45,7318,7319],{},"读取 CSV 后把分数字符串转换为整数。",[10,7321,237],{},[14,7323,240],{"id":240},[10,7325,7326],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,7328,247],{},{"title":81,"searchDepth":94,"depth":94,"links":7330},[7331,7332,7333,7334,7335,7336,7337,7338],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7150,"description":7155},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[260,7346,7347],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7350,"title":7351,"body":7352,"category":260,"cover":261,"description":7356,"extension":262,"meta":7629,"navigation":121,"path":7630,"pinned":265,"publishedAt":266,"seo":7631,"slug":7632,"stem":7633,"summary":7634,"tags":7635,"updatedAt":266,"visible":121,"__hash__":7638},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7353,"toc":7616},[7354,7357,7359,7362,7364,7370,7381,7383,7400,7402,7404,7479,7481,7487,7489,7491,7516,7518,7527,7533,7544,7546,7552,7558,7567,7569,7584,7586,7607,7609,7611,7614],[10,7355,7356],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7358,16],{"id":16},[10,7360,7361],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7363,22],{"id":22},[10,7365,7366],{},[26,7367],{"alt":7368,"src":7369},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7371,7372,7373,7376,7377,7380],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[34,7374,7375],{},"except","；无论是否异常，",[34,7378,7379],{},"finally"," 都会在离开结构前执行。",[14,7382,40],{"id":40},[42,7384,7385,7391,7397],{},[45,7386,7387,7388,7390],{},"只捕获能够处理的具体异常，不使用空的 ",[34,7389,7375],{}," 吞掉全部错误。",[45,7392,7393,7396],{},[34,7394,7395],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[45,7398,7399],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7401,71],{"id":71},[10,7403,74],{},[76,7405,7407],{"className":78,"code":7406,"language":80,"meta":81,"style":81},"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",[34,7408,7409,7414,7419,7424,7429,7434,7438,7443,7448,7453,7458,7462,7467,7473],{"__ignoreMap":81},[85,7410,7411],{"class":87,"line":88},[85,7412,7413],{},"def parse_age(text):\n",[85,7415,7416],{"class":87,"line":94},[85,7417,7418],{},"    age = int(text)\n",[85,7420,7421],{"class":87,"line":100},[85,7422,7423],{},"    if age \u003C 0:\n",[85,7425,7426],{"class":87,"line":106},[85,7427,7428],{},"        raise ValueError(\"年龄不能为负数\")\n",[85,7430,7431],{"class":87,"line":112},[85,7432,7433],{},"    return age\n",[85,7435,7436],{"class":87,"line":118},[85,7437,122],{"emptyLinePlaceholder":121},[85,7439,7440],{"class":87,"line":125},[85,7441,7442],{},"try:\n",[85,7444,7445],{"class":87,"line":131},[85,7446,7447],{},"    age = parse_age(\"18\")\n",[85,7449,7450],{"class":87,"line":137},[85,7451,7452],{},"except ValueError as error:\n",[85,7454,7455],{"class":87,"line":142},[85,7456,7457],{},"    print(\"输入错误：\", error)\n",[85,7459,7460],{"class":87,"line":5859},[85,7461,1180],{},[85,7463,7464],{"class":87,"line":5864},[85,7465,7466],{},"    print(\"年龄：\", age)\n",[85,7468,7470],{"class":87,"line":7469},13,[85,7471,7472],{},"finally:\n",[85,7474,7476],{"class":87,"line":7475},14,[85,7477,7478],{},"    print(\"处理结束\")\n",[10,7480,147],{},[76,7482,7485],{"className":7483,"code":7484,"language":153,"meta":81},[151],"年龄： 18\n处理结束\n",[34,7486,7484],{"__ignoreMap":81},[10,7488,158],{},[14,7490,161],{"id":161},[163,7492,7493,7505],{},[45,7494,7495,7497,7498,7500,7501,7504],{},[34,7496,3069],{}," 或主动 ",[34,7499,7395],{}," 都可能产生 ",[34,7502,7503],{},"ValueError","，控制流立即离开当前正常路径。",[45,7506,7507,7508,7510,7511,7513,7514,396],{},"有异常时进入匹配的 ",[34,7509,7375],{},"；没有异常时执行 ",[34,7512,1194],{},"；两种情况最后都会执行 ",[34,7515,7379],{},[186,7517,188],{"id":188},[10,7519,7520,2291,7522,1191,7524,7526],{},[34,7521,7375],{},[34,7523,1194],{},[34,7525,7379],{}," 的职责不同，不能只看它们出现的顺序。",[10,7528,7529],{},[26,7530],{"alt":7531,"src":7532},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7534,7535,7537,7538,7540,7541,7543],{},[34,7536,7375],{}," 处理匹配异常，",[34,7539,1194],{}," 只在无异常时运行，",[34,7542,7379],{}," 负责两条路径都需要的清理动作。",[186,7545,188],{"id":4250},[10,7547,7548,7551],{},[34,7549,7550],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7553,7554],{},[26,7555],{"alt":7556,"src":7557},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7559,7560,7561,7563,7564,7566],{},"只把可能产生预期异常的操作放进 ",[34,7562,7550],{},"，后续正常业务放进 ",[34,7565,1194],{},"，错误边界会更清楚。",[14,7568,209],{"id":209},[42,7570,7571,7578],{},[45,7572,7573,7574,7577],{},"使用裸 ",[34,7575,7576],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[45,7579,7580,7581,7583],{},"把整个程序包在一个巨大 ",[34,7582,7550],{}," 中，无法判断究竟哪一步允许失败。",[14,7585,220],{"id":220},[163,7587,7588,7601],{},[45,7589,7590,7591,7594,7595,1191,7598,396],{},"让 ",[34,7592,7593],{},"parse_age"," 分别处理 ",[34,7596,7597],{},"\"abc\"",[34,7599,7600],{},"\"-1\"",[45,7602,7603,7604,7606],{},"为文件读取捕获 ",[34,7605,6811],{}," 并给出清晰提示。",[10,7608,237],{},[14,7610,240],{"id":240},[10,7612,7613],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,7615,247],{},{"title":81,"searchDepth":94,"depth":94,"links":7617},[7618,7619,7620,7621,7622,7626,7627,7628],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":7623},[7624,7625],{"id":188,"depth":100,"text":188},{"id":4250,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7351,"description":7356},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[260,7636,7637],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7640,"title":7641,"body":7642,"category":260,"cover":261,"description":7646,"extension":262,"meta":7822,"navigation":121,"path":7823,"pinned":265,"publishedAt":266,"seo":7824,"slug":7825,"stem":7826,"summary":7827,"tags":7828,"updatedAt":266,"visible":121,"__hash__":7830},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7643,"toc":7812},[7644,7647,7649,7652,7654,7660,7666,7668,7684,7686,7688,7742,7744,7750,7752,7754,7767,7769,7782,7784,7803,7805,7807,7810],[10,7645,7646],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7648,16],{"id":16},[10,7650,7651],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7653,22],{"id":22},[10,7655,7656],{},[26,7657],{"alt":7658,"src":7659},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7661,7662,7663,7665],{},"进入 ",[34,7664,6821],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7667,40],{"id":40},[42,7669,7670,7675,7681],{},[45,7671,7672,7674],{},[34,7673,6821],{}," 把资源获取和释放配成一个清晰边界。",[45,7676,7677,7680],{},[34,7678,7679],{},"as file"," 得到的是上下文返回的资源对象。",[45,7682,7683],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7685,71],{"id":71},[10,7687,74],{},[76,7689,7691],{"className":78,"code":7690,"language":80,"meta":81,"style":81},"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,7692,7693,7697,7701,7705,7709,7714,7719,7723,7728,7733,7737],{"__ignoreMap":81},[85,7694,7695],{"class":87,"line":88},[85,7696,6633],{},[85,7698,7699],{"class":87,"line":94},[85,7700,122],{"emptyLinePlaceholder":121},[85,7702,7703],{"class":87,"line":100},[85,7704,6844],{},[85,7706,7707],{"class":87,"line":106},[85,7708,122],{"emptyLinePlaceholder":121},[85,7710,7711],{"class":87,"line":112},[85,7712,7713],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[85,7715,7716],{"class":87,"line":118},[85,7717,7718],{},"    file.write(\"上下文管理器\\n\")\n",[85,7720,7721],{"class":87,"line":125},[85,7722,122],{"emptyLinePlaceholder":121},[85,7724,7725],{"class":87,"line":131},[85,7726,7727],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[85,7729,7730],{"class":87,"line":137},[85,7731,7732],{},"    print(file.read())\n",[85,7734,7735],{"class":87,"line":142},[85,7736,122],{"emptyLinePlaceholder":121},[85,7738,7739],{"class":87,"line":5859},[85,7740,7741],{},"print(file.closed)\n",[10,7743,147],{},[76,7745,7748],{"className":7746,"code":7747,"language":153,"meta":81},[151],"上下文管理器\n\nTrue\n",[34,7749,7747],{"__ignoreMap":81},[10,7751,158],{},[14,7753,161],{"id":161},[163,7755,7756,7764],{},[45,7757,7662,7758,7760,7761,396],{},[34,7759,6821],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[34,7762,7763],{},"file",[45,7765,7766],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7768,209],{"id":209},[42,7770,7771,7776],{},[45,7772,4817,7773,7775],{},[34,7774,6821],{}," 代码块外继续读写已经关闭的文件对象。",[45,7777,7778,7779,7781],{},"误以为 ",[34,7780,6821],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7783,220],{"id":220},[163,7785,7786,7795],{},[45,7787,7788,7789,7792,7793,396],{},"把第 30 篇的手动 ",[34,7790,7791],{},"open\u002Fclose"," 改写为 ",[34,7794,6821],{},[45,7796,4817,7797,7799,7800,396],{},[34,7798,6821],{}," 块后检查 ",[34,7801,7802],{},"file.closed",[10,7804,237],{},[14,7806,240],{"id":240},[10,7808,7809],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,7811,247],{},{"title":81,"searchDepth":94,"depth":94,"links":7813},[7814,7815,7816,7817,7818,7819,7820,7821],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7641,"description":7646},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[260,6821,7829],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7832,"title":7833,"body":7834,"category":260,"cover":261,"description":7838,"extension":262,"meta":8049,"navigation":121,"path":8050,"pinned":265,"publishedAt":266,"seo":8051,"slug":8052,"stem":8053,"summary":8054,"tags":8055,"updatedAt":266,"visible":121,"__hash__":8058},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7835,"toc":8037},[7836,7839,7841,7844,7846,7852,7855,7857,7874,7876,7878,7946,7948,7954,7956,7958,7982,7984,7987,7993,8002,8004,8015,8017,8028,8030,8032,8035],[10,7837,7838],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7840,16],{"id":16},[10,7842,7843],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7845,22],{"id":22},[10,7847,7848],{},[26,7849],{"alt":7850,"src":7851},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7853,7854],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7856,40],{"id":40},[42,7858,7859,7865,7871],{},[45,7860,7861,7864],{},[34,7862,7863],{},"self"," 表示当前实例，由方法调用自动传入。",[45,7866,7867,7870],{},[34,7868,7869],{},"__init__"," 在实例创建过程中初始化属性。",[45,7872,7873],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7875,71],{"id":71},[10,7877,74],{},[76,7879,7881],{"className":78,"code":7880,"language":80,"meta":81,"style":81},"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,7882,7883,7888,7893,7898,7903,7907,7912,7917,7922,7927,7931,7936,7941],{"__ignoreMap":81},[85,7884,7885],{"class":87,"line":88},[85,7886,7887],{},"class LearningRecord:\n",[85,7889,7890],{"class":87,"line":94},[85,7891,7892],{},"    def __init__(self, course, progress=0):\n",[85,7894,7895],{"class":87,"line":100},[85,7896,7897],{},"        self.course = course\n",[85,7899,7900],{"class":87,"line":106},[85,7901,7902],{},"        self.progress = progress\n",[85,7904,7905],{"class":87,"line":112},[85,7906,122],{"emptyLinePlaceholder":121},[85,7908,7909],{"class":87,"line":118},[85,7910,7911],{},"    def advance(self, amount):\n",[85,7913,7914],{"class":87,"line":125},[85,7915,7916],{},"        self.progress = self.progress + amount\n",[85,7918,7919],{"class":87,"line":131},[85,7920,7921],{},"        if self.progress > 100:\n",[85,7923,7924],{"class":87,"line":137},[85,7925,7926],{},"            self.progress = 100\n",[85,7928,7929],{"class":87,"line":142},[85,7930,122],{"emptyLinePlaceholder":121},[85,7932,7933],{"class":87,"line":5859},[85,7934,7935],{},"record = LearningRecord(\"Python\", 40)\n",[85,7937,7938],{"class":87,"line":5864},[85,7939,7940],{},"record.advance(15)\n",[85,7942,7943],{"class":87,"line":7469},[85,7944,7945],{},"print(record.course, record.progress)\n",[10,7947,147],{},[76,7949,7952],{"className":7950,"code":7951,"language":153,"meta":81},[151],"Python 55\n",[34,7953,7951],{"__ignoreMap":81},[10,7955,158],{},[14,7957,161],{"id":161},[163,7959,7960,7969],{},[45,7961,167,7962,7965,7966,7968],{},[34,7963,7964],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[34,7967,7869],{}," 把课程和进度保存在该实例属性中。",[45,7970,7971,7974,7975,7978,7979,7981],{},[34,7972,7973],{},"record.advance(15)"," 自动把 ",[34,7976,7977],{},"record"," 作为 ",[34,7980,7863],{},"，方法更新同一实例的进度并限制上限。",[186,7983,188],{"id":188},[10,7985,7986],{},"类是共同定义，实例则各自保存状态。",[10,7988,7989],{},[26,7990],{"alt":7991,"src":7992},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7994,7995,7996,1191,7998,8001],{},"两个实例共享同一套方法定义，但 ",[34,7997,4614],{},[34,7999,8000],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,8003,209],{"id":209},[42,8005,8006,8012],{},[45,8007,8008,8009,8011],{},"调用实例方法时手工再传一次 ",[34,8010,7863],{},"。通过实例调用时 Python 会自动绑定。",[45,8013,8014],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,8016,220],{"id":220},[163,8018,8019,8025],{},[45,8020,5327,8021,8024],{},[34,8022,8023],{},"Book"," 类，保存标题和阅读页数。",[45,8026,8027],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,8029,237],{},[14,8031,240],{"id":240},[10,8033,8034],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,8036,247],{},{"title":81,"searchDepth":94,"depth":94,"links":8038},[8039,8040,8041,8042,8043,8046,8047,8048],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":8044},[8045],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7833,"description":7838},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[260,8056,8057],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":8060,"title":8061,"body":8062,"category":260,"cover":261,"description":8066,"extension":262,"meta":8244,"navigation":121,"path":8245,"pinned":265,"publishedAt":266,"seo":8246,"slug":8247,"stem":8248,"summary":8249,"tags":8250,"updatedAt":266,"visible":121,"__hash__":8253},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8063,"toc":8234},[8064,8067,8069,8072,8074,8080,8083,8085,8096,8098,8100,8167,8169,8175,8177,8179,8198,8200,8208,8210,8225,8227,8229,8232],[10,8065,8066],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,8068,16],{"id":16},[10,8070,8071],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8073,22],{"id":22},[10,8075,8076],{},[26,8077],{"alt":8078,"src":8079},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8081,8082],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8084,40],{"id":40},[42,8086,8087,8090,8093],{},[45,8088,8089],{},"封装让对象通过方法维护自己的有效状态。",[45,8091,8092],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[45,8094,8095],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8097,71],{"id":71},[10,8099,74],{},[76,8101,8103],{"className":78,"code":8102,"language":80,"meta":81,"style":81},"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,8104,8105,8110,8115,8120,8124,8129,8134,8139,8143,8148,8153,8157,8162],{"__ignoreMap":81},[85,8106,8107],{"class":87,"line":88},[85,8108,8109],{},"class Storage:\n",[85,8111,8112],{"class":87,"line":94},[85,8113,8114],{},"    def save(self, text):\n",[85,8116,8117],{"class":87,"line":100},[85,8118,8119],{},"        print(\"保存：\", text)\n",[85,8121,8122],{"class":87,"line":106},[85,8123,122],{"emptyLinePlaceholder":121},[85,8125,8126],{"class":87,"line":112},[85,8127,8128],{},"class LearningService:\n",[85,8130,8131],{"class":87,"line":118},[85,8132,8133],{},"    def __init__(self, storage):\n",[85,8135,8136],{"class":87,"line":125},[85,8137,8138],{},"        self.storage = storage\n",[85,8140,8141],{"class":87,"line":131},[85,8142,122],{"emptyLinePlaceholder":121},[85,8144,8145],{"class":87,"line":137},[85,8146,8147],{},"    def finish_lesson(self, title):\n",[85,8149,8150],{"class":87,"line":142},[85,8151,8152],{},"        self.storage.save(title)\n",[85,8154,8155],{"class":87,"line":5859},[85,8156,122],{"emptyLinePlaceholder":121},[85,8158,8159],{"class":87,"line":5864},[85,8160,8161],{},"service = LearningService(Storage())\n",[85,8163,8164],{"class":87,"line":7469},[85,8165,8166],{},"service.finish_lesson(\"异常处理\")\n",[10,8168,147],{},[76,8170,8173],{"className":8171,"code":8172,"language":153,"meta":81},[151],"保存： 异常处理\n",[34,8174,8172],{"__ignoreMap":81},[10,8176,158],{},[14,8178,161],{"id":161},[163,8180,8181,8191],{},[45,8182,8183,8186,8187,8190],{},[34,8184,8185],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[34,8188,8189],{},"save()"," 的协作对象。",[45,8192,8193,8194,8197],{},"调用业务方法时，服务把保存动作委托给 ",[34,8195,8196],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8199,209],{"id":209},[42,8201,8202,8205],{},[45,8203,8204],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[45,8206,8207],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8209,220],{"id":220},[163,8211,8212,8222],{},[45,8213,8214,8215,8218,8219,396],{},"用组合让 ",[34,8216,8217],{},"OrderService"," 使用一个 ",[34,8220,8221],{},"Notifier",[45,8223,8224],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8226,237],{},[14,8228,240],{"id":240},[10,8230,8231],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,8233,247],{},{"title":81,"searchDepth":94,"depth":94,"links":8235},[8236,8237,8238,8239,8240,8241,8242,8243],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":8061,"description":8066},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[260,8251,8252],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":4,"title":5,"body":8255,"category":260,"cover":261,"description":12,"extension":262,"meta":8418,"navigation":121,"path":264,"pinned":265,"publishedAt":266,"seo":8419,"slug":268,"stem":269,"summary":270,"tags":8420,"updatedAt":266,"visible":121,"__hash__":274},{"type":7,"value":8256,"toc":8406},[8257,8259,8261,8263,8265,8269,8273,8275,8291,8293,8295,8339,8341,8346,8348,8350,8364,8366,8370,8374,8378,8380,8386,8388,8398,8400,8402,8404],[10,8258,12],{},[14,8260,16],{"id":16},[10,8262,19],{},[14,8264,22],{"id":22},[10,8266,8267],{},[26,8268],{"alt":28,"src":29},[10,8270,32,8271,37],{},[34,8272,36],{},[14,8274,40],{"id":40},[42,8276,8277,8283,8289],{},[45,8278,8279,50,8281,54],{},[34,8280,49],{},[34,8282,53],{},[45,8284,57,8285,61,8287,65],{},[34,8286,60],{},[34,8288,64],{},[45,8290,68],{},[14,8292,71],{"id":71},[10,8294,74],{},[76,8296,8297],{"className":78,"code":79,"language":80,"meta":81,"style":81},[34,8298,8299,8303,8307,8311,8315,8319,8323,8327,8331,8335],{"__ignoreMap":81},[85,8300,8301],{"class":87,"line":88},[85,8302,91],{},[85,8304,8305],{"class":87,"line":94},[85,8306,97],{},[85,8308,8309],{"class":87,"line":100},[85,8310,103],{},[85,8312,8313],{"class":87,"line":106},[85,8314,109],{},[85,8316,8317],{"class":87,"line":112},[85,8318,115],{},[85,8320,8321],{"class":87,"line":118},[85,8322,122],{"emptyLinePlaceholder":121},[85,8324,8325],{"class":87,"line":125},[85,8326,128],{},[85,8328,8329],{"class":87,"line":131},[85,8330,134],{},[85,8332,8333],{"class":87,"line":137},[85,8334,134],{},[85,8336,8337],{"class":87,"line":142},[85,8338,134],{},[10,8340,147],{},[76,8342,8344],{"className":8343,"code":152,"language":153,"meta":81},[151],[34,8345,152],{"__ignoreMap":81},[10,8347,158],{},[14,8349,161],{"id":161},[163,8351,8352,8356],{},[45,8353,167,8354,171],{},[34,8355,170],{},[45,8357,174,8358,177,8360,180,8362,184],{},[34,8359,53],{},[34,8361,36],{},[34,8363,183],{},[186,8365,188],{"id":188},[10,8367,191,8368,194],{},[34,8369,53],{},[10,8371,8372],{},[26,8373],{"alt":199,"src":200},[10,8375,203,8376,206],{},[34,8377,36],{},[14,8379,209],{"id":209},[42,8381,8382,8384],{},[45,8383,214],{},[45,8385,217],{},[14,8387,220],{"id":220},[163,8389,8390,8392],{},[45,8391,225],{},[45,8393,228,8394,231,8396,234],{},[34,8395,64],{},[34,8397,53],{},[10,8399,237],{},[14,8401,240],{"id":240},[10,8403,243],{},[245,8405,247],{},{"title":81,"searchDepth":94,"depth":94,"links":8407},[8408,8409,8410,8411,8412,8415,8416,8417],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":8413},[8414],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5,"description":12},[260,272,273],{"id":8422,"title":8423,"body":8424,"category":260,"cover":261,"description":8428,"extension":262,"meta":8652,"navigation":121,"path":8653,"pinned":265,"publishedAt":266,"seo":8654,"slug":8655,"stem":8656,"summary":8657,"tags":8658,"updatedAt":266,"visible":121,"__hash__":8660},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8425,"toc":8640},[8426,8429,8431,8434,8436,8442,8445,8447,8467,8469,8471,8553,8555,8561,8563,8565,8587,8589,8592,8598,8605,8607,8617,8619,8631,8633,8635,8638],[10,8427,8428],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8430,16],{"id":16},[10,8432,8433],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8435,22],{"id":22},[10,8437,8438],{},[26,8439],{"alt":8440,"src":8441},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8443,8444],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8446,40],{"id":40},[42,8448,8449,8458,8461],{},[45,8450,8451,8454,8455,396],{},[34,8452,8453],{},"@trace"," 等价于 ",[34,8456,8457],{},"add = trace(add)",[45,8459,8460],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[45,8462,8463,8466],{},[34,8464,8465],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8468,71],{"id":71},[10,8470,74],{},[76,8472,8474],{"className":78,"code":8473,"language":80,"meta":81,"style":81},"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,8475,8476,8481,8485,8490,8495,8500,8505,8510,8515,8520,8525,8529,8534,8538,8542,8547],{"__ignoreMap":81},[85,8477,8478],{"class":87,"line":88},[85,8479,8480],{},"from functools import wraps\n",[85,8482,8483],{"class":87,"line":94},[85,8484,122],{"emptyLinePlaceholder":121},[85,8486,8487],{"class":87,"line":100},[85,8488,8489],{},"def trace(function):\n",[85,8491,8492],{"class":87,"line":106},[85,8493,8494],{},"    @wraps(function)\n",[85,8496,8497],{"class":87,"line":112},[85,8498,8499],{},"    def wrapper(*args, **kwargs):\n",[85,8501,8502],{"class":87,"line":118},[85,8503,8504],{},"        print(\"开始：\", function.__name__)\n",[85,8506,8507],{"class":87,"line":125},[85,8508,8509],{},"        result = function(*args, **kwargs)\n",[85,8511,8512],{"class":87,"line":131},[85,8513,8514],{},"        print(\"结束：\", function.__name__)\n",[85,8516,8517],{"class":87,"line":137},[85,8518,8519],{},"        return result\n",[85,8521,8522],{"class":87,"line":142},[85,8523,8524],{},"    return wrapper\n",[85,8526,8527],{"class":87,"line":5859},[85,8528,122],{"emptyLinePlaceholder":121},[85,8530,8531],{"class":87,"line":5864},[85,8532,8533],{},"@trace\n",[85,8535,8536],{"class":87,"line":7469},[85,8537,6212],{},[85,8539,8540],{"class":87,"line":7475},[85,8541,6217],{},[85,8543,8545],{"class":87,"line":8544},15,[85,8546,122],{"emptyLinePlaceholder":121},[85,8548,8550],{"class":87,"line":8549},16,[85,8551,8552],{},"print(add(2, 3))\n",[10,8554,147],{},[76,8556,8559],{"className":8557,"code":8558,"language":153,"meta":81},[151],"开始： add\n结束： add\n5\n",[34,8560,8558],{"__ignoreMap":81},[10,8562,158],{},[14,8564,161],{"id":161},[163,8566,8567,8584],{},[45,8568,8569,8570,8573,8574,8577,8578,8581,8582,396],{},"解释器执行定义时，把原 ",[34,8571,8572],{},"add"," 函数交给 ",[34,8575,8576],{},"trace","，返回的 ",[34,8579,8580],{},"wrapper"," 重新绑定到名字 ",[34,8583,8572],{},[45,8585,8586],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[186,8588,188],{"id":188},[10,8590,8591],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8593,8594],{},[26,8595],{"alt":8596,"src":8597},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8599,8600,8602,8603,396],{},[34,8601,8453],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[34,8604,8457],{},[14,8606,209],{"id":209},[42,8608,8609,8614],{},[45,8610,8611,8612,396],{},"包装函数忘记返回原函数结果，调用方得到 ",[34,8613,5410],{},[45,8615,8616],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8618,220],{"id":220},[163,8620,8621,8624],{},[45,8622,8623],{},"编写只记录调用次数的简单装饰器。",[45,8625,8626,8627,8630],{},"删除包装函数的 ",[34,8628,8629],{},"return result","，观察调用方得到什么。",[10,8632,237],{},[14,8634,240],{"id":240},[10,8636,8637],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,8639,247],{},{"title":81,"searchDepth":94,"depth":94,"links":8641},[8642,8643,8644,8645,8646,8649,8650,8651],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":8647},[8648],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8423,"description":8428},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[260,8659,5361],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8662,"title":8663,"body":8664,"category":260,"cover":261,"description":8668,"extension":262,"meta":8855,"navigation":121,"path":8856,"pinned":265,"publishedAt":266,"seo":8857,"slug":8858,"stem":8859,"summary":8860,"tags":8861,"updatedAt":266,"visible":121,"__hash__":8864},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8665,"toc":8843},[8666,8669,8671,8674,8676,8682,8685,8687,8698,8700,8702,8777,8779,8785,8787,8789,8800,8802,8805,8811,8814,8816,8824,8826,8834,8836,8838,8841],[10,8667,8668],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8670,16],{"id":16},[10,8672,8673],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8675,22],{"id":22},[10,8677,8678],{},[26,8679],{"alt":8680,"src":8681},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8683,8684],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8686,40],{"id":40},[42,8688,8689,8692,8695],{},[45,8690,8691],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[45,8693,8694],{},"日志记录运行状态，测试判断结果是否符合约定。",[45,8696,8697],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8699,71],{"id":71},[10,8701,74],{},[76,8703,8705],{"className":78,"code":8704,"language":80,"meta":81,"style":81},"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,8706,8707,8712,8717,8721,8726,8730,8735,8740,8745,8749,8754,8759,8764,8768,8772],{"__ignoreMap":81},[85,8708,8709],{"class":87,"line":88},[85,8710,8711],{},"import logging\n",[85,8713,8714],{"class":87,"line":94},[85,8715,8716],{},"import unittest\n",[85,8718,8719],{"class":87,"line":100},[85,8720,122],{"emptyLinePlaceholder":121},[85,8722,8723],{"class":87,"line":106},[85,8724,8725],{},"logging.basicConfig(level=logging.INFO)\n",[85,8727,8728],{"class":87,"line":112},[85,8729,122],{"emptyLinePlaceholder":121},[85,8731,8732],{"class":87,"line":118},[85,8733,8734],{},"def clamp_progress(value):\n",[85,8736,8737],{"class":87,"line":125},[85,8738,8739],{},"    logging.info(\"检查进度：%s\", value)\n",[85,8741,8742],{"class":87,"line":131},[85,8743,8744],{},"    return max(0, min(100, value))\n",[85,8746,8747],{"class":87,"line":137},[85,8748,122],{"emptyLinePlaceholder":121},[85,8750,8751],{"class":87,"line":142},[85,8752,8753],{},"class ProgressTest(unittest.TestCase):\n",[85,8755,8756],{"class":87,"line":5859},[85,8757,8758],{},"    def test_upper_limit(self):\n",[85,8760,8761],{"class":87,"line":5864},[85,8762,8763],{},"        self.assertEqual(clamp_progress(120), 100)\n",[85,8765,8766],{"class":87,"line":7469},[85,8767,122],{"emptyLinePlaceholder":121},[85,8769,8770],{"class":87,"line":7475},[85,8771,6226],{},[85,8773,8774],{"class":87,"line":8544},[85,8775,8776],{},"    unittest.main()\n",[10,8778,147],{},[76,8780,8783],{"className":8781,"code":8782,"language":153,"meta":81},[151],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[34,8784,8782],{"__ignoreMap":81},[10,8786,158],{},[14,8788,161],{"id":161},[163,8790,8791,8797],{},[45,8792,8793,8796],{},[34,8794,8795],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[45,8798,8799],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[186,8801,188],{"id":188},[10,8803,8804],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8806,8807],{},[26,8808],{"alt":8809,"src":8810},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8812,8813],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8815,209],{"id":209},[42,8817,8818,8821],{},[45,8819,8820],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[45,8822,8823],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8825,220],{"id":220},[163,8827,8828,8831],{},[45,8829,8830],{},"为负数进度增加测试。",[45,8832,8833],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8835,237],{},[14,8837,240],{"id":240},[10,8839,8840],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,8842,247],{},{"title":81,"searchDepth":94,"depth":94,"links":8844},[8845,8846,8847,8848,8849,8852,8853,8854],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":8850},[8851],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8663,"description":8668},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[260,8862,8863],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8866,"title":8867,"body":8868,"category":260,"cover":261,"description":8872,"extension":262,"meta":9172,"navigation":121,"path":9173,"pinned":265,"publishedAt":266,"seo":9174,"slug":9175,"stem":9176,"summary":9177,"tags":9178,"updatedAt":266,"visible":121,"__hash__":9181},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8869,"toc":9159},[8870,8873,8875,8878,8880,8886,8889,8891,8906,8908,8910,9057,9059,9065,9067,9069,9082,9084,9087,9093,9096,9098,9101,9107,9114,9116,9127,9129,9150,9152,9154,9157],[10,8871,8872],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8874,16],{"id":16},[10,8876,8877],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8879,22],{"id":22},[10,8881,8882],{},[26,8883],{"alt":8884,"src":8885},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8887,8888],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8890,40],{"id":40},[42,8892,8893,8896,8899],{},[45,8894,8895],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[45,8897,8898],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[45,8900,8901,8902,8905],{},"实际扩展前先为 ",[34,8903,8904],{},"add()"," 和存储边界补充测试。",[14,8907,71],{"id":71},[10,8909,74],{},[76,8911,8913],{"className":78,"code":8912,"language":80,"meta":81,"style":81},"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,8914,8915,8919,8923,8927,8932,8937,8942,8947,8951,8956,8961,8966,8971,8976,8980,8985,8990,8996,9001,9007,9012,9017,9023,9029,9035,9040,9046,9051],{"__ignoreMap":81},[85,8916,8917],{"class":87,"line":88},[85,8918,7024],{},[85,8920,8921],{"class":87,"line":94},[85,8922,6633],{},[85,8924,8925],{"class":87,"line":100},[85,8926,122],{"emptyLinePlaceholder":121},[85,8928,8929],{"class":87,"line":106},[85,8930,8931],{},"class LearningRecords:\n",[85,8933,8934],{"class":87,"line":112},[85,8935,8936],{},"    def __init__(self, file_path):\n",[85,8938,8939],{"class":87,"line":118},[85,8940,8941],{},"        self.file_path = Path(file_path)\n",[85,8943,8944],{"class":87,"line":125},[85,8945,8946],{},"        self.items = []\n",[85,8948,8949],{"class":87,"line":131},[85,8950,122],{"emptyLinePlaceholder":121},[85,8952,8953],{"class":87,"line":137},[85,8954,8955],{},"    def add(self, title):\n",[85,8957,8958],{"class":87,"line":142},[85,8959,8960],{},"        title = title.strip()\n",[85,8962,8963],{"class":87,"line":5859},[85,8964,8965],{},"        if not title:\n",[85,8967,8968],{"class":87,"line":5864},[85,8969,8970],{},"            raise ValueError(\"课程名称不能为空\")\n",[85,8972,8973],{"class":87,"line":7469},[85,8974,8975],{},"        self.items.append({\"title\": title, \"done\": False})\n",[85,8977,8978],{"class":87,"line":7475},[85,8979,122],{"emptyLinePlaceholder":121},[85,8981,8982],{"class":87,"line":8544},[85,8983,8984],{},"    def save(self):\n",[85,8986,8987],{"class":87,"line":8549},[85,8988,8989],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[85,8991,8993],{"class":87,"line":8992},17,[85,8994,8995],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[85,8997,8999],{"class":87,"line":8998},18,[85,9000,122],{"emptyLinePlaceholder":121},[85,9002,9004],{"class":87,"line":9003},19,[85,9005,9006],{},"records = LearningRecords(\"learning-records.json\")\n",[85,9008,9010],{"class":87,"line":9009},20,[85,9011,122],{"emptyLinePlaceholder":121},[85,9013,9015],{"class":87,"line":9014},21,[85,9016,7442],{},[85,9018,9020],{"class":87,"line":9019},22,[85,9021,9022],{},"    title = input(\"输入已学习课程：\")\n",[85,9024,9026],{"class":87,"line":9025},23,[85,9027,9028],{},"    records.add(title)\n",[85,9030,9032],{"class":87,"line":9031},24,[85,9033,9034],{},"    records.save()\n",[85,9036,9038],{"class":87,"line":9037},25,[85,9039,7452],{},[85,9041,9043],{"class":87,"line":9042},26,[85,9044,9045],{},"    print(\"无法保存：\", error)\n",[85,9047,9049],{"class":87,"line":9048},27,[85,9050,1180],{},[85,9052,9054],{"class":87,"line":9053},28,[85,9055,9056],{},"    print(\"已保存 1 条学习记录\")\n",[10,9058,147],{},[76,9060,9063],{"className":9061,"code":9062,"language":153,"meta":81},[151],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[34,9064,9062],{"__ignoreMap":81},[10,9066,158],{},[14,9068,161],{"id":161},[163,9070,9071,9077],{},[45,9072,9073,9074,9076],{},"输入层取得课程名后，",[34,9075,8904],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[45,9078,9079,9081],{},[34,9080,8189],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[186,9083,188],{"id":188},[10,9085,9086],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9088,9089],{},[26,9090],{"alt":9091,"src":9092},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9094,9095],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[186,9097,188],{"id":4250},[10,9099,9100],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9102,9103],{},[26,9104],{"alt":9105,"src":9106},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9108,9109,9110,9113],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[34,9111,9112],{},"load()"," 把文件状态恢复到内存。",[14,9115,209],{"id":209},[42,9117,9118,9121],{},[45,9119,9120],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[45,9122,9123,9124,9126],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[34,9125,9112],{}," 是下一项必要扩展。",[14,9128,220],{"id":220},[163,9130,9131,9137,9140],{},[45,9132,9133,9134,9136],{},"增加 ",[34,9135,9112],{},"，文件不存在时从空列表开始。",[45,9138,9139],{},"增加按序号标记完成的功能，并校验序号范围。",[45,9141,9142,9143,9146,9147,9149],{},"把输入循环放进 ",[34,9144,9145],{},"main()","，通过 ",[34,9148,6168],{}," 控制程序入口。",[10,9151,237],{},[14,9153,240],{"id":240},[10,9155,9156],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[245,9158,247],{},{"title":81,"searchDepth":94,"depth":94,"links":9160},[9161,9162,9163,9164,9165,9169,9170,9171],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":9166},[9167,9168],{"id":188,"depth":100,"text":188},{"id":4250,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8867,"description":8872},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[260,9179,9180],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9183,9286,9405,9536,9679,9804,9941,10078,10219,10388,10525,10658,10781,10910,11037,11200,11376,11517,11646,11795,11938,12059,12182,12331,12484,12649,12776,12957,13100,13257,13408,13555,13710,13928,14083,14258,14409,14576,14763,14926,15168,15408],{"id":1427,"title":1428,"body":9184,"category":260,"cover":261,"description":1433,"extension":262,"meta":9283,"navigation":121,"path":1552,"pinned":265,"publishedAt":266,"seo":9284,"slug":1554,"stem":1555,"summary":1556,"tags":9285,"updatedAt":266,"visible":121,"__hash__":1559},{"type":7,"value":9185,"toc":9273},[9186,9188,9190,9192,9194,9198,9202,9204,9214,9216,9218,9226,9228,9233,9235,9237,9247,9249,9257,9259,9265,9267,9269,9271],[10,9187,1433],{},[14,9189,16],{"id":16},[10,9191,1438],{},[14,9193,22],{"id":22},[10,9195,9196],{},[26,9197],{"alt":1445,"src":1446},[10,9199,9200,1451],{},[34,9201,1205],{},[14,9203,40],{"id":40},[42,9205,9206,9210,9212],{},[45,9207,1458,9208,1461],{},[34,9209,1205],{},[45,9211,1464],{},[45,9213,1467],{},[14,9215,71],{"id":71},[10,9217,74],{},[76,9219,9220],{"className":78,"code":1474,"language":80,"meta":81,"style":81},[34,9221,9222],{"__ignoreMap":81},[85,9223,9224],{"class":87,"line":88},[85,9225,1474],{},[10,9227,147],{},[76,9229,9231],{"className":9230,"code":1486,"language":153,"meta":81},[151],[34,9232,1486],{"__ignoreMap":81},[10,9234,158],{},[14,9236,161],{"id":161},[163,9238,9239,9243],{},[45,9240,1497,9241,1501],{},[34,9242,1500],{},[45,9244,1504,9245,1508],{},[34,9246,1507],{},[14,9248,209],{"id":209},[42,9250,9251,9253],{},[45,9252,1515],{},[45,9254,1518,9255,1521],{},[34,9256,1205],{},[14,9258,220],{"id":220},[163,9260,9261,9263],{},[45,9262,1528],{},[45,9264,1531],{},[10,9266,237],{},[14,9268,240],{"id":240},[10,9270,1538],{},[245,9272,247],{},{"title":81,"searchDepth":94,"depth":94,"links":9274},[9275,9276,9277,9278,9279,9280,9281,9282],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":1428,"description":1433},[260,1423,1558],{"id":1561,"title":1562,"body":9287,"category":260,"cover":261,"description":1567,"extension":262,"meta":9402,"navigation":121,"path":1704,"pinned":265,"publishedAt":266,"seo":9403,"slug":1706,"stem":1707,"summary":1708,"tags":9404,"updatedAt":266,"visible":121,"__hash__":1711},{"type":7,"value":9288,"toc":9392},[9289,9291,9293,9295,9297,9301,9305,9307,9317,9319,9321,9341,9343,9348,9350,9352,9362,9364,9374,9376,9384,9386,9388,9390],[10,9290,1567],{},[14,9292,16],{"id":16},[10,9294,1572],{},[14,9296,22],{"id":22},[10,9298,9299],{},[26,9300],{"alt":1579,"src":1580},[10,9302,1583,9303,1586],{},[34,9304,725],{},[14,9306,40],{"id":40},[42,9308,9309,9311,9313],{},[45,9310,1593],{},[45,9312,1596],{},[45,9314,1599,9315,1603],{},[34,9316,1602],{},[14,9318,71],{"id":71},[10,9320,1608],{},[76,9322,9323],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,9324,9325,9331],{"__ignoreMap":81},[85,9326,9327,9329],{"class":87,"line":88},[85,9328,725],{"class":634},[85,9330,638],{"class":637},[85,9332,9333,9335,9337,9339],{"class":87,"line":94},[85,9334,725],{"class":634},[85,9336,667],{"class":637},[85,9338,671],{"class":670},[85,9340,638],{"class":637},[10,9342,147],{},[76,9344,9346],{"className":9345,"code":1634,"language":153,"meta":81},[151],[34,9347,1634],{"__ignoreMap":81},[10,9349,158],{},[14,9351,161],{"id":161},[163,9353,9354,9358],{},[45,9355,9356,1648],{},[34,9357,1647],{},[45,9359,9360,1653],{},[34,9361,733],{},[14,9363,209],{"id":209},[42,9365,9366,9370],{},[45,9367,1660,9368,1663],{},[34,9369,725],{},[45,9371,1666,9372,1669],{},[34,9373,725],{},[14,9375,220],{"id":220},[163,9377,9378,9382],{},[45,9379,972,9380,1679],{},[34,9381,1678],{},[45,9383,1682],{},[10,9385,237],{},[14,9387,240],{"id":240},[10,9389,1689],{},[245,9391,1692],{},{"title":81,"searchDepth":94,"depth":94,"links":9393},[9394,9395,9396,9397,9398,9399,9400,9401],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":1562,"description":1567},[260,1710,1086],{"id":1713,"title":1714,"body":9406,"category":260,"cover":261,"description":1880,"extension":262,"meta":9533,"navigation":121,"path":1882,"pinned":265,"publishedAt":266,"seo":9534,"slug":1884,"stem":1885,"summary":1886,"tags":9535,"updatedAt":266,"visible":121,"__hash__":1890},{"type":7,"value":9407,"toc":9523},[9408,9412,9414,9416,9418,9422,9424,9426,9442,9444,9446,9466,9468,9473,9475,9477,9489,9491,9501,9503,9513,9515,9517,9521],[10,9409,1719,9410,1722],{},[34,9411,1205],{},[14,9413,16],{"id":16},[10,9415,1727],{},[14,9417,22],{"id":22},[10,9419,9420],{},[26,9421],{"alt":1734,"src":1735},[10,9423,1738],{},[14,9425,40],{"id":40},[42,9427,9428,9434,9438],{},[45,9429,1745,9430,1748,9432,396],{},[34,9431,725],{},[34,9433,1751],{},[45,9435,1754,9436,1758],{},[34,9437,1757],{},[45,9439,1761,9440,1764],{},[34,9441,1205],{},[14,9443,71],{"id":71},[10,9445,74],{},[76,9447,9448],{"className":1771,"code":1772,"language":1773,"meta":81,"style":81},[34,9449,9450,9454,9458,9462],{"__ignoreMap":81},[85,9451,9452],{"class":87,"line":88},[85,9453,1780],{},[85,9455,9456],{"class":87,"line":94},[85,9457,1785],{},[85,9459,9460],{"class":87,"line":100},[85,9461,1790],{},[85,9463,9464],{"class":87,"line":106},[85,9465,1795],{},[10,9467,147],{},[76,9469,9471],{"className":9470,"code":1801,"language":153,"meta":81},[151],[34,9472,1801],{"__ignoreMap":81},[10,9474,158],{},[14,9476,161],{"id":161},[163,9478,9479,9485],{},[45,9480,1812,9481,1816,9483,396],{},[34,9482,1815],{},[34,9484,1819],{},[45,9486,1822,9487,1825],{},[34,9488,1507],{},[14,9490,209],{"id":209},[42,9492,9493,9499],{},[45,9494,1832,9495,1835,9497,1838],{},[34,9496,1751],{},[34,9498,1205],{},[45,9500,1841],{},[14,9502,220],{"id":220},[163,9504,9505,9509],{},[45,9506,1848,9507,396],{},[34,9508,1851],{},[45,9510,1854,9511,1857],{},[34,9512,1507],{},[10,9514,237],{},[14,9516,240],{"id":240},[10,9518,1864,9519,1867],{},[34,9520,1205],{},[245,9522,247],{},{"title":81,"searchDepth":94,"depth":94,"links":9524},[9525,9526,9527,9528,9529,9530,9531,9532],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":1714,"description":1880},[260,1888,1889],{"id":1892,"title":1893,"body":9537,"category":260,"cover":261,"description":1898,"extension":262,"meta":9676,"navigation":121,"path":2070,"pinned":265,"publishedAt":266,"seo":9677,"slug":2072,"stem":2073,"summary":2074,"tags":9678,"updatedAt":266,"visible":121,"__hash__":2078},{"type":7,"value":9538,"toc":9666},[9539,9541,9543,9545,9547,9551,9555,9557,9569,9571,9573,9609,9611,9616,9618,9620,9636,9638,9648,9650,9658,9660,9662,9664],[10,9540,1898],{},[14,9542,16],{"id":16},[10,9544,1903],{},[14,9546,22],{"id":22},[10,9548,9549],{},[26,9550],{"alt":1910,"src":1911},[10,9552,9553,1917],{},[34,9554,1916],{},[14,9556,40],{"id":40},[42,9558,9559,9561,9567],{},[45,9560,1924],{},[45,9562,9563,1930,9565,1934],{},[34,9564,1929],{},[34,9566,1933],{},[45,9568,1937],{},[14,9570,71],{"id":71},[10,9572,1608],{},[76,9574,9575],{"className":625,"code":1944,"language":627,"meta":81,"style":81},[34,9576,9577,9583,9589,9593,9603],{"__ignoreMap":81},[85,9578,9579,9581],{"class":87,"line":88},[85,9580,1951],{"class":634},[85,9582,1954],{"class":670},[85,9584,9585,9587],{"class":87,"line":94},[85,9586,1959],{"class":637},[85,9588,1954],{"class":670},[85,9590,9591],{"class":87,"line":100},[85,9592,1966],{"class":637},[85,9594,9595,9597,9599,9601],{"class":87,"line":106},[85,9596,1971],{"class":637},[85,9598,1974],{"class":670},[85,9600,1978],{"class":1977},[85,9602,1249],{"class":670},[85,9604,9605,9607],{"class":87,"line":112},[85,9606,725],{"class":634},[85,9608,1249],{"class":670},[10,9610,147],{},[76,9612,9614],{"className":9613,"code":1992,"language":153,"meta":81},[151],[34,9615,1992],{"__ignoreMap":81},[10,9617,158],{},[14,9619,161],{"id":161},[163,9621,9622,9630],{},[45,9623,9624,2005,9626,2008,9628,2011],{},[34,9625,1951],{},[34,9627,1959],{},[34,9629,1929],{},[45,9631,9632,2016,9634,2020],{},[34,9633,1916],{},[34,9635,2019],{},[14,9637,209],{"id":209},[42,9639,9640,9646],{},[45,9641,2027,9642,1191,9644,396],{},[34,9643,1929],{},[34,9645,1933],{},[45,9647,2034],{},[14,9649,220],{"id":220},[163,9651,9652,9656],{},[45,9653,2041,9654,2045],{},[34,9655,2044],{},[45,9657,2048],{},[10,9659,237],{},[14,9661,240],{"id":240},[10,9663,2055],{},[245,9665,2058],{},{"title":81,"searchDepth":94,"depth":94,"links":9667},[9668,9669,9670,9671,9672,9673,9674,9675],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":1893,"description":1898},[260,2076,2077],{"id":2080,"title":2081,"body":9680,"category":260,"cover":261,"description":2086,"extension":262,"meta":9801,"navigation":121,"path":2235,"pinned":265,"publishedAt":266,"seo":9802,"slug":2237,"stem":2238,"summary":2239,"tags":9803,"updatedAt":266,"visible":121,"__hash__":2243},{"type":7,"value":9681,"toc":9791},[9682,9684,9686,9688,9690,9694,9702,9704,9718,9720,9722,9738,9740,9745,9747,9749,9763,9765,9771,9773,9783,9785,9787,9789],[10,9683,2086],{},[14,9685,16],{"id":16},[10,9687,2091],{},[14,9689,22],{"id":22},[10,9691,9692],{},[26,9693],{"alt":2098,"src":2099},[10,9695,2102,9696,396,9698,2108,9700,396],{},[34,9697,1507],{},[34,9699,2107],{},[34,9701,1815],{},[14,9703,40],{"id":40},[42,9705,9706,9710,9716],{},[45,9707,9708,2120],{},[34,9709,2119],{},[45,9711,9712,2126,9714,396],{},[34,9713,2125],{},[34,9715,2129],{},[45,9717,2132],{},[14,9719,71],{"id":71},[10,9721,74],{},[76,9723,9724],{"className":78,"code":2139,"language":80,"meta":81,"style":81},[34,9725,9726,9730,9734],{"__ignoreMap":81},[85,9727,9728],{"class":87,"line":88},[85,9729,2146],{},[85,9731,9732],{"class":87,"line":94},[85,9733,2151],{},[85,9735,9736],{"class":87,"line":100},[85,9737,2156],{},[10,9739,147],{},[76,9741,9743],{"className":9742,"code":2162,"language":153,"meta":81},[151],[34,9744,2162],{"__ignoreMap":81},[10,9746,158],{},[14,9748,161],{"id":161},[163,9750,9751,9757],{},[45,9752,9753,2176,9755,396],{},[34,9754,2175],{},[34,9756,2129],{},[45,9758,9759,2183,9761,2187],{},[34,9760,1507],{},[34,9762,2186],{},[14,9764,209],{"id":209},[42,9766,9767,9769],{},[45,9768,2194],{},[45,9770,2197],{},[14,9772,220],{"id":220},[163,9774,9775,9777],{},[45,9776,2204],{},[45,9778,2207,9779,2210,9781,2214],{},[34,9780,2107],{},[34,9782,2213],{},[10,9784,237],{},[14,9786,240],{"id":240},[10,9788,2221],{},[245,9790,247],{},{"title":81,"searchDepth":94,"depth":94,"links":9792},[9793,9794,9795,9796,9797,9798,9799,9800],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":2081,"description":2086},[260,2241,2242],{"id":2245,"title":2246,"body":9805,"category":260,"cover":261,"description":2251,"extension":262,"meta":9938,"navigation":121,"path":2419,"pinned":265,"publishedAt":266,"seo":9939,"slug":2421,"stem":2422,"summary":2423,"tags":9940,"updatedAt":266,"visible":121,"__hash__":2427},{"type":7,"value":9806,"toc":9928},[9807,9809,9811,9813,9815,9819,9821,9823,9839,9841,9843,9867,9869,9874,9876,9878,9894,9896,9908,9910,9920,9922,9924,9926],[10,9808,2251],{},[14,9810,16],{"id":16},[10,9812,2256],{},[14,9814,22],{"id":22},[10,9816,9817],{},[26,9818],{"alt":2263,"src":2264},[10,9820,2267],{},[14,9822,40],{"id":40},[42,9824,9825,9827,9833],{},[45,9826,2274],{},[45,9828,2277,9829,2210,9831,2284],{},[34,9830,2280],{},[34,9832,2283],{},[45,9834,2287,9835,2291,9837,2295],{},[34,9836,2290],{},[34,9838,2294],{},[14,9840,71],{"id":71},[10,9842,74],{},[76,9844,9845],{"className":78,"code":2302,"language":80,"meta":81,"style":81},[34,9846,9847,9851,9855,9859,9863],{"__ignoreMap":81},[85,9848,9849],{"class":87,"line":88},[85,9850,2309],{},[85,9852,9853],{"class":87,"line":94},[85,9854,2314],{},[85,9856,9857],{"class":87,"line":100},[85,9858,122],{"emptyLinePlaceholder":121},[85,9860,9861],{"class":87,"line":106},[85,9862,2323],{},[85,9864,9865],{"class":87,"line":112},[85,9866,2314],{},[10,9868,147],{},[76,9870,9872],{"className":9871,"code":2333,"language":153,"meta":81},[151],[34,9873,2333],{"__ignoreMap":81},[10,9875,158],{},[14,9877,161],{"id":161},[163,9879,9880,9886],{},[45,9881,972,9882,2347,9884,2350],{},[34,9883,2346],{},[34,9885,2280],{},[45,9887,972,9888,2356,9890,2360,9892,396],{},[34,9889,2355],{},[34,9891,2359],{},[34,9893,2363],{},[14,9895,209],{"id":209},[42,9897,9898,9900],{},[45,9899,2370],{},[45,9901,2373,9902,2291,9904,2291,9906,2381],{},[34,9903,2290],{},[34,9905,2294],{},[34,9907,2380],{},[14,9909,220],{"id":220},[163,9911,9912,9918],{},[45,9913,2388,9914,1191,9916,2395],{},[34,9915,2391],{},[34,9917,2394],{},[45,9919,2398],{},[10,9921,237],{},[14,9923,240],{"id":240},[10,9925,2405],{},[245,9927,247],{},{"title":81,"searchDepth":94,"depth":94,"links":9929},[9930,9931,9932,9933,9934,9935,9936,9937],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":2246,"description":2251},[260,2425,2426],{"id":2429,"title":2430,"body":9942,"category":260,"cover":261,"description":2435,"extension":262,"meta":10075,"navigation":121,"path":2600,"pinned":265,"publishedAt":266,"seo":10076,"slug":2602,"stem":2603,"summary":2604,"tags":10077,"updatedAt":266,"visible":121,"__hash__":2608},{"type":7,"value":9943,"toc":10065},[9944,9946,9948,9950,9952,9956,9958,9960,9978,9980,9982,10018,10020,10025,10027,10029,10039,10041,10049,10051,10057,10059,10061,10063],[10,9945,2435],{},[14,9947,16],{"id":16},[10,9949,2440],{},[14,9951,22],{"id":22},[10,9953,9954],{},[26,9955],{"alt":2447,"src":2448},[10,9957,2451],{},[14,9959,40],{"id":40},[42,9961,9962,9968,9976],{},[45,9963,9964,2461,9966,2465],{},[34,9965,2460],{},[34,9967,2464],{},[45,9969,9970,2471,9972,2475,9974,2479],{},[34,9971,2470],{},[34,9973,2474],{},[34,9975,2478],{},[45,9977,2482],{},[14,9979,71],{"id":71},[10,9981,74],{},[76,9983,9984],{"className":78,"code":2489,"language":80,"meta":81,"style":81},[34,9985,9986,9990,9994,9998,10002,10006,10010,10014],{"__ignoreMap":81},[85,9987,9988],{"class":87,"line":88},[85,9989,2496],{},[85,9991,9992],{"class":87,"line":94},[85,9993,2501],{},[85,9995,9996],{"class":87,"line":100},[85,9997,2506],{},[85,9999,10000],{"class":87,"line":106},[85,10001,122],{"emptyLinePlaceholder":121},[85,10003,10004],{"class":87,"line":112},[85,10005,2515],{},[85,10007,10008],{"class":87,"line":118},[85,10009,2520],{},[85,10011,10012],{"class":87,"line":125},[85,10013,2525],{},[85,10015,10016],{"class":87,"line":131},[85,10017,2530],{},[10,10019,147],{},[76,10021,10023],{"className":10022,"code":2536,"language":153,"meta":81},[151],[34,10024,2536],{"__ignoreMap":81},[10,10026,158],{},[14,10028,161],{"id":161},[163,10030,10031,10035],{},[45,10032,10033,2550],{},[34,10034,2549],{},[45,10036,10037,2556],{},[34,10038,2555],{},[14,10040,209],{"id":209},[42,10042,10043,10047],{},[45,10044,2563,10045,396],{},[34,10046,2566],{},[45,10048,2569],{},[14,10050,220],{"id":220},[163,10052,10053,10055],{},[45,10054,2576],{},[45,10056,2579],{},[10,10058,237],{},[14,10060,240],{"id":240},[10,10062,2586],{},[245,10064,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10066},[10067,10068,10069,10070,10071,10072,10073,10074],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":2430,"description":2435},[260,2606,2607],{"id":2610,"title":2611,"body":10079,"category":260,"cover":261,"description":2616,"extension":262,"meta":10216,"navigation":121,"path":2792,"pinned":265,"publishedAt":266,"seo":10217,"slug":2794,"stem":2795,"summary":2796,"tags":10218,"updatedAt":266,"visible":121,"__hash__":2800},{"type":7,"value":10080,"toc":10204},[10081,10083,10085,10087,10089,10093,10099,10101,10109,10111,10113,10137,10139,10144,10146,10148,10166,10168,10170,10174,10176,10178,10184,10186,10196,10198,10200,10202],[10,10082,2616],{},[14,10084,16],{"id":16},[10,10086,2621],{},[14,10088,22],{"id":22},[10,10090,10091],{},[26,10092],{"alt":2628,"src":2629},[10,10094,2632,10095,2636,10097,396],{},[34,10096,2635],{},[34,10098,2639],{},[14,10100,40],{"id":40},[42,10102,10103,10105,10107],{},[45,10104,2646],{},[45,10106,2649],{},[45,10108,2652],{},[14,10110,71],{"id":71},[10,10112,74],{},[76,10114,10115],{"className":78,"code":2659,"language":80,"meta":81,"style":81},[34,10116,10117,10121,10125,10129,10133],{"__ignoreMap":81},[85,10118,10119],{"class":87,"line":88},[85,10120,2666],{},[85,10122,10123],{"class":87,"line":94},[85,10124,2671],{},[85,10126,10127],{"class":87,"line":100},[85,10128,2676],{},[85,10130,10131],{"class":87,"line":106},[85,10132,2681],{},[85,10134,10135],{"class":87,"line":112},[85,10136,2686],{},[10,10138,147],{},[76,10140,10142],{"className":10141,"code":2692,"language":153,"meta":81},[151],[34,10143,2692],{"__ignoreMap":81},[10,10145,158],{},[14,10147,161],{"id":161},[163,10149,10150,10158],{},[45,10151,2703,10152,2706,10154,2710,10156,2714],{},[34,10153,260],{},[34,10155,2709],{},[34,10157,2713],{},[45,10159,10160,2720,10162,2724,10164,2728],{},[34,10161,2719],{},[34,10163,2723],{},[34,10165,2727],{},[186,10167,188],{"id":188},[10,10169,2733],{},[10,10171,10172],{},[26,10173],{"alt":2738,"src":2739},[10,10175,2742],{},[14,10177,209],{"id":209},[42,10179,10180,10182],{},[45,10181,2749],{},[45,10183,2752],{},[14,10185,220],{"id":220},[163,10187,10188,10194],{},[45,10189,2759,10190,2763,10192,396],{},[34,10191,2762],{},[34,10193,2766],{},[45,10195,2769],{},[10,10197,237],{},[14,10199,240],{"id":240},[10,10201,2776],{},[245,10203,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10205},[10206,10207,10208,10209,10210,10213,10214,10215],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":10211},[10212],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":2611,"description":2616},[260,2798,2799],{"id":2802,"title":2803,"body":10220,"category":260,"cover":261,"description":2808,"extension":262,"meta":10385,"navigation":121,"path":3023,"pinned":265,"publishedAt":266,"seo":10386,"slug":3025,"stem":3026,"summary":3027,"tags":10387,"updatedAt":266,"visible":121,"__hash__":3031},{"type":7,"value":10221,"toc":10373},[10222,10224,10226,10228,10230,10234,10240,10242,10262,10264,10266,10302,10304,10309,10311,10313,10327,10329,10331,10335,10341,10343,10353,10355,10365,10367,10369,10371],[10,10223,2808],{},[14,10225,16],{"id":16},[10,10227,2813],{},[14,10229,22],{"id":22},[10,10231,10232],{},[26,10233],{"alt":2820,"src":2821},[10,10235,2824,10236,1043,10238,2831],{},[34,10237,2827],{},[34,10239,2830],{},[14,10241,40],{"id":40},[42,10243,10244,10252,10260],{},[45,10245,10246,2841,10248,2845,10250,2849],{},[34,10247,2840],{},[34,10249,2844],{},[34,10251,2848],{},[45,10253,10254,2855,10256,2859,10258,2863],{},[34,10255,2854],{},[34,10257,2858],{},[34,10259,2862],{},[45,10261,2866],{},[14,10263,71],{"id":71},[10,10265,74],{},[76,10267,10268],{"className":78,"code":2873,"language":80,"meta":81,"style":81},[34,10269,10270,10274,10278,10282,10286,10290,10294,10298],{"__ignoreMap":81},[85,10271,10272],{"class":87,"line":88},[85,10273,2880],{},[85,10275,10276],{"class":87,"line":94},[85,10277,2885],{},[85,10279,10280],{"class":87,"line":100},[85,10281,122],{"emptyLinePlaceholder":121},[85,10283,10284],{"class":87,"line":106},[85,10285,2894],{},[85,10287,10288],{"class":87,"line":112},[85,10289,2899],{},[85,10291,10292],{"class":87,"line":118},[85,10293,2904],{},[85,10295,10296],{"class":87,"line":125},[85,10297,2909],{},[85,10299,10300],{"class":87,"line":131},[85,10301,2914],{},[10,10303,147],{},[76,10305,10307],{"className":10306,"code":2920,"language":153,"meta":81},[151],[34,10308,2920],{"__ignoreMap":81},[10,10310,158],{},[14,10312,161],{"id":161},[163,10314,10315,10321],{},[45,10316,10317,2934,10319,2938],{},[34,10318,2933],{},[34,10320,2937],{},[45,10322,10323,2944,10325,2947],{},[34,10324,2943],{},[34,10326,2862],{},[186,10328,188],{"id":188},[10,10330,2952],{},[10,10332,10333],{},[26,10334],{"alt":2957,"src":2958},[10,10336,10337,2963,10339,2966],{},[34,10338,2854],{},[34,10340,2858],{},[14,10342,209],{"id":209},[42,10344,10345,10351],{},[45,10346,2973,10347,2976,10349,2979],{},[34,10348,2848],{},[34,10350,2840],{},[45,10352,2982],{},[14,10354,220],{"id":220},[163,10356,10357,10361],{},[45,10358,2989,10359,2993],{},[34,10360,2992],{},[45,10362,2996,10363,3000],{},[34,10364,2999],{},[10,10366,237],{},[14,10368,240],{"id":240},[10,10370,3007],{},[245,10372,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10374},[10375,10376,10377,10378,10379,10382,10383,10384],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":10380},[10381],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":2803,"description":2808},[260,3029,3030],{"id":3033,"title":3034,"body":10389,"category":260,"cover":261,"description":3039,"extension":262,"meta":10522,"navigation":121,"path":3208,"pinned":265,"publishedAt":266,"seo":10523,"slug":3210,"stem":3211,"summary":3212,"tags":10524,"updatedAt":266,"visible":121,"__hash__":3215},{"type":7,"value":10390,"toc":10512},[10391,10393,10395,10397,10399,10403,10413,10415,10425,10427,10429,10457,10459,10464,10466,10468,10482,10484,10492,10494,10504,10506,10508,10510],[10,10392,3039],{},[14,10394,16],{"id":16},[10,10396,3044],{},[14,10398,22],{"id":22},[10,10400,10401],{},[26,10402],{"alt":3051,"src":3052},[10,10404,10405,3058,10407,3062,10409,3066,10411,3070],{},[34,10406,3057],{},[34,10408,3061],{},[34,10410,3065],{},[34,10412,3069],{},[14,10414,40],{"id":40},[42,10416,10417,10419,10423],{},[45,10418,3077],{},[45,10420,10421,3082],{},[34,10422,3069],{},[45,10424,3085],{},[14,10426,71],{"id":71},[10,10428,74],{},[76,10430,10431],{"className":78,"code":3092,"language":80,"meta":81,"style":81},[34,10432,10433,10437,10441,10445,10449,10453],{"__ignoreMap":81},[85,10434,10435],{"class":87,"line":88},[85,10436,3099],{},[85,10438,10439],{"class":87,"line":94},[85,10440,3104],{},[85,10442,10443],{"class":87,"line":100},[85,10444,3109],{},[85,10446,10447],{"class":87,"line":106},[85,10448,122],{"emptyLinePlaceholder":121},[85,10450,10451],{"class":87,"line":112},[85,10452,3118],{},[85,10454,10455],{"class":87,"line":118},[85,10456,3123],{},[10,10458,147],{},[76,10460,10462],{"className":10461,"code":3129,"language":153,"meta":81},[151],[34,10463,3129],{"__ignoreMap":81},[10,10465,158],{},[14,10467,161],{"id":161},[163,10469,10470,10476],{},[45,10471,3140,10472,3143,10474,3147],{},[34,10473,3057],{},[34,10475,3146],{},[45,10477,10478,3153,10480,3157],{},[34,10479,3152],{},[34,10481,3156],{},[14,10483,209],{"id":209},[42,10485,10486,10490],{},[45,10487,3164,10488,3168],{},[34,10489,3167],{},[45,10491,3171],{},[14,10493,220],{"id":220},[163,10495,10496,10498],{},[45,10497,3178],{},[45,10499,1754,10500,3184,10502,3187],{},[34,10501,3183],{},[34,10503,3069],{},[10,10505,237],{},[14,10507,240],{"id":240},[10,10509,3194],{},[245,10511,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10513},[10514,10515,10516,10517,10518,10519,10520,10521],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":3034,"description":3039},[260,2380,3214],{"id":3217,"title":3218,"body":10526,"category":260,"cover":261,"description":3223,"extension":262,"meta":10655,"navigation":121,"path":3384,"pinned":265,"publishedAt":266,"seo":10656,"slug":3386,"stem":3387,"summary":3388,"tags":10657,"updatedAt":266,"visible":121,"__hash__":3392},{"type":7,"value":10527,"toc":10645},[10528,10530,10532,10534,10536,10540,10544,10546,10556,10558,10560,10592,10594,10599,10601,10603,10615,10617,10627,10629,10637,10639,10641,10643],[10,10529,3223],{},[14,10531,16],{"id":16},[10,10533,3228],{},[14,10535,22],{"id":22},[10,10537,10538],{},[26,10539],{"alt":3235,"src":3236},[10,10541,3239,10542,3243],{},[34,10543,3242],{},[14,10545,40],{"id":40},[42,10547,10548,10550,10552],{},[45,10549,3250],{},[45,10551,3253],{},[45,10553,3256,10554,396],{},[34,10555,3259],{},[14,10557,71],{"id":71},[10,10559,74],{},[76,10561,10562],{"className":78,"code":3266,"language":80,"meta":81,"style":81},[34,10563,10564,10568,10572,10576,10580,10584,10588],{"__ignoreMap":81},[85,10565,10566],{"class":87,"line":88},[85,10567,3273],{},[85,10569,10570],{"class":87,"line":94},[85,10571,3278],{},[85,10573,10574],{"class":87,"line":100},[85,10575,122],{"emptyLinePlaceholder":121},[85,10577,10578],{"class":87,"line":106},[85,10579,3287],{},[85,10581,10582],{"class":87,"line":112},[85,10583,3292],{},[85,10585,10586],{"class":87,"line":118},[85,10587,3297],{},[85,10589,10590],{"class":87,"line":125},[85,10591,3302],{},[10,10593,147],{},[76,10595,10597],{"className":10596,"code":3308,"language":153,"meta":81},[151],[34,10598,3308],{"__ignoreMap":81},[10,10600,158],{},[14,10602,161],{"id":161},[163,10604,10605,10607],{},[45,10606,3319],{},[45,10608,10609,3325,10611,3329,10613,3333],{},[34,10610,3324],{},[34,10612,3328],{},[34,10614,3332],{},[14,10616,209],{"id":209},[42,10618,10619,10625],{},[45,10620,3340,10621,3344,10623,396],{},[34,10622,3343],{},[34,10624,3347],{},[45,10626,3350],{},[14,10628,220],{"id":220},[163,10630,10631,10633],{},[45,10632,3357],{},[45,10634,3360,10635,3363],{},[34,10636,3332],{},[10,10638,237],{},[14,10640,240],{"id":240},[10,10642,3370],{},[245,10644,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10646},[10647,10648,10649,10650,10651,10652,10653,10654],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":3218,"description":3223},[260,3390,3391],{"id":3394,"title":3395,"body":10659,"category":260,"cover":261,"description":3400,"extension":262,"meta":10778,"navigation":121,"path":3542,"pinned":265,"publishedAt":266,"seo":10779,"slug":3544,"stem":3545,"summary":3546,"tags":10780,"updatedAt":266,"visible":121,"__hash__":3549},{"type":7,"value":10660,"toc":10768},[10661,10663,10665,10667,10669,10673,10675,10677,10685,10687,10689,10717,10719,10724,10726,10728,10738,10740,10748,10750,10760,10762,10764,10766],[10,10662,3400],{},[14,10664,16],{"id":16},[10,10666,3405],{},[14,10668,22],{"id":22},[10,10670,10671],{},[26,10672],{"alt":3412,"src":3413},[10,10674,3416],{},[14,10676,40],{"id":40},[42,10678,10679,10681,10683],{},[45,10680,3423],{},[45,10682,3426],{},[45,10684,3429],{},[14,10686,71],{"id":71},[10,10688,74],{},[76,10690,10691],{"className":78,"code":3436,"language":80,"meta":81,"style":81},[34,10692,10693,10697,10701,10705,10709,10713],{"__ignoreMap":81},[85,10694,10695],{"class":87,"line":88},[85,10696,3443],{},[85,10698,10699],{"class":87,"line":94},[85,10700,3448],{},[85,10702,10703],{"class":87,"line":100},[85,10704,3453],{},[85,10706,10707],{"class":87,"line":106},[85,10708,122],{"emptyLinePlaceholder":121},[85,10710,10711],{"class":87,"line":112},[85,10712,3462],{},[85,10714,10715],{"class":87,"line":118},[85,10716,3467],{},[10,10718,147],{},[76,10720,10722],{"className":10721,"code":3473,"language":153,"meta":81},[151],[34,10723,3473],{"__ignoreMap":81},[10,10725,158],{},[14,10727,161],{"id":161},[163,10729,10730,10734],{},[45,10731,10732,3487],{},[34,10733,3486],{},[45,10735,10736,3493],{},[34,10737,3492],{},[14,10739,209],{"id":209},[42,10741,10742,10746],{},[45,10743,3500,10744,3504],{},[34,10745,3503],{},[45,10747,3507],{},[14,10749,220],{"id":220},[163,10751,10752,10754],{},[45,10753,3514],{},[45,10755,2207,10756,2210,10758,3521],{},[34,10757,3503],{},[34,10759,3492],{},[10,10761,237],{},[14,10763,240],{"id":240},[10,10765,3528],{},[245,10767,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10769},[10770,10771,10772,10773,10774,10775,10776,10777],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":3395,"description":3400},[260,3548,3391],{"id":3551,"title":3552,"body":10782,"category":260,"cover":261,"description":3557,"extension":262,"meta":10907,"navigation":121,"path":3713,"pinned":265,"publishedAt":266,"seo":10908,"slug":3715,"stem":3716,"summary":3717,"tags":10909,"updatedAt":266,"visible":121,"__hash__":3720},{"type":7,"value":10783,"toc":10897},[10784,10786,10788,10790,10792,10796,10802,10804,10814,10816,10818,10846,10848,10853,10855,10857,10867,10869,10881,10883,10889,10891,10893,10895],[10,10785,3557],{},[14,10787,16],{"id":16},[10,10789,3562],{},[14,10791,22],{"id":22},[10,10793,10794],{},[26,10795],{"alt":3569,"src":3570},[10,10797,3573,10798,3577,10800,3580],{},[34,10799,3576],{},[34,10801,2280],{},[14,10803,40],{"id":40},[42,10805,10806,10808,10812],{},[45,10807,3587],{},[45,10809,2373,10810,3593],{},[34,10811,3592],{},[45,10813,3596],{},[14,10815,71],{"id":71},[10,10817,74],{},[76,10819,10820],{"className":78,"code":3603,"language":80,"meta":81,"style":81},[34,10821,10822,10826,10830,10834,10838,10842],{"__ignoreMap":81},[85,10823,10824],{"class":87,"line":88},[85,10825,3610],{},[85,10827,10828],{"class":87,"line":94},[85,10829,3615],{},[85,10831,10832],{"class":87,"line":100},[85,10833,122],{"emptyLinePlaceholder":121},[85,10835,10836],{"class":87,"line":106},[85,10837,3624],{},[85,10839,10840],{"class":87,"line":112},[85,10841,3629],{},[85,10843,10844],{"class":87,"line":118},[85,10845,3634],{},[10,10847,147],{},[76,10849,10851],{"className":10850,"code":3640,"language":153,"meta":81},[151],[34,10852,3640],{"__ignoreMap":81},[10,10854,158],{},[14,10856,161],{"id":161},[163,10858,10859,10861],{},[45,10860,3651],{},[45,10862,3654,10863,3657,10865,3661],{},[34,10864,2280],{},[34,10866,3660],{},[14,10868,209],{"id":209},[42,10870,10871,10875],{},[45,10872,3668,10873,3672],{},[34,10874,3671],{},[45,10876,3675,10877,3679,10879,396],{},[34,10878,3678],{},[34,10880,3682],{},[14,10882,220],{"id":220},[163,10884,10885,10887],{},[45,10886,3689],{},[45,10888,3692],{},[10,10890,237],{},[14,10892,240],{"id":240},[10,10894,3699],{},[245,10896,247],{},{"title":81,"searchDepth":94,"depth":94,"links":10898},[10899,10900,10901,10902,10903,10904,10905,10906],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":3552,"description":3557},[260,3719,3391],{"id":3722,"title":3723,"body":10911,"category":260,"cover":261,"description":3728,"extension":262,"meta":11034,"navigation":121,"path":3878,"pinned":265,"publishedAt":266,"seo":11035,"slug":3880,"stem":3881,"summary":3882,"tags":11036,"updatedAt":266,"visible":121,"__hash__":3885},{"type":7,"value":10912,"toc":11024},[10913,10915,10917,10919,10921,10925,10927,10929,10941,10943,10945,10973,10975,10980,10982,10984,10994,10996,11006,11008,11016,11018,11020,11022],[10,10914,3728],{},[14,10916,16],{"id":16},[10,10918,3733],{},[14,10920,22],{"id":22},[10,10922,10923],{},[26,10924],{"alt":3740,"src":3741},[10,10926,3744],{},[14,10928,40],{"id":40},[42,10930,10931,10933,10935],{},[45,10932,3751],{},[45,10934,3754],{},[45,10936,3757,10937,3761,10939,3765],{},[34,10938,3760],{},[34,10940,3764],{},[14,10942,71],{"id":71},[10,10944,74],{},[76,10946,10947],{"className":78,"code":3772,"language":80,"meta":81,"style":81},[34,10948,10949,10953,10957,10961,10965,10969],{"__ignoreMap":81},[85,10950,10951],{"class":87,"line":88},[85,10952,3779],{},[85,10954,10955],{"class":87,"line":94},[85,10956,3784],{},[85,10958,10959],{"class":87,"line":100},[85,10960,122],{"emptyLinePlaceholder":121},[85,10962,10963],{"class":87,"line":106},[85,10964,3793],{},[85,10966,10967],{"class":87,"line":112},[85,10968,3798],{},[85,10970,10971],{"class":87,"line":118},[85,10972,3803],{},[10,10974,147],{},[76,10976,10978],{"className":10977,"code":3809,"language":153,"meta":81},[151],[34,10979,3809],{"__ignoreMap":81},[10,10981,158],{},[14,10983,161],{"id":161},[163,10985,10986,10988],{},[45,10987,3820],{},[45,10989,10990,3826,10992,3830],{},[34,10991,3825],{},[34,10993,3829],{},[14,10995,209],{"id":209},[42,10997,10998,11004],{},[45,10999,2373,11000,3839,11002,396],{},[34,11001,3764],{},[34,11003,3760],{},[45,11005,3844],{},[14,11007,220],{"id":220},[163,11009,11010,11014],{},[45,11011,3851,11012,3854],{},[34,11013,3760],{},[45,11015,3857],{},[10,11017,237],{},[14,11019,240],{"id":240},[10,11021,3864],{},[245,11023,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11025},[11026,11027,11028,11029,11030,11031,11032,11033],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":3723,"description":3728},[260,3884,3391],{"id":3887,"title":3888,"body":11038,"category":260,"cover":261,"description":3893,"extension":262,"meta":11197,"navigation":121,"path":4090,"pinned":265,"publishedAt":266,"seo":11198,"slug":4092,"stem":4093,"summary":4094,"tags":11199,"updatedAt":266,"visible":121,"__hash__":4098},{"type":7,"value":11039,"toc":11185},[11040,11042,11044,11046,11048,11052,11058,11060,11072,11074,11076,11116,11118,11123,11125,11127,11141,11143,11145,11149,11151,11153,11163,11165,11177,11179,11181,11183],[10,11041,3893],{},[14,11043,16],{"id":16},[10,11045,3898],{},[14,11047,22],{"id":22},[10,11049,11050],{},[26,11051],{"alt":3905,"src":3906},[10,11053,11054,3912,11056,3916],{},[34,11055,3911],{},[34,11057,3915],{},[14,11059,40],{"id":40},[42,11061,11062,11068,11070],{},[45,11063,11064,3925,11066,3929],{},[34,11065,2840],{},[34,11067,3928],{},[45,11069,3932],{},[45,11071,3935],{},[14,11073,71],{"id":71},[10,11075,74],{},[76,11077,11078],{"className":78,"code":3942,"language":80,"meta":81,"style":81},[34,11079,11080,11084,11088,11092,11096,11100,11104,11108,11112],{"__ignoreMap":81},[85,11081,11082],{"class":87,"line":88},[85,11083,3949],{},[85,11085,11086],{"class":87,"line":94},[85,11087,3954],{},[85,11089,11090],{"class":87,"line":100},[85,11091,3959],{},[85,11093,11094],{"class":87,"line":106},[85,11095,122],{"emptyLinePlaceholder":121},[85,11097,11098],{"class":87,"line":112},[85,11099,3968],{},[85,11101,11102],{"class":87,"line":118},[85,11103,3973],{},[85,11105,11106],{"class":87,"line":125},[85,11107,3978],{},[85,11109,11110],{"class":87,"line":131},[85,11111,3983],{},[85,11113,11114],{"class":87,"line":137},[85,11115,3988],{},[10,11117,147],{},[76,11119,11121],{"className":11120,"code":3994,"language":153,"meta":81},[151],[34,11122,3994],{"__ignoreMap":81},[10,11124,158],{},[14,11126,161],{"id":161},[163,11128,11129,11133],{},[45,11130,11131,4008],{},[34,11132,4007],{},[45,11134,11135,4014,11137,4018,11139,4022],{},[34,11136,4013],{},[34,11138,4017],{},[34,11140,4021],{},[186,11142,188],{"id":188},[10,11144,4027],{},[10,11146,11147],{},[26,11148],{"alt":4032,"src":4033},[10,11150,4036],{},[14,11152,209],{"id":209},[42,11154,11155,11161],{},[45,11156,228,11157,4045,11159,396],{},[34,11158,2840],{},[34,11160,3928],{},[45,11162,4050],{},[14,11164,220],{"id":220},[163,11166,11167,11169],{},[45,11168,4057],{},[45,11170,2373,11171,4063,11173,1191,11175,396],{},[34,11172,4062],{},[34,11174,3928],{},[34,11176,2840],{},[10,11178,237],{},[14,11180,240],{"id":240},[10,11182,4074],{},[245,11184,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11186},[11187,11188,11189,11190,11191,11194,11195,11196],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":11192},[11193],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":3888,"description":3893},[260,4096,4097],{"id":4100,"title":4101,"body":11201,"category":260,"cover":261,"description":4106,"extension":262,"meta":11373,"navigation":121,"path":4319,"pinned":265,"publishedAt":266,"seo":11374,"slug":4321,"stem":4322,"summary":4323,"tags":11375,"updatedAt":266,"visible":121,"__hash__":4326},{"type":7,"value":11202,"toc":11360},[11203,11205,11207,11209,11211,11215,11223,11225,11233,11235,11237,11281,11283,11288,11290,11292,11304,11306,11308,11312,11318,11320,11322,11326,11330,11332,11344,11346,11352,11354,11356,11358],[10,11204,4106],{},[14,11206,16],{"id":16},[10,11208,4111],{},[14,11210,22],{"id":22},[10,11212,11213],{},[26,11214],{"alt":4118,"src":4119},[10,11216,11217,2291,11219,2291,11221,4129],{},[34,11218,1190],{},[34,11220,4126],{},[34,11222,1194],{},[14,11224,40],{"id":40},[42,11226,11227,11229,11231],{},[45,11228,4136],{},[45,11230,4139],{},[45,11232,4142],{},[14,11234,71],{"id":71},[10,11236,74],{},[76,11238,11239],{"className":78,"code":4149,"language":80,"meta":81,"style":81},[34,11240,11241,11245,11249,11253,11257,11261,11265,11269,11273,11277],{"__ignoreMap":81},[85,11242,11243],{"class":87,"line":88},[85,11244,4156],{},[85,11246,11247],{"class":87,"line":94},[85,11248,122],{"emptyLinePlaceholder":121},[85,11250,11251],{"class":87,"line":100},[85,11252,4165],{},[85,11254,11255],{"class":87,"line":106},[85,11256,4170],{},[85,11258,11259],{"class":87,"line":112},[85,11260,4175],{},[85,11262,11263],{"class":87,"line":118},[85,11264,4180],{},[85,11266,11267],{"class":87,"line":125},[85,11268,1180],{},[85,11270,11271],{"class":87,"line":131},[85,11272,4189],{},[85,11274,11275],{"class":87,"line":137},[85,11276,122],{"emptyLinePlaceholder":121},[85,11278,11279],{"class":87,"line":142},[85,11280,4198],{},[10,11282,147],{},[76,11284,11286],{"className":11285,"code":4204,"language":153,"meta":81},[151],[34,11287,4204],{"__ignoreMap":81},[10,11289,158],{},[14,11291,161],{"id":161},[163,11293,11294,11298],{},[45,11295,4215,11296,4219],{},[34,11297,4218],{},[45,11299,11300,4225,11302,4228],{},[34,11301,4224],{},[34,11303,1194],{},[186,11305,188],{"id":188},[10,11307,4233],{},[10,11309,11310],{},[26,11311],{"alt":4238,"src":4239},[10,11313,11314,4244,11316,4247],{},[34,11315,4218],{},[34,11317,4224],{},[186,11319,188],{"id":4250},[10,11321,4253],{},[10,11323,11324],{},[26,11325],{"alt":4258,"src":4259},[10,11327,4262,11328,4265],{},[34,11329,1190],{},[14,11331,209],{"id":209},[42,11333,11334,11338],{},[45,11335,4272,11336,4275],{},[34,11337,4224],{},[45,11339,4278,11340,4281,11342,4285],{},[34,11341,1190],{},[34,11343,4284],{},[14,11345,220],{"id":220},[163,11347,11348,11350],{},[45,11349,4292],{},[45,11351,4295],{},[10,11353,237],{},[14,11355,240],{"id":240},[10,11357,4302],{},[245,11359,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11361},[11362,11363,11364,11365,11366,11370,11371,11372],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":11367},[11368,11369],{"id":188,"depth":100,"text":188},{"id":4250,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":4101,"description":4106},[260,1190,4325],{"id":4328,"title":4329,"body":11377,"category":260,"cover":261,"description":4334,"extension":262,"meta":11514,"navigation":121,"path":4500,"pinned":265,"publishedAt":266,"seo":11515,"slug":4502,"stem":4503,"summary":4504,"tags":11516,"updatedAt":266,"visible":121,"__hash__":4507},{"type":7,"value":11378,"toc":11502},[11379,11381,11383,11385,11387,11391,11395,11397,11407,11409,11411,11443,11445,11450,11452,11454,11464,11466,11468,11472,11476,11478,11484,11486,11494,11496,11498,11500],[10,11380,4334],{},[14,11382,16],{"id":16},[10,11384,4339],{},[14,11386,22],{"id":22},[10,11388,11389],{},[26,11390],{"alt":4346,"src":4347},[10,11392,11393,4353],{},[34,11394,4352],{},[14,11396,40],{"id":40},[42,11398,11399,11401,11403],{},[45,11400,4360],{},[45,11402,4363],{},[45,11404,4366,11405,4369],{},[34,11406,64],{},[14,11408,71],{"id":71},[10,11410,74],{},[76,11412,11413],{"className":78,"code":4376,"language":80,"meta":81,"style":81},[34,11414,11415,11419,11423,11427,11431,11435,11439],{"__ignoreMap":81},[85,11416,11417],{"class":87,"line":88},[85,11418,4383],{},[85,11420,11421],{"class":87,"line":94},[85,11422,122],{"emptyLinePlaceholder":121},[85,11424,11425],{"class":87,"line":100},[85,11426,4392],{},[85,11428,11429],{"class":87,"line":106},[85,11430,4397],{},[85,11432,11433],{"class":87,"line":112},[85,11434,4402],{},[85,11436,11437],{"class":87,"line":118},[85,11438,122],{"emptyLinePlaceholder":121},[85,11440,11441],{"class":87,"line":125},[85,11442,4411],{},[10,11444,147],{},[76,11446,11448],{"className":11447,"code":4417,"language":153,"meta":81},[151],[34,11449,4417],{"__ignoreMap":81},[10,11451,158],{},[14,11453,161],{"id":161},[163,11455,11456,11460],{},[45,11457,4428,11458,4432],{},[34,11459,4431],{},[45,11461,4435,11462,4438],{},[34,11463,4431],{},[186,11465,188],{"id":188},[10,11467,4443],{},[10,11469,11470],{},[26,11471],{"alt":4448,"src":4449},[10,11473,4452,11474,4455],{},[34,11475,4431],{},[14,11477,209],{"id":209},[42,11479,11480,11482],{},[45,11481,4462],{},[45,11483,4465],{},[14,11485,220],{"id":220},[163,11487,11488,11492],{},[45,11489,2373,11490,4474],{},[34,11491,4352],{},[45,11493,4477],{},[10,11495,237],{},[14,11497,240],{"id":240},[10,11499,4484],{},[245,11501,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11503},[11504,11505,11506,11507,11508,11511,11512,11513],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":11509},[11510],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":4329,"description":4334},[260,4352,4506],{"id":4509,"title":4510,"body":11518,"category":260,"cover":261,"description":4515,"extension":262,"meta":11643,"navigation":121,"path":4664,"pinned":265,"publishedAt":266,"seo":11644,"slug":4666,"stem":4667,"summary":4668,"tags":11645,"updatedAt":266,"visible":121,"__hash__":4671},{"type":7,"value":11519,"toc":11633},[11520,11522,11524,11526,11528,11532,11536,11538,11548,11550,11552,11584,11586,11591,11593,11595,11607,11609,11615,11617,11625,11627,11629,11631],[10,11521,4515],{},[14,11523,16],{"id":16},[10,11525,4520],{},[14,11527,22],{"id":22},[10,11529,11530],{},[26,11531],{"alt":4527,"src":4528},[10,11533,11534,4533],{},[34,11535,64],{},[14,11537,40],{"id":40},[42,11539,11540,11544,11546],{},[45,11541,11542,4543],{},[34,11543,4542],{},[45,11545,4546],{},[45,11547,4549],{},[14,11549,71],{"id":71},[10,11551,74],{},[76,11553,11554],{"className":78,"code":4556,"language":80,"meta":81,"style":81},[34,11555,11556,11560,11564,11568,11572,11576,11580],{"__ignoreMap":81},[85,11557,11558],{"class":87,"line":88},[85,11559,4563],{},[85,11561,11562],{"class":87,"line":94},[85,11563,122],{"emptyLinePlaceholder":121},[85,11565,11566],{"class":87,"line":100},[85,11567,4572],{},[85,11569,11570],{"class":87,"line":106},[85,11571,4577],{},[85,11573,11574],{"class":87,"line":112},[85,11575,122],{"emptyLinePlaceholder":121},[85,11577,11578],{"class":87,"line":118},[85,11579,4586],{},[85,11581,11582],{"class":87,"line":125},[85,11583,4591],{},[10,11585,147],{},[76,11587,11589],{"className":11588,"code":4597,"language":153,"meta":81},[151],[34,11590,4597],{"__ignoreMap":81},[10,11592,158],{},[14,11594,161],{"id":161},[163,11596,11597,11603],{},[45,11598,4608,11599,4611,11601,4615],{},[34,11600,64],{},[34,11602,4614],{},[45,11604,11605,4620],{},[34,11606,4542],{},[14,11608,209],{"id":209},[42,11610,11611,11613],{},[45,11612,4627],{},[45,11614,4630],{},[14,11616,220],{"id":220},[163,11618,11619,11621],{},[45,11620,4637],{},[45,11622,2373,11623,4643],{},[34,11624,4642],{},[10,11626,237],{},[14,11628,240],{"id":240},[10,11630,4650],{},[245,11632,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11634},[11635,11636,11637,11638,11639,11640,11641,11642],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":4510,"description":4515},[260,64,4670],{"id":4673,"title":4674,"body":11647,"category":260,"cover":261,"description":4679,"extension":262,"meta":11792,"navigation":121,"path":4854,"pinned":265,"publishedAt":266,"seo":11793,"slug":4856,"stem":4857,"summary":4858,"tags":11794,"updatedAt":266,"visible":121,"__hash__":4860},{"type":7,"value":11648,"toc":11782},[11649,11651,11653,11655,11657,11661,11667,11669,11683,11685,11687,11731,11733,11738,11740,11742,11752,11754,11766,11768,11774,11776,11778,11780],[10,11650,4679],{},[14,11652,16],{"id":16},[10,11654,4684],{},[14,11656,22],{"id":22},[10,11658,11659],{},[26,11660],{"alt":4691,"src":4692},[10,11662,11663,4698,11665,4702],{},[34,11664,4697],{},[34,11666,4701],{},[14,11668,40],{"id":40},[42,11670,11671,11673,11679],{},[45,11672,4709],{},[45,11674,11675,4714,11677,4717],{},[34,11676,4697],{},[34,11678,4352],{},[45,11680,4720,11681,4723],{},[34,11682,4701],{},[14,11684,71],{"id":71},[10,11686,74],{},[76,11688,11689],{"className":78,"code":4730,"language":80,"meta":81,"style":81},[34,11690,11691,11695,11699,11703,11707,11711,11715,11719,11723,11727],{"__ignoreMap":81},[85,11692,11693],{"class":87,"line":88},[85,11694,4737],{},[85,11696,11697],{"class":87,"line":94},[85,11698,122],{"emptyLinePlaceholder":121},[85,11700,11701],{"class":87,"line":100},[85,11702,4746],{},[85,11704,11705],{"class":87,"line":106},[85,11706,4751],{},[85,11708,11709],{"class":87,"line":112},[85,11710,4756],{},[85,11712,11713],{"class":87,"line":118},[85,11714,4761],{},[85,11716,11717],{"class":87,"line":125},[85,11718,4766],{},[85,11720,11721],{"class":87,"line":131},[85,11722,4591],{},[85,11724,11725],{"class":87,"line":137},[85,11726,122],{"emptyLinePlaceholder":121},[85,11728,11729],{"class":87,"line":142},[85,11730,4779],{},[10,11732,147],{},[76,11734,11736],{"className":11735,"code":4785,"language":153,"meta":81},[151],[34,11737,4785],{"__ignoreMap":81},[10,11739,158],{},[14,11741,161],{"id":161},[163,11743,11744,11748],{},[45,11745,4796,11746,4799],{},[34,11747,4697],{},[45,11749,4802,11750,4805],{},[34,11751,4701],{},[14,11753,209],{"id":209},[42,11755,11756,11760],{},[45,11757,3500,11758,4814],{},[34,11759,4697],{},[45,11761,4817,11762,4820,11764,4823],{},[34,11763,4352],{},[34,11765,4697],{},[14,11767,220],{"id":220},[163,11769,11770,11772],{},[45,11771,4830],{},[45,11773,4833],{},[10,11775,237],{},[14,11777,240],{"id":240},[10,11779,4840],{},[245,11781,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11783},[11784,11785,11786,11787,11788,11789,11790,11791],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":4674,"description":4679},[260,4701,4697],{"id":4862,"title":4863,"body":11796,"category":260,"cover":261,"description":4868,"extension":262,"meta":11935,"navigation":121,"path":5040,"pinned":265,"publishedAt":266,"seo":11936,"slug":5042,"stem":5043,"summary":5044,"tags":11937,"updatedAt":266,"visible":121,"__hash__":5048},{"type":7,"value":11797,"toc":11923},[11798,11800,11802,11804,11806,11810,11812,11814,11830,11832,11834,11862,11864,11869,11871,11873,11885,11887,11889,11893,11895,11897,11907,11909,11915,11917,11919,11921],[10,11799,4868],{},[14,11801,16],{"id":16},[10,11803,4873],{},[14,11805,22],{"id":22},[10,11807,11808],{},[26,11809],{"alt":4880,"src":4881},[10,11811,4884],{},[14,11813,40],{"id":40},[42,11815,11816,11818,11820],{},[45,11817,4891],{},[45,11819,4894],{},[45,11821,4897,11822,2291,11824,4904,11826,2291,11828,396],{},[34,11823,4900],{},[34,11825,4903],{},[34,11827,4907],{},[34,11829,4910],{},[14,11831,71],{"id":71},[10,11833,74],{},[76,11835,11836],{"className":78,"code":4917,"language":80,"meta":81,"style":81},[34,11837,11838,11842,11846,11850,11854,11858],{"__ignoreMap":81},[85,11839,11840],{"class":87,"line":88},[85,11841,4924],{},[85,11843,11844],{"class":87,"line":94},[85,11845,122],{"emptyLinePlaceholder":121},[85,11847,11848],{"class":87,"line":100},[85,11849,4933],{},[85,11851,11852],{"class":87,"line":106},[85,11853,4938],{},[85,11855,11856],{"class":87,"line":112},[85,11857,4943],{},[85,11859,11860],{"class":87,"line":118},[85,11861,4948],{},[10,11863,147],{},[76,11865,11867],{"className":11866,"code":4954,"language":153,"meta":81},[151],[34,11868,4954],{"__ignoreMap":81},[10,11870,158],{},[14,11872,161],{"id":161},[163,11874,11875,11883],{},[45,11876,4965,11877,4968,11879,1191,11881,396],{},[34,11878,4900],{},[34,11880,4971],{},[34,11882,4974],{},[45,11884,4977],{},[186,11886,188],{"id":188},[10,11888,4982],{},[10,11890,11891],{},[26,11892],{"alt":4987,"src":4988},[10,11894,4991],{},[14,11896,209],{"id":209},[42,11898,11899,11905],{},[45,11900,4998,11901,1043,11903,5004],{},[34,11902,5001],{},[34,11904,4907],{},[45,11906,5007],{},[14,11908,220],{"id":220},[163,11910,11911,11913],{},[45,11912,5014],{},[45,11914,5017],{},[10,11916,237],{},[14,11918,240],{"id":240},[10,11920,5024],{},[245,11922,247],{},{"title":81,"searchDepth":94,"depth":94,"links":11924},[11925,11926,11927,11928,11929,11932,11933,11934],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":11930},[11931],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":4863,"description":4868},[260,5046,5047],{"id":5050,"title":5051,"body":11939,"category":260,"cover":261,"description":5056,"extension":262,"meta":12056,"navigation":121,"path":5195,"pinned":265,"publishedAt":266,"seo":12057,"slug":5197,"stem":5198,"summary":5199,"tags":12058,"updatedAt":266,"visible":121,"__hash__":5203},{"type":7,"value":11940,"toc":12046},[11941,11943,11945,11947,11949,11953,11955,11957,11965,11967,11969,12001,12003,12008,12010,12012,12020,12022,12030,12032,12038,12040,12042,12044],[10,11942,5056],{},[14,11944,16],{"id":16},[10,11946,5061],{},[14,11948,22],{"id":22},[10,11950,11951],{},[26,11952],{"alt":5068,"src":5069},[10,11954,5072],{},[14,11956,40],{"id":40},[42,11958,11959,11961,11963],{},[45,11960,5079],{},[45,11962,5082],{},[45,11964,5085],{},[14,11966,71],{"id":71},[10,11968,74],{},[76,11970,11971],{"className":78,"code":5092,"language":80,"meta":81,"style":81},[34,11972,11973,11977,11981,11985,11989,11993,11997],{"__ignoreMap":81},[85,11974,11975],{"class":87,"line":88},[85,11976,5099],{},[85,11978,11979],{"class":87,"line":94},[85,11980,122],{"emptyLinePlaceholder":121},[85,11982,11983],{"class":87,"line":100},[85,11984,5108],{},[85,11986,11987],{"class":87,"line":106},[85,11988,5113],{},[85,11990,11991],{"class":87,"line":112},[85,11992,122],{"emptyLinePlaceholder":121},[85,11994,11995],{"class":87,"line":118},[85,11996,5122],{},[85,11998,11999],{"class":87,"line":125},[85,12000,5127],{},[10,12002,147],{},[76,12004,12006],{"className":12005,"code":5133,"language":153,"meta":81},[151],[34,12007,5133],{"__ignoreMap":81},[10,12009,158],{},[14,12011,161],{"id":161},[163,12013,12014,12016],{},[45,12015,5144],{},[45,12017,5147,12018,5151],{},[34,12019,5150],{},[14,12021,209],{"id":209},[42,12023,12024,12028],{},[45,12025,5158,12026,5161],{},[34,12027,64],{},[45,12029,5164],{},[14,12031,220],{"id":220},[163,12033,12034,12036],{},[45,12035,5171],{},[45,12037,5174],{},[10,12039,237],{},[14,12041,240],{"id":240},[10,12043,5181],{},[245,12045,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12047},[12048,12049,12050,12051,12052,12053,12054,12055],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5051,"description":5056},[260,5201,5202],{"id":5205,"title":5206,"body":12060,"category":260,"cover":261,"description":5211,"extension":262,"meta":12179,"navigation":121,"path":5355,"pinned":265,"publishedAt":266,"seo":12180,"slug":5357,"stem":5358,"summary":5359,"tags":12181,"updatedAt":266,"visible":121,"__hash__":5363},{"type":7,"value":12061,"toc":12169},[12062,12064,12066,12068,12070,12074,12076,12078,12086,12088,12090,12122,12124,12129,12131,12133,12143,12145,12151,12153,12161,12163,12165,12167],[10,12063,5211],{},[14,12065,16],{"id":16},[10,12067,5216],{},[14,12069,22],{"id":22},[10,12071,12072],{},[26,12073],{"alt":5223,"src":5224},[10,12075,5227],{},[14,12077,40],{"id":40},[42,12079,12080,12082,12084],{},[45,12081,5234],{},[45,12083,5237],{},[45,12085,5240],{},[14,12087,71],{"id":71},[10,12089,74],{},[76,12091,12092],{"className":78,"code":5247,"language":80,"meta":81,"style":81},[34,12093,12094,12098,12102,12106,12110,12114,12118],{"__ignoreMap":81},[85,12095,12096],{"class":87,"line":88},[85,12097,5254],{},[85,12099,12100],{"class":87,"line":94},[85,12101,5259],{},[85,12103,12104],{"class":87,"line":100},[85,12105,5264],{},[85,12107,12108],{"class":87,"line":106},[85,12109,122],{"emptyLinePlaceholder":121},[85,12111,12112],{"class":87,"line":112},[85,12113,5273],{},[85,12115,12116],{"class":87,"line":118},[85,12117,5278],{},[85,12119,12120],{"class":87,"line":125},[85,12121,5283],{},[10,12123,147],{},[76,12125,12127],{"className":12126,"code":5289,"language":153,"meta":81},[151],[34,12128,5289],{"__ignoreMap":81},[10,12130,158],{},[14,12132,161],{"id":161},[163,12134,12135,12139],{},[45,12136,972,12137,5303],{},[34,12138,5302],{},[45,12140,5306,12141,5310],{},[34,12142,5309],{},[14,12144,209],{"id":209},[42,12146,12147,12149],{},[45,12148,5317],{},[45,12150,5320],{},[14,12152,220],{"id":220},[163,12154,12155,12159],{},[45,12156,5327,12157,5331],{},[34,12158,5330],{},[45,12160,5334],{},[10,12162,237],{},[14,12164,240],{"id":240},[10,12166,5341],{},[245,12168,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12170},[12171,12172,12173,12174,12175,12176,12177,12178],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5206,"description":5211},[260,5361,5362],{"id":5365,"title":5366,"body":12183,"category":260,"cover":261,"description":5371,"extension":262,"meta":12328,"navigation":121,"path":5552,"pinned":265,"publishedAt":266,"seo":12329,"slug":5554,"stem":5555,"summary":5556,"tags":12330,"updatedAt":266,"visible":121,"__hash__":5560},{"type":7,"value":12184,"toc":12316},[12185,12187,12189,12191,12193,12197,12201,12203,12215,12217,12219,12247,12249,12254,12256,12258,12272,12274,12276,12280,12288,12290,12300,12302,12308,12310,12312,12314],[10,12186,5371],{},[14,12188,16],{"id":16},[10,12190,5376],{},[14,12192,22],{"id":22},[10,12194,12195],{},[26,12196],{"alt":5383,"src":5384},[10,12198,5387,12199,5391],{},[34,12200,5390],{},[14,12202,40],{"id":40},[42,12204,12205,12207,12209],{},[45,12206,5398],{},[45,12208,5401],{},[45,12210,5404,12211,5407,12213,396],{},[34,12212,5390],{},[34,12214,5410],{},[14,12216,71],{"id":71},[10,12218,74],{},[76,12220,12221],{"className":78,"code":5417,"language":80,"meta":81,"style":81},[34,12222,12223,12227,12231,12235,12239,12243],{"__ignoreMap":81},[85,12224,12225],{"class":87,"line":88},[85,12226,5424],{},[85,12228,12229],{"class":87,"line":94},[85,12230,5429],{},[85,12232,12233],{"class":87,"line":100},[85,12234,5434],{},[85,12236,12237],{"class":87,"line":106},[85,12238,122],{"emptyLinePlaceholder":121},[85,12240,12241],{"class":87,"line":112},[85,12242,5443],{},[85,12244,12245],{"class":87,"line":118},[85,12246,5448],{},[10,12248,147],{},[76,12250,12252],{"className":12251,"code":5454,"language":153,"meta":81},[151],[34,12253,5454],{"__ignoreMap":81},[10,12255,158],{},[14,12257,161],{"id":161},[163,12259,12260,12266],{},[45,12261,5465,12262,2291,12264,5471],{},[34,12263,5468],{},[34,12265,4431],{},[45,12267,12268,5477,12270,5481],{},[34,12269,5476],{},[34,12271,5480],{},[186,12273,188],{"id":188},[10,12275,5486],{},[10,12277,12278],{},[26,12279],{"alt":5491,"src":5492},[10,12281,12282,2291,12284,1191,12286,5502],{},[34,12283,5468],{},[34,12285,4431],{},[34,12287,5501],{},[14,12289,209],{"id":209},[42,12291,12292,12296],{},[45,12293,5509,12294,5513],{},[34,12295,5512],{},[45,12297,5516,12298,5519],{},[34,12299,5501],{},[14,12301,220],{"id":220},[163,12303,12304,12306],{},[45,12305,5526],{},[45,12307,5529],{},[10,12309,237],{},[14,12311,240],{"id":240},[10,12313,5536],{},[245,12315,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12317},[12318,12319,12320,12321,12322,12325,12326,12327],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":12323},[12324],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5366,"description":5371},[260,5558,5559],{"id":5562,"title":5563,"body":12332,"category":260,"cover":261,"description":5568,"extension":262,"meta":12481,"navigation":121,"path":5749,"pinned":265,"publishedAt":266,"seo":12482,"slug":5751,"stem":5752,"summary":5753,"tags":12483,"updatedAt":266,"visible":121,"__hash__":5757},{"type":7,"value":12333,"toc":12469},[12334,12336,12338,12340,12342,12346,12348,12350,12362,12364,12366,12410,12412,12417,12419,12421,12433,12435,12437,12441,12443,12445,12453,12455,12461,12463,12465,12467],[10,12335,5568],{},[14,12337,16],{"id":16},[10,12339,5573],{},[14,12341,22],{"id":22},[10,12343,12344],{},[26,12345],{"alt":5580,"src":5581},[10,12347,5584],{},[14,12349,40],{"id":40},[42,12351,12352,12354,12358],{},[45,12353,5591],{},[45,12355,12356,5597],{},[34,12357,5596],{},[45,12359,12360,5603],{},[34,12361,5602],{},[14,12363,71],{"id":71},[10,12365,74],{},[76,12367,12368],{"className":78,"code":5610,"language":80,"meta":81,"style":81},[34,12369,12370,12374,12378,12382,12386,12390,12394,12398,12402,12406],{"__ignoreMap":81},[85,12371,12372],{"class":87,"line":88},[85,12373,5617],{},[85,12375,12376],{"class":87,"line":94},[85,12377,5622],{},[85,12379,12380],{"class":87,"line":100},[85,12381,122],{"emptyLinePlaceholder":121},[85,12383,12384],{"class":87,"line":106},[85,12385,5631],{},[85,12387,12388],{"class":87,"line":112},[85,12389,5636],{},[85,12391,12392],{"class":87,"line":118},[85,12393,122],{"emptyLinePlaceholder":121},[85,12395,12396],{"class":87,"line":125},[85,12397,5645],{},[85,12399,12400],{"class":87,"line":131},[85,12401,5650],{},[85,12403,12404],{"class":87,"line":137},[85,12405,122],{"emptyLinePlaceholder":121},[85,12407,12408],{"class":87,"line":142},[85,12409,5659],{},[10,12411,147],{},[76,12413,12415],{"className":12414,"code":5665,"language":153,"meta":81},[151],[34,12416,5665],{"__ignoreMap":81},[10,12418,158],{},[14,12420,161],{"id":161},[163,12422,12423,12427],{},[45,12424,5676,12425,5680],{},[34,12426,5679],{},[45,12428,12429,5686,12431,396],{},[34,12430,5685],{},[34,12432,5689],{},[186,12434,188],{"id":188},[10,12436,5694],{},[10,12438,12439],{},[26,12440],{"alt":5699,"src":5700},[10,12442,5703],{},[14,12444,209],{"id":209},[42,12446,12447,12451],{},[45,12448,5710,12449,5713],{},[34,12450,5410],{},[45,12452,5716],{},[14,12454,220],{"id":220},[163,12456,12457,12459],{},[45,12458,5723],{},[45,12460,5726],{},[10,12462,237],{},[14,12464,240],{"id":240},[10,12466,5733],{},[245,12468,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12470},[12471,12472,12473,12474,12475,12478,12479,12480],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":12476},[12477],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5563,"description":5568},[260,5755,5756],{"id":5759,"title":5760,"body":12485,"category":260,"cover":261,"description":5765,"extension":262,"meta":12646,"navigation":121,"path":5963,"pinned":265,"publishedAt":266,"seo":12647,"slug":5965,"stem":5966,"summary":5967,"tags":12648,"updatedAt":266,"visible":121,"__hash__":5971},{"type":7,"value":12486,"toc":12634},[12487,12489,12491,12493,12495,12499,12501,12503,12515,12517,12519,12571,12573,12578,12580,12582,12600,12602,12604,12608,12610,12612,12618,12620,12626,12628,12630,12632],[10,12488,5765],{},[14,12490,16],{"id":16},[10,12492,5770],{},[14,12494,22],{"id":22},[10,12496,12497],{},[26,12498],{"alt":5777,"src":5778},[10,12500,5781],{},[14,12502,40],{"id":40},[42,12504,12505,12507,12509],{},[45,12506,5788],{},[45,12508,5791],{},[45,12510,12511,2210,12513,5800],{},[34,12512,5796],{},[34,12514,5799],{},[14,12516,71],{"id":71},[10,12518,74],{},[76,12520,12521],{"className":78,"code":5807,"language":80,"meta":81,"style":81},[34,12522,12523,12527,12531,12535,12539,12543,12547,12551,12555,12559,12563,12567],{"__ignoreMap":81},[85,12524,12525],{"class":87,"line":88},[85,12526,5814],{},[85,12528,12529],{"class":87,"line":94},[85,12530,122],{"emptyLinePlaceholder":121},[85,12532,12533],{"class":87,"line":100},[85,12534,5823],{},[85,12536,12537],{"class":87,"line":106},[85,12538,5828],{},[85,12540,12541],{"class":87,"line":112},[85,12542,122],{"emptyLinePlaceholder":121},[85,12544,12545],{"class":87,"line":118},[85,12546,5837],{},[85,12548,12549],{"class":87,"line":125},[85,12550,5842],{},[85,12552,12553],{"class":87,"line":131},[85,12554,5847],{},[85,12556,12557],{"class":87,"line":137},[85,12558,122],{"emptyLinePlaceholder":121},[85,12560,12561],{"class":87,"line":142},[85,12562,5856],{},[85,12564,12565],{"class":87,"line":5859},[85,12566,122],{"emptyLinePlaceholder":121},[85,12568,12569],{"class":87,"line":5864},[85,12570,5867],{},[10,12572,147],{},[76,12574,12576],{"className":12575,"code":5873,"language":153,"meta":81},[151],[34,12577,5873],{"__ignoreMap":81},[10,12579,158],{},[14,12581,161],{"id":161},[163,12583,12584,12594],{},[45,12585,12586,5887,12588,5891,12590,5894,12592,5898],{},[34,12587,5886],{},[34,12589,5890],{},[34,12591,5679],{},[34,12593,5897],{},[45,12595,12596,5903,12598,5906],{},[34,12597,4614],{},[34,12599,2242],{},[186,12601,188],{"id":188},[10,12603,5911],{},[10,12605,12606],{},[26,12607],{"alt":5916,"src":5917},[10,12609,5920],{},[14,12611,209],{"id":209},[42,12613,12614,12616],{},[45,12615,5927],{},[45,12617,5930],{},[14,12619,220],{"id":220},[163,12621,12622,12624],{},[45,12623,5937],{},[45,12625,5940],{},[10,12627,237],{},[14,12629,240],{"id":240},[10,12631,5947],{},[245,12633,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12635},[12636,12637,12638,12639,12640,12643,12644,12645],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":12641},[12642],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5760,"description":5765},[260,5969,5970],{"id":5973,"title":5974,"body":12650,"category":260,"cover":261,"description":5979,"extension":262,"meta":12773,"navigation":121,"path":6130,"pinned":265,"publishedAt":266,"seo":12774,"slug":6132,"stem":6133,"summary":6134,"tags":12775,"updatedAt":266,"visible":121,"__hash__":6138},{"type":7,"value":12651,"toc":12763},[12652,12654,12656,12658,12660,12664,12666,12668,12682,12684,12686,12714,12716,12721,12723,12725,12735,12737,12745,12747,12755,12757,12759,12761],[10,12653,5979],{},[14,12655,16],{"id":16},[10,12657,5984],{},[14,12659,22],{"id":22},[10,12661,12662],{},[26,12663],{"alt":5991,"src":5992},[10,12665,5995],{},[14,12667,40],{"id":40},[42,12669,12670,12672,12674],{},[45,12671,6002],{},[45,12673,6005],{},[45,12675,6008,12676,2291,12678,2291,12680,6016],{},[34,12677,2294],{},[34,12679,2460],{},[34,12681,6015],{},[14,12683,71],{"id":71},[10,12685,74],{},[76,12687,12688],{"className":78,"code":6023,"language":80,"meta":81,"style":81},[34,12689,12690,12694,12698,12702,12706,12710],{"__ignoreMap":81},[85,12691,12692],{"class":87,"line":88},[85,12693,6030],{},[85,12695,12696],{"class":87,"line":94},[85,12697,6035],{},[85,12699,12700],{"class":87,"line":100},[85,12701,6040],{},[85,12703,12704],{"class":87,"line":106},[85,12705,122],{"emptyLinePlaceholder":121},[85,12707,12708],{"class":87,"line":112},[85,12709,6049],{},[85,12711,12712],{"class":87,"line":118},[85,12713,6054],{},[10,12715,147],{},[76,12717,12719],{"className":12718,"code":6060,"language":153,"meta":81},[151],[34,12720,6060],{"__ignoreMap":81},[10,12722,158],{},[14,12724,161],{"id":161},[163,12726,12727,12733],{},[45,12728,6071,12729,6075,12731,6078],{},[34,12730,6074],{},[34,12732,2280],{},[45,12734,6081],{},[14,12736,209],{"id":209},[42,12738,12739,12743],{},[45,12740,6088,12741,6092],{},[34,12742,6091],{},[45,12744,6095],{},[14,12746,220],{"id":220},[163,12748,12749,12751],{},[45,12750,6102],{},[45,12752,6105,12753,6109],{},[34,12754,6108],{},[10,12756,237],{},[14,12758,240],{"id":240},[10,12760,6116],{},[245,12762,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12764},[12765,12766,12767,12768,12769,12770,12771,12772],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5974,"description":5979},[260,6136,6137],{"id":6140,"title":6141,"body":12777,"category":260,"cover":261,"description":6146,"extension":262,"meta":12954,"navigation":121,"path":6374,"pinned":265,"publishedAt":266,"seo":12955,"slug":6376,"stem":6377,"summary":6378,"tags":12956,"updatedAt":266,"visible":121,"__hash__":6382},{"type":7,"value":12778,"toc":12942},[12779,12781,12783,12787,12789,12793,12799,12801,12813,12815,12819,12843,12847,12863,12869,12871,12876,12878,12880,12896,12898,12900,12904,12908,12910,12922,12924,12934,12936,12938,12940],[10,12780,6146],{},[14,12782,16],{"id":16},[10,12784,6151,12785,6154],{},[329,12786,6074],{},[14,12788,22],{"id":22},[10,12790,12791],{},[26,12792],{"alt":6161,"src":6162},[10,12794,6165,12795,6169,12797,6173],{},[34,12796,6168],{},[34,12798,6172],{},[14,12800,40],{"id":40},[42,12802,12803,12807,12809],{},[45,12804,6180,12805,6183],{},[34,12806,1205],{},[45,12808,6186],{},[45,12810,6189,12811,6193],{},[34,12812,6192],{},[14,12814,71],{"id":71},[10,12816,6198,12817,6202],{},[34,12818,6201],{},[76,12820,12821],{"className":78,"code":6205,"language":80,"meta":81,"style":81},[34,12822,12823,12827,12831,12835,12839],{"__ignoreMap":81},[85,12824,12825],{"class":87,"line":88},[85,12826,6212],{},[85,12828,12829],{"class":87,"line":94},[85,12830,6217],{},[85,12832,12833],{"class":87,"line":100},[85,12834,122],{"emptyLinePlaceholder":121},[85,12836,12837],{"class":87,"line":106},[85,12838,6226],{},[85,12840,12841],{"class":87,"line":112},[85,12842,6231],{},[10,12844,6234,12845,6238],{},[34,12846,6237],{},[76,12848,12849],{"className":78,"code":6241,"language":80,"meta":81,"style":81},[34,12850,12851,12855,12859],{"__ignoreMap":81},[85,12852,12853],{"class":87,"line":88},[85,12854,6248],{},[85,12856,12857],{"class":87,"line":94},[85,12858,122],{"emptyLinePlaceholder":121},[85,12860,12861],{"class":87,"line":100},[85,12862,6257],{},[10,12864,6260,12865,1191,12867,396],{},[34,12866,6263],{},[34,12868,6266],{},[10,12870,147],{},[76,12872,12874],{"className":12873,"code":6272,"language":153,"meta":81},[151],[34,12875,6272],{"__ignoreMap":81},[10,12877,158],{},[14,12879,161],{"id":161},[163,12881,12882,12888],{},[45,12883,6283,12884,6286,12886,6290],{},[34,12885,6201],{},[34,12887,6289],{},[45,12889,12890,6295,12892,6298,12894,6301],{},[34,12891,6237],{},[34,12893,6201],{},[34,12895,6237],{},[186,12897,188],{"id":188},[10,12899,6306],{},[10,12901,12902],{},[26,12903],{"alt":6311,"src":6312},[10,12905,6315,12906,6318],{},[34,12907,6289],{},[14,12909,209],{"id":209},[42,12911,12912,12918],{},[45,12913,6325,12914,1191,12916,396],{},[34,12915,6201],{},[34,12917,6237],{},[45,12919,6332,12920,6336],{},[34,12921,6335],{},[14,12923,220],{"id":220},[163,12925,12926,12930],{},[45,12927,2388,12928,6346],{},[34,12929,6345],{},[45,12931,6349,12932,396],{},[34,12933,6168],{},[10,12935,237],{},[14,12937,240],{"id":240},[10,12939,6358],{},[245,12941,247],{},{"title":81,"searchDepth":94,"depth":94,"links":12943},[12944,12945,12946,12947,12948,12951,12952,12953],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":12949},[12950],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":6141,"description":6146},[260,6380,6381],{"id":6384,"title":6385,"body":12958,"category":260,"cover":261,"description":6390,"extension":262,"meta":13097,"navigation":121,"path":6556,"pinned":265,"publishedAt":266,"seo":13098,"slug":6558,"stem":6559,"summary":6560,"tags":13099,"updatedAt":266,"visible":121,"__hash__":6563},{"type":7,"value":12959,"toc":13087},[12960,12962,12964,12966,12968,12972,12974,12976,12986,12988,12990,13030,13032,13037,13039,13041,13059,13061,13069,13071,13079,13081,13083,13085],[10,12961,6390],{},[14,12963,16],{"id":16},[10,12965,6395],{},[14,12967,22],{"id":22},[10,12969,12970],{},[26,12971],{"alt":6402,"src":6403},[10,12973,6406],{},[14,12975,40],{"id":40},[42,12977,12978,12982,12984],{},[45,12979,12980,6416],{},[34,12981,6415],{},[45,12983,6419],{},[45,12985,6422],{},[14,12987,71],{"id":71},[10,12989,1608],{},[76,12991,12992],{"className":625,"code":6429,"language":627,"meta":81,"style":81},[34,12993,12994,13004,13010,13016,13026],{"__ignoreMap":81},[85,12995,12996,12998,13000,13002],{"class":87,"line":88},[85,12997,725],{"class":634},[85,12999,667],{"class":637},[85,13001,6440],{"class":670},[85,13003,6443],{"class":670},[85,13005,13006,13008],{"class":87,"line":94},[85,13007,6448],{"class":637},[85,13009,6451],{"class":670},[85,13011,13012,13014],{"class":87,"line":100},[85,13013,80],{"class":634},[85,13015,638],{"class":637},[85,13017,13018,13020,13022,13024],{"class":87,"line":106},[85,13019,80],{"class":634},[85,13021,667],{"class":637},[85,13023,671],{"class":670},[85,13025,638],{"class":637},[85,13027,13028],{"class":87,"line":112},[85,13029,6472],{"class":634},[10,13031,147],{},[76,13033,13035],{"className":13034,"code":6478,"language":153,"meta":81},[151],[34,13036,6478],{"__ignoreMap":81},[10,13038,158],{},[14,13040,161],{"id":161},[163,13042,13043,13049],{},[45,13044,13045,6492,13047,6495],{},[34,13046,6491],{},[34,13048,725],{},[45,13050,6498,13051,2210,13053,6504,13055,3761,13057,6510],{},[34,13052,80],{},[34,13054,6503],{},[34,13056,6415],{},[34,13058,6509],{},[14,13060,209],{"id":209},[42,13062,13063,13065],{},[45,13064,6517],{},[45,13066,3500,13067,6522],{},[34,13068,6415],{},[14,13070,220],{"id":220},[163,13072,13073,13077],{},[45,13074,6529,13075,396],{},[34,13076,6532],{},[45,13078,6535],{},[10,13080,237],{},[14,13082,240],{"id":240},[10,13084,6542],{},[245,13086,1692],{},{"title":81,"searchDepth":94,"depth":94,"links":13088},[13089,13090,13091,13092,13093,13094,13095,13096],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":6385,"description":6390},[260,6562,295],{"id":6565,"title":6566,"body":13101,"category":260,"cover":261,"description":6571,"extension":262,"meta":13254,"navigation":121,"path":6760,"pinned":265,"publishedAt":266,"seo":13255,"slug":6762,"stem":6763,"summary":6764,"tags":13256,"updatedAt":266,"visible":121,"__hash__":6768},{"type":7,"value":13102,"toc":13244},[13103,13105,13107,13109,13111,13115,13121,13123,13139,13141,13143,13187,13189,13194,13196,13198,13210,13212,13226,13228,13236,13238,13240,13242],[10,13104,6571],{},[14,13106,16],{"id":16},[10,13108,6576],{},[14,13110,22],{"id":22},[10,13112,13113],{},[26,13114],{"alt":6583,"src":6584},[10,13116,13117,6590,13119,6593],{},[34,13118,6589],{},[34,13120,2470],{},[14,13122,40],{"id":40},[42,13124,13125,13127,13135],{},[45,13126,6600],{},[45,13128,13129,2291,13131,2291,13133,6612],{},[34,13130,6605],{},[34,13132,6608],{},[34,13134,6611],{},[45,13136,6615,13137,6619],{},[34,13138,6618],{},[14,13140,71],{"id":71},[10,13142,74],{},[76,13144,13145],{"className":78,"code":6626,"language":80,"meta":81,"style":81},[34,13146,13147,13151,13155,13159,13163,13167,13171,13175,13179,13183],{"__ignoreMap":81},[85,13148,13149],{"class":87,"line":88},[85,13150,6633],{},[85,13152,13153],{"class":87,"line":94},[85,13154,122],{"emptyLinePlaceholder":121},[85,13156,13157],{"class":87,"line":100},[85,13158,6642],{},[85,13160,13161],{"class":87,"line":106},[85,13162,6647],{},[85,13164,13165],{"class":87,"line":112},[85,13166,6652],{},[85,13168,13169],{"class":87,"line":118},[85,13170,122],{"emptyLinePlaceholder":121},[85,13172,13173],{"class":87,"line":125},[85,13174,6661],{},[85,13176,13177],{"class":87,"line":131},[85,13178,6666],{},[85,13180,13181],{"class":87,"line":137},[85,13182,6671],{},[85,13184,13185],{"class":87,"line":142},[85,13186,6676],{},[10,13188,147],{},[76,13190,13192],{"className":13191,"code":6682,"language":153,"meta":81},[151],[34,13193,6682],{"__ignoreMap":81},[10,13195,158],{},[14,13197,161],{"id":161},[163,13199,13200,13204],{},[45,13201,13202,6696],{},[34,13203,6695],{},[45,13205,2373,13206,6701,13208,6704],{},[34,13207,2470],{},[34,13209,6589],{},[14,13211,209],{"id":209},[42,13213,13214,13220],{},[45,13215,3500,13216,6713,13218,6716],{},[34,13217,6589],{},[34,13219,6605],{},[45,13221,6719,13222,1043,13224,6725],{},[34,13223,2470],{},[34,13225,6724],{},[14,13227,220],{"id":220},[163,13229,13230,13234],{},[45,13231,6732,13232,6736],{},[34,13233,6735],{},[45,13235,6739],{},[10,13237,237],{},[14,13239,240],{"id":240},[10,13241,6746],{},[245,13243,247],{},{"title":81,"searchDepth":94,"depth":94,"links":13245},[13246,13247,13248,13249,13250,13251,13252,13253],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":6566,"description":6571},[260,6766,6767],{"id":6770,"title":6771,"body":13258,"category":260,"cover":261,"description":6776,"extension":262,"meta":13405,"navigation":121,"path":6955,"pinned":265,"publishedAt":266,"seo":13406,"slug":6957,"stem":6958,"summary":6959,"tags":13407,"updatedAt":266,"visible":121,"__hash__":6963},{"type":7,"value":13259,"toc":13395},[13260,13262,13264,13266,13268,13272,13274,13276,13294,13296,13298,13346,13348,13353,13355,13357,13365,13367,13377,13379,13387,13389,13391,13393],[10,13261,6776],{},[14,13263,16],{"id":16},[10,13265,6781],{},[14,13267,22],{"id":22},[10,13269,13270],{},[26,13271],{"alt":6788,"src":6789},[10,13273,6792],{},[14,13275,40],{"id":40},[42,13277,13278,13282,13288],{},[45,13279,13280,6802],{},[34,13281,6801],{},[45,13283,13284,6808,13286,396],{},[34,13285,6807],{},[34,13287,6811],{},[45,13289,6814,13290,6818,13292,6822],{},[34,13291,6817],{},[34,13293,6821],{},[14,13295,71],{"id":71},[10,13297,74],{},[76,13299,13300],{"className":78,"code":6829,"language":80,"meta":81,"style":81},[34,13301,13302,13306,13310,13314,13318,13322,13326,13330,13334,13338,13342],{"__ignoreMap":81},[85,13303,13304],{"class":87,"line":88},[85,13305,6633],{},[85,13307,13308],{"class":87,"line":94},[85,13309,122],{"emptyLinePlaceholder":121},[85,13311,13312],{"class":87,"line":100},[85,13313,6844],{},[85,13315,13316],{"class":87,"line":106},[85,13317,6849],{},[85,13319,13320],{"class":87,"line":112},[85,13321,6854],{},[85,13323,13324],{"class":87,"line":118},[85,13325,6859],{},[85,13327,13328],{"class":87,"line":125},[85,13329,122],{"emptyLinePlaceholder":121},[85,13331,13332],{"class":87,"line":131},[85,13333,6868],{},[85,13335,13336],{"class":87,"line":137},[85,13337,6873],{},[85,13339,13340],{"class":87,"line":142},[85,13341,6878],{},[85,13343,13344],{"class":87,"line":5859},[85,13345,6883],{},[10,13347,147],{},[76,13349,13351],{"className":13350,"code":6889,"language":153,"meta":81},[151],[34,13352,6889],{"__ignoreMap":81},[10,13354,158],{},[14,13356,161],{"id":161},[163,13358,13359,13363],{},[45,13360,6900,13361,6903],{},[34,13362,6817],{},[45,13364,6906],{},[14,13366,209],{"id":209},[42,13368,13369,13373],{},[45,13370,2373,13371,6915],{},[34,13372,6801],{},[45,13374,6918,13375,396],{},[34,13376,6921],{},[14,13378,220],{"id":220},[163,13380,13381,13383],{},[45,13382,6928],{},[45,13384,6931,13385,6934],{},[34,13386,370],{},[10,13388,237],{},[14,13390,240],{"id":240},[10,13392,6941],{},[245,13394,247],{},{"title":81,"searchDepth":94,"depth":94,"links":13396},[13397,13398,13399,13400,13401,13402,13403,13404],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":6771,"description":6776},[260,6961,6962],{"id":6965,"title":6966,"body":13409,"category":260,"cover":261,"description":6971,"extension":262,"meta":13552,"navigation":121,"path":7139,"pinned":265,"publishedAt":266,"seo":13553,"slug":7141,"stem":7142,"summary":7143,"tags":13554,"updatedAt":266,"visible":121,"__hash__":7147},{"type":7,"value":13410,"toc":13542},[13411,13413,13415,13417,13419,13423,13429,13431,13441,13443,13445,13497,13499,13504,13506,13508,13518,13520,13526,13528,13534,13536,13538,13540],[10,13412,6971],{},[14,13414,16],{"id":16},[10,13416,6976],{},[14,13418,22],{"id":22},[10,13420,13421],{},[26,13422],{"alt":6983,"src":6984},[10,13424,13425,6990,13427,6994],{},[34,13426,6989],{},[34,13428,6993],{},[14,13430,40],{"id":40},[42,13432,13433,13435,13439],{},[45,13434,7001],{},[45,13436,13437,7007],{},[34,13438,7006],{},[45,13440,7010],{},[14,13442,71],{"id":71},[10,13444,74],{},[76,13446,13447],{"className":78,"code":7017,"language":80,"meta":81,"style":81},[34,13448,13449,13453,13457,13461,13465,13469,13473,13477,13481,13485,13489,13493],{"__ignoreMap":81},[85,13450,13451],{"class":87,"line":88},[85,13452,7024],{},[85,13454,13455],{"class":87,"line":94},[85,13456,122],{"emptyLinePlaceholder":121},[85,13458,13459],{"class":87,"line":100},[85,13460,7033],{},[85,13462,13463],{"class":87,"line":106},[85,13464,122],{"emptyLinePlaceholder":121},[85,13466,13467],{"class":87,"line":112},[85,13468,7042],{},[85,13470,13471],{"class":87,"line":118},[85,13472,7047],{},[85,13474,13475],{"class":87,"line":125},[85,13476,6859],{},[85,13478,13479],{"class":87,"line":131},[85,13480,122],{"emptyLinePlaceholder":121},[85,13482,13483],{"class":87,"line":137},[85,13484,7060],{},[85,13486,13487],{"class":87,"line":142},[85,13488,7065],{},[85,13490,13491],{"class":87,"line":5859},[85,13492,6878],{},[85,13494,13495],{"class":87,"line":5864},[85,13496,7074],{},[10,13498,147],{},[76,13500,13502],{"className":13501,"code":7080,"language":153,"meta":81},[151],[34,13503,7080],{"__ignoreMap":81},[10,13505,158],{},[14,13507,161],{"id":161},[163,13509,13510,13514],{},[45,13511,13512,7093],{},[34,13513,6989],{},[45,13515,13516,7098],{},[34,13517,6993],{},[14,13519,209],{"id":209},[42,13521,13522,13524],{},[45,13523,7105],{},[45,13525,7108],{},[14,13527,220],{"id":220},[163,13529,13530,13532],{},[45,13531,7115],{},[45,13533,7118],{},[10,13535,237],{},[14,13537,240],{"id":240},[10,13539,7125],{},[245,13541,247],{},{"title":81,"searchDepth":94,"depth":94,"links":13543},[13544,13545,13546,13547,13548,13549,13550,13551],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":6966,"description":6971},[260,7145,7146],{"id":7149,"title":7150,"body":13556,"category":260,"cover":261,"description":7155,"extension":262,"meta":13707,"navigation":121,"path":7340,"pinned":265,"publishedAt":266,"seo":13708,"slug":7342,"stem":7343,"summary":7344,"tags":13709,"updatedAt":266,"visible":121,"__hash__":7348},{"type":7,"value":13557,"toc":13697},[13558,13560,13562,13564,13566,13570,13574,13576,13590,13592,13594,13646,13648,13653,13655,13657,13669,13671,13681,13683,13689,13691,13693,13695],[10,13559,7155],{},[14,13561,16],{"id":16},[10,13563,7160],{},[14,13565,22],{"id":22},[10,13567,13568],{},[26,13569],{"alt":7167,"src":7168},[10,13571,13572,7174],{},[34,13573,7173],{},[14,13575,40],{"id":40},[42,13577,13578,13584,13588],{},[45,13579,2373,13580,7184,13582,7188],{},[34,13581,7183],{},[34,13583,7187],{},[45,13585,7191,13586,7195],{},[34,13587,7194],{},[45,13589,7198],{},[14,13591,71],{"id":71},[10,13593,74],{},[76,13595,13596],{"className":78,"code":7205,"language":80,"meta":81,"style":81},[34,13597,13598,13602,13606,13610,13614,13618,13622,13626,13630,13634,13638,13642],{"__ignoreMap":81},[85,13599,13600],{"class":87,"line":88},[85,13601,7212],{},[85,13603,13604],{"class":87,"line":94},[85,13605,122],{"emptyLinePlaceholder":121},[85,13607,13608],{"class":87,"line":100},[85,13609,7221],{},[85,13611,13612],{"class":87,"line":106},[85,13613,7226],{},[85,13615,13616],{"class":87,"line":112},[85,13617,7231],{},[85,13619,13620],{"class":87,"line":118},[85,13621,7236],{},[85,13623,13624],{"class":87,"line":125},[85,13625,7241],{},[85,13627,13628],{"class":87,"line":131},[85,13629,122],{"emptyLinePlaceholder":121},[85,13631,13632],{"class":87,"line":137},[85,13633,7250],{},[85,13635,13636],{"class":87,"line":142},[85,13637,7255],{},[85,13639,13640],{"class":87,"line":5859},[85,13641,7260],{},[85,13643,13644],{"class":87,"line":5864},[85,13645,7265],{},[10,13647,147],{},[76,13649,13651],{"className":13650,"code":7271,"language":153,"meta":81},[151],[34,13652,7271],{"__ignoreMap":81},[10,13654,158],{},[14,13656,161],{"id":161},[163,13658,13659,13665],{},[45,13660,13661,7285,13663,7288],{},[34,13662,7284],{},[34,13664,7194],{},[45,13666,13667,7293],{},[34,13668,7173],{},[14,13670,209],{"id":209},[42,13672,13673,13675],{},[45,13674,7300],{},[45,13676,7303,13677,7306,13679,7309],{},[34,13678,7183],{},[34,13680,7187],{},[14,13682,220],{"id":220},[163,13684,13685,13687],{},[45,13686,7316],{},[45,13688,7319],{},[10,13690,237],{},[14,13692,240],{"id":240},[10,13694,7326],{},[245,13696,247],{},{"title":81,"searchDepth":94,"depth":94,"links":13698},[13699,13700,13701,13702,13703,13704,13705,13706],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":7150,"description":7155},[260,7346,7347],{"id":7350,"title":7351,"body":13711,"category":260,"cover":261,"description":7356,"extension":262,"meta":13925,"navigation":121,"path":7630,"pinned":265,"publishedAt":266,"seo":13926,"slug":7632,"stem":7633,"summary":7634,"tags":13927,"updatedAt":266,"visible":121,"__hash__":7638},{"type":7,"value":13712,"toc":13912},[13713,13715,13717,13719,13721,13725,13731,13733,13745,13747,13749,13809,13811,13816,13818,13820,13838,13840,13848,13852,13860,13862,13866,13870,13876,13878,13888,13890,13904,13906,13908,13910],[10,13714,7356],{},[14,13716,16],{"id":16},[10,13718,7361],{},[14,13720,22],{"id":22},[10,13722,13723],{},[26,13724],{"alt":7368,"src":7369},[10,13726,7372,13727,7376,13729,7380],{},[34,13728,7375],{},[34,13730,7379],{},[14,13732,40],{"id":40},[42,13734,13735,13739,13743],{},[45,13736,7387,13737,7390],{},[34,13738,7375],{},[45,13740,13741,7396],{},[34,13742,7395],{},[45,13744,7399],{},[14,13746,71],{"id":71},[10,13748,74],{},[76,13750,13751],{"className":78,"code":7406,"language":80,"meta":81,"style":81},[34,13752,13753,13757,13761,13765,13769,13773,13777,13781,13785,13789,13793,13797,13801,13805],{"__ignoreMap":81},[85,13754,13755],{"class":87,"line":88},[85,13756,7413],{},[85,13758,13759],{"class":87,"line":94},[85,13760,7418],{},[85,13762,13763],{"class":87,"line":100},[85,13764,7423],{},[85,13766,13767],{"class":87,"line":106},[85,13768,7428],{},[85,13770,13771],{"class":87,"line":112},[85,13772,7433],{},[85,13774,13775],{"class":87,"line":118},[85,13776,122],{"emptyLinePlaceholder":121},[85,13778,13779],{"class":87,"line":125},[85,13780,7442],{},[85,13782,13783],{"class":87,"line":131},[85,13784,7447],{},[85,13786,13787],{"class":87,"line":137},[85,13788,7452],{},[85,13790,13791],{"class":87,"line":142},[85,13792,7457],{},[85,13794,13795],{"class":87,"line":5859},[85,13796,1180],{},[85,13798,13799],{"class":87,"line":5864},[85,13800,7466],{},[85,13802,13803],{"class":87,"line":7469},[85,13804,7472],{},[85,13806,13807],{"class":87,"line":7475},[85,13808,7478],{},[10,13810,147],{},[76,13812,13814],{"className":13813,"code":7484,"language":153,"meta":81},[151],[34,13815,7484],{"__ignoreMap":81},[10,13817,158],{},[14,13819,161],{"id":161},[163,13821,13822,13830],{},[45,13823,13824,7497,13826,7500,13828,7504],{},[34,13825,3069],{},[34,13827,7395],{},[34,13829,7503],{},[45,13831,7507,13832,7510,13834,7513,13836,396],{},[34,13833,7375],{},[34,13835,1194],{},[34,13837,7379],{},[186,13839,188],{"id":188},[10,13841,13842,2291,13844,1191,13846,7526],{},[34,13843,7375],{},[34,13845,1194],{},[34,13847,7379],{},[10,13849,13850],{},[26,13851],{"alt":7531,"src":7532},[10,13853,13854,7537,13856,7540,13858,7543],{},[34,13855,7375],{},[34,13857,1194],{},[34,13859,7379],{},[186,13861,188],{"id":4250},[10,13863,13864,7551],{},[34,13865,7550],{},[10,13867,13868],{},[26,13869],{"alt":7556,"src":7557},[10,13871,7560,13872,7563,13874,7566],{},[34,13873,7550],{},[34,13875,1194],{},[14,13877,209],{"id":209},[42,13879,13880,13884],{},[45,13881,7573,13882,7577],{},[34,13883,7576],{},[45,13885,7580,13886,7583],{},[34,13887,7550],{},[14,13889,220],{"id":220},[163,13891,13892,13900],{},[45,13893,7590,13894,7594,13896,1191,13898,396],{},[34,13895,7593],{},[34,13897,7597],{},[34,13899,7600],{},[45,13901,7603,13902,7606],{},[34,13903,6811],{},[10,13905,237],{},[14,13907,240],{"id":240},[10,13909,7613],{},[245,13911,247],{},{"title":81,"searchDepth":94,"depth":94,"links":13913},[13914,13915,13916,13917,13918,13922,13923,13924],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":13919},[13920,13921],{"id":188,"depth":100,"text":188},{"id":4250,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":7351,"description":7356},[260,7636,7637],{"id":7640,"title":7641,"body":13929,"category":260,"cover":261,"description":7646,"extension":262,"meta":14080,"navigation":121,"path":7823,"pinned":265,"publishedAt":266,"seo":14081,"slug":7825,"stem":7826,"summary":7827,"tags":14082,"updatedAt":266,"visible":121,"__hash__":7830},{"type":7,"value":13930,"toc":14070},[13931,13933,13935,13937,13939,13943,13947,13949,13961,13963,13965,14013,14015,14020,14022,14024,14034,14036,14046,14048,14062,14064,14066,14068],[10,13932,7646],{},[14,13934,16],{"id":16},[10,13936,7651],{},[14,13938,22],{"id":22},[10,13940,13941],{},[26,13942],{"alt":7658,"src":7659},[10,13944,7662,13945,7665],{},[34,13946,6821],{},[14,13948,40],{"id":40},[42,13950,13951,13955,13959],{},[45,13952,13953,7674],{},[34,13954,6821],{},[45,13956,13957,7680],{},[34,13958,7679],{},[45,13960,7683],{},[14,13962,71],{"id":71},[10,13964,74],{},[76,13966,13967],{"className":78,"code":7690,"language":80,"meta":81,"style":81},[34,13968,13969,13973,13977,13981,13985,13989,13993,13997,14001,14005,14009],{"__ignoreMap":81},[85,13970,13971],{"class":87,"line":88},[85,13972,6633],{},[85,13974,13975],{"class":87,"line":94},[85,13976,122],{"emptyLinePlaceholder":121},[85,13978,13979],{"class":87,"line":100},[85,13980,6844],{},[85,13982,13983],{"class":87,"line":106},[85,13984,122],{"emptyLinePlaceholder":121},[85,13986,13987],{"class":87,"line":112},[85,13988,7713],{},[85,13990,13991],{"class":87,"line":118},[85,13992,7718],{},[85,13994,13995],{"class":87,"line":125},[85,13996,122],{"emptyLinePlaceholder":121},[85,13998,13999],{"class":87,"line":131},[85,14000,7727],{},[85,14002,14003],{"class":87,"line":137},[85,14004,7732],{},[85,14006,14007],{"class":87,"line":142},[85,14008,122],{"emptyLinePlaceholder":121},[85,14010,14011],{"class":87,"line":5859},[85,14012,7741],{},[10,14014,147],{},[76,14016,14018],{"className":14017,"code":7747,"language":153,"meta":81},[151],[34,14019,7747],{"__ignoreMap":81},[10,14021,158],{},[14,14023,161],{"id":161},[163,14025,14026,14032],{},[45,14027,7662,14028,7760,14030,396],{},[34,14029,6821],{},[34,14031,7763],{},[45,14033,7766],{},[14,14035,209],{"id":209},[42,14037,14038,14042],{},[45,14039,4817,14040,7775],{},[34,14041,6821],{},[45,14043,7778,14044,7781],{},[34,14045,6821],{},[14,14047,220],{"id":220},[163,14049,14050,14056],{},[45,14051,7788,14052,7792,14054,396],{},[34,14053,7791],{},[34,14055,6821],{},[45,14057,4817,14058,7799,14060,396],{},[34,14059,6821],{},[34,14061,7802],{},[10,14063,237],{},[14,14065,240],{"id":240},[10,14067,7809],{},[245,14069,247],{},{"title":81,"searchDepth":94,"depth":94,"links":14071},[14072,14073,14074,14075,14076,14077,14078,14079],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":7641,"description":7646},[260,6821,7829],{"id":7832,"title":7833,"body":14084,"category":260,"cover":261,"description":7838,"extension":262,"meta":14255,"navigation":121,"path":8050,"pinned":265,"publishedAt":266,"seo":14256,"slug":8052,"stem":8053,"summary":8054,"tags":14257,"updatedAt":266,"visible":121,"__hash__":8058},{"type":7,"value":14085,"toc":14243},[14086,14088,14090,14092,14094,14098,14100,14102,14114,14116,14118,14174,14176,14181,14183,14185,14201,14203,14205,14209,14215,14217,14225,14227,14235,14237,14239,14241],[10,14087,7838],{},[14,14089,16],{"id":16},[10,14091,7843],{},[14,14093,22],{"id":22},[10,14095,14096],{},[26,14097],{"alt":7850,"src":7851},[10,14099,7854],{},[14,14101,40],{"id":40},[42,14103,14104,14108,14112],{},[45,14105,14106,7864],{},[34,14107,7863],{},[45,14109,14110,7870],{},[34,14111,7869],{},[45,14113,7873],{},[14,14115,71],{"id":71},[10,14117,74],{},[76,14119,14120],{"className":78,"code":7880,"language":80,"meta":81,"style":81},[34,14121,14122,14126,14130,14134,14138,14142,14146,14150,14154,14158,14162,14166,14170],{"__ignoreMap":81},[85,14123,14124],{"class":87,"line":88},[85,14125,7887],{},[85,14127,14128],{"class":87,"line":94},[85,14129,7892],{},[85,14131,14132],{"class":87,"line":100},[85,14133,7897],{},[85,14135,14136],{"class":87,"line":106},[85,14137,7902],{},[85,14139,14140],{"class":87,"line":112},[85,14141,122],{"emptyLinePlaceholder":121},[85,14143,14144],{"class":87,"line":118},[85,14145,7911],{},[85,14147,14148],{"class":87,"line":125},[85,14149,7916],{},[85,14151,14152],{"class":87,"line":131},[85,14153,7921],{},[85,14155,14156],{"class":87,"line":137},[85,14157,7926],{},[85,14159,14160],{"class":87,"line":142},[85,14161,122],{"emptyLinePlaceholder":121},[85,14163,14164],{"class":87,"line":5859},[85,14165,7935],{},[85,14167,14168],{"class":87,"line":5864},[85,14169,7940],{},[85,14171,14172],{"class":87,"line":7469},[85,14173,7945],{},[10,14175,147],{},[76,14177,14179],{"className":14178,"code":7951,"language":153,"meta":81},[151],[34,14180,7951],{"__ignoreMap":81},[10,14182,158],{},[14,14184,161],{"id":161},[163,14186,14187,14193],{},[45,14188,167,14189,7965,14191,7968],{},[34,14190,7964],{},[34,14192,7869],{},[45,14194,14195,7974,14197,7978,14199,7981],{},[34,14196,7973],{},[34,14198,7977],{},[34,14200,7863],{},[186,14202,188],{"id":188},[10,14204,7986],{},[10,14206,14207],{},[26,14208],{"alt":7991,"src":7992},[10,14210,7995,14211,1191,14213,8001],{},[34,14212,4614],{},[34,14214,8000],{},[14,14216,209],{"id":209},[42,14218,14219,14223],{},[45,14220,8008,14221,8011],{},[34,14222,7863],{},[45,14224,8014],{},[14,14226,220],{"id":220},[163,14228,14229,14233],{},[45,14230,5327,14231,8024],{},[34,14232,8023],{},[45,14234,8027],{},[10,14236,237],{},[14,14238,240],{"id":240},[10,14240,8034],{},[245,14242,247],{},{"title":81,"searchDepth":94,"depth":94,"links":14244},[14245,14246,14247,14248,14249,14252,14253,14254],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":14250},[14251],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":7833,"description":7838},[260,8056,8057],{"id":8060,"title":8061,"body":14259,"category":260,"cover":261,"description":8066,"extension":262,"meta":14406,"navigation":121,"path":8245,"pinned":265,"publishedAt":266,"seo":14407,"slug":8247,"stem":8248,"summary":8249,"tags":14408,"updatedAt":266,"visible":121,"__hash__":8253},{"type":7,"value":14260,"toc":14396},[14261,14263,14265,14267,14269,14273,14275,14277,14285,14287,14289,14345,14347,14352,14354,14356,14368,14370,14376,14378,14388,14390,14392,14394],[10,14262,8066],{},[14,14264,16],{"id":16},[10,14266,8071],{},[14,14268,22],{"id":22},[10,14270,14271],{},[26,14272],{"alt":8078,"src":8079},[10,14274,8082],{},[14,14276,40],{"id":40},[42,14278,14279,14281,14283],{},[45,14280,8089],{},[45,14282,8092],{},[45,14284,8095],{},[14,14286,71],{"id":71},[10,14288,74],{},[76,14290,14291],{"className":78,"code":8102,"language":80,"meta":81,"style":81},[34,14292,14293,14297,14301,14305,14309,14313,14317,14321,14325,14329,14333,14337,14341],{"__ignoreMap":81},[85,14294,14295],{"class":87,"line":88},[85,14296,8109],{},[85,14298,14299],{"class":87,"line":94},[85,14300,8114],{},[85,14302,14303],{"class":87,"line":100},[85,14304,8119],{},[85,14306,14307],{"class":87,"line":106},[85,14308,122],{"emptyLinePlaceholder":121},[85,14310,14311],{"class":87,"line":112},[85,14312,8128],{},[85,14314,14315],{"class":87,"line":118},[85,14316,8133],{},[85,14318,14319],{"class":87,"line":125},[85,14320,8138],{},[85,14322,14323],{"class":87,"line":131},[85,14324,122],{"emptyLinePlaceholder":121},[85,14326,14327],{"class":87,"line":137},[85,14328,8147],{},[85,14330,14331],{"class":87,"line":142},[85,14332,8152],{},[85,14334,14335],{"class":87,"line":5859},[85,14336,122],{"emptyLinePlaceholder":121},[85,14338,14339],{"class":87,"line":5864},[85,14340,8161],{},[85,14342,14343],{"class":87,"line":7469},[85,14344,8166],{},[10,14346,147],{},[76,14348,14350],{"className":14349,"code":8172,"language":153,"meta":81},[151],[34,14351,8172],{"__ignoreMap":81},[10,14353,158],{},[14,14355,161],{"id":161},[163,14357,14358,14364],{},[45,14359,14360,8186,14362,8190],{},[34,14361,8185],{},[34,14363,8189],{},[45,14365,8193,14366,8197],{},[34,14367,8196],{},[14,14369,209],{"id":209},[42,14371,14372,14374],{},[45,14373,8204],{},[45,14375,8207],{},[14,14377,220],{"id":220},[163,14379,14380,14386],{},[45,14381,8214,14382,8218,14384,396],{},[34,14383,8217],{},[34,14385,8221],{},[45,14387,8224],{},[10,14389,237],{},[14,14391,240],{"id":240},[10,14393,8231],{},[245,14395,247],{},{"title":81,"searchDepth":94,"depth":94,"links":14397},[14398,14399,14400,14401,14402,14403,14404,14405],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":8061,"description":8066},[260,8251,8252],{"id":4,"title":5,"body":14410,"category":260,"cover":261,"description":12,"extension":262,"meta":14573,"navigation":121,"path":264,"pinned":265,"publishedAt":266,"seo":14574,"slug":268,"stem":269,"summary":270,"tags":14575,"updatedAt":266,"visible":121,"__hash__":274},{"type":7,"value":14411,"toc":14561},[14412,14414,14416,14418,14420,14424,14428,14430,14446,14448,14450,14494,14496,14501,14503,14505,14519,14521,14525,14529,14533,14535,14541,14543,14553,14555,14557,14559],[10,14413,12],{},[14,14415,16],{"id":16},[10,14417,19],{},[14,14419,22],{"id":22},[10,14421,14422],{},[26,14423],{"alt":28,"src":29},[10,14425,32,14426,37],{},[34,14427,36],{},[14,14429,40],{"id":40},[42,14431,14432,14438,14444],{},[45,14433,14434,50,14436,54],{},[34,14435,49],{},[34,14437,53],{},[45,14439,57,14440,61,14442,65],{},[34,14441,60],{},[34,14443,64],{},[45,14445,68],{},[14,14447,71],{"id":71},[10,14449,74],{},[76,14451,14452],{"className":78,"code":79,"language":80,"meta":81,"style":81},[34,14453,14454,14458,14462,14466,14470,14474,14478,14482,14486,14490],{"__ignoreMap":81},[85,14455,14456],{"class":87,"line":88},[85,14457,91],{},[85,14459,14460],{"class":87,"line":94},[85,14461,97],{},[85,14463,14464],{"class":87,"line":100},[85,14465,103],{},[85,14467,14468],{"class":87,"line":106},[85,14469,109],{},[85,14471,14472],{"class":87,"line":112},[85,14473,115],{},[85,14475,14476],{"class":87,"line":118},[85,14477,122],{"emptyLinePlaceholder":121},[85,14479,14480],{"class":87,"line":125},[85,14481,128],{},[85,14483,14484],{"class":87,"line":131},[85,14485,134],{},[85,14487,14488],{"class":87,"line":137},[85,14489,134],{},[85,14491,14492],{"class":87,"line":142},[85,14493,134],{},[10,14495,147],{},[76,14497,14499],{"className":14498,"code":152,"language":153,"meta":81},[151],[34,14500,152],{"__ignoreMap":81},[10,14502,158],{},[14,14504,161],{"id":161},[163,14506,14507,14511],{},[45,14508,167,14509,171],{},[34,14510,170],{},[45,14512,174,14513,177,14515,180,14517,184],{},[34,14514,53],{},[34,14516,36],{},[34,14518,183],{},[186,14520,188],{"id":188},[10,14522,191,14523,194],{},[34,14524,53],{},[10,14526,14527],{},[26,14528],{"alt":199,"src":200},[10,14530,203,14531,206],{},[34,14532,36],{},[14,14534,209],{"id":209},[42,14536,14537,14539],{},[45,14538,214],{},[45,14540,217],{},[14,14542,220],{"id":220},[163,14544,14545,14547],{},[45,14546,225],{},[45,14548,228,14549,231,14551,234],{},[34,14550,64],{},[34,14552,53],{},[10,14554,237],{},[14,14556,240],{"id":240},[10,14558,243],{},[245,14560,247],{},{"title":81,"searchDepth":94,"depth":94,"links":14562},[14563,14564,14565,14566,14567,14570,14571,14572],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":14568},[14569],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":5,"description":12},[260,272,273],{"id":8422,"title":8423,"body":14577,"category":260,"cover":261,"description":8428,"extension":262,"meta":14760,"navigation":121,"path":8653,"pinned":265,"publishedAt":266,"seo":14761,"slug":8655,"stem":8656,"summary":8657,"tags":14762,"updatedAt":266,"visible":121,"__hash__":8660},{"type":7,"value":14578,"toc":14748},[14579,14581,14583,14585,14587,14591,14593,14595,14609,14611,14613,14681,14683,14688,14690,14692,14706,14708,14710,14714,14720,14722,14730,14732,14740,14742,14744,14746],[10,14580,8428],{},[14,14582,16],{"id":16},[10,14584,8433],{},[14,14586,22],{"id":22},[10,14588,14589],{},[26,14590],{"alt":8440,"src":8441},[10,14592,8444],{},[14,14594,40],{"id":40},[42,14596,14597,14603,14605],{},[45,14598,14599,8454,14601,396],{},[34,14600,8453],{},[34,14602,8457],{},[45,14604,8460],{},[45,14606,14607,8466],{},[34,14608,8465],{},[14,14610,71],{"id":71},[10,14612,74],{},[76,14614,14615],{"className":78,"code":8473,"language":80,"meta":81,"style":81},[34,14616,14617,14621,14625,14629,14633,14637,14641,14645,14649,14653,14657,14661,14665,14669,14673,14677],{"__ignoreMap":81},[85,14618,14619],{"class":87,"line":88},[85,14620,8480],{},[85,14622,14623],{"class":87,"line":94},[85,14624,122],{"emptyLinePlaceholder":121},[85,14626,14627],{"class":87,"line":100},[85,14628,8489],{},[85,14630,14631],{"class":87,"line":106},[85,14632,8494],{},[85,14634,14635],{"class":87,"line":112},[85,14636,8499],{},[85,14638,14639],{"class":87,"line":118},[85,14640,8504],{},[85,14642,14643],{"class":87,"line":125},[85,14644,8509],{},[85,14646,14647],{"class":87,"line":131},[85,14648,8514],{},[85,14650,14651],{"class":87,"line":137},[85,14652,8519],{},[85,14654,14655],{"class":87,"line":142},[85,14656,8524],{},[85,14658,14659],{"class":87,"line":5859},[85,14660,122],{"emptyLinePlaceholder":121},[85,14662,14663],{"class":87,"line":5864},[85,14664,8533],{},[85,14666,14667],{"class":87,"line":7469},[85,14668,6212],{},[85,14670,14671],{"class":87,"line":7475},[85,14672,6217],{},[85,14674,14675],{"class":87,"line":8544},[85,14676,122],{"emptyLinePlaceholder":121},[85,14678,14679],{"class":87,"line":8549},[85,14680,8552],{},[10,14682,147],{},[76,14684,14686],{"className":14685,"code":8558,"language":153,"meta":81},[151],[34,14687,8558],{"__ignoreMap":81},[10,14689,158],{},[14,14691,161],{"id":161},[163,14693,14694,14704],{},[45,14695,8569,14696,8573,14698,8577,14700,8581,14702,396],{},[34,14697,8572],{},[34,14699,8576],{},[34,14701,8580],{},[34,14703,8572],{},[45,14705,8586],{},[186,14707,188],{"id":188},[10,14709,8591],{},[10,14711,14712],{},[26,14713],{"alt":8596,"src":8597},[10,14715,14716,8602,14718,396],{},[34,14717,8453],{},[34,14719,8457],{},[14,14721,209],{"id":209},[42,14723,14724,14728],{},[45,14725,8611,14726,396],{},[34,14727,5410],{},[45,14729,8616],{},[14,14731,220],{"id":220},[163,14733,14734,14736],{},[45,14735,8623],{},[45,14737,8626,14738,8630],{},[34,14739,8629],{},[10,14741,237],{},[14,14743,240],{"id":240},[10,14745,8637],{},[245,14747,247],{},{"title":81,"searchDepth":94,"depth":94,"links":14749},[14750,14751,14752,14753,14754,14757,14758,14759],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":14755},[14756],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":8423,"description":8428},[260,8659,5361],{"id":8662,"title":8663,"body":14764,"category":260,"cover":261,"description":8668,"extension":262,"meta":14923,"navigation":121,"path":8856,"pinned":265,"publishedAt":266,"seo":14924,"slug":8858,"stem":8859,"summary":8860,"tags":14925,"updatedAt":266,"visible":121,"__hash__":8864},{"type":7,"value":14765,"toc":14911},[14766,14768,14770,14772,14774,14778,14780,14782,14790,14792,14794,14858,14860,14865,14867,14869,14877,14879,14881,14885,14887,14889,14895,14897,14903,14905,14907,14909],[10,14767,8668],{},[14,14769,16],{"id":16},[10,14771,8673],{},[14,14773,22],{"id":22},[10,14775,14776],{},[26,14777],{"alt":8680,"src":8681},[10,14779,8684],{},[14,14781,40],{"id":40},[42,14783,14784,14786,14788],{},[45,14785,8691],{},[45,14787,8694],{},[45,14789,8697],{},[14,14791,71],{"id":71},[10,14793,74],{},[76,14795,14796],{"className":78,"code":8704,"language":80,"meta":81,"style":81},[34,14797,14798,14802,14806,14810,14814,14818,14822,14826,14830,14834,14838,14842,14846,14850,14854],{"__ignoreMap":81},[85,14799,14800],{"class":87,"line":88},[85,14801,8711],{},[85,14803,14804],{"class":87,"line":94},[85,14805,8716],{},[85,14807,14808],{"class":87,"line":100},[85,14809,122],{"emptyLinePlaceholder":121},[85,14811,14812],{"class":87,"line":106},[85,14813,8725],{},[85,14815,14816],{"class":87,"line":112},[85,14817,122],{"emptyLinePlaceholder":121},[85,14819,14820],{"class":87,"line":118},[85,14821,8734],{},[85,14823,14824],{"class":87,"line":125},[85,14825,8739],{},[85,14827,14828],{"class":87,"line":131},[85,14829,8744],{},[85,14831,14832],{"class":87,"line":137},[85,14833,122],{"emptyLinePlaceholder":121},[85,14835,14836],{"class":87,"line":142},[85,14837,8753],{},[85,14839,14840],{"class":87,"line":5859},[85,14841,8758],{},[85,14843,14844],{"class":87,"line":5864},[85,14845,8763],{},[85,14847,14848],{"class":87,"line":7469},[85,14849,122],{"emptyLinePlaceholder":121},[85,14851,14852],{"class":87,"line":7475},[85,14853,6226],{},[85,14855,14856],{"class":87,"line":8544},[85,14857,8776],{},[10,14859,147],{},[76,14861,14863],{"className":14862,"code":8782,"language":153,"meta":81},[151],[34,14864,8782],{"__ignoreMap":81},[10,14866,158],{},[14,14868,161],{"id":161},[163,14870,14871,14875],{},[45,14872,14873,8796],{},[34,14874,8795],{},[45,14876,8799],{},[186,14878,188],{"id":188},[10,14880,8804],{},[10,14882,14883],{},[26,14884],{"alt":8809,"src":8810},[10,14886,8813],{},[14,14888,209],{"id":209},[42,14890,14891,14893],{},[45,14892,8820],{},[45,14894,8823],{},[14,14896,220],{"id":220},[163,14898,14899,14901],{},[45,14900,8830],{},[45,14902,8833],{},[10,14904,237],{},[14,14906,240],{"id":240},[10,14908,8840],{},[245,14910,247],{},{"title":81,"searchDepth":94,"depth":94,"links":14912},[14913,14914,14915,14916,14917,14920,14921,14922],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":14918},[14919],{"id":188,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":8663,"description":8668},[260,8862,8863],{"id":8866,"title":8867,"body":14927,"category":260,"cover":261,"description":8872,"extension":262,"meta":15165,"navigation":121,"path":9173,"pinned":265,"publishedAt":266,"seo":15166,"slug":9175,"stem":9176,"summary":9177,"tags":15167,"updatedAt":266,"visible":121,"__hash__":9181},{"type":7,"value":14928,"toc":15152},[14929,14931,14933,14935,14937,14941,14943,14945,14955,14957,14959,15075,15077,15082,15084,15086,15096,15098,15100,15104,15106,15108,15110,15114,15118,15120,15128,15130,15144,15146,15148,15150],[10,14930,8872],{},[14,14932,16],{"id":16},[10,14934,8877],{},[14,14936,22],{"id":22},[10,14938,14939],{},[26,14940],{"alt":8884,"src":8885},[10,14942,8888],{},[14,14944,40],{"id":40},[42,14946,14947,14949,14951],{},[45,14948,8895],{},[45,14950,8898],{},[45,14952,8901,14953,8905],{},[34,14954,8904],{},[14,14956,71],{"id":71},[10,14958,74],{},[76,14960,14961],{"className":78,"code":8912,"language":80,"meta":81,"style":81},[34,14962,14963,14967,14971,14975,14979,14983,14987,14991,14995,14999,15003,15007,15011,15015,15019,15023,15027,15031,15035,15039,15043,15047,15051,15055,15059,15063,15067,15071],{"__ignoreMap":81},[85,14964,14965],{"class":87,"line":88},[85,14966,7024],{},[85,14968,14969],{"class":87,"line":94},[85,14970,6633],{},[85,14972,14973],{"class":87,"line":100},[85,14974,122],{"emptyLinePlaceholder":121},[85,14976,14977],{"class":87,"line":106},[85,14978,8931],{},[85,14980,14981],{"class":87,"line":112},[85,14982,8936],{},[85,14984,14985],{"class":87,"line":118},[85,14986,8941],{},[85,14988,14989],{"class":87,"line":125},[85,14990,8946],{},[85,14992,14993],{"class":87,"line":131},[85,14994,122],{"emptyLinePlaceholder":121},[85,14996,14997],{"class":87,"line":137},[85,14998,8955],{},[85,15000,15001],{"class":87,"line":142},[85,15002,8960],{},[85,15004,15005],{"class":87,"line":5859},[85,15006,8965],{},[85,15008,15009],{"class":87,"line":5864},[85,15010,8970],{},[85,15012,15013],{"class":87,"line":7469},[85,15014,8975],{},[85,15016,15017],{"class":87,"line":7475},[85,15018,122],{"emptyLinePlaceholder":121},[85,15020,15021],{"class":87,"line":8544},[85,15022,8984],{},[85,15024,15025],{"class":87,"line":8549},[85,15026,8989],{},[85,15028,15029],{"class":87,"line":8992},[85,15030,8995],{},[85,15032,15033],{"class":87,"line":8998},[85,15034,122],{"emptyLinePlaceholder":121},[85,15036,15037],{"class":87,"line":9003},[85,15038,9006],{},[85,15040,15041],{"class":87,"line":9009},[85,15042,122],{"emptyLinePlaceholder":121},[85,15044,15045],{"class":87,"line":9014},[85,15046,7442],{},[85,15048,15049],{"class":87,"line":9019},[85,15050,9022],{},[85,15052,15053],{"class":87,"line":9025},[85,15054,9028],{},[85,15056,15057],{"class":87,"line":9031},[85,15058,9034],{},[85,15060,15061],{"class":87,"line":9037},[85,15062,7452],{},[85,15064,15065],{"class":87,"line":9042},[85,15066,9045],{},[85,15068,15069],{"class":87,"line":9048},[85,15070,1180],{},[85,15072,15073],{"class":87,"line":9053},[85,15074,9056],{},[10,15076,147],{},[76,15078,15080],{"className":15079,"code":9062,"language":153,"meta":81},[151],[34,15081,9062],{"__ignoreMap":81},[10,15083,158],{},[14,15085,161],{"id":161},[163,15087,15088,15092],{},[45,15089,9073,15090,9076],{},[34,15091,8904],{},[45,15093,15094,9081],{},[34,15095,8189],{},[186,15097,188],{"id":188},[10,15099,9086],{},[10,15101,15102],{},[26,15103],{"alt":9091,"src":9092},[10,15105,9095],{},[186,15107,188],{"id":4250},[10,15109,9100],{},[10,15111,15112],{},[26,15113],{"alt":9105,"src":9106},[10,15115,9109,15116,9113],{},[34,15117,9112],{},[14,15119,209],{"id":209},[42,15121,15122,15124],{},[45,15123,9120],{},[45,15125,9123,15126,9126],{},[34,15127,9112],{},[14,15129,220],{"id":220},[163,15131,15132,15136,15138],{},[45,15133,9133,15134,9136],{},[34,15135,9112],{},[45,15137,9139],{},[45,15139,9142,15140,9146,15142,9149],{},[34,15141,9145],{},[34,15143,6168],{},[10,15145,237],{},[14,15147,240],{"id":240},[10,15149,9156],{},[245,15151,247],{},{"title":81,"searchDepth":94,"depth":94,"links":15153},[15154,15155,15156,15157,15158,15162,15163,15164],{"id":16,"depth":94,"text":16},{"id":22,"depth":94,"text":22},{"id":40,"depth":94,"text":40},{"id":71,"depth":94,"text":71},{"id":161,"depth":94,"text":161,"children":15159},[15160,15161],{"id":188,"depth":100,"text":188},{"id":4250,"depth":100,"text":188},{"id":209,"depth":94,"text":209},{"id":220,"depth":94,"text":220},{"id":240,"depth":94,"text":240},{},{"title":8867,"description":8872},[260,9179,9180],{"id":1090,"title":1091,"body":15169,"category":260,"cover":1099,"description":81,"extension":262,"meta":15405,"navigation":121,"path":1416,"pinned":265,"publishedAt":1417,"seo":15406,"slug":1419,"stem":1420,"summary":1421,"tags":15407,"updatedAt":1417,"visible":121,"__hash__":1425},{"type":7,"value":15170,"toc":15390},[15171,15175,15177,15179,15181,15183,15203,15205,15210,15212,15214,15242,15248,15250,15254,15256,15276,15278,15288,15290,15292,15294,15296,15298,15300,15302,15304,15306,15326,15328,15330,15334,15336,15338,15340,15342,15346,15348,15366,15368,15370,15372,15374,15376,15378,15380,15382,15384,15386,15388],[10,15172,15173],{},[26,15174],{"alt":1098,"src":1099},[10,15176,1102],{},[10,15178,1105],{},[14,15180,1109],{"id":1108},[10,15182,1112],{},[76,15184,15185],{"className":78,"code":1115,"language":80,"meta":81,"style":81},[34,15186,15187,15191,15195,15199],{"__ignoreMap":81},[85,15188,15189],{"class":87,"line":88},[85,15190,1122],{},[85,15192,15193],{"class":87,"line":94},[85,15194,1127],{},[85,15196,15197],{"class":87,"line":100},[85,15198,122],{"emptyLinePlaceholder":121},[85,15200,15201],{"class":87,"line":106},[85,15202,1136],{},[10,15204,1139],{},[76,15206,15208],{"className":15207,"code":1143,"language":153,"meta":81},[151],[34,15209,1143],{"__ignoreMap":81},[10,15211,1148],{},[10,15213,1151],{},[76,15215,15216],{"className":78,"code":1154,"language":80,"meta":81,"style":81},[34,15217,15218,15222,15226,15230,15234,15238],{"__ignoreMap":81},[85,15219,15220],{"class":87,"line":88},[85,15221,1161],{},[85,15223,15224],{"class":87,"line":94},[85,15225,122],{"emptyLinePlaceholder":121},[85,15227,15228],{"class":87,"line":100},[85,15229,1170],{},[85,15231,15232],{"class":87,"line":106},[85,15233,1175],{},[85,15235,15236],{"class":87,"line":112},[85,15237,1180],{},[85,15239,15240],{"class":87,"line":118},[85,15241,1185],{},[10,15243,15244,1191,15246,1195],{},[34,15245,1190],{},[34,15247,1194],{},[14,15249,1199],{"id":1198},[10,15251,1202,15252,1206],{},[34,15253,1205],{},[10,15255,1209],{},[76,15257,15258],{"className":78,"code":1212,"language":80,"meta":81,"style":81},[34,15259,15260,15264,15268,15272],{"__ignoreMap":81},[85,15261,15262],{"class":87,"line":88},[85,15263,1219],{},[85,15265,15266],{"class":87,"line":94},[85,15267,1224],{},[85,15269,15270],{"class":87,"line":100},[85,15271,1229],{},[85,15273,15274],{"class":87,"line":106},[85,15275,1234],{},[10,15277,1237],{},[76,15279,15280],{"className":625,"code":1240,"language":627,"meta":81,"style":81},[34,15281,15282],{"__ignoreMap":81},[85,15283,15284,15286],{"class":87,"line":88},[85,15285,725],{"class":634},[85,15287,1249],{"class":670},[10,15289,1252],{},[14,15291,1256],{"id":1255},[186,15293,1259],{"id":1259},[10,15295,1262],{},[186,15297,1265],{"id":1265},[10,15299,1268],{},[186,15301,1271],{"id":1271},[10,15303,1274],{},[10,15305,1277],{},[76,15307,15308],{"className":78,"code":1280,"language":80,"meta":81,"style":81},[34,15309,15310,15314,15318,15322],{"__ignoreMap":81},[85,15311,15312],{"class":87,"line":88},[85,15313,1287],{},[85,15315,15316],{"class":87,"line":94},[85,15317,122],{"emptyLinePlaceholder":121},[85,15319,15320],{"class":87,"line":100},[85,15321,1296],{},[85,15323,15324],{"class":87,"line":106},[85,15325,1301],{},[10,15327,1304],{},[186,15329,1307],{"id":1307},[10,15331,1310,15332,1313],{},[34,15333,295],{},[10,15335,1316],{},[186,15337,1319],{"id":1319},[10,15339,1322],{},[14,15341,1326],{"id":1325},[10,15343,15344],{},[26,15345],{"alt":1331,"src":1332},[10,15347,1335],{},[42,15349,15350,15352,15354,15356,15358,15360,15362,15364],{},[45,15351,1340],{},[45,15353,1343],{},[45,15355,1346],{},[45,15357,1349],{},[45,15359,1352],{},[45,15361,1355],{},[45,15363,1358],{},[45,15365,1361],{},[10,15367,1364],{},[14,15369,1368],{"id":1367},[10,15371,1371],{},[10,15373,1374],{},[14,15375,1378],{"id":1377},[10,15377,1381],{},[10,15379,1384],{},[10,15381,1387],{},[14,15383,1390],{"id":1390},[10,15385,1393],{},[10,15387,1396],{},[245,15389,1399],{},{"title":81,"searchDepth":94,"depth":94,"links":15391},[15392,15393,15394,15401,15402,15403,15404],{"id":1108,"depth":94,"text":1109},{"id":1198,"depth":94,"text":1199},{"id":1255,"depth":94,"text":1256,"children":15395},[15396,15397,15398,15399,15400],{"id":1259,"depth":100,"text":1259},{"id":1265,"depth":100,"text":1265},{"id":1271,"depth":100,"text":1271},{"id":1307,"depth":100,"text":1307},{"id":1319,"depth":100,"text":1319},{"id":1325,"depth":94,"text":1326},{"id":1367,"depth":94,"text":1368},{"id":1377,"depth":94,"text":1378},{"id":1390,"depth":94,"text":1390},{},{"title":1091,"description":81},[260,1423,1424],{"id":277,"title":278,"body":15409,"category":260,"cover":261,"description":81,"extension":262,"meta":15988,"navigation":121,"path":1079,"pinned":265,"publishedAt":1080,"seo":15989,"slug":1082,"stem":1083,"summary":1084,"tags":15990,"updatedAt":1080,"visible":121,"__hash__":1088},{"type":7,"value":15410,"toc":15964},[15411,15413,15415,15417,15421,15423,15425,15449,15461,15463,15465,15470,15474,15478,15490,15494,15498,15502,15504,15538,15540,15544,15548,15550,15572,15602,15614,15624,15632,15634,15640,15650,15652,15657,15661,15663,15677,15683,15703,15705,15707,15709,15719,15723,15725,15734,15738,15740,15742,15762,15766,15768,15770,15772,15774,15794,15796,15798,15800,15826,15828,15844,15846,15862,15866,15868,15870,15890,15892,15894,15896,15900,15910,15912,15914,15916,15926,15934,15936,15938,15952,15962],[14,15412,283],{"id":283},[10,15414,286],{},[10,15416,289],{},[10,15418,292,15419,296],{},[34,15420,295],{},[14,15422,299],{"id":299},[10,15424,302],{},[304,15426,15427,15429],{},[10,15428,308],{},[304,15430,15431,15437,15439,15443,15445],{},[10,15432,313,15433,317,15435,321],{},[34,15434,316],{},[34,15436,320],{},[10,15438,324],{},[10,15440,327,15441,332],{},[329,15442,331],{},[10,15444,335],{},[10,15446,15447],{},[26,15448],{"alt":340,"src":341},[304,15450,15451,15453],{},[10,15452,346],{},[304,15454,15455,15457],{},[10,15456,351],{},[10,15458,15459],{},[26,15460],{"alt":356,"src":357},[14,15462,361],{"id":360},[186,15464,365],{"id":364},[10,15466,368,15467,376],{},[370,15468,375],{"href":372,"rel":15469},[374],[304,15471,15472],{},[10,15473,381],{},[10,15475,15476],{},[26,15477],{"alt":386,"src":387},[42,15479,15480,15484,15488],{},[45,15481,392,15482,396],{},[329,15483,395],{},[45,15485,399,15486,396],{},[329,15487,402],{},[45,15489,405],{},[10,15491,15492],{},[26,15493],{"alt":410,"src":411},[304,15495,15496],{},[10,15497,416],{},[10,15499,15500],{},[26,15501],{"alt":421,"src":422},[186,15503,426],{"id":425},[304,15505,15506,15510,15514,15534],{},[304,15507,15508],{},[10,15509,433],{},[10,15511,436,15512,440],{},[329,15513,439],{},[76,15515,15516],{"className":78,"code":443,"language":80,"meta":81,"style":81},[34,15517,15518,15522,15526,15530],{"__ignoreMap":81},[85,15519,15520],{"class":87,"line":88},[85,15521,450],{},[85,15523,15524],{"class":87,"line":94},[85,15525,455],{},[85,15527,15528],{"class":87,"line":100},[85,15529,460],{},[85,15531,15532],{"class":87,"line":106},[85,15533,465],{},[10,15535,468,15536,472],{},[329,15537,471],{},[10,15539,475],{},[10,15541,478,15542,481],{},[34,15543,80],{},[10,15545,15546],{},[26,15547],{"alt":486,"src":487},[10,15549,490],{},[304,15551,15552,15554,15558],{},[10,15553,495],{},[10,15555,15556],{},[329,15557,500],{},[304,15559,15560,15564,15568],{},[10,15561,505,15562,508],{},[34,15563,80],{},[10,15565,511,15566,514],{},[34,15567,80],{},[10,15569,517,15570,521],{},[329,15571,520],{},[304,15573,15574,15576,15580],{},[10,15575,526],{},[10,15577,15578],{},[329,15579,531],{},[304,15581,15582,15588,15596,15598],{},[10,15583,15584,539,15586,543],{},[34,15585,538],{},[34,15587,542],{},[10,15589,546,15590,549,15592,553,15594,557],{},[34,15591,538],{},[329,15593,552],{},[329,15595,556],{},[10,15597,560],{},[10,15599,15600,566],{},[329,15601,565],{},[304,15603,15604,15606],{},[10,15605,571],{},[304,15607,15608,15612],{},[10,15609,576,15610,580],{},[329,15611,579],{},[10,15613,583],{},[304,15615,15616,15620],{},[10,15617,588,15618],{},[329,15619,591],{},[10,15621,15622],{},[26,15623],{"alt":596,"src":597},[304,15625,15626,15628],{},[10,15627,602],{},[10,15629,15630],{},[26,15631],{"alt":596,"src":607},[186,15633,611],{"id":610},[10,15635,614,15636,618,15638,622],{},[34,15637,617],{},[34,15639,621],{},[76,15641,15642],{"className":625,"code":626,"language":627,"meta":81,"style":81},[34,15643,15644],{"__ignoreMap":81},[85,15645,15646,15648],{"class":87,"line":88},[85,15647,80],{"class":634},[85,15649,638],{"class":637},[10,15651,641],{},[76,15653,15655],{"className":15654,"code":645,"language":153,"meta":81},[151],[34,15656,645],{"__ignoreMap":81},[10,15658,15659],{},[26,15660],{"alt":596,"src":652},[10,15662,655],{},[76,15664,15665],{"className":625,"code":658,"language":627,"meta":81,"style":81},[34,15666,15667],{"__ignoreMap":81},[85,15668,15669,15671,15673,15675],{"class":87,"line":88},[85,15670,80],{"class":634},[85,15672,667],{"class":637},[85,15674,671],{"class":670},[85,15676,638],{"class":637},[10,15678,676,15679,679,15681,683],{},[34,15680,80],{},[34,15682,682],{},[76,15684,15685],{"className":625,"code":686,"language":627,"meta":81,"style":81},[34,15686,15687,15693],{"__ignoreMap":81},[85,15688,15689,15691],{"class":87,"line":88},[85,15690,542],{"class":634},[85,15692,638],{"class":637},[85,15694,15695,15697,15699,15701],{"class":87,"line":94},[85,15696,542],{"class":634},[85,15698,667],{"class":637},[85,15700,671],{"class":670},[85,15702,638],{"class":637},[14,15704,708],{"id":707},[186,15706,712],{"id":711},[10,15708,715],{},[76,15710,15711],{"className":625,"code":718,"language":627,"meta":81,"style":81},[34,15712,15713],{"__ignoreMap":81},[85,15714,15715,15717],{"class":87,"line":88},[85,15716,725],{"class":634},[85,15718,638],{"class":637},[10,15720,730,15721,734],{},[34,15722,733],{},[186,15724,738],{"id":737},[10,15726,368,15727,746,15730,396,15732,753],{},[370,15728,745],{"href":743,"rel":15729},[374],[329,15731,749],{},[34,15733,752],{},[10,15735,756,15736,760],{},[34,15737,759],{},[186,15739,764],{"id":763},[10,15741,767],{},[76,15743,15744],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,15745,15746,15752],{"__ignoreMap":81},[85,15747,15748,15750],{"class":87,"line":88},[85,15749,725],{"class":634},[85,15751,638],{"class":637},[85,15753,15754,15756,15758,15760],{"class":87,"line":94},[85,15755,725],{"class":634},[85,15757,667],{"class":637},[85,15759,671],{"class":670},[85,15761,638],{"class":637},[10,15763,791,15764,794],{},[34,15765,725],{},[14,15767,798],{"id":797},[10,15769,801],{},[186,15771,805],{"id":804},[10,15773,808],{},[76,15775,15776],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,15777,15778,15784],{"__ignoreMap":81},[85,15779,15780,15782],{"class":87,"line":88},[85,15781,725],{"class":634},[85,15783,638],{"class":637},[85,15785,15786,15788,15790,15792],{"class":87,"line":94},[85,15787,725],{"class":634},[85,15789,667],{"class":637},[85,15791,671],{"class":670},[85,15793,638],{"class":637},[10,15795,831],{},[186,15797,835],{"id":834},[10,15799,838],{},[76,15801,15802],{"className":625,"code":841,"language":627,"meta":81,"style":81},[34,15803,15804,15812],{"__ignoreMap":81},[85,15805,15806,15808,15810],{"class":87,"line":88},[85,15807,848],{"class":634},[85,15809,851],{"class":670},[85,15811,854],{"class":670},[85,15813,15814,15816,15818,15820,15822,15824],{"class":87,"line":94},[85,15815,848],{"class":634},[85,15817,851],{"class":670},[85,15819,863],{"class":670},[85,15821,866],{"class":670},[85,15823,869],{"class":670},[85,15825,872],{"class":670},[10,15827,875],{},[76,15829,15830],{"className":625,"code":878,"language":627,"meta":81,"style":81},[34,15831,15832],{"__ignoreMap":81},[85,15833,15834,15836,15838,15840,15842],{"class":87,"line":88},[85,15835,848],{"class":634},[85,15837,887],{"class":670},[85,15839,863],{"class":670},[85,15841,866],{"class":670},[85,15843,894],{"class":670},[10,15845,897],{},[76,15847,15848],{"className":625,"code":900,"language":627,"meta":81,"style":81},[34,15849,15850],{"__ignoreMap":81},[85,15851,15852,15854,15856,15858,15860],{"class":87,"line":88},[85,15853,848],{"class":634},[85,15855,909],{"class":670},[85,15857,912],{"class":637},[85,15859,915],{"class":670},[85,15861,918],{"class":670},[10,15863,15864,923],{},[34,15865,848],{},[186,15867,927],{"id":926},[10,15869,930],{},[76,15871,15872],{"className":625,"code":770,"language":627,"meta":81,"style":81},[34,15873,15874,15880],{"__ignoreMap":81},[85,15875,15876,15878],{"class":87,"line":88},[85,15877,725],{"class":634},[85,15879,638],{"class":637},[85,15881,15882,15884,15886,15888],{"class":87,"line":94},[85,15883,725],{"class":634},[85,15885,667],{"class":637},[85,15887,671],{"class":670},[85,15889,638],{"class":637},[10,15891,953],{},[14,15893,956],{"id":956},[186,15895,960],{"id":959},[10,15897,963,15898,967],{},[34,15899,966],{},[163,15901,15902,15906,15908],{},[45,15903,972,15904,975],{},[34,15905,682],{},[45,15907,978],{},[45,15909,981],{},[10,15911,984],{},[186,15913,988],{"id":987},[10,15915,991],{},[76,15917,15918],{"className":625,"code":718,"language":627,"meta":81,"style":81},[34,15919,15920],{"__ignoreMap":81},[85,15921,15922,15924],{"class":87,"line":88},[85,15923,725],{"class":634},[85,15925,638],{"class":637},[10,15927,1004,15928,1007,15930,1010,15932,396],{},[34,15929,725],{},[34,15931,80],{},[34,15933,725],{},[186,15935,1016],{"id":1015},[10,15937,1019],{},[76,15939,15940],{"className":625,"code":1022,"language":627,"meta":81,"style":81},[34,15941,15942],{"__ignoreMap":81},[85,15943,15944,15946,15948,15950],{"class":87,"line":88},[85,15945,725],{"class":634},[85,15947,667],{"class":637},[85,15949,671],{"class":670},[85,15951,638],{"class":637},[10,15953,1037,15954,1040,15956,1043,15958,1046,15960,1050],{},[34,15955,725],{},[34,15957,80],{},[34,15959,542],{},[34,15961,1049],{},[245,15963,1053],{},{"title":81,"searchDepth":94,"depth":94,"links":15965},[15966,15967,15968,15973,15978,15983],{"id":283,"depth":94,"text":283},{"id":299,"depth":94,"text":299},{"id":360,"depth":94,"text":361,"children":15969},[15970,15971,15972],{"id":364,"depth":100,"text":365},{"id":425,"depth":100,"text":426},{"id":610,"depth":100,"text":611},{"id":707,"depth":94,"text":708,"children":15974},[15975,15976,15977],{"id":711,"depth":100,"text":712},{"id":737,"depth":100,"text":738},{"id":763,"depth":100,"text":764},{"id":797,"depth":94,"text":798,"children":15979},[15980,15981,15982],{"id":804,"depth":100,"text":805},{"id":834,"depth":100,"text":835},{"id":926,"depth":100,"text":927},{"id":956,"depth":94,"text":956,"children":15984},[15985,15986,15987],{"id":959,"depth":100,"text":960},{"id":987,"depth":100,"text":988},{"id":1015,"depth":100,"text":1016},{},{"title":278,"description":81},[260,1086,1087],1786973366408]