[{"data":1,"prerenderedAt":15975},["ShallowReactive",2],{"post-python-composition-inheritance":3,"sidebar-posts":249,"post-related-source":9166},{"id":4,"title":5,"body":6,"category":234,"cover":235,"description":12,"extension":236,"meta":237,"navigation":90,"path":238,"pinned":239,"publishedAt":240,"seo":241,"slug":242,"stem":243,"summary":244,"tags":245,"updatedAt":240,"visible":90,"__hash__":248},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8,"toc":224},"minimark",[9,13,17,20,23,30,33,36,49,52,55,144,147,155,158,161,181,184,192,195,211,214,217,220],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[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\u002F36-composition-inheritance.svg",[10,31,32],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,34,35],{"id":35},"核心概念",[37,38,39,43,46],"ul",{},[40,41,42],"li",{},"封装让对象通过方法维护自己的有效状态。",[40,44,45],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[40,47,48],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,50,51],{"id":51},"跟着示例运行",[10,53,54],{},"把下面代码保存到本课脚本并运行：",[56,57,62],"pre",{"className":58,"code":59,"language":60,"meta":61,"style":61},"language-python shiki shiki-themes github-dark","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","python","",[63,64,65,73,79,85,92,98,104,110,115,121,127,132,138],"code",{"__ignoreMap":61},[66,67,70],"span",{"class":68,"line":69},"line",1,[66,71,72],{},"class Storage:\n",[66,74,76],{"class":68,"line":75},2,[66,77,78],{},"    def save(self, text):\n",[66,80,82],{"class":68,"line":81},3,[66,83,84],{},"        print(\"保存：\", text)\n",[66,86,88],{"class":68,"line":87},4,[66,89,91],{"emptyLinePlaceholder":90},true,"\n",[66,93,95],{"class":68,"line":94},5,[66,96,97],{},"class LearningService:\n",[66,99,101],{"class":68,"line":100},6,[66,102,103],{},"    def __init__(self, storage):\n",[66,105,107],{"class":68,"line":106},7,[66,108,109],{},"        self.storage = storage\n",[66,111,113],{"class":68,"line":112},8,[66,114,91],{"emptyLinePlaceholder":90},[66,116,118],{"class":68,"line":117},9,[66,119,120],{},"    def finish_lesson(self, title):\n",[66,122,124],{"class":68,"line":123},10,[66,125,126],{},"        self.storage.save(title)\n",[66,128,130],{"class":68,"line":129},11,[66,131,91],{"emptyLinePlaceholder":90},[66,133,135],{"class":68,"line":134},12,[66,136,137],{},"service = LearningService(Storage())\n",[66,139,141],{"class":68,"line":140},13,[66,142,143],{},"service.finish_lesson(\"异常处理\")\n",[10,145,146],{},"预期结果：",[56,148,153],{"className":149,"code":151,"language":152,"meta":61},[150],"language-text","保存： 异常处理\n","text",[63,154,151],{"__ignoreMap":61},[10,156,157],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,159,160],{"id":160},"按执行顺序拆开看",[162,163,164,174],"ol",{},[40,165,166,169,170,173],{},[63,167,168],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[63,171,172],{},"save()"," 的协作对象。",[40,175,176,177,180],{},"调用业务方法时，服务把保存动作委托给 ",[63,178,179],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,182,183],{"id":183},"初学者容易混淆的地方",[37,185,186,189],{},[40,187,188],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[40,190,191],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,193,194],{"id":194},"练习",[162,196,197,208],{},[40,198,199,200,203,204,207],{},"用组合让 ",[63,201,202],{},"OrderService"," 使用一个 ",[63,205,206],{},"Notifier","。",[40,209,210],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,212,213],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,215,216],{"id":216},"本篇边界",[10,218,219],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,222,223],"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":61,"searchDepth":75,"depth":75,"links":225},[226,227,228,229,230,231,232,233],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",false,"2026-08-17",{"title":5,"description":12},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[234,246,247],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",[250,1063,1400,1534,1686,1865,2053,2218,2402,2583,2776,3007,3191,3368,3525,3696,3861,4075,4303,4485,4649,4838,5026,5181,5341,5538,5735,5947,6114,6358,6539,6744,6939,7123,7324,7613,7805,8034,8185,8405,8645,8849],{"id":251,"title":252,"body":253,"category":234,"cover":235,"description":61,"extension":236,"meta":1052,"navigation":90,"path":1053,"pinned":239,"publishedAt":1054,"seo":1055,"slug":1056,"stem":1057,"summary":1058,"tags":1059,"updatedAt":1054,"visible":90,"__hash__":1062},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":254,"toc":1028},[255,258,261,264,271,274,277,316,332,336,341,352,357,363,380,386,391,397,401,447,450,456,462,465,496,541,558,572,582,586,597,613,616,622,627,630,648,658,679,683,687,690,702,709,713,728,735,739,742,763,769,773,776,780,783,803,806,810,813,847,850,869,872,893,898,902,905,925,928,931,935,942,956,959,963,966,976,987,991,994,1009,1025],[14,256,257],{"id":257},"引言",[10,259,260],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,262,263],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,265,266,267,270],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[63,268,269],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,272,273],{"id":273},"扫盲",[10,275,276],{},"那么这里有几个概念：",[278,279,280,283],"blockquote",{},[10,281,282],{},"为什么需要安装python解释器？",[278,284,285,296,299,307,310],{},[10,286,287,288,291,292,295],{},"我们写的代码，电脑其实看不懂，电脑只认识",[63,289,290],{},"0","和",[63,293,294],{},"1","组成的机器指令。",[10,297,298],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,300,301,302,306],{},"这样，我们就能用",[303,304,305],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,308,309],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,311,312],{},[26,313],{"alt":314,"src":315},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[278,317,318,321],{},[10,319,320],{},"pip又是什么？",[278,322,323,326],{},[10,324,325],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,327,328],{},[26,329],{"alt":330,"src":331},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,333,335],{"id":334},"windows-安装","Windows 安装",[337,338,340],"h3",{"id":339},"_1-下载官方安装程序","1. 下载官方安装程序",[10,342,343,344,351],{},"打开 ",[345,346,350],"a",{"href":347,"rel":348},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[349],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[278,353,354],{},[10,355,356],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,358,359],{},[26,360],{"alt":361,"src":362},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[37,364,365,371,377],{},[40,366,367,368,207],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[303,369,370],{},"Windows installer (64-bit)",[40,372,373,374,207],{},"搭载 ARM 处理器的 Windows 设备选择 ",[303,375,376],{},"Windows installer (ARM64)",[40,378,379],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,381,382],{},[26,383],{"alt":384,"src":385},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[278,387,388],{},[10,389,390],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,392,393],{},[26,394],{"alt":395,"src":396},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[337,398,400],{"id":399},"_2-安装并加入-path","2. 安装并加入 PATH",[278,402,403,408,415,440],{},[278,404,405],{},[10,406,407],{},"PATH 环境变量",[10,409,410,411,414],{},"Windows 有一个特殊的变量叫 ",[303,412,413],{},"PATH","，它里面存了一串文件夹路径，比如：",[56,416,418],{"className":58,"code":417,"language":60,"meta":61,"style":61},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[63,419,420,425,430,435],{"__ignoreMap":61},[66,421,422],{"class":68,"line":69},[66,423,424],{},"D:\\Python313\\\n",[66,426,427],{"class":68,"line":75},[66,428,429],{},"D:\\Python313\\Scripts\\\n",[66,431,432],{"class":68,"line":81},[66,433,434],{},"C:\\Windows\\System32\\\n",[66,436,437],{"class":68,"line":87},[66,438,439],{},"...\n",[10,441,442,443,446],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[303,444,445],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,448,449],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,451,452,453,455],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[63,454,60],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,457,458],{},[26,459],{"alt":460,"src":461},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,463,464],{},"对安装界面最底部的两个勾选项分别解释 :",[278,466,467,470,475],{},[10,468,469],{},"Add python.exe to PATH",[10,471,472],{},[303,473,474],{},"把 Python 添加到系统环境变量",[278,476,477,483,489],{},[10,478,479,480,482],{},"勾选后，你可以在命令行任意位置直接输入 ",[63,481,60],{}," 就能运行",[10,484,485,486,488],{},"不勾选的话，命令行输入 ",[63,487,60],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,490,491,492,495],{},"必须",[303,493,494],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[278,497,498,501,506],{},[10,499,500],{},"Use admin privileges when installing py.exe",[10,502,503],{},[303,504,505],{},"使用管理员权限安装 py.exe（Python 启动器）",[278,507,508,518,532,535],{},[10,509,510,513,514,517],{},[63,511,512],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[63,515,516],{},"py"," 来启动 Python。",[10,519,520,521,523,524,527,528,531],{},"勾选后，",[63,522,512],{}," 会安装到",[303,525,526],{},"系统级目录","，电脑上",[303,529,530],{},"所有用户账户","都能用",[10,533,534],{},"不勾选，只有当前用户能用",[10,536,537,540],{},[303,538,539],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[278,542,543,546],{},[10,544,545],{},"操作建议",[278,547,548,555],{},[10,549,550,551,554],{},"两个都勾上之后，再点 ",[303,552,553],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,556,557],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[278,559,560,566],{},[10,561,562,563],{},"Python 安装的",[303,564,565],{},"可选功能页",[10,567,568],{},[26,569],{"alt":570,"src":571},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[278,573,574,577],{},[10,575,576],{},"高级选项页",[10,578,579],{},[26,580],{"alt":570,"src":581},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[337,583,585],{"id":584},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,587,588,589,592,593,596],{},"按 ",[63,590,591],{},"Win + R","，输入 ",[63,594,595],{},"cmd"," 并回车，然后执行：",[56,598,602],{"className":599,"code":600,"language":601,"meta":61,"style":61},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[63,603,604],{"__ignoreMap":61},[66,605,606,609],{"class":68,"line":69},[66,607,60],{"class":608},"svObZ",[66,610,612],{"class":611},"sDLfK"," --version\n",[10,614,615],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[56,617,620],{"className":618,"code":619,"language":152,"meta":61},[150],"Python 3.x.x\n",[63,621,619],{"__ignoreMap":61},[10,623,624],{},[26,625],{"alt":570,"src":626},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,628,629],{},"继续检查 pip：",[56,631,633],{"className":599,"code":632,"language":601,"meta":61,"style":61},"python -m pip --version\n",[63,634,635],{"__ignoreMap":61},[66,636,637,639,642,646],{"class":68,"line":69},[66,638,60],{"class":608},[66,640,641],{"class":611}," -m",[66,643,645],{"class":644},"sU2Wk"," pip",[66,647,612],{"class":611},[10,649,650,651,653,654,657],{},"如果 ",[63,652,60],{}," 无法识别，但 ",[63,655,656],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[56,659,661],{"className":599,"code":660,"language":601,"meta":61,"style":61},"py --version\npy -m pip --version\n",[63,662,663,669],{"__ignoreMap":61},[66,664,665,667],{"class":68,"line":69},[66,666,516],{"class":608},[66,668,612],{"class":611},[66,670,671,673,675,677],{"class":68,"line":75},[66,672,516],{"class":608},[66,674,641],{"class":611},[66,676,645],{"class":644},[66,678,612],{"class":611},[14,680,682],{"id":681},"macos-安装","macOS 安装",[337,684,686],{"id":685},"_1-先检查现有环境","1. 先检查现有环境",[10,688,689],{},"打开“终端”应用，执行：",[56,691,693],{"className":599,"code":692,"language":601,"meta":61,"style":61},"python3 --version\n",[63,694,695],{"__ignoreMap":61},[66,696,697,700],{"class":68,"line":69},[66,698,699],{"class":608},"python3",[66,701,612],{"class":611},[10,703,704,705,708],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[63,706,707],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[337,710,712],{"id":711},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,714,343,715,720,721,207,724,727],{},[345,716,719],{"href":717,"rel":718},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[349],"Python macOS 下载页","，下载当前稳定版的 ",[303,722,723],{},"macOS 64-bit universal2 installer",[63,725,726],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,729,730,731,734],{},"下载完成后打开 ",[63,732,733],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[337,736,738],{"id":737},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,740,741],{},"安装完成后重新打开终端，执行：",[56,743,745],{"className":599,"code":744,"language":601,"meta":61,"style":61},"python3 --version\npython3 -m pip --version\n",[63,746,747,753],{"__ignoreMap":61},[66,748,749,751],{"class":68,"line":69},[66,750,699],{"class":608},[66,752,612],{"class":611},[66,754,755,757,759,761],{"class":68,"line":75},[66,756,699],{"class":608},[66,758,641],{"class":611},[66,760,645],{"class":644},[66,762,612],{"class":611},[10,764,765,766,768],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[63,767,699],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,770,772],{"id":771},"linux-安装","Linux 安装",[10,774,775],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[337,777,779],{"id":778},"_1-检查是否已经安装","1. 检查是否已经安装",[10,781,782],{},"打开终端，执行：",[56,784,785],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,786,787,793],{"__ignoreMap":61},[66,788,789,791],{"class":68,"line":69},[66,790,699],{"class":608},[66,792,612],{"class":611},[66,794,795,797,799,801],{"class":68,"line":75},[66,796,699],{"class":608},[66,798,641],{"class":611},[66,800,645],{"class":644},[66,802,612],{"class":611},[10,804,805],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[337,807,809],{"id":808},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,811,812],{},"Ubuntu 或 Debian：",[56,814,816],{"className":599,"code":815,"language":601,"meta":61,"style":61},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[63,817,818,829],{"__ignoreMap":61},[66,819,820,823,826],{"class":68,"line":69},[66,821,822],{"class":608},"sudo",[66,824,825],{"class":644}," apt",[66,827,828],{"class":644}," update\n",[66,830,831,833,835,838,841,844],{"class":68,"line":75},[66,832,822],{"class":608},[66,834,825],{"class":644},[66,836,837],{"class":644}," install",[66,839,840],{"class":644}," python3",[66,842,843],{"class":644}," python3-pip",[66,845,846],{"class":644}," python3-venv\n",[10,848,849],{},"Fedora：",[56,851,853],{"className":599,"code":852,"language":601,"meta":61,"style":61},"sudo dnf install python3 python3-pip\n",[63,854,855],{"__ignoreMap":61},[66,856,857,859,862,864,866],{"class":68,"line":69},[66,858,822],{"class":608},[66,860,861],{"class":644}," dnf",[66,863,837],{"class":644},[66,865,840],{"class":644},[66,867,868],{"class":644}," python3-pip\n",[10,870,871],{},"Arch Linux：",[56,873,875],{"className":599,"code":874,"language":601,"meta":61,"style":61},"sudo pacman -S python python-pip\n",[63,876,877],{"__ignoreMap":61},[66,878,879,881,884,887,890],{"class":68,"line":69},[66,880,822],{"class":608},[66,882,883],{"class":644}," pacman",[66,885,886],{"class":611}," -S",[66,888,889],{"class":644}," python",[66,891,892],{"class":644}," python-pip\n",[10,894,895,897],{},[63,896,822],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[337,899,901],{"id":900},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,903,904],{},"安装结束后执行：",[56,906,907],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,908,909,915],{"__ignoreMap":61},[66,910,911,913],{"class":68,"line":69},[66,912,699],{"class":608},[66,914,612],{"class":611},[66,916,917,919,921,923],{"class":68,"line":75},[66,918,699],{"class":608},[66,920,641],{"class":611},[66,922,645],{"class":644},[66,924,612],{"class":611},[10,926,927],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,929,930],{"id":930},"常见问题",[337,932,934],{"id":933},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,936,937,938,941],{},"先关闭当前命令提示符并重新打开，再执行 ",[63,939,940],{},"python --version","。如果仍然失败，按下面的顺序检查：",[162,943,944,950,953],{},[40,945,946,947,949],{},"执行 ",[63,948,656],{},"，确认 Python Launcher 是否可用。",[40,951,952],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[40,954,955],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,957,958],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[337,960,962],{"id":961},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,964,965],{},"先尝试：",[56,967,968],{"className":599,"code":692,"language":601,"meta":61,"style":61},[63,969,970],{"__ignoreMap":61},[66,971,972,974],{"class":68,"line":69},[66,973,699],{"class":608},[66,975,612],{"class":611},[10,977,978,979,981,982,984,985,207],{},"在这两个系统中，只有 ",[63,980,699],{}," 命令而没有 ",[63,983,60],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[63,986,699],{},[337,988,990],{"id":989},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,992,993],{},"先使用模块方式检查：",[56,995,997],{"className":599,"code":996,"language":601,"meta":61,"style":61},"python3 -m pip --version\n",[63,998,999],{"__ignoreMap":61},[66,1000,1001,1003,1005,1007],{"class":68,"line":69},[66,1002,699],{"class":608},[66,1004,641],{"class":611},[66,1006,645],{"class":644},[66,1008,612],{"class":611},[10,1010,1011,1012,1014,1015,1017,1018,1020,1021,1024],{},"Windows 用户将命令中的 ",[63,1013,699],{}," 换成 ",[63,1016,60],{}," 或 ",[63,1019,516],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[63,1022,1023],{},"python3-pip","；不要直接使用其他系统的安装命令。",[221,1026,1027],{},"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":61,"searchDepth":75,"depth":75,"links":1029},[1030,1031,1032,1037,1042,1047],{"id":257,"depth":75,"text":257},{"id":273,"depth":75,"text":273},{"id":334,"depth":75,"text":335,"children":1033},[1034,1035,1036],{"id":339,"depth":81,"text":340},{"id":399,"depth":81,"text":400},{"id":584,"depth":81,"text":585},{"id":681,"depth":75,"text":682,"children":1038},[1039,1040,1041],{"id":685,"depth":81,"text":686},{"id":711,"depth":81,"text":712},{"id":737,"depth":81,"text":738},{"id":771,"depth":75,"text":772,"children":1043},[1044,1045,1046],{"id":778,"depth":81,"text":779},{"id":808,"depth":81,"text":809},{"id":900,"depth":81,"text":901},{"id":930,"depth":75,"text":930,"children":1048},[1049,1050,1051],{"id":933,"depth":81,"text":934},{"id":961,"depth":81,"text":962},{"id":989,"depth":81,"text":990},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":252,"description":61},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[234,1060,1061],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1064,"title":1065,"body":1066,"category":234,"cover":1073,"description":61,"extension":236,"meta":1389,"navigation":90,"path":1390,"pinned":239,"publishedAt":1391,"seo":1392,"slug":1393,"stem":1394,"summary":1395,"tags":1396,"updatedAt":1391,"visible":90,"__hash__":1399},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1067,"toc":1374},[1068,1074,1077,1080,1084,1087,1111,1114,1120,1123,1126,1160,1170,1174,1181,1184,1209,1212,1224,1227,1231,1234,1237,1240,1243,1246,1249,1252,1276,1279,1282,1288,1291,1294,1297,1301,1307,1310,1336,1339,1343,1346,1349,1353,1356,1359,1362,1365,1368,1371],[10,1069,1070],{},[26,1071],{"alt":1072,"src":1073},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1075,1076],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1078,1079],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1081,1083],{"id":1082},"python-代码是什么样的","Python 代码是什么样的",[10,1085,1086],{},"下面是一段简单的 Python 代码：",[56,1088,1090],{"className":58,"code":1089,"language":60,"meta":61,"style":61},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[63,1091,1092,1097,1102,1106],{"__ignoreMap":61},[66,1093,1094],{"class":68,"line":69},[66,1095,1096],{},"name = \"Python\"\n",[66,1098,1099],{"class":68,"line":75},[66,1100,1101],{},"year = 2026\n",[66,1103,1104],{"class":68,"line":81},[66,1105,91],{"emptyLinePlaceholder":90},[66,1107,1108],{"class":68,"line":87},[66,1109,1110],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1112,1113],{},"运行结果：",[56,1115,1118],{"className":1116,"code":1117,"language":152,"meta":61},[150],"正在学习 Python，当前年份是 2026\n",[63,1119,1117],{"__ignoreMap":61},[10,1121,1122],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1124,1125],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[56,1127,1129],{"className":58,"code":1128,"language":60,"meta":61,"style":61},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[63,1130,1131,1136,1140,1145,1150,1155],{"__ignoreMap":61},[66,1132,1133],{"class":68,"line":69},[66,1134,1135],{},"score = 85\n",[66,1137,1138],{"class":68,"line":75},[66,1139,91],{"emptyLinePlaceholder":90},[66,1141,1142],{"class":68,"line":81},[66,1143,1144],{},"if score >= 60:\n",[66,1146,1147],{"class":68,"line":87},[66,1148,1149],{},"    print(\"成绩合格\")\n",[66,1151,1152],{"class":68,"line":94},[66,1153,1154],{},"else:\n",[66,1156,1157],{"class":68,"line":100},[66,1158,1159],{},"    print(\"需要继续学习\")\n",[10,1161,1162,1165,1166,1169],{},[63,1163,1164],{},"if"," 和 ",[63,1167,1168],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1171,1173],{"id":1172},"python-如何运行代码","Python 如何运行代码",[10,1175,1176,1177,1180],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[63,1178,1179],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1182,1183],{},"交互式环境适合快速验证一个表达式：",[56,1185,1187],{"className":58,"code":1186,"language":60,"meta":61,"style":61},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[63,1188,1189,1194,1199,1204],{"__ignoreMap":61},[66,1190,1191],{"class":68,"line":69},[66,1192,1193],{},">>> 10 + 20\n",[66,1195,1196],{"class":68,"line":75},[66,1197,1198],{},"30\n",[66,1200,1201],{"class":68,"line":81},[66,1202,1203],{},">>> \"Python\".lower()\n",[66,1205,1206],{"class":68,"line":87},[66,1207,1208],{},"'python'\n",[10,1210,1211],{},"需要保存和重复运行的程序，则可以写入文件：",[56,1213,1215],{"className":599,"code":1214,"language":601,"meta":61,"style":61},"python3 hello.py\n",[63,1216,1217],{"__ignoreMap":61},[66,1218,1219,1221],{"class":68,"line":69},[66,1220,699],{"class":608},[66,1222,1223],{"class":644}," hello.py\n",[10,1225,1226],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1228,1230],{"id":1229},"python-的特点","Python 的特点",[337,1232,1233],{"id":1233},"语法相对简洁",[10,1235,1236],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[337,1238,1239],{"id":1239},"支持多种编程方式",[10,1241,1242],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[337,1244,1245],{"id":1245},"标准库比较完整",[10,1247,1248],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1250,1251],{},"例如，获取当前时间：",[56,1253,1255],{"className":58,"code":1254,"language":60,"meta":61,"style":61},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[63,1256,1257,1262,1266,1271],{"__ignoreMap":61},[66,1258,1259],{"class":68,"line":69},[66,1260,1261],{},"from datetime import datetime\n",[66,1263,1264],{"class":68,"line":75},[66,1265,91],{"emptyLinePlaceholder":90},[66,1267,1268],{"class":68,"line":81},[66,1269,1270],{},"now = datetime.now()\n",[66,1272,1273],{"class":68,"line":87},[66,1274,1275],{},"print(now)\n",[10,1277,1278],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[337,1280,1281],{"id":1281},"第三方工具丰富",[10,1283,1284,1285,1287],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[63,1286,269],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1289,1290],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[337,1292,1293],{"id":1293},"支持多个操作系统",[10,1295,1296],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1298,1300],{"id":1299},"python-可以做什么","Python 可以做什么",[10,1302,1303],{},[26,1304],{"alt":1305,"src":1306},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1308,1309],{},"Python 的应用范围比较广，常见方向包括：",[37,1311,1312,1315,1318,1321,1324,1327,1330,1333],{},[40,1313,1314],{},"编写自动化脚本，批量处理文件和重复任务；",[40,1316,1317],{},"开发网站后端和 API 服务；",[40,1319,1320],{},"进行数据清洗、统计分析和图表展示；",[40,1322,1323],{},"编写网络爬虫和信息采集工具；",[40,1325,1326],{},"开发自动化测试程序；",[40,1328,1329],{},"进行机器学习和人工智能开发；",[40,1331,1332],{},"编写运维、监控和辅助开发工具；",[40,1334,1335],{},"开发部分桌面应用和插件。",[10,1337,1338],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1340,1342],{"id":1341},"python-的发展","Python 的发展",[10,1344,1345],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1347,1348],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1350,1352],{"id":1351},"python-也有局限","Python 也有局限",[10,1354,1355],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1357,1358],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1360,1361],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1363,1364],{"id":1364},"写在最后",[10,1366,1367],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1369,1370],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[221,1372,1373],{},"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":61,"searchDepth":75,"depth":75,"links":1375},[1376,1377,1378,1385,1386,1387,1388],{"id":1082,"depth":75,"text":1083},{"id":1172,"depth":75,"text":1173},{"id":1229,"depth":75,"text":1230,"children":1379},[1380,1381,1382,1383,1384],{"id":1233,"depth":81,"text":1233},{"id":1239,"depth":81,"text":1239},{"id":1245,"depth":81,"text":1245},{"id":1281,"depth":81,"text":1281},{"id":1293,"depth":81,"text":1293},{"id":1299,"depth":75,"text":1300},{"id":1341,"depth":75,"text":1342},{"id":1351,"depth":75,"text":1352},{"id":1364,"depth":75,"text":1364},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1065,"description":61},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[234,1397,1398],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1401,"title":1402,"body":1403,"category":234,"cover":235,"description":1407,"extension":236,"meta":1525,"navigation":90,"path":1526,"pinned":239,"publishedAt":240,"seo":1527,"slug":1528,"stem":1529,"summary":1530,"tags":1531,"updatedAt":240,"visible":90,"__hash__":1533},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1404,"toc":1515},[1405,1408,1410,1413,1415,1421,1426,1428,1442,1444,1446,1455,1457,1463,1465,1467,1483,1485,1496,1498,1506,1508,1510,1513],[10,1406,1407],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1409,16],{"id":16},[10,1411,1412],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1414,22],{"id":22},[10,1416,1417],{},[26,1418],{"alt":1419,"src":1420},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1422,1423,1425],{},[63,1424,1179],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1427,35],{"id":35},[37,1429,1430,1436,1439],{},[40,1431,1432,1433,1435],{},"源代码是人编写的文本，通常保存在 ",[63,1434,1179],{}," 文件中。",[40,1437,1438],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[40,1440,1441],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1443,51],{"id":51},[10,1445,54],{},[56,1447,1449],{"className":58,"code":1448,"language":60,"meta":61,"style":61},"print(\"你好，Python\")\n",[63,1450,1451],{"__ignoreMap":61},[66,1452,1453],{"class":68,"line":69},[66,1454,1448],{},[10,1456,146],{},[56,1458,1461],{"className":1459,"code":1460,"language":152,"meta":61},[150],"你好，Python\n",[63,1462,1460],{"__ignoreMap":61},[10,1464,157],{},[14,1466,160],{"id":160},[162,1468,1469,1476],{},[40,1470,1471,1472,1475],{},"终端启动解释器后，解释器读取 ",[63,1473,1474],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[40,1477,1478,1479,1482],{},"字符串对象先准备好，再交给 ",[63,1480,1481],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1484,183],{"id":183},[37,1486,1487,1490],{},[40,1488,1489],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[40,1491,1492,1493,1495],{},"认为 ",[63,1494,1179],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1497,194],{"id":194},[162,1499,1500,1503],{},[40,1501,1502],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[40,1504,1505],{},"把示例文字改成自己的学习目标并重新运行。",[10,1507,213],{},[14,1509,216],{"id":216},[10,1511,1512],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,1514,223],{},{"title":61,"searchDepth":75,"depth":75,"links":1516},[1517,1518,1519,1520,1521,1522,1523,1524],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1402,"description":1407},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[234,1397,1532],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1535,"title":1536,"body":1537,"category":234,"cover":235,"description":1541,"extension":236,"meta":1677,"navigation":90,"path":1678,"pinned":239,"publishedAt":240,"seo":1679,"slug":1680,"stem":1681,"summary":1682,"tags":1683,"updatedAt":240,"visible":90,"__hash__":1685},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1538,"toc":1667},[1539,1542,1544,1547,1549,1555,1561,1563,1578,1580,1583,1603,1605,1611,1613,1615,1628,1630,1644,1646,1657,1659,1661,1664],[10,1540,1541],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1543,16],{"id":16},[10,1545,1546],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1548,22],{"id":22},[10,1550,1551],{},[26,1552],{"alt":1553,"src":1554},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1556,1557,1558,1560],{},"终端收到 ",[63,1559,699],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1562,35],{"id":35},[37,1564,1565,1568,1571],{},[40,1566,1567],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[40,1569,1570],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[40,1572,1573,1574,1577],{},"检查 pip 时使用 ",[63,1575,1576],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1579,51],{"id":51},[10,1581,1582],{},"在 macOS 终端执行：",[56,1584,1585],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,1586,1587,1593],{"__ignoreMap":61},[66,1588,1589,1591],{"class":68,"line":69},[66,1590,699],{"class":608},[66,1592,612],{"class":611},[66,1594,1595,1597,1599,1601],{"class":68,"line":75},[66,1596,699],{"class":608},[66,1598,641],{"class":611},[66,1600,645],{"class":644},[66,1602,612],{"class":611},[10,1604,146],{},[56,1606,1609],{"className":1607,"code":1608,"language":152,"meta":61},[150],"Python 3.14.x\npip 版本信息与安装路径\n",[63,1610,1608],{"__ignoreMap":61},[10,1612,157],{},[14,1614,160],{"id":160},[162,1616,1617,1623],{},[40,1618,1619,1622],{},[63,1620,1621],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[40,1624,1625,1627],{},[63,1626,707],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1629,183],{"id":183},[37,1631,1632,1638],{},[40,1633,1634,1635,1637],{},"看到系统已有 ",[63,1636,699],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[40,1639,1640,1641,1643],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[63,1642,699],{},"，不修改系统自带工具。",[14,1645,194],{"id":194},[162,1647,1648,1654],{},[40,1649,946,1650,1653],{},[63,1651,1652],{},"which python3","，记录当前解释器路径。",[40,1655,1656],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1658,213],{},[14,1660,216],{"id":216},[10,1662,1663],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,1665,1666],{},"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":61,"searchDepth":75,"depth":75,"links":1668},[1669,1670,1671,1672,1673,1674,1675,1676],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1536,"description":1541},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[234,1684,1060],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1687,"title":1688,"body":1689,"category":234,"cover":235,"description":1854,"extension":236,"meta":1855,"navigation":90,"path":1856,"pinned":239,"publishedAt":240,"seo":1857,"slug":1858,"stem":1859,"summary":1860,"tags":1861,"updatedAt":240,"visible":90,"__hash__":1864},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1690,"toc":1844},[1691,1697,1699,1702,1704,1710,1713,1715,1739,1741,1743,1770,1772,1778,1780,1782,1800,1802,1816,1818,1832,1834,1836,1842],[10,1692,1693,1694,1696],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[63,1695,1179],{}," 脚本。",[14,1698,16],{"id":16},[10,1700,1701],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1703,22],{"id":22},[10,1705,1706],{},[26,1707],{"alt":1708,"src":1709},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1711,1712],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1714,35],{"id":35},[37,1716,1717,1726,1733],{},[40,1718,1719,1720,1722,1723,207],{},"在终端输入 ",[63,1721,699],{}," 进入 REPL，提示符通常是 ",[63,1724,1725],{},">>>",[40,1727,1728,1729,1732],{},"输入 ",[63,1730,1731],{},"exit()"," 或按 Control-D 退出 REPL。",[40,1734,1735,1736,1738],{},"需要保存、复查或多次运行的代码应写入 ",[63,1737,1179],{}," 文件。",[14,1740,51],{"id":51},[10,1742,54],{},[56,1744,1748],{"className":1745,"code":1746,"language":1747,"meta":61,"style":61},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[63,1749,1750,1755,1760,1765],{"__ignoreMap":61},[66,1751,1752],{"class":68,"line":69},[66,1753,1754],{},">>> 2 + 3\n",[66,1756,1757],{"class":68,"line":75},[66,1758,1759],{},"5\n",[66,1761,1762],{"class":68,"line":81},[66,1763,1764],{},">>> \"python\".upper()\n",[66,1766,1767],{"class":68,"line":87},[66,1768,1769],{},"'PYTHON'\n",[10,1771,146],{},[56,1773,1776],{"className":1774,"code":1775,"language":152,"meta":61},[150],"REPL 会直接显示表达式结果\n",[63,1777,1775],{"__ignoreMap":61},[10,1779,157],{},[14,1781,160],{"id":160},[162,1783,1784,1794],{},[40,1785,1786,1787,1790,1791,207],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[63,1788,1789],{},"2 + 3"," 能直接看到 ",[63,1792,1793],{},"5",[40,1795,1796,1797,1799],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[63,1798,1481],{}," 才会写到标准输出。",[14,1801,183],{"id":183},[37,1803,1804,1813],{},[40,1805,1806,1807,1809,1810,1812],{},"把提示符 ",[63,1808,1725],{}," 复制进 ",[63,1811,1179],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[40,1814,1815],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1817,194],{"id":194},[162,1819,1820,1826],{},[40,1821,1822,1823,207],{},"在 REPL 计算 ",[63,1824,1825],{},"12 * 8",[40,1827,1828,1829,1831],{},"把同一表达式写入脚本；观察脚本中不调用 ",[63,1830,1481],{}," 时是否显示结果。",[10,1833,213],{},[14,1835,216],{"id":216},[10,1837,1838,1839,1841],{},"本篇目标是根据任务选择 REPL 或 ",[63,1840,1179],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,1843,223],{},{"title":61,"searchDepth":75,"depth":75,"links":1845},[1846,1847,1848,1849,1850,1851,1852,1853],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1688,"description":1854},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[234,1862,1863],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1866,"title":1867,"body":1868,"category":234,"cover":235,"description":1872,"extension":236,"meta":2043,"navigation":90,"path":2044,"pinned":239,"publishedAt":240,"seo":2045,"slug":2046,"stem":2047,"summary":2048,"tags":2049,"updatedAt":240,"visible":90,"__hash__":2052},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1869,"toc":2033},[1870,1873,1875,1878,1880,1886,1892,1894,1912,1914,1916,1961,1963,1969,1971,1973,1995,1997,2009,2011,2023,2025,2027,2030],[10,1871,1872],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1874,16],{"id":16},[10,1876,1877],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1879,22],{"id":22},[10,1881,1882],{},[26,1883],{"alt":1884,"src":1885},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1887,1888,1891],{},[63,1889,1890],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1893,35],{"id":35},[37,1895,1896,1899,1909],{},[40,1897,1898],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[40,1900,1901,1904,1905,1908],{},[63,1902,1903],{},"pwd"," 显示当前目录，",[63,1906,1907],{},"ls"," 显示目录里的文件。",[40,1910,1911],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1913,51],{"id":51},[10,1915,1582],{},[56,1917,1919],{"className":599,"code":1918,"language":601,"meta":61,"style":61},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[63,1920,1921,1929,1936,1941,1955],{"__ignoreMap":61},[66,1922,1923,1926],{"class":68,"line":69},[66,1924,1925],{"class":608},"mkdir",[66,1927,1928],{"class":644}," python-study\n",[66,1930,1931,1934],{"class":68,"line":75},[66,1932,1933],{"class":611},"cd",[66,1935,1928],{"class":644},[66,1937,1938],{"class":68,"line":81},[66,1939,1940],{"class":611},"pwd\n",[66,1942,1943,1946,1949,1953],{"class":68,"line":87},[66,1944,1945],{"class":611},"printf",[66,1947,1948],{"class":644}," 'print(\"项目已经运行\")\\n'",[66,1950,1952],{"class":1951},"snl16"," >",[66,1954,1223],{"class":644},[66,1956,1957,1959],{"class":68,"line":94},[66,1958,699],{"class":608},[66,1960,1223],{"class":644},[10,1962,146],{},[56,1964,1967],{"className":1965,"code":1966,"language":152,"meta":61},[150],"项目已经运行\n",[63,1968,1966],{"__ignoreMap":61},[10,1970,157],{},[14,1972,160],{"id":160},[162,1974,1975,1986],{},[40,1976,1977,1979,1980,1982,1983,1985],{},[63,1978,1925],{}," 创建目录，",[63,1981,1933],{}," 改变终端当前目录，",[63,1984,1903],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[40,1987,1988,1990,1991,1994],{},[63,1989,1890],{}," 会在当前目录寻找 ",[63,1992,1993],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,1996,183],{"id":183},[37,1998,1999,2006],{},[40,2000,2001,2002,1165,2004,207],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[63,2003,1903],{},[63,2005,1907],{},[40,2007,2008],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2010,194],{"id":194},[162,2012,2013,2020],{},[40,2014,2015,2016,2019],{},"新建 ",[63,2017,2018],{},"lesson01.py"," 并输出课程编号。",[40,2021,2022],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2024,213],{},[14,2026,216],{"id":216},[10,2028,2029],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,2031,2032],{},"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":61,"searchDepth":75,"depth":75,"links":2034},[2035,2036,2037,2038,2039,2040,2041,2042],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1867,"description":1872},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[234,2050,2051],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2054,"title":2055,"body":2056,"category":234,"cover":235,"description":2060,"extension":236,"meta":2208,"navigation":90,"path":2209,"pinned":239,"publishedAt":240,"seo":2210,"slug":2211,"stem":2212,"summary":2213,"tags":2214,"updatedAt":240,"visible":90,"__hash__":2217},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2057,"toc":2198},[2058,2061,2063,2066,2068,2074,2085,2087,2107,2109,2111,2131,2133,2139,2141,2143,2162,2164,2172,2174,2189,2191,2193,2196],[10,2059,2060],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2062,16],{"id":16},[10,2064,2065],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2067,22],{"id":22},[10,2069,2070],{},[26,2071],{"alt":2072,"src":2073},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2075,2076,2077,207,2079,2082,2083,207],{},"Python 先计算表达式，再把得到的对象交给 ",[63,2078,1481],{},[63,2080,2081],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[63,2084,1789],{},[14,2086,35],{"id":35},[37,2088,2089,2095,2104],{},[40,2090,2091,2094],{},[63,2092,2093],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[40,2096,2097,2100,2101,207],{},[63,2098,2099],{},"7 + 5"," 是表达式，运行时先求值得到 ",[63,2102,2103],{},"12",[40,2105,2106],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2108,51],{"id":51},[10,2110,54],{},[56,2112,2114],{"className":58,"code":2113,"language":60,"meta":61,"style":61},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[63,2115,2116,2121,2126],{"__ignoreMap":61},[66,2117,2118],{"class":68,"line":69},[66,2119,2120],{},"print(42)\n",[66,2122,2123],{"class":68,"line":75},[66,2124,2125],{},"print(7 + 5)\n",[66,2127,2128],{"class":68,"line":81},[66,2129,2130],{},"print(\"Python 基础课\")\n",[10,2132,146],{},[56,2134,2137],{"className":2135,"code":2136,"language":152,"meta":61},[150],"42\n12\nPython 基础课\n",[63,2138,2136],{"__ignoreMap":61},[10,2140,157],{},[14,2142,160],{"id":160},[162,2144,2145,2153],{},[40,2146,2147,2150,2151,207],{},[63,2148,2149],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[63,2152,2103],{},[40,2154,2155,2157,2158,2161],{},[63,2156,1481],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[63,2159,2160],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2163,183],{"id":183},[37,2165,2166,2169],{},[40,2167,2168],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[40,2170,2171],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2173,194],{"id":194},[162,2175,2176,2179],{},[40,2177,2178],{},"分别输出一个整数、一个小数和一段文本。",[40,2180,2181,2182,2184,2185,2188],{},"比较 ",[63,2183,2081],{}," 与 ",[63,2186,2187],{},"print(\"2 + 3\")"," 的结果。",[10,2190,213],{},[14,2192,216],{"id":216},[10,2194,2195],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,2197,223],{},{"title":61,"searchDepth":75,"depth":75,"links":2199},[2200,2201,2202,2203,2204,2205,2206,2207],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2055,"description":2060},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[234,2215,2216],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2219,"title":2220,"body":2221,"category":234,"cover":235,"description":2225,"extension":236,"meta":2392,"navigation":90,"path":2393,"pinned":239,"publishedAt":240,"seo":2394,"slug":2395,"stem":2396,"summary":2397,"tags":2398,"updatedAt":240,"visible":90,"__hash__":2401},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2222,"toc":2382},[2223,2226,2228,2231,2233,2239,2242,2244,2270,2272,2274,2302,2304,2310,2312,2314,2338,2340,2356,2358,2373,2375,2377,2380],[10,2224,2225],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2227,16],{"id":16},[10,2229,2230],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2232,22],{"id":22},[10,2234,2235],{},[26,2236],{"alt":2237,"src":2238},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2240,2241],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2243,35],{"id":35},[37,2245,2246,2249,2259],{},[40,2247,2248],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[40,2250,2251,2252,2184,2255,2258],{},"变量名区分大小写，",[63,2253,2254],{},"score",[63,2256,2257],{},"Score"," 是两个名字。",[40,2260,2261,2262,2265,2266,2269],{},"使用能表达含义的名称；不要用 ",[63,2263,2264],{},"list","、",[63,2267,2268],{},"str"," 等内置名称作为普通变量名。",[14,2271,51],{"id":51},[10,2273,54],{},[56,2275,2277],{"className":58,"code":2276,"language":60,"meta":61,"style":61},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[63,2278,2279,2284,2289,2293,2298],{"__ignoreMap":61},[66,2280,2281],{"class":68,"line":69},[66,2282,2283],{},"score = 90\n",[66,2285,2286],{"class":68,"line":75},[66,2287,2288],{},"print(score)\n",[66,2290,2291],{"class":68,"line":81},[66,2292,91],{"emptyLinePlaceholder":90},[66,2294,2295],{"class":68,"line":87},[66,2296,2297],{},"score = 95\n",[66,2299,2300],{"class":68,"line":94},[66,2301,2288],{},[10,2303,146],{},[56,2305,2308],{"className":2306,"code":2307,"language":152,"meta":61},[150],"90\n95\n",[63,2309,2307],{"__ignoreMap":61},[10,2311,157],{},[14,2313,160],{"id":160},[162,2315,2316,2325],{},[40,2317,946,2318,2321,2322,2324],{},[63,2319,2320],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[63,2323,2254],{}," 再绑定到它。",[40,2326,946,2327,2330,2331,2334,2335,207],{},[63,2328,2329],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[63,2332,2333],{},"90"," 没有被改造成 ",[63,2336,2337],{},"95",[14,2339,183],{"id":183},[37,2341,2342,2345],{},[40,2343,2344],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[40,2346,2347,2348,2265,2350,2265,2352,2355],{},"使用 ",[63,2349,2264],{},[63,2351,2268],{},[63,2353,2354],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2357,194],{"id":194},[162,2359,2360,2370],{},[40,2361,2362,2363,1165,2366,2369],{},"创建 ",[63,2364,2365],{},"course_name",[63,2367,2368],{},"lesson_count"," 两个变量并输出。",[40,2371,2372],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2374,213],{},[14,2376,216],{"id":216},[10,2378,2379],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,2381,223],{},{"title":61,"searchDepth":75,"depth":75,"links":2383},[2384,2385,2386,2387,2388,2389,2390,2391],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2220,"description":2225},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[234,2399,2400],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2403,"title":2404,"body":2405,"category":234,"cover":235,"description":2409,"extension":236,"meta":2573,"navigation":90,"path":2574,"pinned":239,"publishedAt":240,"seo":2575,"slug":2576,"stem":2577,"summary":2578,"tags":2579,"updatedAt":240,"visible":90,"__hash__":2582},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2406,"toc":2563},[2407,2410,2412,2415,2417,2423,2426,2428,2457,2459,2461,2505,2507,2513,2515,2517,2531,2533,2544,2546,2554,2556,2558,2561],[10,2408,2409],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2411,16],{"id":16},[10,2413,2414],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2416,22],{"id":22},[10,2418,2419],{},[26,2420],{"alt":2421,"src":2422},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2424,2425],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2427,35],{"id":35},[37,2429,2430,2440,2454],{},[40,2431,2432,2435,2436,2439],{},[63,2433,2434],{},"int"," 表示整数，",[63,2437,2438],{},"float"," 表示浮点数。",[40,2441,2442,2445,2446,2449,2450,2453],{},[63,2443,2444],{},"\u002F"," 总是进行真除法；",[63,2447,2448],{},"\u002F\u002F"," 是向下取整除法，",[63,2451,2452],{},"%"," 得到余数。",[40,2455,2456],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2458,51],{"id":51},[10,2460,54],{},[56,2462,2464],{"className":58,"code":2463,"language":60,"meta":61,"style":61},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[63,2465,2466,2471,2476,2481,2485,2490,2495,2500],{"__ignoreMap":61},[66,2467,2468],{"class":68,"line":69},[66,2469,2470],{},"price = 25\n",[66,2472,2473],{"class":68,"line":75},[66,2474,2475],{},"count = 4\n",[66,2477,2478],{"class":68,"line":81},[66,2479,2480],{},"discount = 0.9\n",[66,2482,2483],{"class":68,"line":87},[66,2484,91],{"emptyLinePlaceholder":90},[66,2486,2487],{"class":68,"line":94},[66,2488,2489],{},"total = price * count * discount\n",[66,2491,2492],{"class":68,"line":100},[66,2493,2494],{},"average = total \u002F count\n",[66,2496,2497],{"class":68,"line":106},[66,2498,2499],{},"print(total)\n",[66,2501,2502],{"class":68,"line":112},[66,2503,2504],{},"print(average)\n",[10,2506,146],{},[56,2508,2511],{"className":2509,"code":2510,"language":152,"meta":61},[150],"90.0\n22.5\n",[63,2512,2510],{"__ignoreMap":61},[10,2514,157],{},[14,2516,160],{"id":160},[162,2518,2519,2525],{},[40,2520,2521,2524],{},[63,2522,2523],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[40,2526,2527,2530],{},[63,2528,2529],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2532,183],{"id":183},[37,2534,2535,2541],{},[40,2536,2537,2538,207],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[63,2539,2540],{},"decimal.Decimal",[40,2542,2543],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2545,194],{"id":194},[162,2547,2548,2551],{},[40,2549,2550],{},"计算 137 除以 10 的商和余数。",[40,2552,2553],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2555,213],{},[14,2557,216],{"id":216},[10,2559,2560],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,2562,223],{},{"title":61,"searchDepth":75,"depth":75,"links":2564},[2565,2566,2567,2568,2569,2570,2571,2572],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2404,"description":2409},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[234,2580,2581],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2584,"title":2585,"body":2586,"category":234,"cover":235,"description":2590,"extension":236,"meta":2766,"navigation":90,"path":2767,"pinned":239,"publishedAt":240,"seo":2768,"slug":2769,"stem":2770,"summary":2771,"tags":2772,"updatedAt":240,"visible":90,"__hash__":2775},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2587,"toc":2754},[2588,2591,2593,2596,2598,2604,2614,2616,2627,2629,2631,2661,2663,2669,2671,2673,2703,2706,2709,2715,2718,2720,2728,2730,2745,2747,2749,2752],[10,2589,2590],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2592,16],{"id":16},[10,2594,2595],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2597,22],{"id":22},[10,2599,2600],{},[26,2601],{"alt":2602,"src":2603},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2605,2606,2607,2610,2611,207],{},"切片 ",[63,2608,2609],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[63,2612,2613],{},"stop - start",[14,2615,35],{"id":35},[37,2617,2618,2621,2624],{},[40,2619,2620],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[40,2622,2623],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[40,2625,2626],{},"切片会创建新的字符串，不会修改原字符串。",[14,2628,51],{"id":51},[10,2630,54],{},[56,2632,2634],{"className":58,"code":2633,"language":60,"meta":61,"style":61},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[63,2635,2636,2641,2646,2651,2656],{"__ignoreMap":61},[66,2637,2638],{"class":68,"line":69},[66,2639,2640],{},"language = \"Python\"\n",[66,2642,2643],{"class":68,"line":75},[66,2644,2645],{},"print(language[0])\n",[66,2647,2648],{"class":68,"line":81},[66,2649,2650],{},"print(language[-1])\n",[66,2652,2653],{"class":68,"line":87},[66,2654,2655],{},"print(language[0:3])\n",[66,2657,2658],{"class":68,"line":94},[66,2659,2660],{},"print(language + \" 3.14\")\n",[10,2662,146],{},[56,2664,2667],{"className":2665,"code":2666,"language":152,"meta":61},[150],"P\nn\nPyt\nPython 3.14\n",[63,2668,2666],{"__ignoreMap":61},[10,2670,157],{},[14,2672,160],{"id":160},[162,2674,2675,2689],{},[40,2676,2677,2678,2680,2681,2684,2685,2688],{},"字符串 ",[63,2679,234],{}," 的正索引从 ",[63,2682,2683],{},"P"," 的 0 开始，负索引从末尾 ",[63,2686,2687],{},"n"," 的 -1 开始。",[40,2690,2691,2694,2695,2698,2699,2702],{},[63,2692,2693],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[63,2696,2697],{},"Pyt","；索引 3 的 ",[63,2700,2701],{},"h"," 不在结果中。",[337,2704,2705],{"id":2705},"再看一个具体细节",[10,2707,2708],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2710,2711],{},[26,2712],{"alt":2713,"src":2714},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2716,2717],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2719,183],{"id":183},[37,2721,2722,2725],{},[40,2723,2724],{},"把第一个字符写成索引 1，造成整体偏移一位。",[40,2726,2727],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2729,194],{"id":194},[162,2731,2732,2742],{},[40,2733,2734,2735,2738,2739,207],{},"从 ",[63,2736,2737],{},"\"programming\""," 中切出 ",[63,2740,2741],{},"\"gram\"",[40,2743,2744],{},"使用负索引取得字符串倒数第二个字符。",[10,2746,213],{},[14,2748,216],{"id":216},[10,2750,2751],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,2753,223],{},{"title":61,"searchDepth":75,"depth":75,"links":2755},[2756,2757,2758,2759,2760,2763,2764,2765],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":2761},[2762],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2585,"description":2590},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[234,2773,2774],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2777,"title":2778,"body":2779,"category":234,"cover":235,"description":2783,"extension":236,"meta":2997,"navigation":90,"path":2998,"pinned":239,"publishedAt":240,"seo":2999,"slug":3000,"stem":3001,"summary":3002,"tags":3003,"updatedAt":240,"visible":90,"__hash__":3006},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2780,"toc":2985},[2781,2784,2786,2789,2791,2797,2807,2809,2842,2844,2846,2890,2892,2898,2900,2902,2923,2925,2928,2934,2942,2944,2958,2960,2976,2978,2980,2983],[10,2782,2783],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2785,16],{"id":16},[10,2787,2788],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2790,22],{"id":22},[10,2792,2793],{},[26,2794],{"alt":2795,"src":2796},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2798,2799,2800,1017,2803,2806],{},"比较表达式先产生 ",[63,2801,2802],{},"True",[63,2804,2805],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2808,35],{"id":35},[37,2810,2811,2825,2839],{},[40,2812,2813,2816,2817,2820,2821,2824],{},[63,2814,2815],{},"=="," 判断是否相等，",[63,2818,2819],{},"!="," 判断是否不等；单个 ",[63,2822,2823],{},"="," 是赋值。",[40,2826,2827,2830,2831,2834,2835,2838],{},[63,2828,2829],{},"and"," 要求两侧都为真，",[63,2832,2833],{},"or"," 只需一侧为真，",[63,2836,2837],{},"not"," 取反。",[40,2840,2841],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2843,51],{"id":51},[10,2845,54],{},[56,2847,2849],{"className":58,"code":2848,"language":60,"meta":61,"style":61},"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",[63,2850,2851,2856,2861,2865,2870,2875,2880,2885],{"__ignoreMap":61},[66,2852,2853],{"class":68,"line":69},[66,2854,2855],{},"age = 20\n",[66,2857,2858],{"class":68,"line":75},[66,2859,2860],{},"has_ticket = True\n",[66,2862,2863],{"class":68,"line":81},[66,2864,91],{"emptyLinePlaceholder":90},[66,2866,2867],{"class":68,"line":87},[66,2868,2869],{},"is_adult = age >= 18\n",[66,2871,2872],{"class":68,"line":94},[66,2873,2874],{},"can_enter = is_adult and has_ticket\n",[66,2876,2877],{"class":68,"line":100},[66,2878,2879],{},"print(is_adult)\n",[66,2881,2882],{"class":68,"line":106},[66,2883,2884],{},"print(can_enter)\n",[66,2886,2887],{"class":68,"line":112},[66,2888,2889],{},"print(not has_ticket)\n",[10,2891,146],{},[56,2893,2896],{"className":2894,"code":2895,"language":152,"meta":61},[150],"True\nTrue\nFalse\n",[63,2897,2895],{"__ignoreMap":61},[10,2899,157],{},[14,2901,160],{"id":160},[162,2903,2904,2914],{},[40,2905,2906,2909,2910,2913],{},[63,2907,2908],{},"age >= 18"," 先产生布尔值并绑定给 ",[63,2911,2912],{},"is_adult","，这一步没有任何分支跳转。",[40,2915,2916,2919,2920,2922],{},[63,2917,2918],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[63,2921,2837],{}," 只对紧随其后的值取反。",[337,2924,2705],{"id":2705},[10,2926,2927],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2929,2930],{},[26,2931],{"alt":2932,"src":2933},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2935,2936,2938,2939,2941],{},[63,2937,2829],{}," 只有“真、真”得到真；",[63,2940,2833],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2943,183],{"id":183},[37,2945,2946,2955],{},[40,2947,2948,2949,2951,2952,2954],{},"用单个等号判断相等。",[63,2950,2823],{}," 是赋值，",[63,2953,2815],{}," 才是相等比较。",[40,2956,2957],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,2959,194],{"id":194},[162,2961,2962,2969],{},[40,2963,2964,2965,2968],{},"判断数字 ",[63,2966,2967],{},"15"," 是否同时大于 10 且小于 20。",[40,2970,2971,2972,2975],{},"分别修改年龄和票据状态，记录 ",[63,2973,2974],{},"can_enter"," 的四种组合结果。",[10,2977,213],{},[14,2979,216],{"id":216},[10,2981,2982],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,2984,223],{},{"title":61,"searchDepth":75,"depth":75,"links":2986},[2987,2988,2989,2990,2991,2994,2995,2996],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":2992},[2993],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2778,"description":2783},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[234,3004,3005],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3008,"title":3009,"body":3010,"category":234,"cover":235,"description":3014,"extension":236,"meta":3182,"navigation":90,"path":3183,"pinned":239,"publishedAt":240,"seo":3184,"slug":3185,"stem":3186,"summary":3187,"tags":3188,"updatedAt":240,"visible":90,"__hash__":3190},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3011,"toc":3172},[3012,3015,3017,3020,3022,3028,3046,3048,3061,3063,3065,3099,3101,3107,3109,3111,3133,3135,3147,3149,3163,3165,3167,3170],[10,3013,3014],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3016,16],{"id":16},[10,3018,3019],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3021,22],{"id":22},[10,3023,3024],{},[26,3025],{"alt":3026,"src":3027},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3029,3030,3033,3034,3037,3038,3041,3042,3045],{},[63,3031,3032],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[63,3035,3036],{},"18","，程序首先得到的也是 ",[63,3039,3040],{},"\"18\"","，需要 ",[63,3043,3044],{},"int()"," 后才能按整数参与计算。",[14,3047,35],{"id":35},[37,3049,3050,3053,3058],{},[40,3051,3052],{},"提示文字应告诉用户需要输入什么。",[40,3054,3055,3057],{},[63,3056,3044],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[40,3059,3060],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3062,51],{"id":51},[10,3064,54],{},[56,3066,3068],{"className":58,"code":3067,"language":60,"meta":61,"style":61},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[63,3069,3070,3075,3080,3085,3089,3094],{"__ignoreMap":61},[66,3071,3072],{"class":68,"line":69},[66,3073,3074],{},"name = input(\"请输入姓名：\")\n",[66,3076,3077],{"class":68,"line":75},[66,3078,3079],{},"age_text = input(\"请输入年龄：\")\n",[66,3081,3082],{"class":68,"line":81},[66,3083,3084],{},"age = int(age_text)\n",[66,3086,3087],{"class":68,"line":87},[66,3088,91],{"emptyLinePlaceholder":90},[66,3090,3091],{"class":68,"line":94},[66,3092,3093],{},"print(\"你好，\" + name)\n",[66,3095,3096],{"class":68,"line":100},[66,3097,3098],{},"print(age + 1)\n",[10,3100,146],{},[56,3102,3105],{"className":3103,"code":3104,"language":152,"meta":61},[150],"根据输入显示姓名，并输出下一年的年龄\n",[63,3106,3104],{"__ignoreMap":61},[10,3108,157],{},[14,3110,160],{"id":160},[162,3112,3113,3123],{},[40,3114,3115,3116,3118,3119,3122],{},"两次 ",[63,3117,3032],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[63,3120,3121],{},"age_text"," 用来提醒这仍是文本。",[40,3124,3125,3128,3129,3132],{},[63,3126,3127],{},"int(age_text)"," 创建整数对象，后面的 ",[63,3130,3131],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3134,183],{"id":183},[37,3136,3137,3144],{},[40,3138,3139,3140,3143],{},"直接计算 ",[63,3141,3142],{},"input(...) + 1","，忽略输入结果是字符串。",[40,3145,3146],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3148,194],{"id":194},[162,3150,3151,3154],{},[40,3152,3153],{},"接收两个整数并输出它们的和。",[40,3155,1728,3156,3159,3160,3162],{},[63,3157,3158],{},"18.5"," 给 ",[63,3161,3044],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3164,213],{},[14,3166,216],{"id":216},[10,3168,3169],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,3171,223],{},{"title":61,"searchDepth":75,"depth":75,"links":3173},[3174,3175,3176,3177,3178,3179,3180,3181],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3009,"description":3014},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[234,2354,3189],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3192,"title":3193,"body":3194,"category":234,"cover":235,"description":3198,"extension":236,"meta":3358,"navigation":90,"path":3359,"pinned":239,"publishedAt":240,"seo":3360,"slug":3361,"stem":3362,"summary":3363,"tags":3364,"updatedAt":240,"visible":90,"__hash__":3367},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3195,"toc":3348},[3196,3199,3201,3204,3206,3212,3219,3221,3235,3237,3239,3278,3280,3286,3288,3290,3309,3311,3326,3328,3339,3341,3343,3346],[10,3197,3198],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3200,16],{"id":16},[10,3202,3203],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3205,22],{"id":22},[10,3207,3208],{},[26,3209],{"alt":3210,"src":3211},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3213,3214,3215,3218],{},"列表为元素维护从 0 开始的位置索引。修改 ",[63,3216,3217],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3220,35],{"id":35},[37,3222,3223,3226,3229],{},[40,3224,3225],{},"列表使用方括号，元素之间用逗号分隔。",[40,3227,3228],{},"列表可变，可以替换、追加和删除元素。",[40,3230,3231,3232,207],{},"访问不存在的索引会产生 ",[63,3233,3234],{},"IndexError",[14,3236,51],{"id":51},[10,3238,54],{},[56,3240,3242],{"className":58,"code":3241,"language":60,"meta":61,"style":61},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[63,3243,3244,3249,3254,3258,3263,3268,3273],{"__ignoreMap":61},[66,3245,3246],{"class":68,"line":69},[66,3247,3248],{},"scores = [82, 90, 76]\n",[66,3250,3251],{"class":68,"line":75},[66,3252,3253],{},"print(scores[0])\n",[66,3255,3256],{"class":68,"line":81},[66,3257,91],{"emptyLinePlaceholder":90},[66,3259,3260],{"class":68,"line":87},[66,3261,3262],{},"scores[1] = 95\n",[66,3264,3265],{"class":68,"line":94},[66,3266,3267],{},"scores.append(88)\n",[66,3269,3270],{"class":68,"line":100},[66,3271,3272],{},"print(scores)\n",[66,3274,3275],{"class":68,"line":106},[66,3276,3277],{},"print(len(scores))\n",[10,3279,146],{},[56,3281,3284],{"className":3282,"code":3283,"language":152,"meta":61},[150],"82\n[82, 95, 76, 88]\n4\n",[63,3285,3283],{"__ignoreMap":61},[10,3287,157],{},[14,3289,160],{"id":160},[162,3291,3292,3295],{},[40,3293,3294],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[40,3296,3297,3300,3301,3304,3305,3308],{},[63,3298,3299],{},"scores[1] = 95"," 替换第二个位置，",[63,3302,3303],{},"append(88)"," 在末尾增加新位置，",[63,3306,3307],{},"len()"," 因而从 3 变为 4。",[14,3310,183],{"id":183},[37,3312,3313,3323],{},[40,3314,3315,3316,3319,3320,207],{},"访问 ",[63,3317,3318],{},"scores[len(scores)]","。最后一个合法正索引是 ",[63,3321,3322],{},"len(scores) - 1",[40,3324,3325],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3327,194],{"id":194},[162,3329,3330,3333],{},[40,3331,3332],{},"建立三项学习任务列表，再追加第四项。",[40,3334,3335,3336,3338],{},"修改第二项，并用 ",[63,3337,3307],{}," 检查元素数量。",[10,3340,213],{},[14,3342,216],{"id":216},[10,3344,3345],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,3347,223],{},{"title":61,"searchDepth":75,"depth":75,"links":3349},[3350,3351,3352,3353,3354,3355,3356,3357],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3193,"description":3198},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[234,3365,3366],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3369,"title":3370,"body":3371,"category":234,"cover":235,"description":3375,"extension":236,"meta":3516,"navigation":90,"path":3517,"pinned":239,"publishedAt":240,"seo":3518,"slug":3519,"stem":3520,"summary":3521,"tags":3522,"updatedAt":240,"visible":90,"__hash__":3524},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3372,"toc":3506},[3373,3376,3378,3381,3383,3389,3392,3394,3405,3407,3409,3443,3445,3451,3453,3455,3469,3471,3483,3485,3497,3499,3501,3504],[10,3374,3375],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3377,16],{"id":16},[10,3379,3380],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3382,22],{"id":22},[10,3384,3385],{},[26,3386],{"alt":3387,"src":3388},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3390,3391],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3393,35],{"id":35},[37,3395,3396,3399,3402],{},[40,3397,3398],{},"元组常用来表达固定数量、固定含义的一组值。",[40,3400,3401],{},"只有一个元素的元组必须保留尾随逗号。",[40,3403,3404],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3406,51],{"id":51},[10,3408,54],{},[56,3410,3412],{"className":58,"code":3411,"language":60,"meta":61,"style":61},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[63,3413,3414,3419,3424,3429,3433,3438],{"__ignoreMap":61},[66,3415,3416],{"class":68,"line":69},[66,3417,3418],{},"point = (120, 80)\n",[66,3420,3421],{"class":68,"line":75},[66,3422,3423],{},"print(point[0])\n",[66,3425,3426],{"class":68,"line":81},[66,3427,3428],{},"print(point[1])\n",[66,3430,3431],{"class":68,"line":87},[66,3432,91],{"emptyLinePlaceholder":90},[66,3434,3435],{"class":68,"line":94},[66,3436,3437],{},"single = (5,)\n",[66,3439,3440],{"class":68,"line":100},[66,3441,3442],{},"print(single)\n",[10,3444,146],{},[56,3446,3449],{"className":3447,"code":3448,"language":152,"meta":61},[150],"120\n80\n(5,)\n",[63,3450,3448],{"__ignoreMap":61},[10,3452,157],{},[14,3454,160],{"id":160},[162,3456,3457,3463],{},[40,3458,3459,3462],{},[63,3460,3461],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[40,3464,3465,3468],{},[63,3466,3467],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3470,183],{"id":183},[37,3472,3473,3480],{},[40,3474,3475,3476,3479],{},"把 ",[63,3477,3478],{},"(5)"," 当作元组，实际它仍是整数。",[40,3481,3482],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3484,194],{"id":194},[162,3486,3487,3490],{},[40,3488,3489],{},"用元组表示宽度和高度。",[40,3491,2181,3492,2184,3494,3496],{},[63,3493,3478],{},[63,3495,3467],{}," 的类型。",[10,3498,213],{},[14,3500,216],{"id":216},[10,3502,3503],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,3505,223],{},{"title":61,"searchDepth":75,"depth":75,"links":3507},[3508,3509,3510,3511,3512,3513,3514,3515],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3370,"description":3375},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[234,3523,3366],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3526,"title":3527,"body":3528,"category":234,"cover":235,"description":3532,"extension":236,"meta":3687,"navigation":90,"path":3688,"pinned":239,"publishedAt":240,"seo":3689,"slug":3690,"stem":3691,"summary":3692,"tags":3693,"updatedAt":240,"visible":90,"__hash__":3695},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3529,"toc":3677},[3530,3533,3535,3538,3540,3546,3556,3558,3572,3574,3576,3610,3612,3618,3620,3622,3637,3639,3658,3660,3668,3670,3672,3675],[10,3531,3532],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3534,16],{"id":16},[10,3536,3537],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3539,22],{"id":22},[10,3541,3542],{},[26,3543],{"alt":3544,"src":3545},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3547,3548,3549,3552,3553,3555],{},"字典通过键定位值，不使用连续位置表达含义。",[63,3550,3551],{},"student[\"score\"]"," 读取的是键 ",[63,3554,2254],{}," 对应的值，而不是“第几个元素”。",[14,3557,35],{"id":35},[37,3559,3560,3563,3569],{},[40,3561,3562],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[40,3564,2347,3565,3568],{},[63,3566,3567],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[40,3570,3571],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3573,51],{"id":51},[10,3575,54],{},[56,3577,3579],{"className":58,"code":3578,"language":60,"meta":61,"style":61},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[63,3580,3581,3586,3591,3595,3600,3605],{"__ignoreMap":61},[66,3582,3583],{"class":68,"line":69},[66,3584,3585],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[66,3587,3588],{"class":68,"line":75},[66,3589,3590],{},"print(student[\"name\"])\n",[66,3592,3593],{"class":68,"line":81},[66,3594,91],{"emptyLinePlaceholder":90},[66,3596,3597],{"class":68,"line":87},[66,3598,3599],{},"student[\"score\"] = 95\n",[66,3601,3602],{"class":68,"line":94},[66,3603,3604],{},"student[\"city\"] = \"郑州\"\n",[66,3606,3607],{"class":68,"line":100},[66,3608,3609],{},"print(student)\n",[10,3611,146],{},[56,3613,3616],{"className":3614,"code":3615,"language":152,"meta":61},[150],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[63,3617,3615],{"__ignoreMap":61},[10,3619,157],{},[14,3621,160],{"id":160},[162,3623,3624,3627],{},[40,3625,3626],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[40,3628,3629,3630,3632,3633,3636],{},"给已有键 ",[63,3631,2254],{}," 赋值会更新映射，给新键 ",[63,3634,3635],{},"city"," 赋值会增加映射。",[14,3638,183],{"id":183},[37,3640,3641,3648],{},[40,3642,3643,3644,3647],{},"按位置理解字典并尝试 ",[63,3645,3646],{},"student[0]","，而实际键是字符串。",[40,3649,3650,3651,3654,3655,207],{},"直接读取不确定存在的键并忽略 ",[63,3652,3653],{},"KeyError","；后续可根据场景使用成员检查或 ",[63,3656,3657],{},"get()",[14,3659,194],{"id":194},[162,3661,3662,3665],{},[40,3663,3664],{},"建立一本书的标题、作者和页数字典。",[40,3666,3667],{},"添加分类键，再修改页数。",[10,3669,213],{},[14,3671,216],{"id":216},[10,3673,3674],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,3676,223],{},{"title":61,"searchDepth":75,"depth":75,"links":3678},[3679,3680,3681,3682,3683,3684,3685,3686],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3527,"description":3532},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[234,3694,3366],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3697,"title":3698,"body":3699,"category":234,"cover":235,"description":3703,"extension":236,"meta":3852,"navigation":90,"path":3853,"pinned":239,"publishedAt":240,"seo":3854,"slug":3855,"stem":3856,"summary":3857,"tags":3858,"updatedAt":240,"visible":90,"__hash__":3860},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3700,"toc":3842},[3701,3704,3706,3709,3711,3717,3720,3722,3741,3743,3745,3779,3781,3787,3789,3791,3806,3808,3820,3822,3833,3835,3837,3840],[10,3702,3703],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3705,16],{"id":16},[10,3707,3708],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3710,22],{"id":22},[10,3712,3713],{},[26,3714],{"alt":3715,"src":3716},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3718,3719],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3721,35],{"id":35},[37,3723,3724,3727,3730],{},[40,3725,3726],{},"集合中的元素不重复。",[40,3728,3729],{},"集合是无序容器，不要依赖打印顺序或索引。",[40,3731,3732,3733,3736,3737,3740],{},"创建空集合必须写 ",[63,3734,3735],{},"set()","；",[63,3738,3739],{},"{}"," 创建的是空字典。",[14,3742,51],{"id":51},[10,3744,54],{},[56,3746,3748],{"className":58,"code":3747,"language":60,"meta":61,"style":61},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[63,3749,3750,3755,3760,3764,3769,3774],{"__ignoreMap":61},[66,3751,3752],{"class":68,"line":69},[66,3753,3754],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[66,3756,3757],{"class":68,"line":75},[66,3758,3759],{},"right = {\"Python\", \"Docker\"}\n",[66,3761,3762],{"class":68,"line":81},[66,3763,91],{"emptyLinePlaceholder":90},[66,3765,3766],{"class":68,"line":87},[66,3767,3768],{},"print(left & right)\n",[66,3770,3771],{"class":68,"line":94},[66,3772,3773],{},"print(left | right)\n",[66,3775,3776],{"class":68,"line":100},[66,3777,3778],{},"print(\"Git\" in left)\n",[10,3780,146],{},[56,3782,3785],{"className":3783,"code":3784,"language":152,"meta":61},[150],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[63,3786,3784],{"__ignoreMap":61},[10,3788,157],{},[14,3790,160],{"id":160},[162,3792,3793,3796],{},[40,3794,3795],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[40,3797,3798,3801,3802,3805],{},[63,3799,3800],{},"&"," 计算交集，",[63,3803,3804],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3807,183],{"id":183},[37,3809,3810,3817],{},[40,3811,2347,3812,3814,3815,207],{},[63,3813,3739],{}," 创建空集合，实际得到空字典；空集合应写 ",[63,3816,3735],{},[40,3818,3819],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3821,194],{"id":194},[162,3823,3824,3830],{},[40,3825,3826,3827,3829],{},"把包含重复标签的列表交给 ",[63,3828,3735],{}," 去重。",[40,3831,3832],{},"计算两组课程标签的交集和差集。",[10,3834,213],{},[14,3836,216],{"id":216},[10,3838,3839],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,3841,223],{},{"title":61,"searchDepth":75,"depth":75,"links":3843},[3844,3845,3846,3847,3848,3849,3850,3851],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3698,"description":3703},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[234,3859,3366],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3862,"title":3863,"body":3864,"category":234,"cover":235,"description":3868,"extension":236,"meta":4065,"navigation":90,"path":4066,"pinned":239,"publishedAt":240,"seo":4067,"slug":4068,"stem":4069,"summary":4070,"tags":4071,"updatedAt":240,"visible":90,"__hash__":4074},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3865,"toc":4053},[3866,3869,3871,3874,3876,3882,3892,3894,3911,3913,3915,3964,3966,3972,3974,3976,3998,4000,4003,4009,4012,4014,4027,4029,4044,4046,4048,4051],[10,3867,3868],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3870,16],{"id":16},[10,3872,3873],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3875,22],{"id":22},[10,3877,3878],{},[26,3879],{"alt":3880,"src":3881},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3883,3884,3887,3888,3891],{},[63,3885,3886],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[63,3889,3890],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3893,35],{"id":35},[37,3895,3896,3905,3908],{},[40,3897,3898,3900,3901,3904],{},[63,3899,2815],{}," 比较内容是否相等，",[63,3902,3903],{},"is"," 比较是否为同一个对象。",[40,3906,3907],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[40,3909,3910],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3912,51],{"id":51},[10,3914,54],{},[56,3916,3918],{"className":58,"code":3917,"language":60,"meta":61,"style":61},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[63,3919,3920,3925,3930,3935,3939,3944,3949,3954,3959],{"__ignoreMap":61},[66,3921,3922],{"class":68,"line":69},[66,3923,3924],{},"tasks = [\"变量\", \"字符串\"]\n",[66,3926,3927],{"class":68,"line":75},[66,3928,3929],{},"shared = tasks\n",[66,3931,3932],{"class":68,"line":81},[66,3933,3934],{},"backup = tasks.copy()\n",[66,3936,3937],{"class":68,"line":87},[66,3938,91],{"emptyLinePlaceholder":90},[66,3940,3941],{"class":68,"line":94},[66,3942,3943],{},"tasks.append(\"列表\")\n",[66,3945,3946],{"class":68,"line":100},[66,3947,3948],{},"print(shared)\n",[66,3950,3951],{"class":68,"line":106},[66,3952,3953],{},"print(backup)\n",[66,3955,3956],{"class":68,"line":112},[66,3957,3958],{},"print(tasks is shared)\n",[66,3960,3961],{"class":68,"line":117},[66,3962,3963],{},"print(tasks is backup)\n",[10,3965,146],{},[56,3967,3970],{"className":3968,"code":3969,"language":152,"meta":61},[150],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[63,3971,3969],{"__ignoreMap":61},[10,3973,157],{},[14,3975,160],{"id":160},[162,3977,3978,3984],{},[40,3979,3980,3983],{},[63,3981,3982],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[40,3985,3986,3989,3990,3993,3994,3997],{},[63,3987,3988],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[63,3991,3992],{},"shared"," 能观察到变化，",[63,3995,3996],{},"backup"," 不会。",[337,3999,2705],{"id":2705},[10,4001,4002],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4004,4005],{},[26,4006],{"alt":4007,"src":4008},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4010,4011],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4013,183],{"id":183},[37,4015,4016,4024],{},[40,4017,4018,4019,4021,4022,207],{},"用 ",[63,4020,2815],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[63,4023,3903],{},[40,4025,4026],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4028,194],{"id":194},[162,4030,4031,4034],{},[40,4032,4033],{},"让两个变量引用同一个字典并修改其中一个。",[40,4035,2347,4036,4039,4040,1165,4042,207],{},[63,4037,4038],{},"copy()"," 创建外层副本，再比较 ",[63,4041,3903],{},[63,4043,2815],{},[10,4045,213],{},[14,4047,216],{"id":216},[10,4049,4050],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,4052,223],{},{"title":61,"searchDepth":75,"depth":75,"links":4054},[4055,4056,4057,4058,4059,4062,4063,4064],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":4060},[4061],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3863,"description":3868},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[234,4072,4073],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4076,"title":4077,"body":4078,"category":234,"cover":235,"description":4082,"extension":236,"meta":4294,"navigation":90,"path":4295,"pinned":239,"publishedAt":240,"seo":4296,"slug":4297,"stem":4298,"summary":4299,"tags":4300,"updatedAt":240,"visible":90,"__hash__":4302},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4079,"toc":4281},[4080,4083,4085,4088,4090,4096,4106,4108,4119,4121,4123,4175,4177,4183,4185,4187,4205,4207,4210,4216,4224,4227,4230,4236,4242,4244,4262,4264,4272,4274,4276,4279],[10,4081,4082],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4084,16],{"id":16},[10,4086,4087],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4089,22],{"id":22},[10,4091,4092],{},[26,4093],{"alt":4094,"src":4095},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4097,4098,2265,4100,2265,4103,4105],{},[63,4099,1164],{},[63,4101,4102],{},"elif",[63,4104,1168],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4107,35],{"id":35},[37,4109,4110,4113,4116],{},[40,4111,4112],{},"冒号表示接下来开始一个代码块。",[40,4114,4115],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[40,4117,4118],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4120,51],{"id":51},[10,4122,54],{},[56,4124,4126],{"className":58,"code":4125,"language":60,"meta":61,"style":61},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[63,4127,4128,4133,4137,4142,4147,4152,4157,4161,4166,4170],{"__ignoreMap":61},[66,4129,4130],{"class":68,"line":69},[66,4131,4132],{},"score = int(input(\"请输入分数：\"))\n",[66,4134,4135],{"class":68,"line":75},[66,4136,91],{"emptyLinePlaceholder":90},[66,4138,4139],{"class":68,"line":81},[66,4140,4141],{},"if score >= 90:\n",[66,4143,4144],{"class":68,"line":87},[66,4145,4146],{},"    level = \"优秀\"\n",[66,4148,4149],{"class":68,"line":94},[66,4150,4151],{},"elif score >= 60:\n",[66,4153,4154],{"class":68,"line":100},[66,4155,4156],{},"    level = \"合格\"\n",[66,4158,4159],{"class":68,"line":106},[66,4160,1154],{},[66,4162,4163],{"class":68,"line":112},[66,4164,4165],{},"    level = \"需要继续学习\"\n",[66,4167,4168],{"class":68,"line":117},[66,4169,91],{"emptyLinePlaceholder":90},[66,4171,4172],{"class":68,"line":123},[66,4173,4174],{},"print(level)\n",[10,4176,146],{},[56,4178,4181],{"className":4179,"code":4180,"language":152,"meta":61},[150],"输入 85 时输出：合格\n",[63,4182,4180],{"__ignoreMap":61},[10,4184,157],{},[14,4186,160],{"id":160},[162,4188,4189,4196],{},[40,4190,4191,4192,4195],{},"输入先转换为整数，程序从 ",[63,4193,4194],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[40,4197,4198,4201,4202,4204],{},[63,4199,4200],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[63,4203,1168],{}," 被跳过；最终三个分支只会选择一个。",[337,4206,2705],{"id":2705},[10,4208,4209],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4211,4212],{},[26,4213],{"alt":4214,"src":4215},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4217,4218,4220,4221,4223],{},[63,4219,4194],{}," 必须放在 ",[63,4222,4200],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[337,4225,2705],{"id":4226},"再看一个具体细节-1",[10,4228,4229],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4231,4232],{},[26,4233],{"alt":4234,"src":4235},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4237,4238,4239,4241],{},"同一缩进层级属于同一个代码块；回到 ",[63,4240,1164],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4243,183],{"id":183},[37,4245,4246,4252],{},[40,4247,4248,4249,4251],{},"先写 ",[63,4250,4200],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[40,4253,4254,4255,4257,4258,4261],{},"混用多个独立 ",[63,4256,1164],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[63,4259,4260],{},"if\u002Felif\u002Felse"," 链。",[14,4263,194],{"id":194},[162,4265,4266,4269],{},[40,4267,4268],{},"根据温度输出“冷、适中、热”三个等级。",[40,4270,4271],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4273,213],{},[14,4275,216],{"id":216},[10,4277,4278],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,4280,223],{},{"title":61,"searchDepth":75,"depth":75,"links":4282},[4283,4284,4285,4286,4287,4291,4292,4293],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":4288},[4289,4290],{"id":2705,"depth":81,"text":2705},{"id":4226,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4077,"description":4082},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[234,1164,4301],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4304,"title":4305,"body":4306,"category":234,"cover":235,"description":4310,"extension":236,"meta":4476,"navigation":90,"path":4477,"pinned":239,"publishedAt":240,"seo":4478,"slug":4479,"stem":4480,"summary":4481,"tags":4482,"updatedAt":240,"visible":90,"__hash__":4484},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4307,"toc":4464},[4308,4311,4313,4316,4318,4324,4330,4332,4347,4349,4351,4389,4391,4397,4399,4401,4416,4418,4421,4427,4433,4435,4443,4445,4455,4457,4459,4462],[10,4309,4310],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4312,16],{"id":16},[10,4314,4315],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4317,22],{"id":22},[10,4319,4320],{},[26,4321],{"alt":4322,"src":4323},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4325,4326,4329],{},[63,4327,4328],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4331,35],{"id":35},[37,4333,4334,4337,4340],{},[40,4335,4336],{},"进入循环前先准备参与条件判断的状态。",[40,4338,4339],{},"循环体中必须有机会让条件变为假。",[40,4341,4342,4343,4346],{},"能够预先确定遍历对象时，后续介绍的 ",[63,4344,4345],{},"for"," 通常更直接。",[14,4348,51],{"id":51},[10,4350,54],{},[56,4352,4354],{"className":58,"code":4353,"language":60,"meta":61,"style":61},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[63,4355,4356,4361,4365,4370,4375,4380,4384],{"__ignoreMap":61},[66,4357,4358],{"class":68,"line":69},[66,4359,4360],{},"count = 1\n",[66,4362,4363],{"class":68,"line":75},[66,4364,91],{"emptyLinePlaceholder":90},[66,4366,4367],{"class":68,"line":81},[66,4368,4369],{},"while count \u003C= 3:\n",[66,4371,4372],{"class":68,"line":87},[66,4373,4374],{},"    print(\"第\", count, \"次练习\")\n",[66,4376,4377],{"class":68,"line":94},[66,4378,4379],{},"    count = count + 1\n",[66,4381,4382],{"class":68,"line":100},[66,4383,91],{"emptyLinePlaceholder":90},[66,4385,4386],{"class":68,"line":106},[66,4387,4388],{},"print(\"练习结束\")\n",[10,4390,146],{},[56,4392,4395],{"className":4393,"code":4394,"language":152,"meta":61},[150],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[63,4396,4394],{"__ignoreMap":61},[10,4398,157],{},[14,4400,160],{"id":160},[162,4402,4403,4410],{},[40,4404,4405,4406,4409],{},"进入循环前 ",[63,4407,4408],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[40,4411,4412,4413,4415],{},"循环体末尾把 ",[63,4414,4408],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[337,4417,2705],{"id":2705},[10,4419,4420],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4422,4423],{},[26,4424],{"alt":4425,"src":4426},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4428,4429,4430,4432],{},"第4次检查时 ",[63,4431,4408],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4434,183],{"id":183},[37,4436,4437,4440],{},[40,4438,4439],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[40,4441,4442],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4444,194],{"id":194},[162,4446,4447,4452],{},[40,4448,2347,4449,4451],{},[63,4450,4328],{}," 输出 1 到 5。",[40,4453,4454],{},"计算 1 到 10 的累加和。",[10,4456,213],{},[14,4458,216],{"id":216},[10,4460,4461],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,4463,223],{},{"title":61,"searchDepth":75,"depth":75,"links":4465},[4466,4467,4468,4469,4470,4473,4474,4475],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":4471},[4472],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4305,"description":4310},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[234,4328,4483],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4486,"title":4487,"body":4488,"category":234,"cover":235,"description":4492,"extension":236,"meta":4640,"navigation":90,"path":4641,"pinned":239,"publishedAt":240,"seo":4642,"slug":4643,"stem":4644,"summary":4645,"tags":4646,"updatedAt":240,"visible":90,"__hash__":4648},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4489,"toc":4630},[4490,4493,4495,4498,4500,4506,4511,4513,4527,4529,4531,4569,4571,4577,4579,4581,4598,4600,4608,4610,4621,4623,4625,4628],[10,4491,4492],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4494,16],{"id":16},[10,4496,4497],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4499,22],{"id":22},[10,4501,4502],{},[26,4503],{"alt":4504,"src":4505},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4507,4508,4510],{},[63,4509,4345],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4512,35],{"id":35},[37,4514,4515,4521,4524],{},[40,4516,4517,4520],{},[63,4518,4519],{},"range(1, 4)"," 包含 1，不包含 4。",[40,4522,4523],{},"只需要元素时直接遍历元素，不必手工维护索引。",[40,4525,4526],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4528,51],{"id":51},[10,4530,54],{},[56,4532,4534],{"className":58,"code":4533,"language":60,"meta":61,"style":61},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[63,4535,4536,4541,4545,4550,4555,4559,4564],{"__ignoreMap":61},[66,4537,4538],{"class":68,"line":69},[66,4539,4540],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[66,4542,4543],{"class":68,"line":75},[66,4544,91],{"emptyLinePlaceholder":90},[66,4546,4547],{"class":68,"line":81},[66,4548,4549],{},"for course in courses:\n",[66,4551,4552],{"class":68,"line":87},[66,4553,4554],{},"    print(course)\n",[66,4556,4557],{"class":68,"line":94},[66,4558,91],{"emptyLinePlaceholder":90},[66,4560,4561],{"class":68,"line":100},[66,4562,4563],{},"for number in range(1, 4):\n",[66,4565,4566],{"class":68,"line":106},[66,4567,4568],{},"    print(number)\n",[10,4570,146],{},[56,4572,4575],{"className":4573,"code":4574,"language":152,"meta":61},[150],"变量\n字符串\n列表\n1\n2\n3\n",[63,4576,4574],{"__ignoreMap":61},[10,4578,157],{},[14,4580,160],{"id":160},[162,4582,4583,4593],{},[40,4584,4585,4586,4588,4589,4592],{},"第一个 ",[63,4587,4345],{}," 依次从列表取得字符串，循环变量 ",[63,4590,4591],{},"course"," 每轮重新绑定。",[40,4594,4595,4597],{},[63,4596,4519],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4599,183],{"id":183},[37,4601,4602,4605],{},[40,4603,4604],{},"只需要元素却手工维护索引，增加越界风险。",[40,4606,4607],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4609,194],{"id":194},[162,4611,4612,4615],{},[40,4613,4614],{},"逐项输出一个字符串中的字符。",[40,4616,2347,4617,4620],{},[63,4618,4619],{},"range()"," 输出 2、4、6、8。",[10,4622,213],{},[14,4624,216],{"id":216},[10,4626,4627],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,4629,223],{},{"title":61,"searchDepth":75,"depth":75,"links":4631},[4632,4633,4634,4635,4636,4637,4638,4639],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4487,"description":4492},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[234,4345,4647],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4650,"title":4651,"body":4652,"category":234,"cover":235,"description":4656,"extension":236,"meta":4830,"navigation":90,"path":4831,"pinned":239,"publishedAt":240,"seo":4832,"slug":4833,"stem":4834,"summary":4835,"tags":4836,"updatedAt":240,"visible":90,"__hash__":4837},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4653,"toc":4820},[4654,4657,4659,4662,4664,4670,4680,4682,4701,4703,4705,4757,4759,4765,4767,4769,4783,4785,4801,4803,4811,4813,4815,4818],[10,4655,4656],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4658,16],{"id":16},[10,4660,4661],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4663,22],{"id":22},[10,4665,4666],{},[26,4667],{"alt":4668,"src":4669},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4671,4672,4675,4676,4679],{},[63,4673,4674],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[63,4677,4678],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4681,35],{"id":35},[37,4683,4684,4687,4695],{},[40,4685,4686],{},"先写普通循环，再在确有需要时加入流程控制语句。",[40,4688,4689,4691,4692,4694],{},[63,4690,4674],{}," 前要确认不会跳过 ",[63,4693,4328],{}," 循环中的状态更新。",[40,4696,4697,4698,4700],{},"多层嵌套中 ",[63,4699,4678],{}," 只结束它所在的最内层循环。",[14,4702,51],{"id":51},[10,4704,54],{},[56,4706,4708],{"className":58,"code":4707,"language":60,"meta":61,"style":61},"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",[63,4709,4710,4715,4719,4724,4729,4734,4739,4744,4748,4752],{"__ignoreMap":61},[66,4711,4712],{"class":68,"line":69},[66,4713,4714],{},"numbers = [3, -1, 0, 8, 12]\n",[66,4716,4717],{"class":68,"line":75},[66,4718,91],{"emptyLinePlaceholder":90},[66,4720,4721],{"class":68,"line":81},[66,4722,4723],{},"for number in numbers:\n",[66,4725,4726],{"class":68,"line":87},[66,4727,4728],{},"    if number \u003C 0:\n",[66,4730,4731],{"class":68,"line":94},[66,4732,4733],{},"        continue\n",[66,4735,4736],{"class":68,"line":100},[66,4737,4738],{},"    if number == 0:\n",[66,4740,4741],{"class":68,"line":106},[66,4742,4743],{},"        break\n",[66,4745,4746],{"class":68,"line":112},[66,4747,4568],{},[66,4749,4750],{"class":68,"line":117},[66,4751,91],{"emptyLinePlaceholder":90},[66,4753,4754],{"class":68,"line":123},[66,4755,4756],{},"print(\"循环结束\")\n",[10,4758,146],{},[56,4760,4763],{"className":4761,"code":4762,"language":152,"meta":61},[150],"3\n循环结束\n",[63,4764,4762],{"__ignoreMap":61},[10,4766,157],{},[14,4768,160],{"id":160},[162,4770,4771,4777],{},[40,4772,4773,4774,4776],{},"遇到 -1 时 ",[63,4775,4674],{}," 立即结束本轮，后面的判断和输出都不执行。",[40,4778,4779,4780,4782],{},"遇到 0 时 ",[63,4781,4678],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4784,183],{"id":183},[37,4786,4787,4792],{},[40,4788,3475,4789,4791],{},[63,4790,4674],{}," 当作结束循环，实际它只跳到下一轮。",[40,4793,4794,4795,4797,4798,4800],{},"在 ",[63,4796,4328],{}," 中把状态更新放在可能被 ",[63,4799,4674],{}," 跳过的位置，造成无限循环。",[14,4802,194],{"id":194},[162,4804,4805,4808],{},[40,4806,4807],{},"跳过列表中的空字符串并输出其他内容。",[40,4809,4810],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4812,213],{},[14,4814,216],{"id":216},[10,4816,4817],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,4819,223],{},{"title":61,"searchDepth":75,"depth":75,"links":4821},[4822,4823,4824,4825,4826,4827,4828,4829],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4651,"description":4656},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[234,4678,4674],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4839,"title":4840,"body":4841,"category":234,"cover":235,"description":4845,"extension":236,"meta":5016,"navigation":90,"path":5017,"pinned":239,"publishedAt":240,"seo":5018,"slug":5019,"stem":5020,"summary":5021,"tags":5022,"updatedAt":240,"visible":90,"__hash__":5025},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4842,"toc":5004},[4843,4846,4848,4851,4853,4859,4862,4864,4888,4890,4892,4926,4928,4934,4936,4938,4955,4957,4960,4966,4969,4971,4985,4987,4995,4997,4999,5002],[10,4844,4845],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4847,16],{"id":16},[10,4849,4850],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4852,22],{"id":22},[10,4854,4855],{},[26,4856],{"alt":4857,"src":4858},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4860,4861],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4863,35],{"id":35},[37,4865,4866,4869,4872],{},[40,4867,4868],{},"每增加一层嵌套，阅读成本都会上升。",[40,4870,4871],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[40,4873,4874,4875,2265,4878,4881,4882,2265,4885,207],{},"变量名使用 ",[63,4876,4877],{},"row",[63,4879,4880],{},"cell"," 等层级含义，避免全部写成 ",[63,4883,4884],{},"i",[63,4886,4887],{},"j",[14,4889,51],{"id":51},[10,4891,54],{},[56,4893,4895],{"className":58,"code":4894,"language":60,"meta":61,"style":61},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[63,4896,4897,4902,4906,4911,4916,4921],{"__ignoreMap":61},[66,4898,4899],{"class":68,"line":69},[66,4900,4901],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[66,4903,4904],{"class":68,"line":75},[66,4905,91],{"emptyLinePlaceholder":90},[66,4907,4908],{"class":68,"line":81},[66,4909,4910],{},"for row in table:\n",[66,4912,4913],{"class":68,"line":87},[66,4914,4915],{},"    for cell in row:\n",[66,4917,4918],{"class":68,"line":94},[66,4919,4920],{},"        print(cell)\n",[66,4922,4923],{"class":68,"line":100},[66,4924,4925],{},"    print(\"一行结束\")\n",[10,4927,146],{},[56,4929,4932],{"className":4930,"code":4931,"language":152,"meta":61},[150],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[63,4933,4931],{"__ignoreMap":61},[10,4935,157],{},[14,4937,160],{"id":160},[162,4939,4940,4952],{},[40,4941,4942,4943,4945,4946,1165,4949,207],{},"外层变量 ",[63,4944,4877],{}," 先引用第一行列表，内层才依次处理 ",[63,4947,4948],{},"A1",[63,4950,4951],{},"A2",[40,4953,4954],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[337,4956,2705],{"id":2705},[10,4958,4959],{},"二维列表的输出顺序可以展开成一条时间线。",[10,4961,4962],{},[26,4963],{"alt":4964,"src":4965},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,4967,4968],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,4970,183],{"id":183},[37,4972,4973,4982],{},[40,4974,4975,4976,1017,4979,4981],{},"把两层循环变量都叫 ",[63,4977,4978],{},"item",[63,4980,4884],{},"，难以确认当前层级。",[40,4983,4984],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,4986,194],{"id":194},[162,4988,4989,4992],{},[40,4990,4991],{},"打印一个 2×3 数字表。",[40,4993,4994],{},"在内层增加条件，只输出大于 3 的元素。",[10,4996,213],{},[14,4998,216],{"id":216},[10,5000,5001],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,5003,223],{},{"title":61,"searchDepth":75,"depth":75,"links":5005},[5006,5007,5008,5009,5010,5013,5014,5015],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":5011},[5012],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4840,"description":4845},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[234,5023,5024],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5027,"title":5028,"body":5029,"category":234,"cover":235,"description":5033,"extension":236,"meta":5171,"navigation":90,"path":5172,"pinned":239,"publishedAt":240,"seo":5173,"slug":5174,"stem":5175,"summary":5176,"tags":5177,"updatedAt":240,"visible":90,"__hash__":5180},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5030,"toc":5161},[5031,5034,5036,5039,5041,5047,5050,5052,5063,5065,5067,5105,5107,5113,5115,5117,5129,5131,5142,5144,5152,5154,5156,5159],[10,5032,5033],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5035,16],{"id":16},[10,5037,5038],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5040,22],{"id":22},[10,5042,5043],{},[26,5044],{"alt":5045,"src":5046},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5048,5049],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5051,35],{"id":35},[37,5053,5054,5057,5060],{},[40,5055,5056],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[40,5058,5059],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[40,5061,5062],{},"推导式创建新列表，不修改输入列表。",[14,5064,51],{"id":51},[10,5066,54],{},[56,5068,5070],{"className":58,"code":5069,"language":60,"meta":61,"style":61},"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",[63,5071,5072,5077,5081,5086,5091,5095,5100],{"__ignoreMap":61},[66,5073,5074],{"class":68,"line":69},[66,5075,5076],{},"numbers = [1, 2, 3, 4, 5]\n",[66,5078,5079],{"class":68,"line":75},[66,5080,91],{"emptyLinePlaceholder":90},[66,5082,5083],{"class":68,"line":81},[66,5084,5085],{},"squares = [number * number for number in numbers]\n",[66,5087,5088],{"class":68,"line":87},[66,5089,5090],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[66,5092,5093],{"class":68,"line":94},[66,5094,91],{"emptyLinePlaceholder":90},[66,5096,5097],{"class":68,"line":100},[66,5098,5099],{},"print(squares)\n",[66,5101,5102],{"class":68,"line":106},[66,5103,5104],{},"print(even_squares)\n",[10,5106,146],{},[56,5108,5111],{"className":5109,"code":5110,"language":152,"meta":61},[150],"[1, 4, 9, 16, 25]\n[4, 16]\n",[63,5112,5110],{"__ignoreMap":61},[10,5114,157],{},[14,5116,160],{"id":160},[162,5118,5119,5122],{},[40,5120,5121],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[40,5123,5124,5125,5128],{},"第二条先用 ",[63,5126,5127],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5130,183],{"id":183},[37,5132,5133,5139],{},[40,5134,5135,5136,5138],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[63,5137,4345],{}," 开始找输入。",[40,5140,5141],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5143,194],{"id":194},[162,5145,5146,5149],{},[40,5147,5148],{},"把字符串列表转换为长度列表。",[40,5150,5151],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5153,213],{},[14,5155,216],{"id":216},[10,5157,5158],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,5160,223],{},{"title":61,"searchDepth":75,"depth":75,"links":5162},[5163,5164,5165,5166,5167,5168,5169,5170],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5028,"description":5033},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[234,5178,5179],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5182,"title":5183,"body":5184,"category":234,"cover":235,"description":5188,"extension":236,"meta":5331,"navigation":90,"path":5332,"pinned":239,"publishedAt":240,"seo":5333,"slug":5334,"stem":5335,"summary":5336,"tags":5337,"updatedAt":240,"visible":90,"__hash__":5340},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5185,"toc":5321},[5186,5189,5191,5194,5196,5202,5205,5207,5218,5220,5222,5261,5263,5269,5271,5273,5288,5290,5298,5300,5312,5314,5316,5319],[10,5187,5188],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5190,16],{"id":16},[10,5192,5193],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5195,22],{"id":22},[10,5197,5198],{},[26,5199],{"alt":5200,"src":5201},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5203,5204],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5206,35],{"id":35},[37,5208,5209,5212,5215],{},[40,5210,5211],{},"函数名描述动作，使用小写字母和下划线。",[40,5213,5214],{},"函数定义要先执行，之后才能调用。",[40,5216,5217],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5219,51],{"id":51},[10,5221,54],{},[56,5223,5225],{"className":58,"code":5224,"language":60,"meta":61,"style":61},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[63,5226,5227,5232,5237,5242,5246,5251,5256],{"__ignoreMap":61},[66,5228,5229],{"class":68,"line":69},[66,5230,5231],{},"def show_progress():\n",[66,5233,5234],{"class":68,"line":75},[66,5235,5236],{},"    print(\"正在学习函数\")\n",[66,5238,5239],{"class":68,"line":81},[66,5240,5241],{},"    print(\"本节完成 50%\")\n",[66,5243,5244],{"class":68,"line":87},[66,5245,91],{"emptyLinePlaceholder":90},[66,5247,5248],{"class":68,"line":94},[66,5249,5250],{},"print(\"调用前\")\n",[66,5252,5253],{"class":68,"line":100},[66,5254,5255],{},"show_progress()\n",[66,5257,5258],{"class":68,"line":106},[66,5259,5260],{},"print(\"调用后\")\n",[10,5262,146],{},[56,5264,5267],{"className":5265,"code":5266,"language":152,"meta":61},[150],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[63,5268,5266],{"__ignoreMap":61},[10,5270,157],{},[14,5272,160],{"id":160},[162,5274,5275,5281],{},[40,5276,946,5277,5280],{},[63,5278,5279],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[40,5282,5283,5284,5287],{},"运行到 ",[63,5285,5286],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5289,183],{"id":183},[37,5291,5292,5295],{},[40,5293,5294],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[40,5296,5297],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5299,194],{"id":194},[162,5301,5302,5309],{},[40,5303,5304,5305,5308],{},"定义 ",[63,5306,5307],{},"show_plan()"," 输出两行学习计划。",[40,5310,5311],{},"连续调用同一个函数两次，观察执行顺序。",[10,5313,213],{},[14,5315,216],{"id":216},[10,5317,5318],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,5320,223],{},{"title":61,"searchDepth":75,"depth":75,"links":5322},[5323,5324,5325,5326,5327,5328,5329,5330],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5183,"description":5188},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[234,5338,5339],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5342,"title":5343,"body":5344,"category":234,"cover":235,"description":5348,"extension":236,"meta":5528,"navigation":90,"path":5529,"pinned":239,"publishedAt":240,"seo":5530,"slug":5531,"stem":5532,"summary":5533,"tags":5534,"updatedAt":240,"visible":90,"__hash__":5537},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5345,"toc":5516},[5346,5349,5351,5354,5356,5362,5369,5371,5388,5390,5392,5426,5428,5434,5436,5438,5459,5461,5464,5470,5480,5482,5497,5499,5507,5509,5511,5514],[10,5347,5348],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5350,16],{"id":16},[10,5352,5353],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5355,22],{"id":22},[10,5357,5358],{},[26,5359],{"alt":5360,"src":5361},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5363,5364,5365,5368],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[63,5366,5367],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5370,35],{"id":35},[37,5372,5373,5376,5379],{},[40,5374,5375],{},"形参出现在函数定义中，实参出现在函数调用中。",[40,5377,5378],{},"局部变量默认只在函数内部可见。",[40,5380,5381,5382,5384,5385,207],{},"没有显式 ",[63,5383,5367],{}," 的函数会返回 ",[63,5386,5387],{},"None",[14,5389,51],{"id":51},[10,5391,54],{},[56,5393,5395],{"className":58,"code":5394,"language":60,"meta":61,"style":61},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[63,5396,5397,5402,5407,5412,5416,5421],{"__ignoreMap":61},[66,5398,5399],{"class":68,"line":69},[66,5400,5401],{},"def calculate_total(price, count):\n",[66,5403,5404],{"class":68,"line":75},[66,5405,5406],{},"    total = price * count\n",[66,5408,5409],{"class":68,"line":81},[66,5410,5411],{},"    return total\n",[66,5413,5414],{"class":68,"line":87},[66,5415,91],{"emptyLinePlaceholder":90},[66,5417,5418],{"class":68,"line":94},[66,5419,5420],{},"result = calculate_total(25, 4)\n",[66,5422,5423],{"class":68,"line":100},[66,5424,5425],{},"print(result)\n",[10,5427,146],{},[56,5429,5432],{"className":5430,"code":5431,"language":152,"meta":61},[150],"100\n",[63,5433,5431],{"__ignoreMap":61},[10,5435,157],{},[14,5437,160],{"id":160},[162,5439,5440,5449],{},[40,5441,5442,5443,2265,5446,5448],{},"调用时 25 和 4 分别绑定到 ",[63,5444,5445],{},"price",[63,5447,4408],{},"，它们只在本次函数调用的局部范围中使用。",[40,5450,5451,5454,5455,5458],{},[63,5452,5453],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[63,5456,5457],{},"result"," 并输出。",[337,5460,2705],{"id":2705},[10,5462,5463],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5465,5466],{},[26,5467],{"alt":5468,"src":5469},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5471,5472,2265,5474,1165,5476,5479],{},[63,5473,5445],{},[63,5475,4408],{},[63,5477,5478],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5481,183],{"id":183},[37,5483,5484,5491],{},[40,5485,5486,5487,5490],{},"在函数内部只 ",[63,5488,5489],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[40,5492,5493,5494,5496],{},"试图在函数外直接访问局部变量 ",[63,5495,5478],{},"，它的名字只在调用期间的局部作用域存在。",[14,5498,194],{"id":194},[162,5500,5501,5504],{},[40,5502,5503],{},"编写计算长方形面积的函数。",[40,5505,5506],{},"让函数返回结果后在调用方加上单位再输出。",[10,5508,213],{},[14,5510,216],{"id":216},[10,5512,5513],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,5515,223],{},{"title":61,"searchDepth":75,"depth":75,"links":5517},[5518,5519,5520,5521,5522,5525,5526,5527],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":5523},[5524],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5343,"description":5348},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[234,5535,5536],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5539,"title":5540,"body":5541,"category":234,"cover":235,"description":5545,"extension":236,"meta":5725,"navigation":90,"path":5726,"pinned":239,"publishedAt":240,"seo":5727,"slug":5728,"stem":5729,"summary":5730,"tags":5731,"updatedAt":240,"visible":90,"__hash__":5734},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5542,"toc":5713},[5543,5546,5548,5551,5553,5559,5562,5564,5581,5583,5585,5637,5639,5645,5647,5649,5667,5669,5672,5678,5681,5683,5694,5696,5704,5706,5708,5711],[10,5544,5545],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5547,16],{"id":16},[10,5549,5550],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5552,22],{"id":22},[10,5554,5555],{},[26,5556],{"alt":5557,"src":5558},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5560,5561],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5563,35],{"id":35},[37,5565,5566,5569,5575],{},[40,5567,5568],{},"必需参数应放在有默认值的参数之前。",[40,5570,5571,5574],{},[63,5572,5573],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[40,5576,5577,5580],{},[63,5578,5579],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5582,51],{"id":51},[10,5584,54],{},[56,5586,5588],{"className":58,"code":5587,"language":60,"meta":61,"style":61},"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",[63,5589,5590,5595,5600,5604,5609,5614,5618,5623,5628,5632],{"__ignoreMap":61},[66,5591,5592],{"class":68,"line":69},[66,5593,5594],{},"def build_title(name, level=\"基础\"):\n",[66,5596,5597],{"class":68,"line":75},[66,5598,5599],{},"    return name + \"｜\" + level\n",[66,5601,5602],{"class":68,"line":81},[66,5603,91],{"emptyLinePlaceholder":90},[66,5605,5606],{"class":68,"line":87},[66,5607,5608],{},"print(build_title(\"Python\"))\n",[66,5610,5611],{"class":68,"line":94},[66,5612,5613],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[66,5615,5616],{"class":68,"line":100},[66,5617,91],{"emptyLinePlaceholder":90},[66,5619,5620],{"class":68,"line":106},[66,5621,5622],{},"def total(*numbers):\n",[66,5624,5625],{"class":68,"line":112},[66,5626,5627],{},"    return sum(numbers)\n",[66,5629,5630],{"class":68,"line":117},[66,5631,91],{"emptyLinePlaceholder":90},[66,5633,5634],{"class":68,"line":123},[66,5635,5636],{},"print(total(10, 20, 30))\n",[10,5638,146],{},[56,5640,5643],{"className":5641,"code":5642,"language":152,"meta":61},[150],"Python｜基础\n异常处理｜进阶\n60\n",[63,5644,5642],{"__ignoreMap":61},[10,5646,157],{},[14,5648,160],{"id":160},[162,5650,5651,5658],{},[40,5652,5653,5654,5657],{},"第一次调用只提供必需参数，",[63,5655,5656],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[40,5659,5660,5663,5664,207],{},[63,5661,5662],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[63,5665,5666],{},"sum()",[337,5668,2705],{"id":2705},[10,5670,5671],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5673,5674],{},[26,5675],{"alt":5676,"src":5677},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5679,5680],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5682,183],{"id":183},[37,5684,5685,5691],{},[40,5686,5687,5688,5690],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[63,5689,5387],{}," 再在函数内创建。",[40,5692,5693],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5695,194],{"id":194},[162,5697,5698,5701],{},[40,5699,5700],{},"给问候函数增加默认称呼。",[40,5702,5703],{},"编写接收任意数量分数并返回总分的函数。",[10,5705,213],{},[14,5707,216],{"id":216},[10,5709,5710],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,5712,223],{},{"title":61,"searchDepth":75,"depth":75,"links":5714},[5715,5716,5717,5718,5719,5722,5723,5724],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":5720},[5721],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5540,"description":5545},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[234,5732,5733],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5736,"title":5737,"body":5738,"category":234,"cover":235,"description":5742,"extension":236,"meta":5937,"navigation":90,"path":5938,"pinned":239,"publishedAt":240,"seo":5939,"slug":5940,"stem":5941,"summary":5942,"tags":5943,"updatedAt":240,"visible":90,"__hash__":5946},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5739,"toc":5925},[5740,5743,5745,5748,5750,5756,5759,5761,5778,5780,5782,5843,5845,5851,5853,5855,5882,5884,5887,5893,5896,5898,5906,5908,5916,5918,5920,5923],[10,5741,5742],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5744,16],{"id":16},[10,5746,5747],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5749,22],{"id":22},[10,5751,5752],{},[26,5753],{"alt":5754,"src":5755},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5757,5758],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5760,35],{"id":35},[37,5762,5763,5766,5769],{},[40,5764,5765],{},"函数内部赋值默认创建局部变量。",[40,5767,5768],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[40,5770,5771,2184,5774,5777],{},[63,5772,5773],{},"global",[63,5775,5776],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5779,51],{"id":51},[10,5781,54],{},[56,5783,5785],{"className":58,"code":5784,"language":60,"meta":61,"style":61},"course = \"Python\"\n\ndef outer():\n    level = \"基础\"\n\n    def show():\n        lesson = \"作用域\"\n        print(course, level, lesson)\n\n    show()\n\nouter()\n",[63,5786,5787,5792,5796,5801,5806,5810,5815,5820,5825,5829,5834,5838],{"__ignoreMap":61},[66,5788,5789],{"class":68,"line":69},[66,5790,5791],{},"course = \"Python\"\n",[66,5793,5794],{"class":68,"line":75},[66,5795,91],{"emptyLinePlaceholder":90},[66,5797,5798],{"class":68,"line":81},[66,5799,5800],{},"def outer():\n",[66,5802,5803],{"class":68,"line":87},[66,5804,5805],{},"    level = \"基础\"\n",[66,5807,5808],{"class":68,"line":94},[66,5809,91],{"emptyLinePlaceholder":90},[66,5811,5812],{"class":68,"line":100},[66,5813,5814],{},"    def show():\n",[66,5816,5817],{"class":68,"line":106},[66,5818,5819],{},"        lesson = \"作用域\"\n",[66,5821,5822],{"class":68,"line":112},[66,5823,5824],{},"        print(course, level, lesson)\n",[66,5826,5827],{"class":68,"line":117},[66,5828,91],{"emptyLinePlaceholder":90},[66,5830,5831],{"class":68,"line":123},[66,5832,5833],{},"    show()\n",[66,5835,5836],{"class":68,"line":129},[66,5837,91],{"emptyLinePlaceholder":90},[66,5839,5840],{"class":68,"line":134},[66,5841,5842],{},"outer()\n",[10,5844,146],{},[56,5846,5849],{"className":5847,"code":5848,"language":152,"meta":61},[150],"Python 基础 作用域\n",[63,5850,5848],{"__ignoreMap":61},[10,5852,157],{},[14,5854,160],{"id":160},[162,5856,5857,5874],{},[40,5858,5859,5862,5863,5866,5867,5869,5870,5873],{},[63,5860,5861],{},"show()"," 中查找 ",[63,5864,5865],{},"lesson"," 时先在局部找到，查找 ",[63,5868,5656],{}," 时到外层 ",[63,5871,5872],{},"outer()"," 找到。",[40,5875,5876,5878,5879,5881],{},[63,5877,4591],{}," 在局部和外层都不存在，继续到模块全局找到；",[63,5880,2216],{}," 最后在内置作用域找到。",[337,5883,2705],{"id":2705},[10,5885,5886],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5888,5889],{},[26,5890],{"alt":5891,"src":5892},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5894,5895],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5897,183],{"id":183},[37,5899,5900,5903],{},[40,5901,5902],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[40,5904,5905],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5907,194],{"id":194},[162,5909,5910,5913],{},[40,5911,5912],{},"在内外层定义同名变量，观察最近作用域优先。",[40,5914,5915],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5917,213],{},[14,5919,216],{"id":216},[10,5921,5922],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,5924,223],{},{"title":61,"searchDepth":75,"depth":75,"links":5926},[5927,5928,5929,5930,5931,5934,5935,5936],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":5932},[5933],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5737,"description":5742},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[234,5944,5945],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5948,"title":5949,"body":5950,"category":234,"cover":235,"description":5954,"extension":236,"meta":6104,"navigation":90,"path":6105,"pinned":239,"publishedAt":240,"seo":6106,"slug":6107,"stem":6108,"summary":6109,"tags":6110,"updatedAt":240,"visible":90,"__hash__":6113},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5951,"toc":6094},[5952,5955,5957,5960,5962,5968,5971,5973,5992,5994,5996,6030,6032,6038,6040,6042,6057,6059,6071,6073,6085,6087,6089,6092],[10,5953,5954],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,5956,16],{"id":16},[10,5958,5959],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5961,22],{"id":22},[10,5963,5964],{},[26,5965],{"alt":5966,"src":5967},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,5969,5970],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,5972,35],{"id":35},[37,5974,5975,5978,5981],{},[40,5976,5977],{},"文档字符串紧跟在函数定义后的第一条语句。",[40,5979,5980],{},"注解表达接口意图，不代替输入校验和测试。",[40,5982,5983,5984,2265,5986,2265,5988,5991],{},"基础注解优先使用 ",[63,5985,2268],{},[63,5987,2434],{},[63,5989,5990],{},"list[str]"," 等直接写法。",[14,5993,51],{"id":51},[10,5995,54],{},[56,5997,5999],{"className":58,"code":5998,"language":60,"meta":61,"style":61},"def format_score(name: str, score: int) -> str:\n    \"\"\"返回带姓名的分数文本。\"\"\"\n    return name + \"：\" + str(score)\n\nprint(format_score(\"小郑\", 95))\nprint(format_score.__doc__)\n",[63,6000,6001,6006,6011,6016,6020,6025],{"__ignoreMap":61},[66,6002,6003],{"class":68,"line":69},[66,6004,6005],{},"def format_score(name: str, score: int) -> str:\n",[66,6007,6008],{"class":68,"line":75},[66,6009,6010],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[66,6012,6013],{"class":68,"line":81},[66,6014,6015],{},"    return name + \"：\" + str(score)\n",[66,6017,6018],{"class":68,"line":87},[66,6019,91],{"emptyLinePlaceholder":90},[66,6021,6022],{"class":68,"line":94},[66,6023,6024],{},"print(format_score(\"小郑\", 95))\n",[66,6026,6027],{"class":68,"line":100},[66,6028,6029],{},"print(format_score.__doc__)\n",[10,6031,146],{},[56,6033,6036],{"className":6034,"code":6035,"language":152,"meta":61},[150],"小郑：95\n返回带姓名的分数文本。\n",[63,6037,6035],{"__ignoreMap":61},[10,6039,157],{},[14,6041,160],{"id":160},[162,6043,6044,6054],{},[40,6045,6046,6047,6050,6051,6053],{},"函数签名说明 ",[63,6048,6049],{},"name"," 预期为字符串、",[63,6052,2254],{}," 预期为整数，返回值预期为字符串。",[40,6055,6056],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6058,183],{"id":183},[37,6060,6061,6068],{},[40,6062,6063,6064,6067],{},"认为加了 ",[63,6065,6066],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[40,6069,6070],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6072,194],{"id":194},[162,6074,6075,6078],{},[40,6076,6077],{},"为面积函数补充参数和返回值注解。",[40,6079,6080,6081,6084],{},"通过 ",[63,6082,6083],{},"函数名.__doc__"," 查看文档字符串。",[10,6086,213],{},[14,6088,216],{"id":216},[10,6090,6091],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,6093,223],{},{"title":61,"searchDepth":75,"depth":75,"links":6095},[6096,6097,6098,6099,6100,6101,6102,6103],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5949,"description":5954},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[234,6111,6112],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6115,"title":6116,"body":6117,"category":234,"cover":235,"description":6121,"extension":236,"meta":6348,"navigation":90,"path":6349,"pinned":239,"publishedAt":240,"seo":6350,"slug":6351,"stem":6352,"summary":6353,"tags":6354,"updatedAt":240,"visible":90,"__hash__":6357},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6118,"toc":6336},[6119,6122,6124,6130,6132,6138,6149,6151,6169,6171,6178,6207,6214,6233,6242,6244,6250,6252,6254,6277,6279,6282,6288,6294,6296,6312,6314,6327,6329,6331,6334],[10,6120,6121],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6123,16],{"id":16},[10,6125,6126,6127,6129],{},"本篇只处理“模块、import 与 ",[303,6128,6049],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6131,22],{"id":22},[10,6133,6134],{},[26,6135],{"alt":6136,"src":6137},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6139,6140,6141,6144,6145,6148],{},"同一个文件直接运行时 ",[63,6142,6143],{},"__name__"," 等于 ",[63,6146,6147],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6150,35],{"id":35},[37,6152,6153,6159,6162],{},[40,6154,6155,6156,6158],{},"一个 ",[63,6157,1179],{}," 文件就是一个模块。",[40,6160,6161],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[40,6163,6164,6165,6168],{},"避免使用 ",[63,6166,6167],{},"from module import *","，它会让名字来源不清楚。",[14,6170,51],{"id":51},[10,6172,6173,6174,6177],{},"先在同一个目录中创建两个文件。把函数放进 ",[63,6175,6176],{},"calculator.py","：",[56,6179,6181],{"className":58,"code":6180,"language":60,"meta":61,"style":61},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[63,6182,6183,6188,6193,6197,6202],{"__ignoreMap":61},[66,6184,6185],{"class":68,"line":69},[66,6186,6187],{},"def add(left, right):\n",[66,6189,6190],{"class":68,"line":75},[66,6191,6192],{},"    return left + right\n",[66,6194,6195],{"class":68,"line":81},[66,6196,91],{"emptyLinePlaceholder":90},[66,6198,6199],{"class":68,"line":87},[66,6200,6201],{},"if __name__ == \"__main__\":\n",[66,6203,6204],{"class":68,"line":94},[66,6205,6206],{},"    print(add(2, 3))\n",[10,6208,6209,6210,6213],{},"再创建 ",[63,6211,6212],{},"app.py","，从模块中导入函数：",[56,6215,6217],{"className":58,"code":6216,"language":60,"meta":61,"style":61},"from calculator import add\n\nprint(add(10, 20))\n",[63,6218,6219,6224,6228],{"__ignoreMap":61},[66,6220,6221],{"class":68,"line":69},[66,6222,6223],{},"from calculator import add\n",[66,6225,6226],{"class":68,"line":75},[66,6227,91],{"emptyLinePlaceholder":90},[66,6229,6230],{"class":68,"line":81},[66,6231,6232],{},"print(add(10, 20))\n",[10,6234,6235,6236,1165,6239,207],{},"分别执行 ",[63,6237,6238],{},"python3 calculator.py",[63,6240,6241],{},"python3 app.py",[10,6243,146],{},[56,6245,6248],{"className":6246,"code":6247,"language":152,"meta":61},[150],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[63,6249,6247],{"__ignoreMap":61},[10,6251,157],{},[14,6253,160],{"id":160},[162,6255,6256,6266],{},[40,6257,6258,6259,6261,6262,6265],{},"直接运行 ",[63,6260,6176],{}," 时，模块名是 ",[63,6263,6264],{},"__main__","，入口代码输出 5。",[40,6267,6268,6270,6271,6273,6274,6276],{},[63,6269,6212],{}," 导入模块时，",[63,6272,6176],{}," 的函数定义会执行，但入口判断为假；随后 ",[63,6275,6212],{}," 调用函数输出 30。",[337,6278,2705],{"id":2705},[10,6280,6281],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6283,6284],{},[26,6285],{"alt":6286,"src":6287},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6289,6290,6291,6293],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[63,6292,6264],{}," 保护下的演示代码。",[14,6295,183],{"id":183},[37,6297,6298,6305],{},[40,6299,6300,6301,1165,6303,207],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[63,6302,6176],{},[63,6304,6212],{},[40,6306,6307,6308,6311],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[63,6309,6310],{},"json.py","，导致导入目标被遮蔽。",[14,6313,194],{"id":194},[162,6315,6316,6322],{},[40,6317,2362,6318,6321],{},[63,6319,6320],{},"text_tools.py"," 并导出一个格式化函数。",[40,6323,6324,6325,207],{},"分别直接运行模块和从另一个脚本导入，输出 ",[63,6326,6143],{},[10,6328,213],{},[14,6330,216],{"id":216},[10,6332,6333],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,6335,223],{},{"title":61,"searchDepth":75,"depth":75,"links":6337},[6338,6339,6340,6341,6342,6345,6346,6347],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":6343},[6344],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6116,"description":6121},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[234,6355,6356],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6359,"title":6360,"body":6361,"category":234,"cover":235,"description":6365,"extension":236,"meta":6530,"navigation":90,"path":6531,"pinned":239,"publishedAt":240,"seo":6532,"slug":6533,"stem":6534,"summary":6535,"tags":6536,"updatedAt":240,"visible":90,"__hash__":6538},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6362,"toc":6520},[6363,6366,6368,6371,6373,6379,6382,6384,6398,6400,6402,6448,6450,6456,6458,6460,6486,6488,6498,6500,6511,6513,6515,6518],[10,6364,6365],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6367,16],{"id":16},[10,6369,6370],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6372,22],{"id":22},[10,6374,6375],{},[26,6376],{"alt":6377,"src":6378},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6380,6381],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6383,35],{"id":35},[37,6385,6386,6392,6395],{},[40,6387,6388,6391],{},[63,6389,6390],{},".venv"," 是常见目录名，不应提交到 Git。",[40,6393,6394],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[40,6396,6397],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6399,51],{"id":51},[10,6401,1582],{},[56,6403,6405],{"className":599,"code":6404,"language":601,"meta":61,"style":61},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[63,6406,6407,6419,6427,6433,6443],{"__ignoreMap":61},[66,6408,6409,6411,6413,6416],{"class":68,"line":69},[66,6410,699],{"class":608},[66,6412,641],{"class":611},[66,6414,6415],{"class":644}," venv",[66,6417,6418],{"class":644}," .venv\n",[66,6420,6421,6424],{"class":68,"line":75},[66,6422,6423],{"class":611},"source",[66,6425,6426],{"class":644}," .venv\u002Fbin\u002Factivate\n",[66,6428,6429,6431],{"class":68,"line":81},[66,6430,60],{"class":608},[66,6432,612],{"class":611},[66,6434,6435,6437,6439,6441],{"class":68,"line":87},[66,6436,60],{"class":608},[66,6438,641],{"class":611},[66,6440,645],{"class":644},[66,6442,612],{"class":611},[66,6444,6445],{"class":68,"line":94},[66,6446,6447],{"class":608},"deactivate\n",[10,6449,146],{},[56,6451,6454],{"className":6452,"code":6453,"language":152,"meta":61},[150],"Python 和 pip 的路径应指向当前项目的 .venv\n",[63,6455,6453],{"__ignoreMap":61},[10,6457,157],{},[14,6459,160],{"id":160},[162,6461,6462,6471],{},[40,6463,6464,6467,6468,6470],{},[63,6465,6466],{},"venv"," 根据当前 ",[63,6469,699],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[40,6472,6473,6474,2184,6476,6479,6480,3736,6482,6485],{},"激活后 ",[63,6475,60],{},[63,6477,6478],{},"python -m pip"," 优先指向 ",[63,6481,6390],{},[63,6483,6484],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6487,183],{"id":183},[37,6489,6490,6493],{},[40,6491,6492],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[40,6494,3475,6495,6497],{},[63,6496,6390],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6499,194],{"id":194},[162,6501,6502,6508],{},[40,6503,6504,6505,207],{},"创建虚拟环境并记录激活前后的 ",[63,6506,6507],{},"which python",[40,6509,6510],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6512,213],{},[14,6514,216],{"id":216},[10,6516,6517],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,6519,1666],{},{"title":61,"searchDepth":75,"depth":75,"links":6521},[6522,6523,6524,6525,6526,6527,6528,6529],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6360,"description":6365},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[234,6537,269],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6540,"title":6541,"body":6542,"category":234,"cover":235,"description":6546,"extension":236,"meta":6734,"navigation":90,"path":6735,"pinned":239,"publishedAt":240,"seo":6736,"slug":6737,"stem":6738,"summary":6739,"tags":6740,"updatedAt":240,"visible":90,"__hash__":6743},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6543,"toc":6724},[6544,6547,6549,6552,6554,6560,6569,6571,6595,6597,6599,6652,6654,6660,6662,6664,6680,6682,6701,6703,6715,6717,6719,6722],[10,6545,6546],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6548,16],{"id":16},[10,6550,6551],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6553,22],{"id":22},[10,6555,6556],{},[26,6557],{"alt":6558,"src":6559},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6561,6562,6565,6566,6568],{},[63,6563,6564],{},"Path"," 使用 ",[63,6567,2444],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6570,35],{"id":35},[37,6572,6573,6576,6588],{},[40,6574,6575],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[40,6577,6578,2265,6581,2265,6584,6587],{},[63,6579,6580],{},"exists()",[63,6582,6583],{},"is_file()",[63,6585,6586],{},"is_dir()"," 检查真实文件系统状态。",[40,6589,6590,6591,6594],{},"创建目录前明确目标；",[63,6592,6593],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6596,51],{"id":51},[10,6598,54],{},[56,6600,6602],{"className":58,"code":6601,"language":60,"meta":61,"style":61},"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",[63,6603,6604,6609,6613,6618,6623,6628,6632,6637,6642,6647],{"__ignoreMap":61},[66,6605,6606],{"class":68,"line":69},[66,6607,6608],{},"from pathlib import Path\n",[66,6610,6611],{"class":68,"line":75},[66,6612,91],{"emptyLinePlaceholder":90},[66,6614,6615],{"class":68,"line":81},[66,6616,6617],{},"project = Path.cwd()\n",[66,6619,6620],{"class":68,"line":87},[66,6621,6622],{},"data_dir = project \u002F \"data\"\n",[66,6624,6625],{"class":68,"line":94},[66,6626,6627],{},"file_path = data_dir \u002F \"records.json\"\n",[66,6629,6630],{"class":68,"line":100},[66,6631,91],{"emptyLinePlaceholder":90},[66,6633,6634],{"class":68,"line":106},[66,6635,6636],{},"print(project)\n",[66,6638,6639],{"class":68,"line":112},[66,6640,6641],{},"print(file_path.name)\n",[66,6643,6644],{"class":68,"line":117},[66,6645,6646],{},"print(file_path.suffix)\n",[66,6648,6649],{"class":68,"line":123},[66,6650,6651],{},"print(file_path.exists())\n",[10,6653,146],{},[56,6655,6658],{"className":6656,"code":6657,"language":152,"meta":61},[150],"显示当前项目路径、records.json、.json 和存在状态\n",[63,6659,6657],{"__ignoreMap":61},[10,6661,157],{},[14,6663,160],{"id":160},[162,6665,6666,6672],{},[40,6667,6668,6671],{},[63,6669,6670],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[40,6673,2347,6674,6676,6677,6679],{},[63,6675,2444],{}," 组合路径片段只创建新的 ",[63,6678,6564],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6681,183],{"id":183},[37,6683,6684,6692],{},[40,6685,3475,6686,6688,6689,6691],{},[63,6687,6564],{}," 对象存在当成真实文件存在，仍需调用 ",[63,6690,6580],{}," 等方法确认。",[40,6693,6694,6695,1017,6697,6700],{},"手工拼接 ",[63,6696,2444],{},[63,6698,6699],{},"\\"," 分隔符，降低跨平台可读性。",[14,6702,194],{"id":194},[162,6704,6705,6712],{},[40,6706,6707,6708,6711],{},"组合 ",[63,6709,6710],{},"output\u002Freport.txt"," 路径但先不创建文件。",[40,6713,6714],{},"输出路径的父目录、文件名和扩展名。",[10,6716,213],{},[14,6718,216],{"id":216},[10,6720,6721],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,6723,223],{},{"title":61,"searchDepth":75,"depth":75,"links":6725},[6726,6727,6728,6729,6730,6731,6732,6733],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6541,"description":6546},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[234,6741,6742],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6745,"title":6746,"body":6747,"category":234,"cover":235,"description":6751,"extension":236,"meta":6929,"navigation":90,"path":6930,"pinned":239,"publishedAt":240,"seo":6931,"slug":6932,"stem":6933,"summary":6934,"tags":6935,"updatedAt":240,"visible":90,"__hash__":6938},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6748,"toc":6919},[6749,6752,6754,6757,6759,6765,6768,6770,6798,6800,6802,6859,6861,6867,6869,6871,6882,6884,6897,6899,6910,6912,6914,6917],[10,6750,6751],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6753,16],{"id":16},[10,6755,6756],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6758,22],{"id":22},[10,6760,6761],{},[26,6762],{"alt":6763,"src":6764},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6766,6767],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6769,35],{"id":35},[37,6771,6772,6778,6787],{},[40,6773,6774,6777],{},[63,6775,6776],{},"w"," 模式会截断原文件，写入前必须确认目标。",[40,6779,6780,6783,6784,207],{},[63,6781,6782],{},"r"," 模式读取不存在文件会产生 ",[63,6785,6786],{},"FileNotFoundError",[40,6788,6789,6790,6793,6794,6797],{},"本篇显式调用 ",[63,6791,6792],{},"close()","；第 34 篇会用 ",[63,6795,6796],{},"with"," 更可靠地管理关闭动作。",[14,6799,51],{"id":51},[10,6801,54],{},[56,6803,6805],{"className":58,"code":6804,"language":60,"meta":61,"style":61},"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",[63,6806,6807,6811,6815,6820,6825,6830,6835,6839,6844,6849,6854],{"__ignoreMap":61},[66,6808,6809],{"class":68,"line":69},[66,6810,6608],{},[66,6812,6813],{"class":68,"line":75},[66,6814,91],{"emptyLinePlaceholder":90},[66,6816,6817],{"class":68,"line":81},[66,6818,6819],{},"file_path = Path(\"notes.txt\")\n",[66,6821,6822],{"class":68,"line":87},[66,6823,6824],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[66,6826,6827],{"class":68,"line":94},[66,6828,6829],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[66,6831,6832],{"class":68,"line":100},[66,6833,6834],{},"writer.close()\n",[66,6836,6837],{"class":68,"line":106},[66,6838,91],{"emptyLinePlaceholder":90},[66,6840,6841],{"class":68,"line":112},[66,6842,6843],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[66,6845,6846],{"class":68,"line":117},[66,6847,6848],{},"content = reader.read()\n",[66,6850,6851],{"class":68,"line":123},[66,6852,6853],{},"reader.close()\n",[66,6855,6856],{"class":68,"line":129},[66,6857,6858],{},"print(content)\n",[10,6860,146],{},[56,6862,6865],{"className":6863,"code":6864,"language":152,"meta":61},[150],"变量\n循环\n函数\n",[63,6866,6864],{"__ignoreMap":61},[10,6868,157],{},[14,6870,160],{"id":160},[162,6872,6873,6879],{},[40,6874,6875,6876,6878],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[63,6877,6792],{}," 确保缓冲内容交给文件系统。",[40,6880,6881],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6883,183],{"id":183},[37,6885,6886,6891],{},[40,6887,2347,6888,6890],{},[63,6889,6776],{}," 模式打开重要文件却未确认覆盖风险。",[40,6892,6893,6894,207],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[63,6895,6896],{},"encoding=\"utf-8\"",[14,6898,194],{"id":194},[162,6900,6901,6904],{},[40,6902,6903],{},"写入三行学习记录并读取。",[40,6905,6906,6907,6909],{},"改用 ",[63,6908,345],{}," 模式追加一行，确认原内容仍保留。",[10,6911,213],{},[14,6913,216],{"id":216},[10,6915,6916],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,6918,223],{},{"title":61,"searchDepth":75,"depth":75,"links":6920},[6921,6922,6923,6924,6925,6926,6927,6928],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6746,"description":6751},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[234,6936,6937],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6940,"title":6941,"body":6942,"category":234,"cover":235,"description":6946,"extension":236,"meta":7113,"navigation":90,"path":7114,"pinned":239,"publishedAt":240,"seo":7115,"slug":7116,"stem":7117,"summary":7118,"tags":7119,"updatedAt":240,"visible":90,"__hash__":7122},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6943,"toc":7103},[6944,6947,6949,6952,6954,6960,6970,6972,6986,6988,6990,7050,7052,7058,7060,7062,7074,7076,7084,7086,7094,7096,7098,7101],[10,6945,6946],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6948,16],{"id":16},[10,6950,6951],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6953,22],{"id":22},[10,6955,6956],{},[26,6957],{"alt":6958,"src":6959},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,6961,6962,6965,6966,6969],{},[63,6963,6964],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[63,6967,6968],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,6971,35],{"id":35},[37,6973,6974,6977,6983],{},[40,6975,6976],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[40,6978,6979,6982],{},[63,6980,6981],{},"ensure_ascii=False"," 让中文以可读字符写入。",[40,6984,6985],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,6987,51],{"id":51},[10,6989,54],{},[56,6991,6993],{"className":58,"code":6992,"language":60,"meta":61,"style":61},"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",[63,6994,6995,7000,7004,7009,7013,7018,7023,7027,7031,7036,7041,7045],{"__ignoreMap":61},[66,6996,6997],{"class":68,"line":69},[66,6998,6999],{},"import json\n",[66,7001,7002],{"class":68,"line":75},[66,7003,91],{"emptyLinePlaceholder":90},[66,7005,7006],{"class":68,"line":81},[66,7007,7008],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[66,7010,7011],{"class":68,"line":87},[66,7012,91],{"emptyLinePlaceholder":90},[66,7014,7015],{"class":68,"line":94},[66,7016,7017],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[66,7019,7020],{"class":68,"line":100},[66,7021,7022],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[66,7024,7025],{"class":68,"line":106},[66,7026,6834],{},[66,7028,7029],{"class":68,"line":112},[66,7030,91],{"emptyLinePlaceholder":90},[66,7032,7033],{"class":68,"line":117},[66,7034,7035],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[66,7037,7038],{"class":68,"line":123},[66,7039,7040],{},"loaded = json.load(reader)\n",[66,7042,7043],{"class":68,"line":129},[66,7044,6853],{},[66,7046,7047],{"class":68,"line":134},[66,7048,7049],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7051,146],{},[56,7053,7056],{"className":7054,"code":7055,"language":152,"meta":61},[150],"Python 60\n",[63,7057,7055],{"__ignoreMap":61},[10,7059,157],{},[14,7061,160],{"id":160},[162,7063,7064,7069],{},[40,7065,7066,7068],{},[63,7067,6964],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[40,7070,7071,7073],{},[63,7072,6968],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7075,183],{"id":183},[37,7077,7078,7081],{},[40,7079,7080],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[40,7082,7083],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7085,194],{"id":194},[162,7087,7088,7091],{},[40,7089,7090],{},"保存包含两条学习记录的列表。",[40,7092,7093],{},"读取后修改进度，再重新写回文件。",[10,7095,213],{},[14,7097,216],{"id":216},[10,7099,7100],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,7102,223],{},{"title":61,"searchDepth":75,"depth":75,"links":7104},[7105,7106,7107,7108,7109,7110,7111,7112],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6941,"description":6946},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[234,7120,7121],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7124,"title":7125,"body":7126,"category":234,"cover":235,"description":7130,"extension":236,"meta":7314,"navigation":90,"path":7315,"pinned":239,"publishedAt":240,"seo":7316,"slug":7317,"stem":7318,"summary":7319,"tags":7320,"updatedAt":240,"visible":90,"__hash__":7323},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7127,"toc":7304},[7128,7131,7133,7136,7138,7144,7150,7152,7174,7176,7178,7241,7243,7249,7251,7253,7269,7271,7285,7287,7295,7297,7299,7302],[10,7129,7130],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7132,16],{"id":16},[10,7134,7135],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7137,22],{"id":22},[10,7139,7140],{},[26,7141],{"alt":7142,"src":7143},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7145,7146,7149],{},[63,7147,7148],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7151,35],{"id":35},[37,7153,7154,7164,7171],{},[40,7155,2347,7156,7159,7160,7163],{},[63,7157,7158],{},"newline=\"\""," 让 ",[63,7161,7162],{},"csv"," 模块正确处理换行。",[40,7165,7166,7167,7170],{},"字段顺序由 ",[63,7168,7169],{},"fieldnames"," 决定，字典键需要与字段名一致。",[40,7172,7173],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7175,51],{"id":51},[10,7177,54],{},[56,7179,7181],{"className":58,"code":7180,"language":60,"meta":61,"style":61},"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",[63,7182,7183,7188,7192,7197,7202,7207,7212,7217,7221,7226,7231,7236],{"__ignoreMap":61},[66,7184,7185],{"class":68,"line":69},[66,7186,7187],{},"import csv\n",[66,7189,7190],{"class":68,"line":75},[66,7191,91],{"emptyLinePlaceholder":90},[66,7193,7194],{"class":68,"line":81},[66,7195,7196],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[66,7198,7199],{"class":68,"line":87},[66,7200,7201],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[66,7203,7204],{"class":68,"line":94},[66,7205,7206],{},"writer.writeheader()\n",[66,7208,7209],{"class":68,"line":100},[66,7210,7211],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[66,7213,7214],{"class":68,"line":106},[66,7215,7216],{},"writer_file.close()\n",[66,7218,7219],{"class":68,"line":112},[66,7220,91],{"emptyLinePlaceholder":90},[66,7222,7223],{"class":68,"line":117},[66,7224,7225],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[66,7227,7228],{"class":68,"line":123},[66,7229,7230],{},"for row in csv.DictReader(reader_file):\n",[66,7232,7233],{"class":68,"line":129},[66,7234,7235],{},"    print(row[\"name\"], row[\"score\"])\n",[66,7237,7238],{"class":68,"line":134},[66,7239,7240],{},"reader_file.close()\n",[10,7242,146],{},[56,7244,7247],{"className":7245,"code":7246,"language":152,"meta":61},[150],"小郑 95\n",[63,7248,7246],{"__ignoreMap":61},[10,7250,157],{},[14,7252,160],{"id":160},[162,7254,7255,7264],{},[40,7256,7257,7260,7261,7263],{},[63,7258,7259],{},"DictWriter"," 按 ",[63,7262,7169],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[40,7265,7266,7268],{},[63,7267,7148],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7270,183],{"id":183},[37,7272,7273,7276],{},[40,7274,7275],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[40,7277,7278,7279,7281,7282,7284],{},"在 macOS 以外环境忽略 ",[63,7280,7158],{}," 可能出现额外空行；统一交给 ",[63,7283,7162],{}," 模块管理换行。",[14,7286,194],{"id":194},[162,7288,7289,7292],{},[40,7290,7291],{},"写入三名学习者的课程和分数。",[40,7293,7294],{},"读取 CSV 后把分数字符串转换为整数。",[10,7296,213],{},[14,7298,216],{"id":216},[10,7300,7301],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,7303,223],{},{"title":61,"searchDepth":75,"depth":75,"links":7305},[7306,7307,7308,7309,7310,7311,7312,7313],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7125,"description":7130},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[234,7321,7322],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7325,"title":7326,"body":7327,"category":234,"cover":235,"description":7331,"extension":236,"meta":7603,"navigation":90,"path":7604,"pinned":239,"publishedAt":240,"seo":7605,"slug":7606,"stem":7607,"summary":7608,"tags":7609,"updatedAt":240,"visible":90,"__hash__":7612},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7328,"toc":7590},[7329,7332,7334,7337,7339,7345,7356,7358,7375,7377,7379,7453,7455,7461,7463,7465,7490,7492,7501,7507,7518,7520,7526,7532,7541,7543,7558,7560,7581,7583,7585,7588],[10,7330,7331],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7333,16],{"id":16},[10,7335,7336],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7338,22],{"id":22},[10,7340,7341],{},[26,7342],{"alt":7343,"src":7344},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7346,7347,7348,7351,7352,7355],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[63,7349,7350],{},"except","；无论是否异常，",[63,7353,7354],{},"finally"," 都会在离开结构前执行。",[14,7357,35],{"id":35},[37,7359,7360,7366,7372],{},[40,7361,7362,7363,7365],{},"只捕获能够处理的具体异常，不使用空的 ",[63,7364,7350],{}," 吞掉全部错误。",[40,7367,7368,7371],{},[63,7369,7370],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[40,7373,7374],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7376,51],{"id":51},[10,7378,54],{},[56,7380,7382],{"className":58,"code":7381,"language":60,"meta":61,"style":61},"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",[63,7383,7384,7389,7394,7399,7404,7409,7413,7418,7423,7428,7433,7437,7442,7447],{"__ignoreMap":61},[66,7385,7386],{"class":68,"line":69},[66,7387,7388],{},"def parse_age(text):\n",[66,7390,7391],{"class":68,"line":75},[66,7392,7393],{},"    age = int(text)\n",[66,7395,7396],{"class":68,"line":81},[66,7397,7398],{},"    if age \u003C 0:\n",[66,7400,7401],{"class":68,"line":87},[66,7402,7403],{},"        raise ValueError(\"年龄不能为负数\")\n",[66,7405,7406],{"class":68,"line":94},[66,7407,7408],{},"    return age\n",[66,7410,7411],{"class":68,"line":100},[66,7412,91],{"emptyLinePlaceholder":90},[66,7414,7415],{"class":68,"line":106},[66,7416,7417],{},"try:\n",[66,7419,7420],{"class":68,"line":112},[66,7421,7422],{},"    age = parse_age(\"18\")\n",[66,7424,7425],{"class":68,"line":117},[66,7426,7427],{},"except ValueError as error:\n",[66,7429,7430],{"class":68,"line":123},[66,7431,7432],{},"    print(\"输入错误：\", error)\n",[66,7434,7435],{"class":68,"line":129},[66,7436,1154],{},[66,7438,7439],{"class":68,"line":134},[66,7440,7441],{},"    print(\"年龄：\", age)\n",[66,7443,7444],{"class":68,"line":140},[66,7445,7446],{},"finally:\n",[66,7448,7450],{"class":68,"line":7449},14,[66,7451,7452],{},"    print(\"处理结束\")\n",[10,7454,146],{},[56,7456,7459],{"className":7457,"code":7458,"language":152,"meta":61},[150],"年龄： 18\n处理结束\n",[63,7460,7458],{"__ignoreMap":61},[10,7462,157],{},[14,7464,160],{"id":160},[162,7466,7467,7479],{},[40,7468,7469,7471,7472,7474,7475,7478],{},[63,7470,3044],{}," 或主动 ",[63,7473,7370],{}," 都可能产生 ",[63,7476,7477],{},"ValueError","，控制流立即离开当前正常路径。",[40,7480,7481,7482,7484,7485,7487,7488,207],{},"有异常时进入匹配的 ",[63,7483,7350],{},"；没有异常时执行 ",[63,7486,1168],{},"；两种情况最后都会执行 ",[63,7489,7354],{},[337,7491,2705],{"id":2705},[10,7493,7494,2265,7496,1165,7498,7500],{},[63,7495,7350],{},[63,7497,1168],{},[63,7499,7354],{}," 的职责不同，不能只看它们出现的顺序。",[10,7502,7503],{},[26,7504],{"alt":7505,"src":7506},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7508,7509,7511,7512,7514,7515,7517],{},[63,7510,7350],{}," 处理匹配异常，",[63,7513,1168],{}," 只在无异常时运行，",[63,7516,7354],{}," 负责两条路径都需要的清理动作。",[337,7519,2705],{"id":4226},[10,7521,7522,7525],{},[63,7523,7524],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7527,7528],{},[26,7529],{"alt":7530,"src":7531},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7533,7534,7535,7537,7538,7540],{},"只把可能产生预期异常的操作放进 ",[63,7536,7524],{},"，后续正常业务放进 ",[63,7539,1168],{},"，错误边界会更清楚。",[14,7542,183],{"id":183},[37,7544,7545,7552],{},[40,7546,7547,7548,7551],{},"使用裸 ",[63,7549,7550],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[40,7553,7554,7555,7557],{},"把整个程序包在一个巨大 ",[63,7556,7524],{}," 中，无法判断究竟哪一步允许失败。",[14,7559,194],{"id":194},[162,7561,7562,7575],{},[40,7563,7564,7565,7568,7569,1165,7572,207],{},"让 ",[63,7566,7567],{},"parse_age"," 分别处理 ",[63,7570,7571],{},"\"abc\"",[63,7573,7574],{},"\"-1\"",[40,7576,7577,7578,7580],{},"为文件读取捕获 ",[63,7579,6786],{}," 并给出清晰提示。",[10,7582,213],{},[14,7584,216],{"id":216},[10,7586,7587],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,7589,223],{},{"title":61,"searchDepth":75,"depth":75,"links":7591},[7592,7593,7594,7595,7596,7600,7601,7602],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":7597},[7598,7599],{"id":2705,"depth":81,"text":2705},{"id":4226,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7326,"description":7331},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[234,7610,7611],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7614,"title":7615,"body":7616,"category":234,"cover":235,"description":7620,"extension":236,"meta":7796,"navigation":90,"path":7797,"pinned":239,"publishedAt":240,"seo":7798,"slug":7799,"stem":7800,"summary":7801,"tags":7802,"updatedAt":240,"visible":90,"__hash__":7804},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7617,"toc":7786},[7618,7621,7623,7626,7628,7634,7640,7642,7658,7660,7662,7716,7718,7724,7726,7728,7741,7743,7756,7758,7777,7779,7781,7784],[10,7619,7620],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7622,16],{"id":16},[10,7624,7625],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7627,22],{"id":22},[10,7629,7630],{},[26,7631],{"alt":7632,"src":7633},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7635,7636,7637,7639],{},"进入 ",[63,7638,6796],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7641,35],{"id":35},[37,7643,7644,7649,7655],{},[40,7645,7646,7648],{},[63,7647,6796],{}," 把资源获取和释放配成一个清晰边界。",[40,7650,7651,7654],{},[63,7652,7653],{},"as file"," 得到的是上下文返回的资源对象。",[40,7656,7657],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7659,51],{"id":51},[10,7661,54],{},[56,7663,7665],{"className":58,"code":7664,"language":60,"meta":61,"style":61},"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",[63,7666,7667,7671,7675,7679,7683,7688,7693,7697,7702,7707,7711],{"__ignoreMap":61},[66,7668,7669],{"class":68,"line":69},[66,7670,6608],{},[66,7672,7673],{"class":68,"line":75},[66,7674,91],{"emptyLinePlaceholder":90},[66,7676,7677],{"class":68,"line":81},[66,7678,6819],{},[66,7680,7681],{"class":68,"line":87},[66,7682,91],{"emptyLinePlaceholder":90},[66,7684,7685],{"class":68,"line":94},[66,7686,7687],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[66,7689,7690],{"class":68,"line":100},[66,7691,7692],{},"    file.write(\"上下文管理器\\n\")\n",[66,7694,7695],{"class":68,"line":106},[66,7696,91],{"emptyLinePlaceholder":90},[66,7698,7699],{"class":68,"line":112},[66,7700,7701],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[66,7703,7704],{"class":68,"line":117},[66,7705,7706],{},"    print(file.read())\n",[66,7708,7709],{"class":68,"line":123},[66,7710,91],{"emptyLinePlaceholder":90},[66,7712,7713],{"class":68,"line":129},[66,7714,7715],{},"print(file.closed)\n",[10,7717,146],{},[56,7719,7722],{"className":7720,"code":7721,"language":152,"meta":61},[150],"上下文管理器\n\nTrue\n",[63,7723,7721],{"__ignoreMap":61},[10,7725,157],{},[14,7727,160],{"id":160},[162,7729,7730,7738],{},[40,7731,7636,7732,7734,7735,207],{},[63,7733,6796],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[63,7736,7737],{},"file",[40,7739,7740],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7742,183],{"id":183},[37,7744,7745,7750],{},[40,7746,4794,7747,7749],{},[63,7748,6796],{}," 代码块外继续读写已经关闭的文件对象。",[40,7751,7752,7753,7755],{},"误以为 ",[63,7754,6796],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7757,194],{"id":194},[162,7759,7760,7769],{},[40,7761,7762,7763,7766,7767,207],{},"把第 30 篇的手动 ",[63,7764,7765],{},"open\u002Fclose"," 改写为 ",[63,7768,6796],{},[40,7770,4794,7771,7773,7774,207],{},[63,7772,6796],{}," 块后检查 ",[63,7775,7776],{},"file.closed",[10,7778,213],{},[14,7780,216],{"id":216},[10,7782,7783],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,7785,223],{},{"title":61,"searchDepth":75,"depth":75,"links":7787},[7788,7789,7790,7791,7792,7793,7794,7795],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7615,"description":7620},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[234,6796,7803],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7806,"title":7807,"body":7808,"category":234,"cover":235,"description":7812,"extension":236,"meta":8024,"navigation":90,"path":8025,"pinned":239,"publishedAt":240,"seo":8026,"slug":8027,"stem":8028,"summary":8029,"tags":8030,"updatedAt":240,"visible":90,"__hash__":8033},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7809,"toc":8012},[7810,7813,7815,7818,7820,7826,7829,7831,7848,7850,7852,7920,7922,7928,7930,7932,7957,7959,7962,7968,7977,7979,7990,7992,8003,8005,8007,8010],[10,7811,7812],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7814,16],{"id":16},[10,7816,7817],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7819,22],{"id":22},[10,7821,7822],{},[26,7823],{"alt":7824,"src":7825},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7827,7828],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7830,35],{"id":35},[37,7832,7833,7839,7845],{},[40,7834,7835,7838],{},[63,7836,7837],{},"self"," 表示当前实例，由方法调用自动传入。",[40,7840,7841,7844],{},[63,7842,7843],{},"__init__"," 在实例创建过程中初始化属性。",[40,7846,7847],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7849,51],{"id":51},[10,7851,54],{},[56,7853,7855],{"className":58,"code":7854,"language":60,"meta":61,"style":61},"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",[63,7856,7857,7862,7867,7872,7877,7881,7886,7891,7896,7901,7905,7910,7915],{"__ignoreMap":61},[66,7858,7859],{"class":68,"line":69},[66,7860,7861],{},"class LearningRecord:\n",[66,7863,7864],{"class":68,"line":75},[66,7865,7866],{},"    def __init__(self, course, progress=0):\n",[66,7868,7869],{"class":68,"line":81},[66,7870,7871],{},"        self.course = course\n",[66,7873,7874],{"class":68,"line":87},[66,7875,7876],{},"        self.progress = progress\n",[66,7878,7879],{"class":68,"line":94},[66,7880,91],{"emptyLinePlaceholder":90},[66,7882,7883],{"class":68,"line":100},[66,7884,7885],{},"    def advance(self, amount):\n",[66,7887,7888],{"class":68,"line":106},[66,7889,7890],{},"        self.progress = self.progress + amount\n",[66,7892,7893],{"class":68,"line":112},[66,7894,7895],{},"        if self.progress > 100:\n",[66,7897,7898],{"class":68,"line":117},[66,7899,7900],{},"            self.progress = 100\n",[66,7902,7903],{"class":68,"line":123},[66,7904,91],{"emptyLinePlaceholder":90},[66,7906,7907],{"class":68,"line":129},[66,7908,7909],{},"record = LearningRecord(\"Python\", 40)\n",[66,7911,7912],{"class":68,"line":134},[66,7913,7914],{},"record.advance(15)\n",[66,7916,7917],{"class":68,"line":140},[66,7918,7919],{},"print(record.course, record.progress)\n",[10,7921,146],{},[56,7923,7926],{"className":7924,"code":7925,"language":152,"meta":61},[150],"Python 55\n",[63,7927,7925],{"__ignoreMap":61},[10,7929,157],{},[14,7931,160],{"id":160},[162,7933,7934,7944],{},[40,7935,7936,7937,7940,7941,7943],{},"调用 ",[63,7938,7939],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[63,7942,7843],{}," 把课程和进度保存在该实例属性中。",[40,7945,7946,7949,7950,7953,7954,7956],{},[63,7947,7948],{},"record.advance(15)"," 自动把 ",[63,7951,7952],{},"record"," 作为 ",[63,7955,7837],{},"，方法更新同一实例的进度并限制上限。",[337,7958,2705],{"id":2705},[10,7960,7961],{},"类是共同定义，实例则各自保存状态。",[10,7963,7964],{},[26,7965],{"alt":7966,"src":7967},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7969,7970,7971,1165,7973,7976],{},"两个实例共享同一套方法定义，但 ",[63,7972,4591],{},[63,7974,7975],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,7978,183],{"id":183},[37,7980,7981,7987],{},[40,7982,7983,7984,7986],{},"调用实例方法时手工再传一次 ",[63,7985,7837],{},"。通过实例调用时 Python 会自动绑定。",[40,7988,7989],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,7991,194],{"id":194},[162,7993,7994,8000],{},[40,7995,5304,7996,7999],{},[63,7997,7998],{},"Book"," 类，保存标题和阅读页数。",[40,8001,8002],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,8004,213],{},[14,8006,216],{"id":216},[10,8008,8009],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,8011,223],{},{"title":61,"searchDepth":75,"depth":75,"links":8013},[8014,8015,8016,8017,8018,8021,8022,8023],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":8019},[8020],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7807,"description":7812},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[234,8031,8032],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":4,"title":5,"body":8035,"category":234,"cover":235,"description":12,"extension":236,"meta":8182,"navigation":90,"path":238,"pinned":239,"publishedAt":240,"seo":8183,"slug":242,"stem":243,"summary":244,"tags":8184,"updatedAt":240,"visible":90,"__hash__":248},{"type":7,"value":8036,"toc":8172},[8037,8039,8041,8043,8045,8049,8051,8053,8061,8063,8065,8121,8123,8128,8130,8132,8144,8146,8152,8154,8164,8166,8168,8170],[10,8038,12],{},[14,8040,16],{"id":16},[10,8042,19],{},[14,8044,22],{"id":22},[10,8046,8047],{},[26,8048],{"alt":28,"src":29},[10,8050,32],{},[14,8052,35],{"id":35},[37,8054,8055,8057,8059],{},[40,8056,42],{},[40,8058,45],{},[40,8060,48],{},[14,8062,51],{"id":51},[10,8064,54],{},[56,8066,8067],{"className":58,"code":59,"language":60,"meta":61,"style":61},[63,8068,8069,8073,8077,8081,8085,8089,8093,8097,8101,8105,8109,8113,8117],{"__ignoreMap":61},[66,8070,8071],{"class":68,"line":69},[66,8072,72],{},[66,8074,8075],{"class":68,"line":75},[66,8076,78],{},[66,8078,8079],{"class":68,"line":81},[66,8080,84],{},[66,8082,8083],{"class":68,"line":87},[66,8084,91],{"emptyLinePlaceholder":90},[66,8086,8087],{"class":68,"line":94},[66,8088,97],{},[66,8090,8091],{"class":68,"line":100},[66,8092,103],{},[66,8094,8095],{"class":68,"line":106},[66,8096,109],{},[66,8098,8099],{"class":68,"line":112},[66,8100,91],{"emptyLinePlaceholder":90},[66,8102,8103],{"class":68,"line":117},[66,8104,120],{},[66,8106,8107],{"class":68,"line":123},[66,8108,126],{},[66,8110,8111],{"class":68,"line":129},[66,8112,91],{"emptyLinePlaceholder":90},[66,8114,8115],{"class":68,"line":134},[66,8116,137],{},[66,8118,8119],{"class":68,"line":140},[66,8120,143],{},[10,8122,146],{},[56,8124,8126],{"className":8125,"code":151,"language":152,"meta":61},[150],[63,8127,151],{"__ignoreMap":61},[10,8129,157],{},[14,8131,160],{"id":160},[162,8133,8134,8140],{},[40,8135,8136,169,8138,173],{},[63,8137,168],{},[63,8139,172],{},[40,8141,176,8142,180],{},[63,8143,179],{},[14,8145,183],{"id":183},[37,8147,8148,8150],{},[40,8149,188],{},[40,8151,191],{},[14,8153,194],{"id":194},[162,8155,8156,8162],{},[40,8157,199,8158,203,8160,207],{},[63,8159,202],{},[63,8161,206],{},[40,8163,210],{},[10,8165,213],{},[14,8167,216],{"id":216},[10,8169,219],{},[221,8171,223],{},{"title":61,"searchDepth":75,"depth":75,"links":8173},[8174,8175,8176,8177,8178,8179,8180,8181],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5,"description":12},[234,246,247],{"id":8186,"title":8187,"body":8188,"category":234,"cover":235,"description":8192,"extension":236,"meta":8395,"navigation":90,"path":8396,"pinned":239,"publishedAt":240,"seo":8397,"slug":8398,"stem":8399,"summary":8400,"tags":8401,"updatedAt":240,"visible":90,"__hash__":8404},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8189,"toc":8383},[8190,8193,8195,8198,8200,8206,8213,8215,8240,8242,8244,8296,8298,8304,8306,8308,8329,8331,8337,8343,8349,8351,8359,8361,8374,8376,8378,8381],[10,8191,8192],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8194,16],{"id":16},[10,8196,8197],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8199,22],{"id":22},[10,8201,8202],{},[26,8203],{"alt":8204,"src":8205},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8207,8208,8209,8212],{},"生成器运行到 ",[63,8210,8211],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8214,35],{"id":35},[37,8216,8217,8227,8237],{},[40,8218,8219,8222,8223,8226],{},[63,8220,8221],{},"iter()"," 从可迭代对象取得迭代器，",[63,8224,8225],{},"next()"," 请求下一个值。",[40,8228,8229,8230,8233,8234,8236],{},"没有更多值时迭代器抛出 ",[63,8231,8232],{},"StopIteration","，",[63,8235,4345],{}," 会自动处理。",[40,8238,8239],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8241,51],{"id":51},[10,8243,54],{},[56,8245,8247],{"className":58,"code":8246,"language":60,"meta":61,"style":61},"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",[63,8248,8249,8254,8259,8264,8269,8274,8278,8283,8288,8292],{"__ignoreMap":61},[66,8250,8251],{"class":68,"line":69},[66,8252,8253],{},"def countdown(start):\n",[66,8255,8256],{"class":68,"line":75},[66,8257,8258],{},"    current = start\n",[66,8260,8261],{"class":68,"line":81},[66,8262,8263],{},"    while current > 0:\n",[66,8265,8266],{"class":68,"line":87},[66,8267,8268],{},"        yield current\n",[66,8270,8271],{"class":68,"line":94},[66,8272,8273],{},"        current = current - 1\n",[66,8275,8276],{"class":68,"line":100},[66,8277,91],{"emptyLinePlaceholder":90},[66,8279,8280],{"class":68,"line":106},[66,8281,8282],{},"iterator = countdown(3)\n",[66,8284,8285],{"class":68,"line":112},[66,8286,8287],{},"print(next(iterator))\n",[66,8289,8290],{"class":68,"line":117},[66,8291,8287],{},[66,8293,8294],{"class":68,"line":123},[66,8295,8287],{},[10,8297,146],{},[56,8299,8302],{"className":8300,"code":8301,"language":152,"meta":61},[150],"3\n2\n1\n",[63,8303,8301],{"__ignoreMap":61},[10,8305,157],{},[14,8307,160],{"id":160},[162,8309,8310,8316],{},[40,8311,7936,8312,8315],{},[63,8313,8314],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[40,8317,8318,8319,8321,8322,8324,8325,8328],{},"每次 ",[63,8320,8225],{}," 运行到下一个 ",[63,8323,8211],{}," 并暂停，局部变量 ",[63,8326,8327],{},"current"," 和执行位置被保留。",[337,8330,2705],{"id":2705},[10,8332,8333,8334,8336],{},"生成器的暂停位置可以展开成多次 ",[63,8335,8225],{}," 的时间线。",[10,8338,8339],{},[26,8340],{"alt":8341,"src":8342},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8344,8345,8346,8348],{},"每次请求只推进到下一个 ",[63,8347,8211],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8350,183],{"id":183},[37,8352,8353,8356],{},[40,8354,8355],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[40,8357,8358],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8360,194],{"id":194},[162,8362,8363,8366],{},[40,8364,8365],{},"编写产生 1 到指定上限偶数的生成器。",[40,8367,4018,8368,8370,8371,8373],{},[63,8369,4345],{}," 遍历生成器，比较手动 ",[63,8372,8225],{}," 的差异。",[10,8375,213],{},[14,8377,216],{"id":216},[10,8379,8380],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,8382,223],{},{"title":61,"searchDepth":75,"depth":75,"links":8384},[8385,8386,8387,8388,8389,8392,8393,8394],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":8390},[8391],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8187,"description":8192},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[234,8402,8403],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8406,"title":8407,"body":8408,"category":234,"cover":235,"description":8412,"extension":236,"meta":8636,"navigation":90,"path":8637,"pinned":239,"publishedAt":240,"seo":8638,"slug":8639,"stem":8640,"summary":8641,"tags":8642,"updatedAt":240,"visible":90,"__hash__":8644},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8409,"toc":8624},[8410,8413,8415,8418,8420,8426,8429,8431,8451,8453,8455,8537,8539,8545,8547,8549,8571,8573,8576,8582,8589,8591,8601,8603,8615,8617,8619,8622],[10,8411,8412],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8414,16],{"id":16},[10,8416,8417],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8419,22],{"id":22},[10,8421,8422],{},[26,8423],{"alt":8424,"src":8425},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8427,8428],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8430,35],{"id":35},[37,8432,8433,8442,8445],{},[40,8434,8435,8438,8439,207],{},[63,8436,8437],{},"@trace"," 等价于 ",[63,8440,8441],{},"add = trace(add)",[40,8443,8444],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[40,8446,8447,8450],{},[63,8448,8449],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8452,51],{"id":51},[10,8454,54],{},[56,8456,8458],{"className":58,"code":8457,"language":60,"meta":61,"style":61},"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",[63,8459,8460,8465,8469,8474,8479,8484,8489,8494,8499,8504,8509,8513,8518,8522,8526,8531],{"__ignoreMap":61},[66,8461,8462],{"class":68,"line":69},[66,8463,8464],{},"from functools import wraps\n",[66,8466,8467],{"class":68,"line":75},[66,8468,91],{"emptyLinePlaceholder":90},[66,8470,8471],{"class":68,"line":81},[66,8472,8473],{},"def trace(function):\n",[66,8475,8476],{"class":68,"line":87},[66,8477,8478],{},"    @wraps(function)\n",[66,8480,8481],{"class":68,"line":94},[66,8482,8483],{},"    def wrapper(*args, **kwargs):\n",[66,8485,8486],{"class":68,"line":100},[66,8487,8488],{},"        print(\"开始：\", function.__name__)\n",[66,8490,8491],{"class":68,"line":106},[66,8492,8493],{},"        result = function(*args, **kwargs)\n",[66,8495,8496],{"class":68,"line":112},[66,8497,8498],{},"        print(\"结束：\", function.__name__)\n",[66,8500,8501],{"class":68,"line":117},[66,8502,8503],{},"        return result\n",[66,8505,8506],{"class":68,"line":123},[66,8507,8508],{},"    return wrapper\n",[66,8510,8511],{"class":68,"line":129},[66,8512,91],{"emptyLinePlaceholder":90},[66,8514,8515],{"class":68,"line":134},[66,8516,8517],{},"@trace\n",[66,8519,8520],{"class":68,"line":140},[66,8521,6187],{},[66,8523,8524],{"class":68,"line":7449},[66,8525,6192],{},[66,8527,8529],{"class":68,"line":8528},15,[66,8530,91],{"emptyLinePlaceholder":90},[66,8532,8534],{"class":68,"line":8533},16,[66,8535,8536],{},"print(add(2, 3))\n",[10,8538,146],{},[56,8540,8543],{"className":8541,"code":8542,"language":152,"meta":61},[150],"开始： add\n结束： add\n5\n",[63,8544,8542],{"__ignoreMap":61},[10,8546,157],{},[14,8548,160],{"id":160},[162,8550,8551,8568],{},[40,8552,8553,8554,8557,8558,8561,8562,8565,8566,207],{},"解释器执行定义时，把原 ",[63,8555,8556],{},"add"," 函数交给 ",[63,8559,8560],{},"trace","，返回的 ",[63,8563,8564],{},"wrapper"," 重新绑定到名字 ",[63,8567,8556],{},[40,8569,8570],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[337,8572,2705],{"id":2705},[10,8574,8575],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8577,8578],{},[26,8579],{"alt":8580,"src":8581},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8583,8584,8586,8587,207],{},[63,8585,8437],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[63,8588,8441],{},[14,8590,183],{"id":183},[37,8592,8593,8598],{},[40,8594,8595,8596,207],{},"包装函数忘记返回原函数结果，调用方得到 ",[63,8597,5387],{},[40,8599,8600],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8602,194],{"id":194},[162,8604,8605,8608],{},[40,8606,8607],{},"编写只记录调用次数的简单装饰器。",[40,8609,8610,8611,8614],{},"删除包装函数的 ",[63,8612,8613],{},"return result","，观察调用方得到什么。",[10,8616,213],{},[14,8618,216],{"id":216},[10,8620,8621],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,8623,223],{},{"title":61,"searchDepth":75,"depth":75,"links":8625},[8626,8627,8628,8629,8630,8633,8634,8635],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":8631},[8632],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8407,"description":8412},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[234,8643,5338],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8646,"title":8647,"body":8648,"category":234,"cover":235,"description":8652,"extension":236,"meta":8839,"navigation":90,"path":8840,"pinned":239,"publishedAt":240,"seo":8841,"slug":8842,"stem":8843,"summary":8844,"tags":8845,"updatedAt":240,"visible":90,"__hash__":8848},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8649,"toc":8827},[8650,8653,8655,8658,8660,8666,8669,8671,8682,8684,8686,8761,8763,8769,8771,8773,8784,8786,8789,8795,8798,8800,8808,8810,8818,8820,8822,8825],[10,8651,8652],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8654,16],{"id":16},[10,8656,8657],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8659,22],{"id":22},[10,8661,8662],{},[26,8663],{"alt":8664,"src":8665},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8667,8668],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8670,35],{"id":35},[37,8672,8673,8676,8679],{},[40,8674,8675],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[40,8677,8678],{},"日志记录运行状态，测试判断结果是否符合约定。",[40,8680,8681],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8683,51],{"id":51},[10,8685,54],{},[56,8687,8689],{"className":58,"code":8688,"language":60,"meta":61,"style":61},"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",[63,8690,8691,8696,8701,8705,8710,8714,8719,8724,8729,8733,8738,8743,8748,8752,8756],{"__ignoreMap":61},[66,8692,8693],{"class":68,"line":69},[66,8694,8695],{},"import logging\n",[66,8697,8698],{"class":68,"line":75},[66,8699,8700],{},"import unittest\n",[66,8702,8703],{"class":68,"line":81},[66,8704,91],{"emptyLinePlaceholder":90},[66,8706,8707],{"class":68,"line":87},[66,8708,8709],{},"logging.basicConfig(level=logging.INFO)\n",[66,8711,8712],{"class":68,"line":94},[66,8713,91],{"emptyLinePlaceholder":90},[66,8715,8716],{"class":68,"line":100},[66,8717,8718],{},"def clamp_progress(value):\n",[66,8720,8721],{"class":68,"line":106},[66,8722,8723],{},"    logging.info(\"检查进度：%s\", value)\n",[66,8725,8726],{"class":68,"line":112},[66,8727,8728],{},"    return max(0, min(100, value))\n",[66,8730,8731],{"class":68,"line":117},[66,8732,91],{"emptyLinePlaceholder":90},[66,8734,8735],{"class":68,"line":123},[66,8736,8737],{},"class ProgressTest(unittest.TestCase):\n",[66,8739,8740],{"class":68,"line":129},[66,8741,8742],{},"    def test_upper_limit(self):\n",[66,8744,8745],{"class":68,"line":134},[66,8746,8747],{},"        self.assertEqual(clamp_progress(120), 100)\n",[66,8749,8750],{"class":68,"line":140},[66,8751,91],{"emptyLinePlaceholder":90},[66,8753,8754],{"class":68,"line":7449},[66,8755,6201],{},[66,8757,8758],{"class":68,"line":8528},[66,8759,8760],{},"    unittest.main()\n",[10,8762,146],{},[56,8764,8767],{"className":8765,"code":8766,"language":152,"meta":61},[150],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[63,8768,8766],{"__ignoreMap":61},[10,8770,157],{},[14,8772,160],{"id":160},[162,8774,8775,8781],{},[40,8776,8777,8780],{},[63,8778,8779],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[40,8782,8783],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[337,8785,2705],{"id":2705},[10,8787,8788],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8790,8791],{},[26,8792],{"alt":8793,"src":8794},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8796,8797],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8799,183],{"id":183},[37,8801,8802,8805],{},[40,8803,8804],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[40,8806,8807],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8809,194],{"id":194},[162,8811,8812,8815],{},[40,8813,8814],{},"为负数进度增加测试。",[40,8816,8817],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8819,213],{},[14,8821,216],{"id":216},[10,8823,8824],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,8826,223],{},{"title":61,"searchDepth":75,"depth":75,"links":8828},[8829,8830,8831,8832,8833,8836,8837,8838],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":8834},[8835],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8647,"description":8652},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[234,8846,8847],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8850,"title":8851,"body":8852,"category":234,"cover":235,"description":8856,"extension":236,"meta":9156,"navigation":90,"path":9157,"pinned":239,"publishedAt":240,"seo":9158,"slug":9159,"stem":9160,"summary":9161,"tags":9162,"updatedAt":240,"visible":90,"__hash__":9165},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8853,"toc":9143},[8854,8857,8859,8862,8864,8870,8873,8875,8890,8892,8894,9041,9043,9049,9051,9053,9066,9068,9071,9077,9080,9082,9085,9091,9098,9100,9111,9113,9134,9136,9138,9141],[10,8855,8856],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8858,16],{"id":16},[10,8860,8861],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8863,22],{"id":22},[10,8865,8866],{},[26,8867],{"alt":8868,"src":8869},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8871,8872],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8874,35],{"id":35},[37,8876,8877,8880,8883],{},[40,8878,8879],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[40,8881,8882],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[40,8884,8885,8886,8889],{},"实际扩展前先为 ",[63,8887,8888],{},"add()"," 和存储边界补充测试。",[14,8891,51],{"id":51},[10,8893,54],{},[56,8895,8897],{"className":58,"code":8896,"language":60,"meta":61,"style":61},"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",[63,8898,8899,8903,8907,8911,8916,8921,8926,8931,8935,8940,8945,8950,8955,8960,8964,8969,8974,8980,8985,8991,8996,9001,9007,9013,9019,9024,9030,9035],{"__ignoreMap":61},[66,8900,8901],{"class":68,"line":69},[66,8902,6999],{},[66,8904,8905],{"class":68,"line":75},[66,8906,6608],{},[66,8908,8909],{"class":68,"line":81},[66,8910,91],{"emptyLinePlaceholder":90},[66,8912,8913],{"class":68,"line":87},[66,8914,8915],{},"class LearningRecords:\n",[66,8917,8918],{"class":68,"line":94},[66,8919,8920],{},"    def __init__(self, file_path):\n",[66,8922,8923],{"class":68,"line":100},[66,8924,8925],{},"        self.file_path = Path(file_path)\n",[66,8927,8928],{"class":68,"line":106},[66,8929,8930],{},"        self.items = []\n",[66,8932,8933],{"class":68,"line":112},[66,8934,91],{"emptyLinePlaceholder":90},[66,8936,8937],{"class":68,"line":117},[66,8938,8939],{},"    def add(self, title):\n",[66,8941,8942],{"class":68,"line":123},[66,8943,8944],{},"        title = title.strip()\n",[66,8946,8947],{"class":68,"line":129},[66,8948,8949],{},"        if not title:\n",[66,8951,8952],{"class":68,"line":134},[66,8953,8954],{},"            raise ValueError(\"课程名称不能为空\")\n",[66,8956,8957],{"class":68,"line":140},[66,8958,8959],{},"        self.items.append({\"title\": title, \"done\": False})\n",[66,8961,8962],{"class":68,"line":7449},[66,8963,91],{"emptyLinePlaceholder":90},[66,8965,8966],{"class":68,"line":8528},[66,8967,8968],{},"    def save(self):\n",[66,8970,8971],{"class":68,"line":8533},[66,8972,8973],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[66,8975,8977],{"class":68,"line":8976},17,[66,8978,8979],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[66,8981,8983],{"class":68,"line":8982},18,[66,8984,91],{"emptyLinePlaceholder":90},[66,8986,8988],{"class":68,"line":8987},19,[66,8989,8990],{},"records = LearningRecords(\"learning-records.json\")\n",[66,8992,8994],{"class":68,"line":8993},20,[66,8995,91],{"emptyLinePlaceholder":90},[66,8997,8999],{"class":68,"line":8998},21,[66,9000,7417],{},[66,9002,9004],{"class":68,"line":9003},22,[66,9005,9006],{},"    title = input(\"输入已学习课程：\")\n",[66,9008,9010],{"class":68,"line":9009},23,[66,9011,9012],{},"    records.add(title)\n",[66,9014,9016],{"class":68,"line":9015},24,[66,9017,9018],{},"    records.save()\n",[66,9020,9022],{"class":68,"line":9021},25,[66,9023,7427],{},[66,9025,9027],{"class":68,"line":9026},26,[66,9028,9029],{},"    print(\"无法保存：\", error)\n",[66,9031,9033],{"class":68,"line":9032},27,[66,9034,1154],{},[66,9036,9038],{"class":68,"line":9037},28,[66,9039,9040],{},"    print(\"已保存 1 条学习记录\")\n",[10,9042,146],{},[56,9044,9047],{"className":9045,"code":9046,"language":152,"meta":61},[150],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[63,9048,9046],{"__ignoreMap":61},[10,9050,157],{},[14,9052,160],{"id":160},[162,9054,9055,9061],{},[40,9056,9057,9058,9060],{},"输入层取得课程名后，",[63,9059,8888],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[40,9062,9063,9065],{},[63,9064,172],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[337,9067,2705],{"id":2705},[10,9069,9070],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9072,9073],{},[26,9074],{"alt":9075,"src":9076},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9078,9079],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[337,9081,2705],{"id":4226},[10,9083,9084],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9086,9087],{},[26,9088],{"alt":9089,"src":9090},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9092,9093,9094,9097],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[63,9095,9096],{},"load()"," 把文件状态恢复到内存。",[14,9099,183],{"id":183},[37,9101,9102,9105],{},[40,9103,9104],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[40,9106,9107,9108,9110],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[63,9109,9096],{}," 是下一项必要扩展。",[14,9112,194],{"id":194},[162,9114,9115,9121,9124],{},[40,9116,9117,9118,9120],{},"增加 ",[63,9119,9096],{},"，文件不存在时从空列表开始。",[40,9122,9123],{},"增加按序号标记完成的功能，并校验序号范围。",[40,9125,9126,9127,9130,9131,9133],{},"把输入循环放进 ",[63,9128,9129],{},"main()","，通过 ",[63,9132,6143],{}," 控制程序入口。",[10,9135,213],{},[14,9137,216],{"id":216},[10,9139,9140],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[221,9142,223],{},{"title":61,"searchDepth":75,"depth":75,"links":9144},[9145,9146,9147,9148,9149,9153,9154,9155],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":9150},[9151,9152],{"id":2705,"depth":81,"text":2705},{"id":4226,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8851,"description":8856},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[234,9163,9164],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9167,9270,9389,9520,9663,9788,9925,10062,10203,10372,10509,10642,10765,10894,11021,11184,11360,11501,11630,11779,11922,12043,12166,12315,12468,12633,12760,12941,13084,13241,13392,13539,13694,13912,14067,14242,14393,14560,14747,14910,15152,15392],{"id":1401,"title":1402,"body":9168,"category":234,"cover":235,"description":1407,"extension":236,"meta":9267,"navigation":90,"path":1526,"pinned":239,"publishedAt":240,"seo":9268,"slug":1528,"stem":1529,"summary":1530,"tags":9269,"updatedAt":240,"visible":90,"__hash__":1533},{"type":7,"value":9169,"toc":9257},[9170,9172,9174,9176,9178,9182,9186,9188,9198,9200,9202,9210,9212,9217,9219,9221,9231,9233,9241,9243,9249,9251,9253,9255],[10,9171,1407],{},[14,9173,16],{"id":16},[10,9175,1412],{},[14,9177,22],{"id":22},[10,9179,9180],{},[26,9181],{"alt":1419,"src":1420},[10,9183,9184,1425],{},[63,9185,1179],{},[14,9187,35],{"id":35},[37,9189,9190,9194,9196],{},[40,9191,1432,9192,1435],{},[63,9193,1179],{},[40,9195,1438],{},[40,9197,1441],{},[14,9199,51],{"id":51},[10,9201,54],{},[56,9203,9204],{"className":58,"code":1448,"language":60,"meta":61,"style":61},[63,9205,9206],{"__ignoreMap":61},[66,9207,9208],{"class":68,"line":69},[66,9209,1448],{},[10,9211,146],{},[56,9213,9215],{"className":9214,"code":1460,"language":152,"meta":61},[150],[63,9216,1460],{"__ignoreMap":61},[10,9218,157],{},[14,9220,160],{"id":160},[162,9222,9223,9227],{},[40,9224,1471,9225,1475],{},[63,9226,1474],{},[40,9228,1478,9229,1482],{},[63,9230,1481],{},[14,9232,183],{"id":183},[37,9234,9235,9237],{},[40,9236,1489],{},[40,9238,1492,9239,1495],{},[63,9240,1179],{},[14,9242,194],{"id":194},[162,9244,9245,9247],{},[40,9246,1502],{},[40,9248,1505],{},[10,9250,213],{},[14,9252,216],{"id":216},[10,9254,1512],{},[221,9256,223],{},{"title":61,"searchDepth":75,"depth":75,"links":9258},[9259,9260,9261,9262,9263,9264,9265,9266],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":1402,"description":1407},[234,1397,1532],{"id":1535,"title":1536,"body":9271,"category":234,"cover":235,"description":1541,"extension":236,"meta":9386,"navigation":90,"path":1678,"pinned":239,"publishedAt":240,"seo":9387,"slug":1680,"stem":1681,"summary":1682,"tags":9388,"updatedAt":240,"visible":90,"__hash__":1685},{"type":7,"value":9272,"toc":9376},[9273,9275,9277,9279,9281,9285,9289,9291,9301,9303,9305,9325,9327,9332,9334,9336,9346,9348,9358,9360,9368,9370,9372,9374],[10,9274,1541],{},[14,9276,16],{"id":16},[10,9278,1546],{},[14,9280,22],{"id":22},[10,9282,9283],{},[26,9284],{"alt":1553,"src":1554},[10,9286,1557,9287,1560],{},[63,9288,699],{},[14,9290,35],{"id":35},[37,9292,9293,9295,9297],{},[40,9294,1567],{},[40,9296,1570],{},[40,9298,1573,9299,1577],{},[63,9300,1576],{},[14,9302,51],{"id":51},[10,9304,1582],{},[56,9306,9307],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,9308,9309,9315],{"__ignoreMap":61},[66,9310,9311,9313],{"class":68,"line":69},[66,9312,699],{"class":608},[66,9314,612],{"class":611},[66,9316,9317,9319,9321,9323],{"class":68,"line":75},[66,9318,699],{"class":608},[66,9320,641],{"class":611},[66,9322,645],{"class":644},[66,9324,612],{"class":611},[10,9326,146],{},[56,9328,9330],{"className":9329,"code":1608,"language":152,"meta":61},[150],[63,9331,1608],{"__ignoreMap":61},[10,9333,157],{},[14,9335,160],{"id":160},[162,9337,9338,9342],{},[40,9339,9340,1622],{},[63,9341,1621],{},[40,9343,9344,1627],{},[63,9345,707],{},[14,9347,183],{"id":183},[37,9349,9350,9354],{},[40,9351,1634,9352,1637],{},[63,9353,699],{},[40,9355,1640,9356,1643],{},[63,9357,699],{},[14,9359,194],{"id":194},[162,9361,9362,9366],{},[40,9363,946,9364,1653],{},[63,9365,1652],{},[40,9367,1656],{},[10,9369,213],{},[14,9371,216],{"id":216},[10,9373,1663],{},[221,9375,1666],{},{"title":61,"searchDepth":75,"depth":75,"links":9377},[9378,9379,9380,9381,9382,9383,9384,9385],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":1536,"description":1541},[234,1684,1060],{"id":1687,"title":1688,"body":9390,"category":234,"cover":235,"description":1854,"extension":236,"meta":9517,"navigation":90,"path":1856,"pinned":239,"publishedAt":240,"seo":9518,"slug":1858,"stem":1859,"summary":1860,"tags":9519,"updatedAt":240,"visible":90,"__hash__":1864},{"type":7,"value":9391,"toc":9507},[9392,9396,9398,9400,9402,9406,9408,9410,9426,9428,9430,9450,9452,9457,9459,9461,9473,9475,9485,9487,9497,9499,9501,9505],[10,9393,1693,9394,1696],{},[63,9395,1179],{},[14,9397,16],{"id":16},[10,9399,1701],{},[14,9401,22],{"id":22},[10,9403,9404],{},[26,9405],{"alt":1708,"src":1709},[10,9407,1712],{},[14,9409,35],{"id":35},[37,9411,9412,9418,9422],{},[40,9413,1719,9414,1722,9416,207],{},[63,9415,699],{},[63,9417,1725],{},[40,9419,1728,9420,1732],{},[63,9421,1731],{},[40,9423,1735,9424,1738],{},[63,9425,1179],{},[14,9427,51],{"id":51},[10,9429,54],{},[56,9431,9432],{"className":1745,"code":1746,"language":1747,"meta":61,"style":61},[63,9433,9434,9438,9442,9446],{"__ignoreMap":61},[66,9435,9436],{"class":68,"line":69},[66,9437,1754],{},[66,9439,9440],{"class":68,"line":75},[66,9441,1759],{},[66,9443,9444],{"class":68,"line":81},[66,9445,1764],{},[66,9447,9448],{"class":68,"line":87},[66,9449,1769],{},[10,9451,146],{},[56,9453,9455],{"className":9454,"code":1775,"language":152,"meta":61},[150],[63,9456,1775],{"__ignoreMap":61},[10,9458,157],{},[14,9460,160],{"id":160},[162,9462,9463,9469],{},[40,9464,1786,9465,1790,9467,207],{},[63,9466,1789],{},[63,9468,1793],{},[40,9470,1796,9471,1799],{},[63,9472,1481],{},[14,9474,183],{"id":183},[37,9476,9477,9483],{},[40,9478,1806,9479,1809,9481,1812],{},[63,9480,1725],{},[63,9482,1179],{},[40,9484,1815],{},[14,9486,194],{"id":194},[162,9488,9489,9493],{},[40,9490,1822,9491,207],{},[63,9492,1825],{},[40,9494,1828,9495,1831],{},[63,9496,1481],{},[10,9498,213],{},[14,9500,216],{"id":216},[10,9502,1838,9503,1841],{},[63,9504,1179],{},[221,9506,223],{},{"title":61,"searchDepth":75,"depth":75,"links":9508},[9509,9510,9511,9512,9513,9514,9515,9516],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":1688,"description":1854},[234,1862,1863],{"id":1866,"title":1867,"body":9521,"category":234,"cover":235,"description":1872,"extension":236,"meta":9660,"navigation":90,"path":2044,"pinned":239,"publishedAt":240,"seo":9661,"slug":2046,"stem":2047,"summary":2048,"tags":9662,"updatedAt":240,"visible":90,"__hash__":2052},{"type":7,"value":9522,"toc":9650},[9523,9525,9527,9529,9531,9535,9539,9541,9553,9555,9557,9593,9595,9600,9602,9604,9620,9622,9632,9634,9642,9644,9646,9648],[10,9524,1872],{},[14,9526,16],{"id":16},[10,9528,1877],{},[14,9530,22],{"id":22},[10,9532,9533],{},[26,9534],{"alt":1884,"src":1885},[10,9536,9537,1891],{},[63,9538,1890],{},[14,9540,35],{"id":35},[37,9542,9543,9545,9551],{},[40,9544,1898],{},[40,9546,9547,1904,9549,1908],{},[63,9548,1903],{},[63,9550,1907],{},[40,9552,1911],{},[14,9554,51],{"id":51},[10,9556,1582],{},[56,9558,9559],{"className":599,"code":1918,"language":601,"meta":61,"style":61},[63,9560,9561,9567,9573,9577,9587],{"__ignoreMap":61},[66,9562,9563,9565],{"class":68,"line":69},[66,9564,1925],{"class":608},[66,9566,1928],{"class":644},[66,9568,9569,9571],{"class":68,"line":75},[66,9570,1933],{"class":611},[66,9572,1928],{"class":644},[66,9574,9575],{"class":68,"line":81},[66,9576,1940],{"class":611},[66,9578,9579,9581,9583,9585],{"class":68,"line":87},[66,9580,1945],{"class":611},[66,9582,1948],{"class":644},[66,9584,1952],{"class":1951},[66,9586,1223],{"class":644},[66,9588,9589,9591],{"class":68,"line":94},[66,9590,699],{"class":608},[66,9592,1223],{"class":644},[10,9594,146],{},[56,9596,9598],{"className":9597,"code":1966,"language":152,"meta":61},[150],[63,9599,1966],{"__ignoreMap":61},[10,9601,157],{},[14,9603,160],{"id":160},[162,9605,9606,9614],{},[40,9607,9608,1979,9610,1982,9612,1985],{},[63,9609,1925],{},[63,9611,1933],{},[63,9613,1903],{},[40,9615,9616,1990,9618,1994],{},[63,9617,1890],{},[63,9619,1993],{},[14,9621,183],{"id":183},[37,9623,9624,9630],{},[40,9625,2001,9626,1165,9628,207],{},[63,9627,1903],{},[63,9629,1907],{},[40,9631,2008],{},[14,9633,194],{"id":194},[162,9635,9636,9640],{},[40,9637,2015,9638,2019],{},[63,9639,2018],{},[40,9641,2022],{},[10,9643,213],{},[14,9645,216],{"id":216},[10,9647,2029],{},[221,9649,2032],{},{"title":61,"searchDepth":75,"depth":75,"links":9651},[9652,9653,9654,9655,9656,9657,9658,9659],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":1867,"description":1872},[234,2050,2051],{"id":2054,"title":2055,"body":9664,"category":234,"cover":235,"description":2060,"extension":236,"meta":9785,"navigation":90,"path":2209,"pinned":239,"publishedAt":240,"seo":9786,"slug":2211,"stem":2212,"summary":2213,"tags":9787,"updatedAt":240,"visible":90,"__hash__":2217},{"type":7,"value":9665,"toc":9775},[9666,9668,9670,9672,9674,9678,9686,9688,9702,9704,9706,9722,9724,9729,9731,9733,9747,9749,9755,9757,9767,9769,9771,9773],[10,9667,2060],{},[14,9669,16],{"id":16},[10,9671,2065],{},[14,9673,22],{"id":22},[10,9675,9676],{},[26,9677],{"alt":2072,"src":2073},[10,9679,2076,9680,207,9682,2082,9684,207],{},[63,9681,1481],{},[63,9683,2081],{},[63,9685,1789],{},[14,9687,35],{"id":35},[37,9689,9690,9694,9700],{},[40,9691,9692,2094],{},[63,9693,2093],{},[40,9695,9696,2100,9698,207],{},[63,9697,2099],{},[63,9699,2103],{},[40,9701,2106],{},[14,9703,51],{"id":51},[10,9705,54],{},[56,9707,9708],{"className":58,"code":2113,"language":60,"meta":61,"style":61},[63,9709,9710,9714,9718],{"__ignoreMap":61},[66,9711,9712],{"class":68,"line":69},[66,9713,2120],{},[66,9715,9716],{"class":68,"line":75},[66,9717,2125],{},[66,9719,9720],{"class":68,"line":81},[66,9721,2130],{},[10,9723,146],{},[56,9725,9727],{"className":9726,"code":2136,"language":152,"meta":61},[150],[63,9728,2136],{"__ignoreMap":61},[10,9730,157],{},[14,9732,160],{"id":160},[162,9734,9735,9741],{},[40,9736,9737,2150,9739,207],{},[63,9738,2149],{},[63,9740,2103],{},[40,9742,9743,2157,9745,2161],{},[63,9744,1481],{},[63,9746,2160],{},[14,9748,183],{"id":183},[37,9750,9751,9753],{},[40,9752,2168],{},[40,9754,2171],{},[14,9756,194],{"id":194},[162,9758,9759,9761],{},[40,9760,2178],{},[40,9762,2181,9763,2184,9765,2188],{},[63,9764,2081],{},[63,9766,2187],{},[10,9768,213],{},[14,9770,216],{"id":216},[10,9772,2195],{},[221,9774,223],{},{"title":61,"searchDepth":75,"depth":75,"links":9776},[9777,9778,9779,9780,9781,9782,9783,9784],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":2055,"description":2060},[234,2215,2216],{"id":2219,"title":2220,"body":9789,"category":234,"cover":235,"description":2225,"extension":236,"meta":9922,"navigation":90,"path":2393,"pinned":239,"publishedAt":240,"seo":9923,"slug":2395,"stem":2396,"summary":2397,"tags":9924,"updatedAt":240,"visible":90,"__hash__":2401},{"type":7,"value":9790,"toc":9912},[9791,9793,9795,9797,9799,9803,9805,9807,9823,9825,9827,9851,9853,9858,9860,9862,9878,9880,9892,9894,9904,9906,9908,9910],[10,9792,2225],{},[14,9794,16],{"id":16},[10,9796,2230],{},[14,9798,22],{"id":22},[10,9800,9801],{},[26,9802],{"alt":2237,"src":2238},[10,9804,2241],{},[14,9806,35],{"id":35},[37,9808,9809,9811,9817],{},[40,9810,2248],{},[40,9812,2251,9813,2184,9815,2258],{},[63,9814,2254],{},[63,9816,2257],{},[40,9818,2261,9819,2265,9821,2269],{},[63,9820,2264],{},[63,9822,2268],{},[14,9824,51],{"id":51},[10,9826,54],{},[56,9828,9829],{"className":58,"code":2276,"language":60,"meta":61,"style":61},[63,9830,9831,9835,9839,9843,9847],{"__ignoreMap":61},[66,9832,9833],{"class":68,"line":69},[66,9834,2283],{},[66,9836,9837],{"class":68,"line":75},[66,9838,2288],{},[66,9840,9841],{"class":68,"line":81},[66,9842,91],{"emptyLinePlaceholder":90},[66,9844,9845],{"class":68,"line":87},[66,9846,2297],{},[66,9848,9849],{"class":68,"line":94},[66,9850,2288],{},[10,9852,146],{},[56,9854,9856],{"className":9855,"code":2307,"language":152,"meta":61},[150],[63,9857,2307],{"__ignoreMap":61},[10,9859,157],{},[14,9861,160],{"id":160},[162,9863,9864,9870],{},[40,9865,946,9866,2321,9868,2324],{},[63,9867,2320],{},[63,9869,2254],{},[40,9871,946,9872,2330,9874,2334,9876,207],{},[63,9873,2329],{},[63,9875,2333],{},[63,9877,2337],{},[14,9879,183],{"id":183},[37,9881,9882,9884],{},[40,9883,2344],{},[40,9885,2347,9886,2265,9888,2265,9890,2355],{},[63,9887,2264],{},[63,9889,2268],{},[63,9891,2354],{},[14,9893,194],{"id":194},[162,9895,9896,9902],{},[40,9897,2362,9898,1165,9900,2369],{},[63,9899,2365],{},[63,9901,2368],{},[40,9903,2372],{},[10,9905,213],{},[14,9907,216],{"id":216},[10,9909,2379],{},[221,9911,223],{},{"title":61,"searchDepth":75,"depth":75,"links":9913},[9914,9915,9916,9917,9918,9919,9920,9921],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":2220,"description":2225},[234,2399,2400],{"id":2403,"title":2404,"body":9926,"category":234,"cover":235,"description":2409,"extension":236,"meta":10059,"navigation":90,"path":2574,"pinned":239,"publishedAt":240,"seo":10060,"slug":2576,"stem":2577,"summary":2578,"tags":10061,"updatedAt":240,"visible":90,"__hash__":2582},{"type":7,"value":9927,"toc":10049},[9928,9930,9932,9934,9936,9940,9942,9944,9962,9964,9966,10002,10004,10009,10011,10013,10023,10025,10033,10035,10041,10043,10045,10047],[10,9929,2409],{},[14,9931,16],{"id":16},[10,9933,2414],{},[14,9935,22],{"id":22},[10,9937,9938],{},[26,9939],{"alt":2421,"src":2422},[10,9941,2425],{},[14,9943,35],{"id":35},[37,9945,9946,9952,9960],{},[40,9947,9948,2435,9950,2439],{},[63,9949,2434],{},[63,9951,2438],{},[40,9953,9954,2445,9956,2449,9958,2453],{},[63,9955,2444],{},[63,9957,2448],{},[63,9959,2452],{},[40,9961,2456],{},[14,9963,51],{"id":51},[10,9965,54],{},[56,9967,9968],{"className":58,"code":2463,"language":60,"meta":61,"style":61},[63,9969,9970,9974,9978,9982,9986,9990,9994,9998],{"__ignoreMap":61},[66,9971,9972],{"class":68,"line":69},[66,9973,2470],{},[66,9975,9976],{"class":68,"line":75},[66,9977,2475],{},[66,9979,9980],{"class":68,"line":81},[66,9981,2480],{},[66,9983,9984],{"class":68,"line":87},[66,9985,91],{"emptyLinePlaceholder":90},[66,9987,9988],{"class":68,"line":94},[66,9989,2489],{},[66,9991,9992],{"class":68,"line":100},[66,9993,2494],{},[66,9995,9996],{"class":68,"line":106},[66,9997,2499],{},[66,9999,10000],{"class":68,"line":112},[66,10001,2504],{},[10,10003,146],{},[56,10005,10007],{"className":10006,"code":2510,"language":152,"meta":61},[150],[63,10008,2510],{"__ignoreMap":61},[10,10010,157],{},[14,10012,160],{"id":160},[162,10014,10015,10019],{},[40,10016,10017,2524],{},[63,10018,2523],{},[40,10020,10021,2530],{},[63,10022,2529],{},[14,10024,183],{"id":183},[37,10026,10027,10031],{},[40,10028,2537,10029,207],{},[63,10030,2540],{},[40,10032,2543],{},[14,10034,194],{"id":194},[162,10036,10037,10039],{},[40,10038,2550],{},[40,10040,2553],{},[10,10042,213],{},[14,10044,216],{"id":216},[10,10046,2560],{},[221,10048,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10050},[10051,10052,10053,10054,10055,10056,10057,10058],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":2404,"description":2409},[234,2580,2581],{"id":2584,"title":2585,"body":10063,"category":234,"cover":235,"description":2590,"extension":236,"meta":10200,"navigation":90,"path":2767,"pinned":239,"publishedAt":240,"seo":10201,"slug":2769,"stem":2770,"summary":2771,"tags":10202,"updatedAt":240,"visible":90,"__hash__":2775},{"type":7,"value":10064,"toc":10188},[10065,10067,10069,10071,10073,10077,10083,10085,10093,10095,10097,10121,10123,10128,10130,10132,10150,10152,10154,10158,10160,10162,10168,10170,10180,10182,10184,10186],[10,10066,2590],{},[14,10068,16],{"id":16},[10,10070,2595],{},[14,10072,22],{"id":22},[10,10074,10075],{},[26,10076],{"alt":2602,"src":2603},[10,10078,2606,10079,2610,10081,207],{},[63,10080,2609],{},[63,10082,2613],{},[14,10084,35],{"id":35},[37,10086,10087,10089,10091],{},[40,10088,2620],{},[40,10090,2623],{},[40,10092,2626],{},[14,10094,51],{"id":51},[10,10096,54],{},[56,10098,10099],{"className":58,"code":2633,"language":60,"meta":61,"style":61},[63,10100,10101,10105,10109,10113,10117],{"__ignoreMap":61},[66,10102,10103],{"class":68,"line":69},[66,10104,2640],{},[66,10106,10107],{"class":68,"line":75},[66,10108,2645],{},[66,10110,10111],{"class":68,"line":81},[66,10112,2650],{},[66,10114,10115],{"class":68,"line":87},[66,10116,2655],{},[66,10118,10119],{"class":68,"line":94},[66,10120,2660],{},[10,10122,146],{},[56,10124,10126],{"className":10125,"code":2666,"language":152,"meta":61},[150],[63,10127,2666],{"__ignoreMap":61},[10,10129,157],{},[14,10131,160],{"id":160},[162,10133,10134,10142],{},[40,10135,2677,10136,2680,10138,2684,10140,2688],{},[63,10137,234],{},[63,10139,2683],{},[63,10141,2687],{},[40,10143,10144,2694,10146,2698,10148,2702],{},[63,10145,2693],{},[63,10147,2697],{},[63,10149,2701],{},[337,10151,2705],{"id":2705},[10,10153,2708],{},[10,10155,10156],{},[26,10157],{"alt":2713,"src":2714},[10,10159,2717],{},[14,10161,183],{"id":183},[37,10163,10164,10166],{},[40,10165,2724],{},[40,10167,2727],{},[14,10169,194],{"id":194},[162,10171,10172,10178],{},[40,10173,2734,10174,2738,10176,207],{},[63,10175,2737],{},[63,10177,2741],{},[40,10179,2744],{},[10,10181,213],{},[14,10183,216],{"id":216},[10,10185,2751],{},[221,10187,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10189},[10190,10191,10192,10193,10194,10197,10198,10199],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":10195},[10196],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":2585,"description":2590},[234,2773,2774],{"id":2777,"title":2778,"body":10204,"category":234,"cover":235,"description":2783,"extension":236,"meta":10369,"navigation":90,"path":2998,"pinned":239,"publishedAt":240,"seo":10370,"slug":3000,"stem":3001,"summary":3002,"tags":10371,"updatedAt":240,"visible":90,"__hash__":3006},{"type":7,"value":10205,"toc":10357},[10206,10208,10210,10212,10214,10218,10224,10226,10246,10248,10250,10286,10288,10293,10295,10297,10311,10313,10315,10319,10325,10327,10337,10339,10349,10351,10353,10355],[10,10207,2783],{},[14,10209,16],{"id":16},[10,10211,2788],{},[14,10213,22],{"id":22},[10,10215,10216],{},[26,10217],{"alt":2795,"src":2796},[10,10219,2799,10220,1017,10222,2806],{},[63,10221,2802],{},[63,10223,2805],{},[14,10225,35],{"id":35},[37,10227,10228,10236,10244],{},[40,10229,10230,2816,10232,2820,10234,2824],{},[63,10231,2815],{},[63,10233,2819],{},[63,10235,2823],{},[40,10237,10238,2830,10240,2834,10242,2838],{},[63,10239,2829],{},[63,10241,2833],{},[63,10243,2837],{},[40,10245,2841],{},[14,10247,51],{"id":51},[10,10249,54],{},[56,10251,10252],{"className":58,"code":2848,"language":60,"meta":61,"style":61},[63,10253,10254,10258,10262,10266,10270,10274,10278,10282],{"__ignoreMap":61},[66,10255,10256],{"class":68,"line":69},[66,10257,2855],{},[66,10259,10260],{"class":68,"line":75},[66,10261,2860],{},[66,10263,10264],{"class":68,"line":81},[66,10265,91],{"emptyLinePlaceholder":90},[66,10267,10268],{"class":68,"line":87},[66,10269,2869],{},[66,10271,10272],{"class":68,"line":94},[66,10273,2874],{},[66,10275,10276],{"class":68,"line":100},[66,10277,2879],{},[66,10279,10280],{"class":68,"line":106},[66,10281,2884],{},[66,10283,10284],{"class":68,"line":112},[66,10285,2889],{},[10,10287,146],{},[56,10289,10291],{"className":10290,"code":2895,"language":152,"meta":61},[150],[63,10292,2895],{"__ignoreMap":61},[10,10294,157],{},[14,10296,160],{"id":160},[162,10298,10299,10305],{},[40,10300,10301,2909,10303,2913],{},[63,10302,2908],{},[63,10304,2912],{},[40,10306,10307,2919,10309,2922],{},[63,10308,2918],{},[63,10310,2837],{},[337,10312,2705],{"id":2705},[10,10314,2927],{},[10,10316,10317],{},[26,10318],{"alt":2932,"src":2933},[10,10320,10321,2938,10323,2941],{},[63,10322,2829],{},[63,10324,2833],{},[14,10326,183],{"id":183},[37,10328,10329,10335],{},[40,10330,2948,10331,2951,10333,2954],{},[63,10332,2823],{},[63,10334,2815],{},[40,10336,2957],{},[14,10338,194],{"id":194},[162,10340,10341,10345],{},[40,10342,2964,10343,2968],{},[63,10344,2967],{},[40,10346,2971,10347,2975],{},[63,10348,2974],{},[10,10350,213],{},[14,10352,216],{"id":216},[10,10354,2982],{},[221,10356,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10358},[10359,10360,10361,10362,10363,10366,10367,10368],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":10364},[10365],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":2778,"description":2783},[234,3004,3005],{"id":3008,"title":3009,"body":10373,"category":234,"cover":235,"description":3014,"extension":236,"meta":10506,"navigation":90,"path":3183,"pinned":239,"publishedAt":240,"seo":10507,"slug":3185,"stem":3186,"summary":3187,"tags":10508,"updatedAt":240,"visible":90,"__hash__":3190},{"type":7,"value":10374,"toc":10496},[10375,10377,10379,10381,10383,10387,10397,10399,10409,10411,10413,10441,10443,10448,10450,10452,10466,10468,10476,10478,10488,10490,10492,10494],[10,10376,3014],{},[14,10378,16],{"id":16},[10,10380,3019],{},[14,10382,22],{"id":22},[10,10384,10385],{},[26,10386],{"alt":3026,"src":3027},[10,10388,10389,3033,10391,3037,10393,3041,10395,3045],{},[63,10390,3032],{},[63,10392,3036],{},[63,10394,3040],{},[63,10396,3044],{},[14,10398,35],{"id":35},[37,10400,10401,10403,10407],{},[40,10402,3052],{},[40,10404,10405,3057],{},[63,10406,3044],{},[40,10408,3060],{},[14,10410,51],{"id":51},[10,10412,54],{},[56,10414,10415],{"className":58,"code":3067,"language":60,"meta":61,"style":61},[63,10416,10417,10421,10425,10429,10433,10437],{"__ignoreMap":61},[66,10418,10419],{"class":68,"line":69},[66,10420,3074],{},[66,10422,10423],{"class":68,"line":75},[66,10424,3079],{},[66,10426,10427],{"class":68,"line":81},[66,10428,3084],{},[66,10430,10431],{"class":68,"line":87},[66,10432,91],{"emptyLinePlaceholder":90},[66,10434,10435],{"class":68,"line":94},[66,10436,3093],{},[66,10438,10439],{"class":68,"line":100},[66,10440,3098],{},[10,10442,146],{},[56,10444,10446],{"className":10445,"code":3104,"language":152,"meta":61},[150],[63,10447,3104],{"__ignoreMap":61},[10,10449,157],{},[14,10451,160],{"id":160},[162,10453,10454,10460],{},[40,10455,3115,10456,3118,10458,3122],{},[63,10457,3032],{},[63,10459,3121],{},[40,10461,10462,3128,10464,3132],{},[63,10463,3127],{},[63,10465,3131],{},[14,10467,183],{"id":183},[37,10469,10470,10474],{},[40,10471,3139,10472,3143],{},[63,10473,3142],{},[40,10475,3146],{},[14,10477,194],{"id":194},[162,10479,10480,10482],{},[40,10481,3153],{},[40,10483,1728,10484,3159,10486,3162],{},[63,10485,3158],{},[63,10487,3044],{},[10,10489,213],{},[14,10491,216],{"id":216},[10,10493,3169],{},[221,10495,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10497},[10498,10499,10500,10501,10502,10503,10504,10505],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":3009,"description":3014},[234,2354,3189],{"id":3192,"title":3193,"body":10510,"category":234,"cover":235,"description":3198,"extension":236,"meta":10639,"navigation":90,"path":3359,"pinned":239,"publishedAt":240,"seo":10640,"slug":3361,"stem":3362,"summary":3363,"tags":10641,"updatedAt":240,"visible":90,"__hash__":3367},{"type":7,"value":10511,"toc":10629},[10512,10514,10516,10518,10520,10524,10528,10530,10540,10542,10544,10576,10578,10583,10585,10587,10599,10601,10611,10613,10621,10623,10625,10627],[10,10513,3198],{},[14,10515,16],{"id":16},[10,10517,3203],{},[14,10519,22],{"id":22},[10,10521,10522],{},[26,10523],{"alt":3210,"src":3211},[10,10525,3214,10526,3218],{},[63,10527,3217],{},[14,10529,35],{"id":35},[37,10531,10532,10534,10536],{},[40,10533,3225],{},[40,10535,3228],{},[40,10537,3231,10538,207],{},[63,10539,3234],{},[14,10541,51],{"id":51},[10,10543,54],{},[56,10545,10546],{"className":58,"code":3241,"language":60,"meta":61,"style":61},[63,10547,10548,10552,10556,10560,10564,10568,10572],{"__ignoreMap":61},[66,10549,10550],{"class":68,"line":69},[66,10551,3248],{},[66,10553,10554],{"class":68,"line":75},[66,10555,3253],{},[66,10557,10558],{"class":68,"line":81},[66,10559,91],{"emptyLinePlaceholder":90},[66,10561,10562],{"class":68,"line":87},[66,10563,3262],{},[66,10565,10566],{"class":68,"line":94},[66,10567,3267],{},[66,10569,10570],{"class":68,"line":100},[66,10571,3272],{},[66,10573,10574],{"class":68,"line":106},[66,10575,3277],{},[10,10577,146],{},[56,10579,10581],{"className":10580,"code":3283,"language":152,"meta":61},[150],[63,10582,3283],{"__ignoreMap":61},[10,10584,157],{},[14,10586,160],{"id":160},[162,10588,10589,10591],{},[40,10590,3294],{},[40,10592,10593,3300,10595,3304,10597,3308],{},[63,10594,3299],{},[63,10596,3303],{},[63,10598,3307],{},[14,10600,183],{"id":183},[37,10602,10603,10609],{},[40,10604,3315,10605,3319,10607,207],{},[63,10606,3318],{},[63,10608,3322],{},[40,10610,3325],{},[14,10612,194],{"id":194},[162,10614,10615,10617],{},[40,10616,3332],{},[40,10618,3335,10619,3338],{},[63,10620,3307],{},[10,10622,213],{},[14,10624,216],{"id":216},[10,10626,3345],{},[221,10628,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10630},[10631,10632,10633,10634,10635,10636,10637,10638],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":3193,"description":3198},[234,3365,3366],{"id":3369,"title":3370,"body":10643,"category":234,"cover":235,"description":3375,"extension":236,"meta":10762,"navigation":90,"path":3517,"pinned":239,"publishedAt":240,"seo":10763,"slug":3519,"stem":3520,"summary":3521,"tags":10764,"updatedAt":240,"visible":90,"__hash__":3524},{"type":7,"value":10644,"toc":10752},[10645,10647,10649,10651,10653,10657,10659,10661,10669,10671,10673,10701,10703,10708,10710,10712,10722,10724,10732,10734,10744,10746,10748,10750],[10,10646,3375],{},[14,10648,16],{"id":16},[10,10650,3380],{},[14,10652,22],{"id":22},[10,10654,10655],{},[26,10656],{"alt":3387,"src":3388},[10,10658,3391],{},[14,10660,35],{"id":35},[37,10662,10663,10665,10667],{},[40,10664,3398],{},[40,10666,3401],{},[40,10668,3404],{},[14,10670,51],{"id":51},[10,10672,54],{},[56,10674,10675],{"className":58,"code":3411,"language":60,"meta":61,"style":61},[63,10676,10677,10681,10685,10689,10693,10697],{"__ignoreMap":61},[66,10678,10679],{"class":68,"line":69},[66,10680,3418],{},[66,10682,10683],{"class":68,"line":75},[66,10684,3423],{},[66,10686,10687],{"class":68,"line":81},[66,10688,3428],{},[66,10690,10691],{"class":68,"line":87},[66,10692,91],{"emptyLinePlaceholder":90},[66,10694,10695],{"class":68,"line":94},[66,10696,3437],{},[66,10698,10699],{"class":68,"line":100},[66,10700,3442],{},[10,10702,146],{},[56,10704,10706],{"className":10705,"code":3448,"language":152,"meta":61},[150],[63,10707,3448],{"__ignoreMap":61},[10,10709,157],{},[14,10711,160],{"id":160},[162,10713,10714,10718],{},[40,10715,10716,3462],{},[63,10717,3461],{},[40,10719,10720,3468],{},[63,10721,3467],{},[14,10723,183],{"id":183},[37,10725,10726,10730],{},[40,10727,3475,10728,3479],{},[63,10729,3478],{},[40,10731,3482],{},[14,10733,194],{"id":194},[162,10735,10736,10738],{},[40,10737,3489],{},[40,10739,2181,10740,2184,10742,3496],{},[63,10741,3478],{},[63,10743,3467],{},[10,10745,213],{},[14,10747,216],{"id":216},[10,10749,3503],{},[221,10751,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10753},[10754,10755,10756,10757,10758,10759,10760,10761],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":3370,"description":3375},[234,3523,3366],{"id":3526,"title":3527,"body":10766,"category":234,"cover":235,"description":3532,"extension":236,"meta":10891,"navigation":90,"path":3688,"pinned":239,"publishedAt":240,"seo":10892,"slug":3690,"stem":3691,"summary":3692,"tags":10893,"updatedAt":240,"visible":90,"__hash__":3695},{"type":7,"value":10767,"toc":10881},[10768,10770,10772,10774,10776,10780,10786,10788,10798,10800,10802,10830,10832,10837,10839,10841,10851,10853,10865,10867,10873,10875,10877,10879],[10,10769,3532],{},[14,10771,16],{"id":16},[10,10773,3537],{},[14,10775,22],{"id":22},[10,10777,10778],{},[26,10779],{"alt":3544,"src":3545},[10,10781,3548,10782,3552,10784,3555],{},[63,10783,3551],{},[63,10785,2254],{},[14,10787,35],{"id":35},[37,10789,10790,10792,10796],{},[40,10791,3562],{},[40,10793,2347,10794,3568],{},[63,10795,3567],{},[40,10797,3571],{},[14,10799,51],{"id":51},[10,10801,54],{},[56,10803,10804],{"className":58,"code":3578,"language":60,"meta":61,"style":61},[63,10805,10806,10810,10814,10818,10822,10826],{"__ignoreMap":61},[66,10807,10808],{"class":68,"line":69},[66,10809,3585],{},[66,10811,10812],{"class":68,"line":75},[66,10813,3590],{},[66,10815,10816],{"class":68,"line":81},[66,10817,91],{"emptyLinePlaceholder":90},[66,10819,10820],{"class":68,"line":87},[66,10821,3599],{},[66,10823,10824],{"class":68,"line":94},[66,10825,3604],{},[66,10827,10828],{"class":68,"line":100},[66,10829,3609],{},[10,10831,146],{},[56,10833,10835],{"className":10834,"code":3615,"language":152,"meta":61},[150],[63,10836,3615],{"__ignoreMap":61},[10,10838,157],{},[14,10840,160],{"id":160},[162,10842,10843,10845],{},[40,10844,3626],{},[40,10846,3629,10847,3632,10849,3636],{},[63,10848,2254],{},[63,10850,3635],{},[14,10852,183],{"id":183},[37,10854,10855,10859],{},[40,10856,3643,10857,3647],{},[63,10858,3646],{},[40,10860,3650,10861,3654,10863,207],{},[63,10862,3653],{},[63,10864,3657],{},[14,10866,194],{"id":194},[162,10868,10869,10871],{},[40,10870,3664],{},[40,10872,3667],{},[10,10874,213],{},[14,10876,216],{"id":216},[10,10878,3674],{},[221,10880,223],{},{"title":61,"searchDepth":75,"depth":75,"links":10882},[10883,10884,10885,10886,10887,10888,10889,10890],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":3527,"description":3532},[234,3694,3366],{"id":3697,"title":3698,"body":10895,"category":234,"cover":235,"description":3703,"extension":236,"meta":11018,"navigation":90,"path":3853,"pinned":239,"publishedAt":240,"seo":11019,"slug":3855,"stem":3856,"summary":3857,"tags":11020,"updatedAt":240,"visible":90,"__hash__":3860},{"type":7,"value":10896,"toc":11008},[10897,10899,10901,10903,10905,10909,10911,10913,10925,10927,10929,10957,10959,10964,10966,10968,10978,10980,10990,10992,11000,11002,11004,11006],[10,10898,3703],{},[14,10900,16],{"id":16},[10,10902,3708],{},[14,10904,22],{"id":22},[10,10906,10907],{},[26,10908],{"alt":3715,"src":3716},[10,10910,3719],{},[14,10912,35],{"id":35},[37,10914,10915,10917,10919],{},[40,10916,3726],{},[40,10918,3729],{},[40,10920,3732,10921,3736,10923,3740],{},[63,10922,3735],{},[63,10924,3739],{},[14,10926,51],{"id":51},[10,10928,54],{},[56,10930,10931],{"className":58,"code":3747,"language":60,"meta":61,"style":61},[63,10932,10933,10937,10941,10945,10949,10953],{"__ignoreMap":61},[66,10934,10935],{"class":68,"line":69},[66,10936,3754],{},[66,10938,10939],{"class":68,"line":75},[66,10940,3759],{},[66,10942,10943],{"class":68,"line":81},[66,10944,91],{"emptyLinePlaceholder":90},[66,10946,10947],{"class":68,"line":87},[66,10948,3768],{},[66,10950,10951],{"class":68,"line":94},[66,10952,3773],{},[66,10954,10955],{"class":68,"line":100},[66,10956,3778],{},[10,10958,146],{},[56,10960,10962],{"className":10961,"code":3784,"language":152,"meta":61},[150],[63,10963,3784],{"__ignoreMap":61},[10,10965,157],{},[14,10967,160],{"id":160},[162,10969,10970,10972],{},[40,10971,3795],{},[40,10973,10974,3801,10976,3805],{},[63,10975,3800],{},[63,10977,3804],{},[14,10979,183],{"id":183},[37,10981,10982,10988],{},[40,10983,2347,10984,3814,10986,207],{},[63,10985,3739],{},[63,10987,3735],{},[40,10989,3819],{},[14,10991,194],{"id":194},[162,10993,10994,10998],{},[40,10995,3826,10996,3829],{},[63,10997,3735],{},[40,10999,3832],{},[10,11001,213],{},[14,11003,216],{"id":216},[10,11005,3839],{},[221,11007,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11009},[11010,11011,11012,11013,11014,11015,11016,11017],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":3698,"description":3703},[234,3859,3366],{"id":3862,"title":3863,"body":11022,"category":234,"cover":235,"description":3868,"extension":236,"meta":11181,"navigation":90,"path":4066,"pinned":239,"publishedAt":240,"seo":11182,"slug":4068,"stem":4069,"summary":4070,"tags":11183,"updatedAt":240,"visible":90,"__hash__":4074},{"type":7,"value":11023,"toc":11169},[11024,11026,11028,11030,11032,11036,11042,11044,11056,11058,11060,11100,11102,11107,11109,11111,11125,11127,11129,11133,11135,11137,11147,11149,11161,11163,11165,11167],[10,11025,3868],{},[14,11027,16],{"id":16},[10,11029,3873],{},[14,11031,22],{"id":22},[10,11033,11034],{},[26,11035],{"alt":3880,"src":3881},[10,11037,11038,3887,11040,3891],{},[63,11039,3886],{},[63,11041,3890],{},[14,11043,35],{"id":35},[37,11045,11046,11052,11054],{},[40,11047,11048,3900,11050,3904],{},[63,11049,2815],{},[63,11051,3903],{},[40,11053,3907],{},[40,11055,3910],{},[14,11057,51],{"id":51},[10,11059,54],{},[56,11061,11062],{"className":58,"code":3917,"language":60,"meta":61,"style":61},[63,11063,11064,11068,11072,11076,11080,11084,11088,11092,11096],{"__ignoreMap":61},[66,11065,11066],{"class":68,"line":69},[66,11067,3924],{},[66,11069,11070],{"class":68,"line":75},[66,11071,3929],{},[66,11073,11074],{"class":68,"line":81},[66,11075,3934],{},[66,11077,11078],{"class":68,"line":87},[66,11079,91],{"emptyLinePlaceholder":90},[66,11081,11082],{"class":68,"line":94},[66,11083,3943],{},[66,11085,11086],{"class":68,"line":100},[66,11087,3948],{},[66,11089,11090],{"class":68,"line":106},[66,11091,3953],{},[66,11093,11094],{"class":68,"line":112},[66,11095,3958],{},[66,11097,11098],{"class":68,"line":117},[66,11099,3963],{},[10,11101,146],{},[56,11103,11105],{"className":11104,"code":3969,"language":152,"meta":61},[150],[63,11106,3969],{"__ignoreMap":61},[10,11108,157],{},[14,11110,160],{"id":160},[162,11112,11113,11117],{},[40,11114,11115,3983],{},[63,11116,3982],{},[40,11118,11119,3989,11121,3993,11123,3997],{},[63,11120,3988],{},[63,11122,3992],{},[63,11124,3996],{},[337,11126,2705],{"id":2705},[10,11128,4002],{},[10,11130,11131],{},[26,11132],{"alt":4007,"src":4008},[10,11134,4011],{},[14,11136,183],{"id":183},[37,11138,11139,11145],{},[40,11140,4018,11141,4021,11143,207],{},[63,11142,2815],{},[63,11144,3903],{},[40,11146,4026],{},[14,11148,194],{"id":194},[162,11150,11151,11153],{},[40,11152,4033],{},[40,11154,2347,11155,4039,11157,1165,11159,207],{},[63,11156,4038],{},[63,11158,3903],{},[63,11160,2815],{},[10,11162,213],{},[14,11164,216],{"id":216},[10,11166,4050],{},[221,11168,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11170},[11171,11172,11173,11174,11175,11178,11179,11180],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":11176},[11177],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":3863,"description":3868},[234,4072,4073],{"id":4076,"title":4077,"body":11185,"category":234,"cover":235,"description":4082,"extension":236,"meta":11357,"navigation":90,"path":4295,"pinned":239,"publishedAt":240,"seo":11358,"slug":4297,"stem":4298,"summary":4299,"tags":11359,"updatedAt":240,"visible":90,"__hash__":4302},{"type":7,"value":11186,"toc":11344},[11187,11189,11191,11193,11195,11199,11207,11209,11217,11219,11221,11265,11267,11272,11274,11276,11288,11290,11292,11296,11302,11304,11306,11310,11314,11316,11328,11330,11336,11338,11340,11342],[10,11188,4082],{},[14,11190,16],{"id":16},[10,11192,4087],{},[14,11194,22],{"id":22},[10,11196,11197],{},[26,11198],{"alt":4094,"src":4095},[10,11200,11201,2265,11203,2265,11205,4105],{},[63,11202,1164],{},[63,11204,4102],{},[63,11206,1168],{},[14,11208,35],{"id":35},[37,11210,11211,11213,11215],{},[40,11212,4112],{},[40,11214,4115],{},[40,11216,4118],{},[14,11218,51],{"id":51},[10,11220,54],{},[56,11222,11223],{"className":58,"code":4125,"language":60,"meta":61,"style":61},[63,11224,11225,11229,11233,11237,11241,11245,11249,11253,11257,11261],{"__ignoreMap":61},[66,11226,11227],{"class":68,"line":69},[66,11228,4132],{},[66,11230,11231],{"class":68,"line":75},[66,11232,91],{"emptyLinePlaceholder":90},[66,11234,11235],{"class":68,"line":81},[66,11236,4141],{},[66,11238,11239],{"class":68,"line":87},[66,11240,4146],{},[66,11242,11243],{"class":68,"line":94},[66,11244,4151],{},[66,11246,11247],{"class":68,"line":100},[66,11248,4156],{},[66,11250,11251],{"class":68,"line":106},[66,11252,1154],{},[66,11254,11255],{"class":68,"line":112},[66,11256,4165],{},[66,11258,11259],{"class":68,"line":117},[66,11260,91],{"emptyLinePlaceholder":90},[66,11262,11263],{"class":68,"line":123},[66,11264,4174],{},[10,11266,146],{},[56,11268,11270],{"className":11269,"code":4180,"language":152,"meta":61},[150],[63,11271,4180],{"__ignoreMap":61},[10,11273,157],{},[14,11275,160],{"id":160},[162,11277,11278,11282],{},[40,11279,4191,11280,4195],{},[63,11281,4194],{},[40,11283,11284,4201,11286,4204],{},[63,11285,4200],{},[63,11287,1168],{},[337,11289,2705],{"id":2705},[10,11291,4209],{},[10,11293,11294],{},[26,11295],{"alt":4214,"src":4215},[10,11297,11298,4220,11300,4223],{},[63,11299,4194],{},[63,11301,4200],{},[337,11303,2705],{"id":4226},[10,11305,4229],{},[10,11307,11308],{},[26,11309],{"alt":4234,"src":4235},[10,11311,4238,11312,4241],{},[63,11313,1164],{},[14,11315,183],{"id":183},[37,11317,11318,11322],{},[40,11319,4248,11320,4251],{},[63,11321,4200],{},[40,11323,4254,11324,4257,11326,4261],{},[63,11325,1164],{},[63,11327,4260],{},[14,11329,194],{"id":194},[162,11331,11332,11334],{},[40,11333,4268],{},[40,11335,4271],{},[10,11337,213],{},[14,11339,216],{"id":216},[10,11341,4278],{},[221,11343,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11345},[11346,11347,11348,11349,11350,11354,11355,11356],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":11351},[11352,11353],{"id":2705,"depth":81,"text":2705},{"id":4226,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":4077,"description":4082},[234,1164,4301],{"id":4304,"title":4305,"body":11361,"category":234,"cover":235,"description":4310,"extension":236,"meta":11498,"navigation":90,"path":4477,"pinned":239,"publishedAt":240,"seo":11499,"slug":4479,"stem":4480,"summary":4481,"tags":11500,"updatedAt":240,"visible":90,"__hash__":4484},{"type":7,"value":11362,"toc":11486},[11363,11365,11367,11369,11371,11375,11379,11381,11391,11393,11395,11427,11429,11434,11436,11438,11448,11450,11452,11456,11460,11462,11468,11470,11478,11480,11482,11484],[10,11364,4310],{},[14,11366,16],{"id":16},[10,11368,4315],{},[14,11370,22],{"id":22},[10,11372,11373],{},[26,11374],{"alt":4322,"src":4323},[10,11376,11377,4329],{},[63,11378,4328],{},[14,11380,35],{"id":35},[37,11382,11383,11385,11387],{},[40,11384,4336],{},[40,11386,4339],{},[40,11388,4342,11389,4346],{},[63,11390,4345],{},[14,11392,51],{"id":51},[10,11394,54],{},[56,11396,11397],{"className":58,"code":4353,"language":60,"meta":61,"style":61},[63,11398,11399,11403,11407,11411,11415,11419,11423],{"__ignoreMap":61},[66,11400,11401],{"class":68,"line":69},[66,11402,4360],{},[66,11404,11405],{"class":68,"line":75},[66,11406,91],{"emptyLinePlaceholder":90},[66,11408,11409],{"class":68,"line":81},[66,11410,4369],{},[66,11412,11413],{"class":68,"line":87},[66,11414,4374],{},[66,11416,11417],{"class":68,"line":94},[66,11418,4379],{},[66,11420,11421],{"class":68,"line":100},[66,11422,91],{"emptyLinePlaceholder":90},[66,11424,11425],{"class":68,"line":106},[66,11426,4388],{},[10,11428,146],{},[56,11430,11432],{"className":11431,"code":4394,"language":152,"meta":61},[150],[63,11433,4394],{"__ignoreMap":61},[10,11435,157],{},[14,11437,160],{"id":160},[162,11439,11440,11444],{},[40,11441,4405,11442,4409],{},[63,11443,4408],{},[40,11445,4412,11446,4415],{},[63,11447,4408],{},[337,11449,2705],{"id":2705},[10,11451,4420],{},[10,11453,11454],{},[26,11455],{"alt":4425,"src":4426},[10,11457,4429,11458,4432],{},[63,11459,4408],{},[14,11461,183],{"id":183},[37,11463,11464,11466],{},[40,11465,4439],{},[40,11467,4442],{},[14,11469,194],{"id":194},[162,11471,11472,11476],{},[40,11473,2347,11474,4451],{},[63,11475,4328],{},[40,11477,4454],{},[10,11479,213],{},[14,11481,216],{"id":216},[10,11483,4461],{},[221,11485,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11487},[11488,11489,11490,11491,11492,11495,11496,11497],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":11493},[11494],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":4305,"description":4310},[234,4328,4483],{"id":4486,"title":4487,"body":11502,"category":234,"cover":235,"description":4492,"extension":236,"meta":11627,"navigation":90,"path":4641,"pinned":239,"publishedAt":240,"seo":11628,"slug":4643,"stem":4644,"summary":4645,"tags":11629,"updatedAt":240,"visible":90,"__hash__":4648},{"type":7,"value":11503,"toc":11617},[11504,11506,11508,11510,11512,11516,11520,11522,11532,11534,11536,11568,11570,11575,11577,11579,11591,11593,11599,11601,11609,11611,11613,11615],[10,11505,4492],{},[14,11507,16],{"id":16},[10,11509,4497],{},[14,11511,22],{"id":22},[10,11513,11514],{},[26,11515],{"alt":4504,"src":4505},[10,11517,11518,4510],{},[63,11519,4345],{},[14,11521,35],{"id":35},[37,11523,11524,11528,11530],{},[40,11525,11526,4520],{},[63,11527,4519],{},[40,11529,4523],{},[40,11531,4526],{},[14,11533,51],{"id":51},[10,11535,54],{},[56,11537,11538],{"className":58,"code":4533,"language":60,"meta":61,"style":61},[63,11539,11540,11544,11548,11552,11556,11560,11564],{"__ignoreMap":61},[66,11541,11542],{"class":68,"line":69},[66,11543,4540],{},[66,11545,11546],{"class":68,"line":75},[66,11547,91],{"emptyLinePlaceholder":90},[66,11549,11550],{"class":68,"line":81},[66,11551,4549],{},[66,11553,11554],{"class":68,"line":87},[66,11555,4554],{},[66,11557,11558],{"class":68,"line":94},[66,11559,91],{"emptyLinePlaceholder":90},[66,11561,11562],{"class":68,"line":100},[66,11563,4563],{},[66,11565,11566],{"class":68,"line":106},[66,11567,4568],{},[10,11569,146],{},[56,11571,11573],{"className":11572,"code":4574,"language":152,"meta":61},[150],[63,11574,4574],{"__ignoreMap":61},[10,11576,157],{},[14,11578,160],{"id":160},[162,11580,11581,11587],{},[40,11582,4585,11583,4588,11585,4592],{},[63,11584,4345],{},[63,11586,4591],{},[40,11588,11589,4597],{},[63,11590,4519],{},[14,11592,183],{"id":183},[37,11594,11595,11597],{},[40,11596,4604],{},[40,11598,4607],{},[14,11600,194],{"id":194},[162,11602,11603,11605],{},[40,11604,4614],{},[40,11606,2347,11607,4620],{},[63,11608,4619],{},[10,11610,213],{},[14,11612,216],{"id":216},[10,11614,4627],{},[221,11616,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11618},[11619,11620,11621,11622,11623,11624,11625,11626],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":4487,"description":4492},[234,4345,4647],{"id":4650,"title":4651,"body":11631,"category":234,"cover":235,"description":4656,"extension":236,"meta":11776,"navigation":90,"path":4831,"pinned":239,"publishedAt":240,"seo":11777,"slug":4833,"stem":4834,"summary":4835,"tags":11778,"updatedAt":240,"visible":90,"__hash__":4837},{"type":7,"value":11632,"toc":11766},[11633,11635,11637,11639,11641,11645,11651,11653,11667,11669,11671,11715,11717,11722,11724,11726,11736,11738,11750,11752,11758,11760,11762,11764],[10,11634,4656],{},[14,11636,16],{"id":16},[10,11638,4661],{},[14,11640,22],{"id":22},[10,11642,11643],{},[26,11644],{"alt":4668,"src":4669},[10,11646,11647,4675,11649,4679],{},[63,11648,4674],{},[63,11650,4678],{},[14,11652,35],{"id":35},[37,11654,11655,11657,11663],{},[40,11656,4686],{},[40,11658,11659,4691,11661,4694],{},[63,11660,4674],{},[63,11662,4328],{},[40,11664,4697,11665,4700],{},[63,11666,4678],{},[14,11668,51],{"id":51},[10,11670,54],{},[56,11672,11673],{"className":58,"code":4707,"language":60,"meta":61,"style":61},[63,11674,11675,11679,11683,11687,11691,11695,11699,11703,11707,11711],{"__ignoreMap":61},[66,11676,11677],{"class":68,"line":69},[66,11678,4714],{},[66,11680,11681],{"class":68,"line":75},[66,11682,91],{"emptyLinePlaceholder":90},[66,11684,11685],{"class":68,"line":81},[66,11686,4723],{},[66,11688,11689],{"class":68,"line":87},[66,11690,4728],{},[66,11692,11693],{"class":68,"line":94},[66,11694,4733],{},[66,11696,11697],{"class":68,"line":100},[66,11698,4738],{},[66,11700,11701],{"class":68,"line":106},[66,11702,4743],{},[66,11704,11705],{"class":68,"line":112},[66,11706,4568],{},[66,11708,11709],{"class":68,"line":117},[66,11710,91],{"emptyLinePlaceholder":90},[66,11712,11713],{"class":68,"line":123},[66,11714,4756],{},[10,11716,146],{},[56,11718,11720],{"className":11719,"code":4762,"language":152,"meta":61},[150],[63,11721,4762],{"__ignoreMap":61},[10,11723,157],{},[14,11725,160],{"id":160},[162,11727,11728,11732],{},[40,11729,4773,11730,4776],{},[63,11731,4674],{},[40,11733,4779,11734,4782],{},[63,11735,4678],{},[14,11737,183],{"id":183},[37,11739,11740,11744],{},[40,11741,3475,11742,4791],{},[63,11743,4674],{},[40,11745,4794,11746,4797,11748,4800],{},[63,11747,4328],{},[63,11749,4674],{},[14,11751,194],{"id":194},[162,11753,11754,11756],{},[40,11755,4807],{},[40,11757,4810],{},[10,11759,213],{},[14,11761,216],{"id":216},[10,11763,4817],{},[221,11765,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11767},[11768,11769,11770,11771,11772,11773,11774,11775],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":4651,"description":4656},[234,4678,4674],{"id":4839,"title":4840,"body":11780,"category":234,"cover":235,"description":4845,"extension":236,"meta":11919,"navigation":90,"path":5017,"pinned":239,"publishedAt":240,"seo":11920,"slug":5019,"stem":5020,"summary":5021,"tags":11921,"updatedAt":240,"visible":90,"__hash__":5025},{"type":7,"value":11781,"toc":11907},[11782,11784,11786,11788,11790,11794,11796,11798,11814,11816,11818,11846,11848,11853,11855,11857,11869,11871,11873,11877,11879,11881,11891,11893,11899,11901,11903,11905],[10,11783,4845],{},[14,11785,16],{"id":16},[10,11787,4850],{},[14,11789,22],{"id":22},[10,11791,11792],{},[26,11793],{"alt":4857,"src":4858},[10,11795,4861],{},[14,11797,35],{"id":35},[37,11799,11800,11802,11804],{},[40,11801,4868],{},[40,11803,4871],{},[40,11805,4874,11806,2265,11808,4881,11810,2265,11812,207],{},[63,11807,4877],{},[63,11809,4880],{},[63,11811,4884],{},[63,11813,4887],{},[14,11815,51],{"id":51},[10,11817,54],{},[56,11819,11820],{"className":58,"code":4894,"language":60,"meta":61,"style":61},[63,11821,11822,11826,11830,11834,11838,11842],{"__ignoreMap":61},[66,11823,11824],{"class":68,"line":69},[66,11825,4901],{},[66,11827,11828],{"class":68,"line":75},[66,11829,91],{"emptyLinePlaceholder":90},[66,11831,11832],{"class":68,"line":81},[66,11833,4910],{},[66,11835,11836],{"class":68,"line":87},[66,11837,4915],{},[66,11839,11840],{"class":68,"line":94},[66,11841,4920],{},[66,11843,11844],{"class":68,"line":100},[66,11845,4925],{},[10,11847,146],{},[56,11849,11851],{"className":11850,"code":4931,"language":152,"meta":61},[150],[63,11852,4931],{"__ignoreMap":61},[10,11854,157],{},[14,11856,160],{"id":160},[162,11858,11859,11867],{},[40,11860,4942,11861,4945,11863,1165,11865,207],{},[63,11862,4877],{},[63,11864,4948],{},[63,11866,4951],{},[40,11868,4954],{},[337,11870,2705],{"id":2705},[10,11872,4959],{},[10,11874,11875],{},[26,11876],{"alt":4964,"src":4965},[10,11878,4968],{},[14,11880,183],{"id":183},[37,11882,11883,11889],{},[40,11884,4975,11885,1017,11887,4981],{},[63,11886,4978],{},[63,11888,4884],{},[40,11890,4984],{},[14,11892,194],{"id":194},[162,11894,11895,11897],{},[40,11896,4991],{},[40,11898,4994],{},[10,11900,213],{},[14,11902,216],{"id":216},[10,11904,5001],{},[221,11906,223],{},{"title":61,"searchDepth":75,"depth":75,"links":11908},[11909,11910,11911,11912,11913,11916,11917,11918],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":11914},[11915],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":4840,"description":4845},[234,5023,5024],{"id":5027,"title":5028,"body":11923,"category":234,"cover":235,"description":5033,"extension":236,"meta":12040,"navigation":90,"path":5172,"pinned":239,"publishedAt":240,"seo":12041,"slug":5174,"stem":5175,"summary":5176,"tags":12042,"updatedAt":240,"visible":90,"__hash__":5180},{"type":7,"value":11924,"toc":12030},[11925,11927,11929,11931,11933,11937,11939,11941,11949,11951,11953,11985,11987,11992,11994,11996,12004,12006,12014,12016,12022,12024,12026,12028],[10,11926,5033],{},[14,11928,16],{"id":16},[10,11930,5038],{},[14,11932,22],{"id":22},[10,11934,11935],{},[26,11936],{"alt":5045,"src":5046},[10,11938,5049],{},[14,11940,35],{"id":35},[37,11942,11943,11945,11947],{},[40,11944,5056],{},[40,11946,5059],{},[40,11948,5062],{},[14,11950,51],{"id":51},[10,11952,54],{},[56,11954,11955],{"className":58,"code":5069,"language":60,"meta":61,"style":61},[63,11956,11957,11961,11965,11969,11973,11977,11981],{"__ignoreMap":61},[66,11958,11959],{"class":68,"line":69},[66,11960,5076],{},[66,11962,11963],{"class":68,"line":75},[66,11964,91],{"emptyLinePlaceholder":90},[66,11966,11967],{"class":68,"line":81},[66,11968,5085],{},[66,11970,11971],{"class":68,"line":87},[66,11972,5090],{},[66,11974,11975],{"class":68,"line":94},[66,11976,91],{"emptyLinePlaceholder":90},[66,11978,11979],{"class":68,"line":100},[66,11980,5099],{},[66,11982,11983],{"class":68,"line":106},[66,11984,5104],{},[10,11986,146],{},[56,11988,11990],{"className":11989,"code":5110,"language":152,"meta":61},[150],[63,11991,5110],{"__ignoreMap":61},[10,11993,157],{},[14,11995,160],{"id":160},[162,11997,11998,12000],{},[40,11999,5121],{},[40,12001,5124,12002,5128],{},[63,12003,5127],{},[14,12005,183],{"id":183},[37,12007,12008,12012],{},[40,12009,5135,12010,5138],{},[63,12011,4345],{},[40,12013,5141],{},[14,12015,194],{"id":194},[162,12017,12018,12020],{},[40,12019,5148],{},[40,12021,5151],{},[10,12023,213],{},[14,12025,216],{"id":216},[10,12027,5158],{},[221,12029,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12031},[12032,12033,12034,12035,12036,12037,12038,12039],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5028,"description":5033},[234,5178,5179],{"id":5182,"title":5183,"body":12044,"category":234,"cover":235,"description":5188,"extension":236,"meta":12163,"navigation":90,"path":5332,"pinned":239,"publishedAt":240,"seo":12164,"slug":5334,"stem":5335,"summary":5336,"tags":12165,"updatedAt":240,"visible":90,"__hash__":5340},{"type":7,"value":12045,"toc":12153},[12046,12048,12050,12052,12054,12058,12060,12062,12070,12072,12074,12106,12108,12113,12115,12117,12127,12129,12135,12137,12145,12147,12149,12151],[10,12047,5188],{},[14,12049,16],{"id":16},[10,12051,5193],{},[14,12053,22],{"id":22},[10,12055,12056],{},[26,12057],{"alt":5200,"src":5201},[10,12059,5204],{},[14,12061,35],{"id":35},[37,12063,12064,12066,12068],{},[40,12065,5211],{},[40,12067,5214],{},[40,12069,5217],{},[14,12071,51],{"id":51},[10,12073,54],{},[56,12075,12076],{"className":58,"code":5224,"language":60,"meta":61,"style":61},[63,12077,12078,12082,12086,12090,12094,12098,12102],{"__ignoreMap":61},[66,12079,12080],{"class":68,"line":69},[66,12081,5231],{},[66,12083,12084],{"class":68,"line":75},[66,12085,5236],{},[66,12087,12088],{"class":68,"line":81},[66,12089,5241],{},[66,12091,12092],{"class":68,"line":87},[66,12093,91],{"emptyLinePlaceholder":90},[66,12095,12096],{"class":68,"line":94},[66,12097,5250],{},[66,12099,12100],{"class":68,"line":100},[66,12101,5255],{},[66,12103,12104],{"class":68,"line":106},[66,12105,5260],{},[10,12107,146],{},[56,12109,12111],{"className":12110,"code":5266,"language":152,"meta":61},[150],[63,12112,5266],{"__ignoreMap":61},[10,12114,157],{},[14,12116,160],{"id":160},[162,12118,12119,12123],{},[40,12120,946,12121,5280],{},[63,12122,5279],{},[40,12124,5283,12125,5287],{},[63,12126,5286],{},[14,12128,183],{"id":183},[37,12130,12131,12133],{},[40,12132,5294],{},[40,12134,5297],{},[14,12136,194],{"id":194},[162,12138,12139,12143],{},[40,12140,5304,12141,5308],{},[63,12142,5307],{},[40,12144,5311],{},[10,12146,213],{},[14,12148,216],{"id":216},[10,12150,5318],{},[221,12152,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12154},[12155,12156,12157,12158,12159,12160,12161,12162],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5183,"description":5188},[234,5338,5339],{"id":5342,"title":5343,"body":12167,"category":234,"cover":235,"description":5348,"extension":236,"meta":12312,"navigation":90,"path":5529,"pinned":239,"publishedAt":240,"seo":12313,"slug":5531,"stem":5532,"summary":5533,"tags":12314,"updatedAt":240,"visible":90,"__hash__":5537},{"type":7,"value":12168,"toc":12300},[12169,12171,12173,12175,12177,12181,12185,12187,12199,12201,12203,12231,12233,12238,12240,12242,12256,12258,12260,12264,12272,12274,12284,12286,12292,12294,12296,12298],[10,12170,5348],{},[14,12172,16],{"id":16},[10,12174,5353],{},[14,12176,22],{"id":22},[10,12178,12179],{},[26,12180],{"alt":5360,"src":5361},[10,12182,5364,12183,5368],{},[63,12184,5367],{},[14,12186,35],{"id":35},[37,12188,12189,12191,12193],{},[40,12190,5375],{},[40,12192,5378],{},[40,12194,5381,12195,5384,12197,207],{},[63,12196,5367],{},[63,12198,5387],{},[14,12200,51],{"id":51},[10,12202,54],{},[56,12204,12205],{"className":58,"code":5394,"language":60,"meta":61,"style":61},[63,12206,12207,12211,12215,12219,12223,12227],{"__ignoreMap":61},[66,12208,12209],{"class":68,"line":69},[66,12210,5401],{},[66,12212,12213],{"class":68,"line":75},[66,12214,5406],{},[66,12216,12217],{"class":68,"line":81},[66,12218,5411],{},[66,12220,12221],{"class":68,"line":87},[66,12222,91],{"emptyLinePlaceholder":90},[66,12224,12225],{"class":68,"line":94},[66,12226,5420],{},[66,12228,12229],{"class":68,"line":100},[66,12230,5425],{},[10,12232,146],{},[56,12234,12236],{"className":12235,"code":5431,"language":152,"meta":61},[150],[63,12237,5431],{"__ignoreMap":61},[10,12239,157],{},[14,12241,160],{"id":160},[162,12243,12244,12250],{},[40,12245,5442,12246,2265,12248,5448],{},[63,12247,5445],{},[63,12249,4408],{},[40,12251,12252,5454,12254,5458],{},[63,12253,5453],{},[63,12255,5457],{},[337,12257,2705],{"id":2705},[10,12259,5463],{},[10,12261,12262],{},[26,12263],{"alt":5468,"src":5469},[10,12265,12266,2265,12268,1165,12270,5479],{},[63,12267,5445],{},[63,12269,4408],{},[63,12271,5478],{},[14,12273,183],{"id":183},[37,12275,12276,12280],{},[40,12277,5486,12278,5490],{},[63,12279,5489],{},[40,12281,5493,12282,5496],{},[63,12283,5478],{},[14,12285,194],{"id":194},[162,12287,12288,12290],{},[40,12289,5503],{},[40,12291,5506],{},[10,12293,213],{},[14,12295,216],{"id":216},[10,12297,5513],{},[221,12299,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12301},[12302,12303,12304,12305,12306,12309,12310,12311],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":12307},[12308],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5343,"description":5348},[234,5535,5536],{"id":5539,"title":5540,"body":12316,"category":234,"cover":235,"description":5545,"extension":236,"meta":12465,"navigation":90,"path":5726,"pinned":239,"publishedAt":240,"seo":12466,"slug":5728,"stem":5729,"summary":5730,"tags":12467,"updatedAt":240,"visible":90,"__hash__":5734},{"type":7,"value":12317,"toc":12453},[12318,12320,12322,12324,12326,12330,12332,12334,12346,12348,12350,12394,12396,12401,12403,12405,12417,12419,12421,12425,12427,12429,12437,12439,12445,12447,12449,12451],[10,12319,5545],{},[14,12321,16],{"id":16},[10,12323,5550],{},[14,12325,22],{"id":22},[10,12327,12328],{},[26,12329],{"alt":5557,"src":5558},[10,12331,5561],{},[14,12333,35],{"id":35},[37,12335,12336,12338,12342],{},[40,12337,5568],{},[40,12339,12340,5574],{},[63,12341,5573],{},[40,12343,12344,5580],{},[63,12345,5579],{},[14,12347,51],{"id":51},[10,12349,54],{},[56,12351,12352],{"className":58,"code":5587,"language":60,"meta":61,"style":61},[63,12353,12354,12358,12362,12366,12370,12374,12378,12382,12386,12390],{"__ignoreMap":61},[66,12355,12356],{"class":68,"line":69},[66,12357,5594],{},[66,12359,12360],{"class":68,"line":75},[66,12361,5599],{},[66,12363,12364],{"class":68,"line":81},[66,12365,91],{"emptyLinePlaceholder":90},[66,12367,12368],{"class":68,"line":87},[66,12369,5608],{},[66,12371,12372],{"class":68,"line":94},[66,12373,5613],{},[66,12375,12376],{"class":68,"line":100},[66,12377,91],{"emptyLinePlaceholder":90},[66,12379,12380],{"class":68,"line":106},[66,12381,5622],{},[66,12383,12384],{"class":68,"line":112},[66,12385,5627],{},[66,12387,12388],{"class":68,"line":117},[66,12389,91],{"emptyLinePlaceholder":90},[66,12391,12392],{"class":68,"line":123},[66,12393,5636],{},[10,12395,146],{},[56,12397,12399],{"className":12398,"code":5642,"language":152,"meta":61},[150],[63,12400,5642],{"__ignoreMap":61},[10,12402,157],{},[14,12404,160],{"id":160},[162,12406,12407,12411],{},[40,12408,5653,12409,5657],{},[63,12410,5656],{},[40,12412,12413,5663,12415,207],{},[63,12414,5662],{},[63,12416,5666],{},[337,12418,2705],{"id":2705},[10,12420,5671],{},[10,12422,12423],{},[26,12424],{"alt":5676,"src":5677},[10,12426,5680],{},[14,12428,183],{"id":183},[37,12430,12431,12435],{},[40,12432,5687,12433,5690],{},[63,12434,5387],{},[40,12436,5693],{},[14,12438,194],{"id":194},[162,12440,12441,12443],{},[40,12442,5700],{},[40,12444,5703],{},[10,12446,213],{},[14,12448,216],{"id":216},[10,12450,5710],{},[221,12452,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12454},[12455,12456,12457,12458,12459,12462,12463,12464],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":12460},[12461],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5540,"description":5545},[234,5732,5733],{"id":5736,"title":5737,"body":12469,"category":234,"cover":235,"description":5742,"extension":236,"meta":12630,"navigation":90,"path":5938,"pinned":239,"publishedAt":240,"seo":12631,"slug":5940,"stem":5941,"summary":5942,"tags":12632,"updatedAt":240,"visible":90,"__hash__":5946},{"type":7,"value":12470,"toc":12618},[12471,12473,12475,12477,12479,12483,12485,12487,12499,12501,12503,12555,12557,12562,12564,12566,12584,12586,12588,12592,12594,12596,12602,12604,12610,12612,12614,12616],[10,12472,5742],{},[14,12474,16],{"id":16},[10,12476,5747],{},[14,12478,22],{"id":22},[10,12480,12481],{},[26,12482],{"alt":5754,"src":5755},[10,12484,5758],{},[14,12486,35],{"id":35},[37,12488,12489,12491,12493],{},[40,12490,5765],{},[40,12492,5768],{},[40,12494,12495,2184,12497,5777],{},[63,12496,5773],{},[63,12498,5776],{},[14,12500,51],{"id":51},[10,12502,54],{},[56,12504,12505],{"className":58,"code":5784,"language":60,"meta":61,"style":61},[63,12506,12507,12511,12515,12519,12523,12527,12531,12535,12539,12543,12547,12551],{"__ignoreMap":61},[66,12508,12509],{"class":68,"line":69},[66,12510,5791],{},[66,12512,12513],{"class":68,"line":75},[66,12514,91],{"emptyLinePlaceholder":90},[66,12516,12517],{"class":68,"line":81},[66,12518,5800],{},[66,12520,12521],{"class":68,"line":87},[66,12522,5805],{},[66,12524,12525],{"class":68,"line":94},[66,12526,91],{"emptyLinePlaceholder":90},[66,12528,12529],{"class":68,"line":100},[66,12530,5814],{},[66,12532,12533],{"class":68,"line":106},[66,12534,5819],{},[66,12536,12537],{"class":68,"line":112},[66,12538,5824],{},[66,12540,12541],{"class":68,"line":117},[66,12542,91],{"emptyLinePlaceholder":90},[66,12544,12545],{"class":68,"line":123},[66,12546,5833],{},[66,12548,12549],{"class":68,"line":129},[66,12550,91],{"emptyLinePlaceholder":90},[66,12552,12553],{"class":68,"line":134},[66,12554,5842],{},[10,12556,146],{},[56,12558,12560],{"className":12559,"code":5848,"language":152,"meta":61},[150],[63,12561,5848],{"__ignoreMap":61},[10,12563,157],{},[14,12565,160],{"id":160},[162,12567,12568,12578],{},[40,12569,12570,5862,12572,5866,12574,5869,12576,5873],{},[63,12571,5861],{},[63,12573,5865],{},[63,12575,5656],{},[63,12577,5872],{},[40,12579,12580,5878,12582,5881],{},[63,12581,4591],{},[63,12583,2216],{},[337,12585,2705],{"id":2705},[10,12587,5886],{},[10,12589,12590],{},[26,12591],{"alt":5891,"src":5892},[10,12593,5895],{},[14,12595,183],{"id":183},[37,12597,12598,12600],{},[40,12599,5902],{},[40,12601,5905],{},[14,12603,194],{"id":194},[162,12605,12606,12608],{},[40,12607,5912],{},[40,12609,5915],{},[10,12611,213],{},[14,12613,216],{"id":216},[10,12615,5922],{},[221,12617,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12619},[12620,12621,12622,12623,12624,12627,12628,12629],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":12625},[12626],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5737,"description":5742},[234,5944,5945],{"id":5948,"title":5949,"body":12634,"category":234,"cover":235,"description":5954,"extension":236,"meta":12757,"navigation":90,"path":6105,"pinned":239,"publishedAt":240,"seo":12758,"slug":6107,"stem":6108,"summary":6109,"tags":12759,"updatedAt":240,"visible":90,"__hash__":6113},{"type":7,"value":12635,"toc":12747},[12636,12638,12640,12642,12644,12648,12650,12652,12666,12668,12670,12698,12700,12705,12707,12709,12719,12721,12729,12731,12739,12741,12743,12745],[10,12637,5954],{},[14,12639,16],{"id":16},[10,12641,5959],{},[14,12643,22],{"id":22},[10,12645,12646],{},[26,12647],{"alt":5966,"src":5967},[10,12649,5970],{},[14,12651,35],{"id":35},[37,12653,12654,12656,12658],{},[40,12655,5977],{},[40,12657,5980],{},[40,12659,5983,12660,2265,12662,2265,12664,5991],{},[63,12661,2268],{},[63,12663,2434],{},[63,12665,5990],{},[14,12667,51],{"id":51},[10,12669,54],{},[56,12671,12672],{"className":58,"code":5998,"language":60,"meta":61,"style":61},[63,12673,12674,12678,12682,12686,12690,12694],{"__ignoreMap":61},[66,12675,12676],{"class":68,"line":69},[66,12677,6005],{},[66,12679,12680],{"class":68,"line":75},[66,12681,6010],{},[66,12683,12684],{"class":68,"line":81},[66,12685,6015],{},[66,12687,12688],{"class":68,"line":87},[66,12689,91],{"emptyLinePlaceholder":90},[66,12691,12692],{"class":68,"line":94},[66,12693,6024],{},[66,12695,12696],{"class":68,"line":100},[66,12697,6029],{},[10,12699,146],{},[56,12701,12703],{"className":12702,"code":6035,"language":152,"meta":61},[150],[63,12704,6035],{"__ignoreMap":61},[10,12706,157],{},[14,12708,160],{"id":160},[162,12710,12711,12717],{},[40,12712,6046,12713,6050,12715,6053],{},[63,12714,6049],{},[63,12716,2254],{},[40,12718,6056],{},[14,12720,183],{"id":183},[37,12722,12723,12727],{},[40,12724,6063,12725,6067],{},[63,12726,6066],{},[40,12728,6070],{},[14,12730,194],{"id":194},[162,12732,12733,12735],{},[40,12734,6077],{},[40,12736,6080,12737,6084],{},[63,12738,6083],{},[10,12740,213],{},[14,12742,216],{"id":216},[10,12744,6091],{},[221,12746,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12748},[12749,12750,12751,12752,12753,12754,12755,12756],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5949,"description":5954},[234,6111,6112],{"id":6115,"title":6116,"body":12761,"category":234,"cover":235,"description":6121,"extension":236,"meta":12938,"navigation":90,"path":6349,"pinned":239,"publishedAt":240,"seo":12939,"slug":6351,"stem":6352,"summary":6353,"tags":12940,"updatedAt":240,"visible":90,"__hash__":6357},{"type":7,"value":12762,"toc":12926},[12763,12765,12767,12771,12773,12777,12783,12785,12797,12799,12803,12827,12831,12847,12853,12855,12860,12862,12864,12880,12882,12884,12888,12892,12894,12906,12908,12918,12920,12922,12924],[10,12764,6121],{},[14,12766,16],{"id":16},[10,12768,6126,12769,6129],{},[303,12770,6049],{},[14,12772,22],{"id":22},[10,12774,12775],{},[26,12776],{"alt":6136,"src":6137},[10,12778,6140,12779,6144,12781,6148],{},[63,12780,6143],{},[63,12782,6147],{},[14,12784,35],{"id":35},[37,12786,12787,12791,12793],{},[40,12788,6155,12789,6158],{},[63,12790,1179],{},[40,12792,6161],{},[40,12794,6164,12795,6168],{},[63,12796,6167],{},[14,12798,51],{"id":51},[10,12800,6173,12801,6177],{},[63,12802,6176],{},[56,12804,12805],{"className":58,"code":6180,"language":60,"meta":61,"style":61},[63,12806,12807,12811,12815,12819,12823],{"__ignoreMap":61},[66,12808,12809],{"class":68,"line":69},[66,12810,6187],{},[66,12812,12813],{"class":68,"line":75},[66,12814,6192],{},[66,12816,12817],{"class":68,"line":81},[66,12818,91],{"emptyLinePlaceholder":90},[66,12820,12821],{"class":68,"line":87},[66,12822,6201],{},[66,12824,12825],{"class":68,"line":94},[66,12826,6206],{},[10,12828,6209,12829,6213],{},[63,12830,6212],{},[56,12832,12833],{"className":58,"code":6216,"language":60,"meta":61,"style":61},[63,12834,12835,12839,12843],{"__ignoreMap":61},[66,12836,12837],{"class":68,"line":69},[66,12838,6223],{},[66,12840,12841],{"class":68,"line":75},[66,12842,91],{"emptyLinePlaceholder":90},[66,12844,12845],{"class":68,"line":81},[66,12846,6232],{},[10,12848,6235,12849,1165,12851,207],{},[63,12850,6238],{},[63,12852,6241],{},[10,12854,146],{},[56,12856,12858],{"className":12857,"code":6247,"language":152,"meta":61},[150],[63,12859,6247],{"__ignoreMap":61},[10,12861,157],{},[14,12863,160],{"id":160},[162,12865,12866,12872],{},[40,12867,6258,12868,6261,12870,6265],{},[63,12869,6176],{},[63,12871,6264],{},[40,12873,12874,6270,12876,6273,12878,6276],{},[63,12875,6212],{},[63,12877,6176],{},[63,12879,6212],{},[337,12881,2705],{"id":2705},[10,12883,6281],{},[10,12885,12886],{},[26,12887],{"alt":6286,"src":6287},[10,12889,6290,12890,6293],{},[63,12891,6264],{},[14,12893,183],{"id":183},[37,12895,12896,12902],{},[40,12897,6300,12898,1165,12900,207],{},[63,12899,6176],{},[63,12901,6212],{},[40,12903,6307,12904,6311],{},[63,12905,6310],{},[14,12907,194],{"id":194},[162,12909,12910,12914],{},[40,12911,2362,12912,6321],{},[63,12913,6320],{},[40,12915,6324,12916,207],{},[63,12917,6143],{},[10,12919,213],{},[14,12921,216],{"id":216},[10,12923,6333],{},[221,12925,223],{},{"title":61,"searchDepth":75,"depth":75,"links":12927},[12928,12929,12930,12931,12932,12935,12936,12937],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":12933},[12934],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":6116,"description":6121},[234,6355,6356],{"id":6359,"title":6360,"body":12942,"category":234,"cover":235,"description":6365,"extension":236,"meta":13081,"navigation":90,"path":6531,"pinned":239,"publishedAt":240,"seo":13082,"slug":6533,"stem":6534,"summary":6535,"tags":13083,"updatedAt":240,"visible":90,"__hash__":6538},{"type":7,"value":12943,"toc":13071},[12944,12946,12948,12950,12952,12956,12958,12960,12970,12972,12974,13014,13016,13021,13023,13025,13043,13045,13053,13055,13063,13065,13067,13069],[10,12945,6365],{},[14,12947,16],{"id":16},[10,12949,6370],{},[14,12951,22],{"id":22},[10,12953,12954],{},[26,12955],{"alt":6377,"src":6378},[10,12957,6381],{},[14,12959,35],{"id":35},[37,12961,12962,12966,12968],{},[40,12963,12964,6391],{},[63,12965,6390],{},[40,12967,6394],{},[40,12969,6397],{},[14,12971,51],{"id":51},[10,12973,1582],{},[56,12975,12976],{"className":599,"code":6404,"language":601,"meta":61,"style":61},[63,12977,12978,12988,12994,13000,13010],{"__ignoreMap":61},[66,12979,12980,12982,12984,12986],{"class":68,"line":69},[66,12981,699],{"class":608},[66,12983,641],{"class":611},[66,12985,6415],{"class":644},[66,12987,6418],{"class":644},[66,12989,12990,12992],{"class":68,"line":75},[66,12991,6423],{"class":611},[66,12993,6426],{"class":644},[66,12995,12996,12998],{"class":68,"line":81},[66,12997,60],{"class":608},[66,12999,612],{"class":611},[66,13001,13002,13004,13006,13008],{"class":68,"line":87},[66,13003,60],{"class":608},[66,13005,641],{"class":611},[66,13007,645],{"class":644},[66,13009,612],{"class":611},[66,13011,13012],{"class":68,"line":94},[66,13013,6447],{"class":608},[10,13015,146],{},[56,13017,13019],{"className":13018,"code":6453,"language":152,"meta":61},[150],[63,13020,6453],{"__ignoreMap":61},[10,13022,157],{},[14,13024,160],{"id":160},[162,13026,13027,13033],{},[40,13028,13029,6467,13031,6470],{},[63,13030,6466],{},[63,13032,699],{},[40,13034,6473,13035,2184,13037,6479,13039,3736,13041,6485],{},[63,13036,60],{},[63,13038,6478],{},[63,13040,6390],{},[63,13042,6484],{},[14,13044,183],{"id":183},[37,13046,13047,13049],{},[40,13048,6492],{},[40,13050,3475,13051,6497],{},[63,13052,6390],{},[14,13054,194],{"id":194},[162,13056,13057,13061],{},[40,13058,6504,13059,207],{},[63,13060,6507],{},[40,13062,6510],{},[10,13064,213],{},[14,13066,216],{"id":216},[10,13068,6517],{},[221,13070,1666],{},{"title":61,"searchDepth":75,"depth":75,"links":13072},[13073,13074,13075,13076,13077,13078,13079,13080],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":6360,"description":6365},[234,6537,269],{"id":6540,"title":6541,"body":13085,"category":234,"cover":235,"description":6546,"extension":236,"meta":13238,"navigation":90,"path":6735,"pinned":239,"publishedAt":240,"seo":13239,"slug":6737,"stem":6738,"summary":6739,"tags":13240,"updatedAt":240,"visible":90,"__hash__":6743},{"type":7,"value":13086,"toc":13228},[13087,13089,13091,13093,13095,13099,13105,13107,13123,13125,13127,13171,13173,13178,13180,13182,13194,13196,13210,13212,13220,13222,13224,13226],[10,13088,6546],{},[14,13090,16],{"id":16},[10,13092,6551],{},[14,13094,22],{"id":22},[10,13096,13097],{},[26,13098],{"alt":6558,"src":6559},[10,13100,13101,6565,13103,6568],{},[63,13102,6564],{},[63,13104,2444],{},[14,13106,35],{"id":35},[37,13108,13109,13111,13119],{},[40,13110,6575],{},[40,13112,13113,2265,13115,2265,13117,6587],{},[63,13114,6580],{},[63,13116,6583],{},[63,13118,6586],{},[40,13120,6590,13121,6594],{},[63,13122,6593],{},[14,13124,51],{"id":51},[10,13126,54],{},[56,13128,13129],{"className":58,"code":6601,"language":60,"meta":61,"style":61},[63,13130,13131,13135,13139,13143,13147,13151,13155,13159,13163,13167],{"__ignoreMap":61},[66,13132,13133],{"class":68,"line":69},[66,13134,6608],{},[66,13136,13137],{"class":68,"line":75},[66,13138,91],{"emptyLinePlaceholder":90},[66,13140,13141],{"class":68,"line":81},[66,13142,6617],{},[66,13144,13145],{"class":68,"line":87},[66,13146,6622],{},[66,13148,13149],{"class":68,"line":94},[66,13150,6627],{},[66,13152,13153],{"class":68,"line":100},[66,13154,91],{"emptyLinePlaceholder":90},[66,13156,13157],{"class":68,"line":106},[66,13158,6636],{},[66,13160,13161],{"class":68,"line":112},[66,13162,6641],{},[66,13164,13165],{"class":68,"line":117},[66,13166,6646],{},[66,13168,13169],{"class":68,"line":123},[66,13170,6651],{},[10,13172,146],{},[56,13174,13176],{"className":13175,"code":6657,"language":152,"meta":61},[150],[63,13177,6657],{"__ignoreMap":61},[10,13179,157],{},[14,13181,160],{"id":160},[162,13183,13184,13188],{},[40,13185,13186,6671],{},[63,13187,6670],{},[40,13189,2347,13190,6676,13192,6679],{},[63,13191,2444],{},[63,13193,6564],{},[14,13195,183],{"id":183},[37,13197,13198,13204],{},[40,13199,3475,13200,6688,13202,6691],{},[63,13201,6564],{},[63,13203,6580],{},[40,13205,6694,13206,1017,13208,6700],{},[63,13207,2444],{},[63,13209,6699],{},[14,13211,194],{"id":194},[162,13213,13214,13218],{},[40,13215,6707,13216,6711],{},[63,13217,6710],{},[40,13219,6714],{},[10,13221,213],{},[14,13223,216],{"id":216},[10,13225,6721],{},[221,13227,223],{},{"title":61,"searchDepth":75,"depth":75,"links":13229},[13230,13231,13232,13233,13234,13235,13236,13237],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":6541,"description":6546},[234,6741,6742],{"id":6745,"title":6746,"body":13242,"category":234,"cover":235,"description":6751,"extension":236,"meta":13389,"navigation":90,"path":6930,"pinned":239,"publishedAt":240,"seo":13390,"slug":6932,"stem":6933,"summary":6934,"tags":13391,"updatedAt":240,"visible":90,"__hash__":6938},{"type":7,"value":13243,"toc":13379},[13244,13246,13248,13250,13252,13256,13258,13260,13278,13280,13282,13330,13332,13337,13339,13341,13349,13351,13361,13363,13371,13373,13375,13377],[10,13245,6751],{},[14,13247,16],{"id":16},[10,13249,6756],{},[14,13251,22],{"id":22},[10,13253,13254],{},[26,13255],{"alt":6763,"src":6764},[10,13257,6767],{},[14,13259,35],{"id":35},[37,13261,13262,13266,13272],{},[40,13263,13264,6777],{},[63,13265,6776],{},[40,13267,13268,6783,13270,207],{},[63,13269,6782],{},[63,13271,6786],{},[40,13273,6789,13274,6793,13276,6797],{},[63,13275,6792],{},[63,13277,6796],{},[14,13279,51],{"id":51},[10,13281,54],{},[56,13283,13284],{"className":58,"code":6804,"language":60,"meta":61,"style":61},[63,13285,13286,13290,13294,13298,13302,13306,13310,13314,13318,13322,13326],{"__ignoreMap":61},[66,13287,13288],{"class":68,"line":69},[66,13289,6608],{},[66,13291,13292],{"class":68,"line":75},[66,13293,91],{"emptyLinePlaceholder":90},[66,13295,13296],{"class":68,"line":81},[66,13297,6819],{},[66,13299,13300],{"class":68,"line":87},[66,13301,6824],{},[66,13303,13304],{"class":68,"line":94},[66,13305,6829],{},[66,13307,13308],{"class":68,"line":100},[66,13309,6834],{},[66,13311,13312],{"class":68,"line":106},[66,13313,91],{"emptyLinePlaceholder":90},[66,13315,13316],{"class":68,"line":112},[66,13317,6843],{},[66,13319,13320],{"class":68,"line":117},[66,13321,6848],{},[66,13323,13324],{"class":68,"line":123},[66,13325,6853],{},[66,13327,13328],{"class":68,"line":129},[66,13329,6858],{},[10,13331,146],{},[56,13333,13335],{"className":13334,"code":6864,"language":152,"meta":61},[150],[63,13336,6864],{"__ignoreMap":61},[10,13338,157],{},[14,13340,160],{"id":160},[162,13342,13343,13347],{},[40,13344,6875,13345,6878],{},[63,13346,6792],{},[40,13348,6881],{},[14,13350,183],{"id":183},[37,13352,13353,13357],{},[40,13354,2347,13355,6890],{},[63,13356,6776],{},[40,13358,6893,13359,207],{},[63,13360,6896],{},[14,13362,194],{"id":194},[162,13364,13365,13367],{},[40,13366,6903],{},[40,13368,6906,13369,6909],{},[63,13370,345],{},[10,13372,213],{},[14,13374,216],{"id":216},[10,13376,6916],{},[221,13378,223],{},{"title":61,"searchDepth":75,"depth":75,"links":13380},[13381,13382,13383,13384,13385,13386,13387,13388],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":6746,"description":6751},[234,6936,6937],{"id":6940,"title":6941,"body":13393,"category":234,"cover":235,"description":6946,"extension":236,"meta":13536,"navigation":90,"path":7114,"pinned":239,"publishedAt":240,"seo":13537,"slug":7116,"stem":7117,"summary":7118,"tags":13538,"updatedAt":240,"visible":90,"__hash__":7122},{"type":7,"value":13394,"toc":13526},[13395,13397,13399,13401,13403,13407,13413,13415,13425,13427,13429,13481,13483,13488,13490,13492,13502,13504,13510,13512,13518,13520,13522,13524],[10,13396,6946],{},[14,13398,16],{"id":16},[10,13400,6951],{},[14,13402,22],{"id":22},[10,13404,13405],{},[26,13406],{"alt":6958,"src":6959},[10,13408,13409,6965,13411,6969],{},[63,13410,6964],{},[63,13412,6968],{},[14,13414,35],{"id":35},[37,13416,13417,13419,13423],{},[40,13418,6976],{},[40,13420,13421,6982],{},[63,13422,6981],{},[40,13424,6985],{},[14,13426,51],{"id":51},[10,13428,54],{},[56,13430,13431],{"className":58,"code":6992,"language":60,"meta":61,"style":61},[63,13432,13433,13437,13441,13445,13449,13453,13457,13461,13465,13469,13473,13477],{"__ignoreMap":61},[66,13434,13435],{"class":68,"line":69},[66,13436,6999],{},[66,13438,13439],{"class":68,"line":75},[66,13440,91],{"emptyLinePlaceholder":90},[66,13442,13443],{"class":68,"line":81},[66,13444,7008],{},[66,13446,13447],{"class":68,"line":87},[66,13448,91],{"emptyLinePlaceholder":90},[66,13450,13451],{"class":68,"line":94},[66,13452,7017],{},[66,13454,13455],{"class":68,"line":100},[66,13456,7022],{},[66,13458,13459],{"class":68,"line":106},[66,13460,6834],{},[66,13462,13463],{"class":68,"line":112},[66,13464,91],{"emptyLinePlaceholder":90},[66,13466,13467],{"class":68,"line":117},[66,13468,7035],{},[66,13470,13471],{"class":68,"line":123},[66,13472,7040],{},[66,13474,13475],{"class":68,"line":129},[66,13476,6853],{},[66,13478,13479],{"class":68,"line":134},[66,13480,7049],{},[10,13482,146],{},[56,13484,13486],{"className":13485,"code":7055,"language":152,"meta":61},[150],[63,13487,7055],{"__ignoreMap":61},[10,13489,157],{},[14,13491,160],{"id":160},[162,13493,13494,13498],{},[40,13495,13496,7068],{},[63,13497,6964],{},[40,13499,13500,7073],{},[63,13501,6968],{},[14,13503,183],{"id":183},[37,13505,13506,13508],{},[40,13507,7080],{},[40,13509,7083],{},[14,13511,194],{"id":194},[162,13513,13514,13516],{},[40,13515,7090],{},[40,13517,7093],{},[10,13519,213],{},[14,13521,216],{"id":216},[10,13523,7100],{},[221,13525,223],{},{"title":61,"searchDepth":75,"depth":75,"links":13527},[13528,13529,13530,13531,13532,13533,13534,13535],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":6941,"description":6946},[234,7120,7121],{"id":7124,"title":7125,"body":13540,"category":234,"cover":235,"description":7130,"extension":236,"meta":13691,"navigation":90,"path":7315,"pinned":239,"publishedAt":240,"seo":13692,"slug":7317,"stem":7318,"summary":7319,"tags":13693,"updatedAt":240,"visible":90,"__hash__":7323},{"type":7,"value":13541,"toc":13681},[13542,13544,13546,13548,13550,13554,13558,13560,13574,13576,13578,13630,13632,13637,13639,13641,13653,13655,13665,13667,13673,13675,13677,13679],[10,13543,7130],{},[14,13545,16],{"id":16},[10,13547,7135],{},[14,13549,22],{"id":22},[10,13551,13552],{},[26,13553],{"alt":7142,"src":7143},[10,13555,13556,7149],{},[63,13557,7148],{},[14,13559,35],{"id":35},[37,13561,13562,13568,13572],{},[40,13563,2347,13564,7159,13566,7163],{},[63,13565,7158],{},[63,13567,7162],{},[40,13569,7166,13570,7170],{},[63,13571,7169],{},[40,13573,7173],{},[14,13575,51],{"id":51},[10,13577,54],{},[56,13579,13580],{"className":58,"code":7180,"language":60,"meta":61,"style":61},[63,13581,13582,13586,13590,13594,13598,13602,13606,13610,13614,13618,13622,13626],{"__ignoreMap":61},[66,13583,13584],{"class":68,"line":69},[66,13585,7187],{},[66,13587,13588],{"class":68,"line":75},[66,13589,91],{"emptyLinePlaceholder":90},[66,13591,13592],{"class":68,"line":81},[66,13593,7196],{},[66,13595,13596],{"class":68,"line":87},[66,13597,7201],{},[66,13599,13600],{"class":68,"line":94},[66,13601,7206],{},[66,13603,13604],{"class":68,"line":100},[66,13605,7211],{},[66,13607,13608],{"class":68,"line":106},[66,13609,7216],{},[66,13611,13612],{"class":68,"line":112},[66,13613,91],{"emptyLinePlaceholder":90},[66,13615,13616],{"class":68,"line":117},[66,13617,7225],{},[66,13619,13620],{"class":68,"line":123},[66,13621,7230],{},[66,13623,13624],{"class":68,"line":129},[66,13625,7235],{},[66,13627,13628],{"class":68,"line":134},[66,13629,7240],{},[10,13631,146],{},[56,13633,13635],{"className":13634,"code":7246,"language":152,"meta":61},[150],[63,13636,7246],{"__ignoreMap":61},[10,13638,157],{},[14,13640,160],{"id":160},[162,13642,13643,13649],{},[40,13644,13645,7260,13647,7263],{},[63,13646,7259],{},[63,13648,7169],{},[40,13650,13651,7268],{},[63,13652,7148],{},[14,13654,183],{"id":183},[37,13656,13657,13659],{},[40,13658,7275],{},[40,13660,7278,13661,7281,13663,7284],{},[63,13662,7158],{},[63,13664,7162],{},[14,13666,194],{"id":194},[162,13668,13669,13671],{},[40,13670,7291],{},[40,13672,7294],{},[10,13674,213],{},[14,13676,216],{"id":216},[10,13678,7301],{},[221,13680,223],{},{"title":61,"searchDepth":75,"depth":75,"links":13682},[13683,13684,13685,13686,13687,13688,13689,13690],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":7125,"description":7130},[234,7321,7322],{"id":7325,"title":7326,"body":13695,"category":234,"cover":235,"description":7331,"extension":236,"meta":13909,"navigation":90,"path":7604,"pinned":239,"publishedAt":240,"seo":13910,"slug":7606,"stem":7607,"summary":7608,"tags":13911,"updatedAt":240,"visible":90,"__hash__":7612},{"type":7,"value":13696,"toc":13896},[13697,13699,13701,13703,13705,13709,13715,13717,13729,13731,13733,13793,13795,13800,13802,13804,13822,13824,13832,13836,13844,13846,13850,13854,13860,13862,13872,13874,13888,13890,13892,13894],[10,13698,7331],{},[14,13700,16],{"id":16},[10,13702,7336],{},[14,13704,22],{"id":22},[10,13706,13707],{},[26,13708],{"alt":7343,"src":7344},[10,13710,7347,13711,7351,13713,7355],{},[63,13712,7350],{},[63,13714,7354],{},[14,13716,35],{"id":35},[37,13718,13719,13723,13727],{},[40,13720,7362,13721,7365],{},[63,13722,7350],{},[40,13724,13725,7371],{},[63,13726,7370],{},[40,13728,7374],{},[14,13730,51],{"id":51},[10,13732,54],{},[56,13734,13735],{"className":58,"code":7381,"language":60,"meta":61,"style":61},[63,13736,13737,13741,13745,13749,13753,13757,13761,13765,13769,13773,13777,13781,13785,13789],{"__ignoreMap":61},[66,13738,13739],{"class":68,"line":69},[66,13740,7388],{},[66,13742,13743],{"class":68,"line":75},[66,13744,7393],{},[66,13746,13747],{"class":68,"line":81},[66,13748,7398],{},[66,13750,13751],{"class":68,"line":87},[66,13752,7403],{},[66,13754,13755],{"class":68,"line":94},[66,13756,7408],{},[66,13758,13759],{"class":68,"line":100},[66,13760,91],{"emptyLinePlaceholder":90},[66,13762,13763],{"class":68,"line":106},[66,13764,7417],{},[66,13766,13767],{"class":68,"line":112},[66,13768,7422],{},[66,13770,13771],{"class":68,"line":117},[66,13772,7427],{},[66,13774,13775],{"class":68,"line":123},[66,13776,7432],{},[66,13778,13779],{"class":68,"line":129},[66,13780,1154],{},[66,13782,13783],{"class":68,"line":134},[66,13784,7441],{},[66,13786,13787],{"class":68,"line":140},[66,13788,7446],{},[66,13790,13791],{"class":68,"line":7449},[66,13792,7452],{},[10,13794,146],{},[56,13796,13798],{"className":13797,"code":7458,"language":152,"meta":61},[150],[63,13799,7458],{"__ignoreMap":61},[10,13801,157],{},[14,13803,160],{"id":160},[162,13805,13806,13814],{},[40,13807,13808,7471,13810,7474,13812,7478],{},[63,13809,3044],{},[63,13811,7370],{},[63,13813,7477],{},[40,13815,7481,13816,7484,13818,7487,13820,207],{},[63,13817,7350],{},[63,13819,1168],{},[63,13821,7354],{},[337,13823,2705],{"id":2705},[10,13825,13826,2265,13828,1165,13830,7500],{},[63,13827,7350],{},[63,13829,1168],{},[63,13831,7354],{},[10,13833,13834],{},[26,13835],{"alt":7505,"src":7506},[10,13837,13838,7511,13840,7514,13842,7517],{},[63,13839,7350],{},[63,13841,1168],{},[63,13843,7354],{},[337,13845,2705],{"id":4226},[10,13847,13848,7525],{},[63,13849,7524],{},[10,13851,13852],{},[26,13853],{"alt":7530,"src":7531},[10,13855,7534,13856,7537,13858,7540],{},[63,13857,7524],{},[63,13859,1168],{},[14,13861,183],{"id":183},[37,13863,13864,13868],{},[40,13865,7547,13866,7551],{},[63,13867,7550],{},[40,13869,7554,13870,7557],{},[63,13871,7524],{},[14,13873,194],{"id":194},[162,13875,13876,13884],{},[40,13877,7564,13878,7568,13880,1165,13882,207],{},[63,13879,7567],{},[63,13881,7571],{},[63,13883,7574],{},[40,13885,7577,13886,7580],{},[63,13887,6786],{},[10,13889,213],{},[14,13891,216],{"id":216},[10,13893,7587],{},[221,13895,223],{},{"title":61,"searchDepth":75,"depth":75,"links":13897},[13898,13899,13900,13901,13902,13906,13907,13908],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":13903},[13904,13905],{"id":2705,"depth":81,"text":2705},{"id":4226,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":7326,"description":7331},[234,7610,7611],{"id":7614,"title":7615,"body":13913,"category":234,"cover":235,"description":7620,"extension":236,"meta":14064,"navigation":90,"path":7797,"pinned":239,"publishedAt":240,"seo":14065,"slug":7799,"stem":7800,"summary":7801,"tags":14066,"updatedAt":240,"visible":90,"__hash__":7804},{"type":7,"value":13914,"toc":14054},[13915,13917,13919,13921,13923,13927,13931,13933,13945,13947,13949,13997,13999,14004,14006,14008,14018,14020,14030,14032,14046,14048,14050,14052],[10,13916,7620],{},[14,13918,16],{"id":16},[10,13920,7625],{},[14,13922,22],{"id":22},[10,13924,13925],{},[26,13926],{"alt":7632,"src":7633},[10,13928,7636,13929,7639],{},[63,13930,6796],{},[14,13932,35],{"id":35},[37,13934,13935,13939,13943],{},[40,13936,13937,7648],{},[63,13938,6796],{},[40,13940,13941,7654],{},[63,13942,7653],{},[40,13944,7657],{},[14,13946,51],{"id":51},[10,13948,54],{},[56,13950,13951],{"className":58,"code":7664,"language":60,"meta":61,"style":61},[63,13952,13953,13957,13961,13965,13969,13973,13977,13981,13985,13989,13993],{"__ignoreMap":61},[66,13954,13955],{"class":68,"line":69},[66,13956,6608],{},[66,13958,13959],{"class":68,"line":75},[66,13960,91],{"emptyLinePlaceholder":90},[66,13962,13963],{"class":68,"line":81},[66,13964,6819],{},[66,13966,13967],{"class":68,"line":87},[66,13968,91],{"emptyLinePlaceholder":90},[66,13970,13971],{"class":68,"line":94},[66,13972,7687],{},[66,13974,13975],{"class":68,"line":100},[66,13976,7692],{},[66,13978,13979],{"class":68,"line":106},[66,13980,91],{"emptyLinePlaceholder":90},[66,13982,13983],{"class":68,"line":112},[66,13984,7701],{},[66,13986,13987],{"class":68,"line":117},[66,13988,7706],{},[66,13990,13991],{"class":68,"line":123},[66,13992,91],{"emptyLinePlaceholder":90},[66,13994,13995],{"class":68,"line":129},[66,13996,7715],{},[10,13998,146],{},[56,14000,14002],{"className":14001,"code":7721,"language":152,"meta":61},[150],[63,14003,7721],{"__ignoreMap":61},[10,14005,157],{},[14,14007,160],{"id":160},[162,14009,14010,14016],{},[40,14011,7636,14012,7734,14014,207],{},[63,14013,6796],{},[63,14015,7737],{},[40,14017,7740],{},[14,14019,183],{"id":183},[37,14021,14022,14026],{},[40,14023,4794,14024,7749],{},[63,14025,6796],{},[40,14027,7752,14028,7755],{},[63,14029,6796],{},[14,14031,194],{"id":194},[162,14033,14034,14040],{},[40,14035,7762,14036,7766,14038,207],{},[63,14037,7765],{},[63,14039,6796],{},[40,14041,4794,14042,7773,14044,207],{},[63,14043,6796],{},[63,14045,7776],{},[10,14047,213],{},[14,14049,216],{"id":216},[10,14051,7783],{},[221,14053,223],{},{"title":61,"searchDepth":75,"depth":75,"links":14055},[14056,14057,14058,14059,14060,14061,14062,14063],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":7615,"description":7620},[234,6796,7803],{"id":7806,"title":7807,"body":14068,"category":234,"cover":235,"description":7812,"extension":236,"meta":14239,"navigation":90,"path":8025,"pinned":239,"publishedAt":240,"seo":14240,"slug":8027,"stem":8028,"summary":8029,"tags":14241,"updatedAt":240,"visible":90,"__hash__":8033},{"type":7,"value":14069,"toc":14227},[14070,14072,14074,14076,14078,14082,14084,14086,14098,14100,14102,14158,14160,14165,14167,14169,14185,14187,14189,14193,14199,14201,14209,14211,14219,14221,14223,14225],[10,14071,7812],{},[14,14073,16],{"id":16},[10,14075,7817],{},[14,14077,22],{"id":22},[10,14079,14080],{},[26,14081],{"alt":7824,"src":7825},[10,14083,7828],{},[14,14085,35],{"id":35},[37,14087,14088,14092,14096],{},[40,14089,14090,7838],{},[63,14091,7837],{},[40,14093,14094,7844],{},[63,14095,7843],{},[40,14097,7847],{},[14,14099,51],{"id":51},[10,14101,54],{},[56,14103,14104],{"className":58,"code":7854,"language":60,"meta":61,"style":61},[63,14105,14106,14110,14114,14118,14122,14126,14130,14134,14138,14142,14146,14150,14154],{"__ignoreMap":61},[66,14107,14108],{"class":68,"line":69},[66,14109,7861],{},[66,14111,14112],{"class":68,"line":75},[66,14113,7866],{},[66,14115,14116],{"class":68,"line":81},[66,14117,7871],{},[66,14119,14120],{"class":68,"line":87},[66,14121,7876],{},[66,14123,14124],{"class":68,"line":94},[66,14125,91],{"emptyLinePlaceholder":90},[66,14127,14128],{"class":68,"line":100},[66,14129,7885],{},[66,14131,14132],{"class":68,"line":106},[66,14133,7890],{},[66,14135,14136],{"class":68,"line":112},[66,14137,7895],{},[66,14139,14140],{"class":68,"line":117},[66,14141,7900],{},[66,14143,14144],{"class":68,"line":123},[66,14145,91],{"emptyLinePlaceholder":90},[66,14147,14148],{"class":68,"line":129},[66,14149,7909],{},[66,14151,14152],{"class":68,"line":134},[66,14153,7914],{},[66,14155,14156],{"class":68,"line":140},[66,14157,7919],{},[10,14159,146],{},[56,14161,14163],{"className":14162,"code":7925,"language":152,"meta":61},[150],[63,14164,7925],{"__ignoreMap":61},[10,14166,157],{},[14,14168,160],{"id":160},[162,14170,14171,14177],{},[40,14172,7936,14173,7940,14175,7943],{},[63,14174,7939],{},[63,14176,7843],{},[40,14178,14179,7949,14181,7953,14183,7956],{},[63,14180,7948],{},[63,14182,7952],{},[63,14184,7837],{},[337,14186,2705],{"id":2705},[10,14188,7961],{},[10,14190,14191],{},[26,14192],{"alt":7966,"src":7967},[10,14194,7970,14195,1165,14197,7976],{},[63,14196,4591],{},[63,14198,7975],{},[14,14200,183],{"id":183},[37,14202,14203,14207],{},[40,14204,7983,14205,7986],{},[63,14206,7837],{},[40,14208,7989],{},[14,14210,194],{"id":194},[162,14212,14213,14217],{},[40,14214,5304,14215,7999],{},[63,14216,7998],{},[40,14218,8002],{},[10,14220,213],{},[14,14222,216],{"id":216},[10,14224,8009],{},[221,14226,223],{},{"title":61,"searchDepth":75,"depth":75,"links":14228},[14229,14230,14231,14232,14233,14236,14237,14238],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":14234},[14235],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":7807,"description":7812},[234,8031,8032],{"id":4,"title":5,"body":14243,"category":234,"cover":235,"description":12,"extension":236,"meta":14390,"navigation":90,"path":238,"pinned":239,"publishedAt":240,"seo":14391,"slug":242,"stem":243,"summary":244,"tags":14392,"updatedAt":240,"visible":90,"__hash__":248},{"type":7,"value":14244,"toc":14380},[14245,14247,14249,14251,14253,14257,14259,14261,14269,14271,14273,14329,14331,14336,14338,14340,14352,14354,14360,14362,14372,14374,14376,14378],[10,14246,12],{},[14,14248,16],{"id":16},[10,14250,19],{},[14,14252,22],{"id":22},[10,14254,14255],{},[26,14256],{"alt":28,"src":29},[10,14258,32],{},[14,14260,35],{"id":35},[37,14262,14263,14265,14267],{},[40,14264,42],{},[40,14266,45],{},[40,14268,48],{},[14,14270,51],{"id":51},[10,14272,54],{},[56,14274,14275],{"className":58,"code":59,"language":60,"meta":61,"style":61},[63,14276,14277,14281,14285,14289,14293,14297,14301,14305,14309,14313,14317,14321,14325],{"__ignoreMap":61},[66,14278,14279],{"class":68,"line":69},[66,14280,72],{},[66,14282,14283],{"class":68,"line":75},[66,14284,78],{},[66,14286,14287],{"class":68,"line":81},[66,14288,84],{},[66,14290,14291],{"class":68,"line":87},[66,14292,91],{"emptyLinePlaceholder":90},[66,14294,14295],{"class":68,"line":94},[66,14296,97],{},[66,14298,14299],{"class":68,"line":100},[66,14300,103],{},[66,14302,14303],{"class":68,"line":106},[66,14304,109],{},[66,14306,14307],{"class":68,"line":112},[66,14308,91],{"emptyLinePlaceholder":90},[66,14310,14311],{"class":68,"line":117},[66,14312,120],{},[66,14314,14315],{"class":68,"line":123},[66,14316,126],{},[66,14318,14319],{"class":68,"line":129},[66,14320,91],{"emptyLinePlaceholder":90},[66,14322,14323],{"class":68,"line":134},[66,14324,137],{},[66,14326,14327],{"class":68,"line":140},[66,14328,143],{},[10,14330,146],{},[56,14332,14334],{"className":14333,"code":151,"language":152,"meta":61},[150],[63,14335,151],{"__ignoreMap":61},[10,14337,157],{},[14,14339,160],{"id":160},[162,14341,14342,14348],{},[40,14343,14344,169,14346,173],{},[63,14345,168],{},[63,14347,172],{},[40,14349,176,14350,180],{},[63,14351,179],{},[14,14353,183],{"id":183},[37,14355,14356,14358],{},[40,14357,188],{},[40,14359,191],{},[14,14361,194],{"id":194},[162,14363,14364,14370],{},[40,14365,199,14366,203,14368,207],{},[63,14367,202],{},[63,14369,206],{},[40,14371,210],{},[10,14373,213],{},[14,14375,216],{"id":216},[10,14377,219],{},[221,14379,223],{},{"title":61,"searchDepth":75,"depth":75,"links":14381},[14382,14383,14384,14385,14386,14387,14388,14389],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":5,"description":12},[234,246,247],{"id":8186,"title":8187,"body":14394,"category":234,"cover":235,"description":8192,"extension":236,"meta":14557,"navigation":90,"path":8396,"pinned":239,"publishedAt":240,"seo":14558,"slug":8398,"stem":8399,"summary":8400,"tags":14559,"updatedAt":240,"visible":90,"__hash__":8404},{"type":7,"value":14395,"toc":14545},[14396,14398,14400,14402,14404,14408,14412,14414,14430,14432,14434,14478,14480,14485,14487,14489,14503,14505,14509,14513,14517,14519,14525,14527,14537,14539,14541,14543],[10,14397,8192],{},[14,14399,16],{"id":16},[10,14401,8197],{},[14,14403,22],{"id":22},[10,14405,14406],{},[26,14407],{"alt":8204,"src":8205},[10,14409,8208,14410,8212],{},[63,14411,8211],{},[14,14413,35],{"id":35},[37,14415,14416,14422,14428],{},[40,14417,14418,8222,14420,8226],{},[63,14419,8221],{},[63,14421,8225],{},[40,14423,8229,14424,8233,14426,8236],{},[63,14425,8232],{},[63,14427,4345],{},[40,14429,8239],{},[14,14431,51],{"id":51},[10,14433,54],{},[56,14435,14436],{"className":58,"code":8246,"language":60,"meta":61,"style":61},[63,14437,14438,14442,14446,14450,14454,14458,14462,14466,14470,14474],{"__ignoreMap":61},[66,14439,14440],{"class":68,"line":69},[66,14441,8253],{},[66,14443,14444],{"class":68,"line":75},[66,14445,8258],{},[66,14447,14448],{"class":68,"line":81},[66,14449,8263],{},[66,14451,14452],{"class":68,"line":87},[66,14453,8268],{},[66,14455,14456],{"class":68,"line":94},[66,14457,8273],{},[66,14459,14460],{"class":68,"line":100},[66,14461,91],{"emptyLinePlaceholder":90},[66,14463,14464],{"class":68,"line":106},[66,14465,8282],{},[66,14467,14468],{"class":68,"line":112},[66,14469,8287],{},[66,14471,14472],{"class":68,"line":117},[66,14473,8287],{},[66,14475,14476],{"class":68,"line":123},[66,14477,8287],{},[10,14479,146],{},[56,14481,14483],{"className":14482,"code":8301,"language":152,"meta":61},[150],[63,14484,8301],{"__ignoreMap":61},[10,14486,157],{},[14,14488,160],{"id":160},[162,14490,14491,14495],{},[40,14492,7936,14493,8315],{},[63,14494,8314],{},[40,14496,8318,14497,8321,14499,8324,14501,8328],{},[63,14498,8225],{},[63,14500,8211],{},[63,14502,8327],{},[337,14504,2705],{"id":2705},[10,14506,8333,14507,8336],{},[63,14508,8225],{},[10,14510,14511],{},[26,14512],{"alt":8341,"src":8342},[10,14514,8345,14515,8348],{},[63,14516,8211],{},[14,14518,183],{"id":183},[37,14520,14521,14523],{},[40,14522,8355],{},[40,14524,8358],{},[14,14526,194],{"id":194},[162,14528,14529,14531],{},[40,14530,8365],{},[40,14532,4018,14533,8370,14535,8373],{},[63,14534,4345],{},[63,14536,8225],{},[10,14538,213],{},[14,14540,216],{"id":216},[10,14542,8380],{},[221,14544,223],{},{"title":61,"searchDepth":75,"depth":75,"links":14546},[14547,14548,14549,14550,14551,14554,14555,14556],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":14552},[14553],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":8187,"description":8192},[234,8402,8403],{"id":8406,"title":8407,"body":14561,"category":234,"cover":235,"description":8412,"extension":236,"meta":14744,"navigation":90,"path":8637,"pinned":239,"publishedAt":240,"seo":14745,"slug":8639,"stem":8640,"summary":8641,"tags":14746,"updatedAt":240,"visible":90,"__hash__":8644},{"type":7,"value":14562,"toc":14732},[14563,14565,14567,14569,14571,14575,14577,14579,14593,14595,14597,14665,14667,14672,14674,14676,14690,14692,14694,14698,14704,14706,14714,14716,14724,14726,14728,14730],[10,14564,8412],{},[14,14566,16],{"id":16},[10,14568,8417],{},[14,14570,22],{"id":22},[10,14572,14573],{},[26,14574],{"alt":8424,"src":8425},[10,14576,8428],{},[14,14578,35],{"id":35},[37,14580,14581,14587,14589],{},[40,14582,14583,8438,14585,207],{},[63,14584,8437],{},[63,14586,8441],{},[40,14588,8444],{},[40,14590,14591,8450],{},[63,14592,8449],{},[14,14594,51],{"id":51},[10,14596,54],{},[56,14598,14599],{"className":58,"code":8457,"language":60,"meta":61,"style":61},[63,14600,14601,14605,14609,14613,14617,14621,14625,14629,14633,14637,14641,14645,14649,14653,14657,14661],{"__ignoreMap":61},[66,14602,14603],{"class":68,"line":69},[66,14604,8464],{},[66,14606,14607],{"class":68,"line":75},[66,14608,91],{"emptyLinePlaceholder":90},[66,14610,14611],{"class":68,"line":81},[66,14612,8473],{},[66,14614,14615],{"class":68,"line":87},[66,14616,8478],{},[66,14618,14619],{"class":68,"line":94},[66,14620,8483],{},[66,14622,14623],{"class":68,"line":100},[66,14624,8488],{},[66,14626,14627],{"class":68,"line":106},[66,14628,8493],{},[66,14630,14631],{"class":68,"line":112},[66,14632,8498],{},[66,14634,14635],{"class":68,"line":117},[66,14636,8503],{},[66,14638,14639],{"class":68,"line":123},[66,14640,8508],{},[66,14642,14643],{"class":68,"line":129},[66,14644,91],{"emptyLinePlaceholder":90},[66,14646,14647],{"class":68,"line":134},[66,14648,8517],{},[66,14650,14651],{"class":68,"line":140},[66,14652,6187],{},[66,14654,14655],{"class":68,"line":7449},[66,14656,6192],{},[66,14658,14659],{"class":68,"line":8528},[66,14660,91],{"emptyLinePlaceholder":90},[66,14662,14663],{"class":68,"line":8533},[66,14664,8536],{},[10,14666,146],{},[56,14668,14670],{"className":14669,"code":8542,"language":152,"meta":61},[150],[63,14671,8542],{"__ignoreMap":61},[10,14673,157],{},[14,14675,160],{"id":160},[162,14677,14678,14688],{},[40,14679,8553,14680,8557,14682,8561,14684,8565,14686,207],{},[63,14681,8556],{},[63,14683,8560],{},[63,14685,8564],{},[63,14687,8556],{},[40,14689,8570],{},[337,14691,2705],{"id":2705},[10,14693,8575],{},[10,14695,14696],{},[26,14697],{"alt":8580,"src":8581},[10,14699,14700,8586,14702,207],{},[63,14701,8437],{},[63,14703,8441],{},[14,14705,183],{"id":183},[37,14707,14708,14712],{},[40,14709,8595,14710,207],{},[63,14711,5387],{},[40,14713,8600],{},[14,14715,194],{"id":194},[162,14717,14718,14720],{},[40,14719,8607],{},[40,14721,8610,14722,8614],{},[63,14723,8613],{},[10,14725,213],{},[14,14727,216],{"id":216},[10,14729,8621],{},[221,14731,223],{},{"title":61,"searchDepth":75,"depth":75,"links":14733},[14734,14735,14736,14737,14738,14741,14742,14743],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":14739},[14740],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":8407,"description":8412},[234,8643,5338],{"id":8646,"title":8647,"body":14748,"category":234,"cover":235,"description":8652,"extension":236,"meta":14907,"navigation":90,"path":8840,"pinned":239,"publishedAt":240,"seo":14908,"slug":8842,"stem":8843,"summary":8844,"tags":14909,"updatedAt":240,"visible":90,"__hash__":8848},{"type":7,"value":14749,"toc":14895},[14750,14752,14754,14756,14758,14762,14764,14766,14774,14776,14778,14842,14844,14849,14851,14853,14861,14863,14865,14869,14871,14873,14879,14881,14887,14889,14891,14893],[10,14751,8652],{},[14,14753,16],{"id":16},[10,14755,8657],{},[14,14757,22],{"id":22},[10,14759,14760],{},[26,14761],{"alt":8664,"src":8665},[10,14763,8668],{},[14,14765,35],{"id":35},[37,14767,14768,14770,14772],{},[40,14769,8675],{},[40,14771,8678],{},[40,14773,8681],{},[14,14775,51],{"id":51},[10,14777,54],{},[56,14779,14780],{"className":58,"code":8688,"language":60,"meta":61,"style":61},[63,14781,14782,14786,14790,14794,14798,14802,14806,14810,14814,14818,14822,14826,14830,14834,14838],{"__ignoreMap":61},[66,14783,14784],{"class":68,"line":69},[66,14785,8695],{},[66,14787,14788],{"class":68,"line":75},[66,14789,8700],{},[66,14791,14792],{"class":68,"line":81},[66,14793,91],{"emptyLinePlaceholder":90},[66,14795,14796],{"class":68,"line":87},[66,14797,8709],{},[66,14799,14800],{"class":68,"line":94},[66,14801,91],{"emptyLinePlaceholder":90},[66,14803,14804],{"class":68,"line":100},[66,14805,8718],{},[66,14807,14808],{"class":68,"line":106},[66,14809,8723],{},[66,14811,14812],{"class":68,"line":112},[66,14813,8728],{},[66,14815,14816],{"class":68,"line":117},[66,14817,91],{"emptyLinePlaceholder":90},[66,14819,14820],{"class":68,"line":123},[66,14821,8737],{},[66,14823,14824],{"class":68,"line":129},[66,14825,8742],{},[66,14827,14828],{"class":68,"line":134},[66,14829,8747],{},[66,14831,14832],{"class":68,"line":140},[66,14833,91],{"emptyLinePlaceholder":90},[66,14835,14836],{"class":68,"line":7449},[66,14837,6201],{},[66,14839,14840],{"class":68,"line":8528},[66,14841,8760],{},[10,14843,146],{},[56,14845,14847],{"className":14846,"code":8766,"language":152,"meta":61},[150],[63,14848,8766],{"__ignoreMap":61},[10,14850,157],{},[14,14852,160],{"id":160},[162,14854,14855,14859],{},[40,14856,14857,8780],{},[63,14858,8779],{},[40,14860,8783],{},[337,14862,2705],{"id":2705},[10,14864,8788],{},[10,14866,14867],{},[26,14868],{"alt":8793,"src":8794},[10,14870,8797],{},[14,14872,183],{"id":183},[37,14874,14875,14877],{},[40,14876,8804],{},[40,14878,8807],{},[14,14880,194],{"id":194},[162,14882,14883,14885],{},[40,14884,8814],{},[40,14886,8817],{},[10,14888,213],{},[14,14890,216],{"id":216},[10,14892,8824],{},[221,14894,223],{},{"title":61,"searchDepth":75,"depth":75,"links":14896},[14897,14898,14899,14900,14901,14904,14905,14906],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":14902},[14903],{"id":2705,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":8647,"description":8652},[234,8846,8847],{"id":8850,"title":8851,"body":14911,"category":234,"cover":235,"description":8856,"extension":236,"meta":15149,"navigation":90,"path":9157,"pinned":239,"publishedAt":240,"seo":15150,"slug":9159,"stem":9160,"summary":9161,"tags":15151,"updatedAt":240,"visible":90,"__hash__":9165},{"type":7,"value":14912,"toc":15136},[14913,14915,14917,14919,14921,14925,14927,14929,14939,14941,14943,15059,15061,15066,15068,15070,15080,15082,15084,15088,15090,15092,15094,15098,15102,15104,15112,15114,15128,15130,15132,15134],[10,14914,8856],{},[14,14916,16],{"id":16},[10,14918,8861],{},[14,14920,22],{"id":22},[10,14922,14923],{},[26,14924],{"alt":8868,"src":8869},[10,14926,8872],{},[14,14928,35],{"id":35},[37,14930,14931,14933,14935],{},[40,14932,8879],{},[40,14934,8882],{},[40,14936,8885,14937,8889],{},[63,14938,8888],{},[14,14940,51],{"id":51},[10,14942,54],{},[56,14944,14945],{"className":58,"code":8896,"language":60,"meta":61,"style":61},[63,14946,14947,14951,14955,14959,14963,14967,14971,14975,14979,14983,14987,14991,14995,14999,15003,15007,15011,15015,15019,15023,15027,15031,15035,15039,15043,15047,15051,15055],{"__ignoreMap":61},[66,14948,14949],{"class":68,"line":69},[66,14950,6999],{},[66,14952,14953],{"class":68,"line":75},[66,14954,6608],{},[66,14956,14957],{"class":68,"line":81},[66,14958,91],{"emptyLinePlaceholder":90},[66,14960,14961],{"class":68,"line":87},[66,14962,8915],{},[66,14964,14965],{"class":68,"line":94},[66,14966,8920],{},[66,14968,14969],{"class":68,"line":100},[66,14970,8925],{},[66,14972,14973],{"class":68,"line":106},[66,14974,8930],{},[66,14976,14977],{"class":68,"line":112},[66,14978,91],{"emptyLinePlaceholder":90},[66,14980,14981],{"class":68,"line":117},[66,14982,8939],{},[66,14984,14985],{"class":68,"line":123},[66,14986,8944],{},[66,14988,14989],{"class":68,"line":129},[66,14990,8949],{},[66,14992,14993],{"class":68,"line":134},[66,14994,8954],{},[66,14996,14997],{"class":68,"line":140},[66,14998,8959],{},[66,15000,15001],{"class":68,"line":7449},[66,15002,91],{"emptyLinePlaceholder":90},[66,15004,15005],{"class":68,"line":8528},[66,15006,8968],{},[66,15008,15009],{"class":68,"line":8533},[66,15010,8973],{},[66,15012,15013],{"class":68,"line":8976},[66,15014,8979],{},[66,15016,15017],{"class":68,"line":8982},[66,15018,91],{"emptyLinePlaceholder":90},[66,15020,15021],{"class":68,"line":8987},[66,15022,8990],{},[66,15024,15025],{"class":68,"line":8993},[66,15026,91],{"emptyLinePlaceholder":90},[66,15028,15029],{"class":68,"line":8998},[66,15030,7417],{},[66,15032,15033],{"class":68,"line":9003},[66,15034,9006],{},[66,15036,15037],{"class":68,"line":9009},[66,15038,9012],{},[66,15040,15041],{"class":68,"line":9015},[66,15042,9018],{},[66,15044,15045],{"class":68,"line":9021},[66,15046,7427],{},[66,15048,15049],{"class":68,"line":9026},[66,15050,9029],{},[66,15052,15053],{"class":68,"line":9032},[66,15054,1154],{},[66,15056,15057],{"class":68,"line":9037},[66,15058,9040],{},[10,15060,146],{},[56,15062,15064],{"className":15063,"code":9046,"language":152,"meta":61},[150],[63,15065,9046],{"__ignoreMap":61},[10,15067,157],{},[14,15069,160],{"id":160},[162,15071,15072,15076],{},[40,15073,9057,15074,9060],{},[63,15075,8888],{},[40,15077,15078,9065],{},[63,15079,172],{},[337,15081,2705],{"id":2705},[10,15083,9070],{},[10,15085,15086],{},[26,15087],{"alt":9075,"src":9076},[10,15089,9079],{},[337,15091,2705],{"id":4226},[10,15093,9084],{},[10,15095,15096],{},[26,15097],{"alt":9089,"src":9090},[10,15099,9093,15100,9097],{},[63,15101,9096],{},[14,15103,183],{"id":183},[37,15105,15106,15108],{},[40,15107,9104],{},[40,15109,9107,15110,9110],{},[63,15111,9096],{},[14,15113,194],{"id":194},[162,15115,15116,15120,15122],{},[40,15117,9117,15118,9120],{},[63,15119,9096],{},[40,15121,9123],{},[40,15123,9126,15124,9130,15126,9133],{},[63,15125,9129],{},[63,15127,6143],{},[10,15129,213],{},[14,15131,216],{"id":216},[10,15133,9140],{},[221,15135,223],{},{"title":61,"searchDepth":75,"depth":75,"links":15137},[15138,15139,15140,15141,15142,15146,15147,15148],{"id":16,"depth":75,"text":16},{"id":22,"depth":75,"text":22},{"id":35,"depth":75,"text":35},{"id":51,"depth":75,"text":51},{"id":160,"depth":75,"text":160,"children":15143},[15144,15145],{"id":2705,"depth":81,"text":2705},{"id":4226,"depth":81,"text":2705},{"id":183,"depth":75,"text":183},{"id":194,"depth":75,"text":194},{"id":216,"depth":75,"text":216},{},{"title":8851,"description":8856},[234,9163,9164],{"id":1064,"title":1065,"body":15153,"category":234,"cover":1073,"description":61,"extension":236,"meta":15389,"navigation":90,"path":1390,"pinned":239,"publishedAt":1391,"seo":15390,"slug":1393,"stem":1394,"summary":1395,"tags":15391,"updatedAt":1391,"visible":90,"__hash__":1399},{"type":7,"value":15154,"toc":15374},[15155,15159,15161,15163,15165,15167,15187,15189,15194,15196,15198,15226,15232,15234,15238,15240,15260,15262,15272,15274,15276,15278,15280,15282,15284,15286,15288,15290,15310,15312,15314,15318,15320,15322,15324,15326,15330,15332,15350,15352,15354,15356,15358,15360,15362,15364,15366,15368,15370,15372],[10,15156,15157],{},[26,15158],{"alt":1072,"src":1073},[10,15160,1076],{},[10,15162,1079],{},[14,15164,1083],{"id":1082},[10,15166,1086],{},[56,15168,15169],{"className":58,"code":1089,"language":60,"meta":61,"style":61},[63,15170,15171,15175,15179,15183],{"__ignoreMap":61},[66,15172,15173],{"class":68,"line":69},[66,15174,1096],{},[66,15176,15177],{"class":68,"line":75},[66,15178,1101],{},[66,15180,15181],{"class":68,"line":81},[66,15182,91],{"emptyLinePlaceholder":90},[66,15184,15185],{"class":68,"line":87},[66,15186,1110],{},[10,15188,1113],{},[56,15190,15192],{"className":15191,"code":1117,"language":152,"meta":61},[150],[63,15193,1117],{"__ignoreMap":61},[10,15195,1122],{},[10,15197,1125],{},[56,15199,15200],{"className":58,"code":1128,"language":60,"meta":61,"style":61},[63,15201,15202,15206,15210,15214,15218,15222],{"__ignoreMap":61},[66,15203,15204],{"class":68,"line":69},[66,15205,1135],{},[66,15207,15208],{"class":68,"line":75},[66,15209,91],{"emptyLinePlaceholder":90},[66,15211,15212],{"class":68,"line":81},[66,15213,1144],{},[66,15215,15216],{"class":68,"line":87},[66,15217,1149],{},[66,15219,15220],{"class":68,"line":94},[66,15221,1154],{},[66,15223,15224],{"class":68,"line":100},[66,15225,1159],{},[10,15227,15228,1165,15230,1169],{},[63,15229,1164],{},[63,15231,1168],{},[14,15233,1173],{"id":1172},[10,15235,1176,15236,1180],{},[63,15237,1179],{},[10,15239,1183],{},[56,15241,15242],{"className":58,"code":1186,"language":60,"meta":61,"style":61},[63,15243,15244,15248,15252,15256],{"__ignoreMap":61},[66,15245,15246],{"class":68,"line":69},[66,15247,1193],{},[66,15249,15250],{"class":68,"line":75},[66,15251,1198],{},[66,15253,15254],{"class":68,"line":81},[66,15255,1203],{},[66,15257,15258],{"class":68,"line":87},[66,15259,1208],{},[10,15261,1211],{},[56,15263,15264],{"className":599,"code":1214,"language":601,"meta":61,"style":61},[63,15265,15266],{"__ignoreMap":61},[66,15267,15268,15270],{"class":68,"line":69},[66,15269,699],{"class":608},[66,15271,1223],{"class":644},[10,15273,1226],{},[14,15275,1230],{"id":1229},[337,15277,1233],{"id":1233},[10,15279,1236],{},[337,15281,1239],{"id":1239},[10,15283,1242],{},[337,15285,1245],{"id":1245},[10,15287,1248],{},[10,15289,1251],{},[56,15291,15292],{"className":58,"code":1254,"language":60,"meta":61,"style":61},[63,15293,15294,15298,15302,15306],{"__ignoreMap":61},[66,15295,15296],{"class":68,"line":69},[66,15297,1261],{},[66,15299,15300],{"class":68,"line":75},[66,15301,91],{"emptyLinePlaceholder":90},[66,15303,15304],{"class":68,"line":81},[66,15305,1270],{},[66,15307,15308],{"class":68,"line":87},[66,15309,1275],{},[10,15311,1278],{},[337,15313,1281],{"id":1281},[10,15315,1284,15316,1287],{},[63,15317,269],{},[10,15319,1290],{},[337,15321,1293],{"id":1293},[10,15323,1296],{},[14,15325,1300],{"id":1299},[10,15327,15328],{},[26,15329],{"alt":1305,"src":1306},[10,15331,1309],{},[37,15333,15334,15336,15338,15340,15342,15344,15346,15348],{},[40,15335,1314],{},[40,15337,1317],{},[40,15339,1320],{},[40,15341,1323],{},[40,15343,1326],{},[40,15345,1329],{},[40,15347,1332],{},[40,15349,1335],{},[10,15351,1338],{},[14,15353,1342],{"id":1341},[10,15355,1345],{},[10,15357,1348],{},[14,15359,1352],{"id":1351},[10,15361,1355],{},[10,15363,1358],{},[10,15365,1361],{},[14,15367,1364],{"id":1364},[10,15369,1367],{},[10,15371,1370],{},[221,15373,1373],{},{"title":61,"searchDepth":75,"depth":75,"links":15375},[15376,15377,15378,15385,15386,15387,15388],{"id":1082,"depth":75,"text":1083},{"id":1172,"depth":75,"text":1173},{"id":1229,"depth":75,"text":1230,"children":15379},[15380,15381,15382,15383,15384],{"id":1233,"depth":81,"text":1233},{"id":1239,"depth":81,"text":1239},{"id":1245,"depth":81,"text":1245},{"id":1281,"depth":81,"text":1281},{"id":1293,"depth":81,"text":1293},{"id":1299,"depth":75,"text":1300},{"id":1341,"depth":75,"text":1342},{"id":1351,"depth":75,"text":1352},{"id":1364,"depth":75,"text":1364},{},{"title":1065,"description":61},[234,1397,1398],{"id":251,"title":252,"body":15393,"category":234,"cover":235,"description":61,"extension":236,"meta":15972,"navigation":90,"path":1053,"pinned":239,"publishedAt":1054,"seo":15973,"slug":1056,"stem":1057,"summary":1058,"tags":15974,"updatedAt":1054,"visible":90,"__hash__":1062},{"type":7,"value":15394,"toc":15948},[15395,15397,15399,15401,15405,15407,15409,15433,15445,15447,15449,15454,15458,15462,15474,15478,15482,15486,15488,15522,15524,15528,15532,15534,15556,15586,15598,15608,15616,15618,15624,15634,15636,15641,15645,15647,15661,15667,15687,15689,15691,15693,15703,15707,15709,15718,15722,15724,15726,15746,15750,15752,15754,15756,15758,15778,15780,15782,15784,15810,15812,15828,15830,15846,15850,15852,15854,15874,15876,15878,15880,15884,15894,15896,15898,15900,15910,15918,15920,15922,15936,15946],[14,15396,257],{"id":257},[10,15398,260],{},[10,15400,263],{},[10,15402,266,15403,270],{},[63,15404,269],{},[14,15406,273],{"id":273},[10,15408,276],{},[278,15410,15411,15413],{},[10,15412,282],{},[278,15414,15415,15421,15423,15427,15429],{},[10,15416,287,15417,291,15419,295],{},[63,15418,290],{},[63,15420,294],{},[10,15422,298],{},[10,15424,301,15425,306],{},[303,15426,305],{},[10,15428,309],{},[10,15430,15431],{},[26,15432],{"alt":314,"src":315},[278,15434,15435,15437],{},[10,15436,320],{},[278,15438,15439,15441],{},[10,15440,325],{},[10,15442,15443],{},[26,15444],{"alt":330,"src":331},[14,15446,335],{"id":334},[337,15448,340],{"id":339},[10,15450,343,15451,351],{},[345,15452,350],{"href":347,"rel":15453},[349],[278,15455,15456],{},[10,15457,356],{},[10,15459,15460],{},[26,15461],{"alt":361,"src":362},[37,15463,15464,15468,15472],{},[40,15465,367,15466,207],{},[303,15467,370],{},[40,15469,373,15470,207],{},[303,15471,376],{},[40,15473,379],{},[10,15475,15476],{},[26,15477],{"alt":384,"src":385},[278,15479,15480],{},[10,15481,390],{},[10,15483,15484],{},[26,15485],{"alt":395,"src":396},[337,15487,400],{"id":399},[278,15489,15490,15494,15498,15518],{},[278,15491,15492],{},[10,15493,407],{},[10,15495,410,15496,414],{},[303,15497,413],{},[56,15499,15500],{"className":58,"code":417,"language":60,"meta":61,"style":61},[63,15501,15502,15506,15510,15514],{"__ignoreMap":61},[66,15503,15504],{"class":68,"line":69},[66,15505,424],{},[66,15507,15508],{"class":68,"line":75},[66,15509,429],{},[66,15511,15512],{"class":68,"line":81},[66,15513,434],{},[66,15515,15516],{"class":68,"line":87},[66,15517,439],{},[10,15519,442,15520,446],{},[303,15521,445],{},[10,15523,449],{},[10,15525,452,15526,455],{},[63,15527,60],{},[10,15529,15530],{},[26,15531],{"alt":460,"src":461},[10,15533,464],{},[278,15535,15536,15538,15542],{},[10,15537,469],{},[10,15539,15540],{},[303,15541,474],{},[278,15543,15544,15548,15552],{},[10,15545,479,15546,482],{},[63,15547,60],{},[10,15549,485,15550,488],{},[63,15551,60],{},[10,15553,491,15554,495],{},[303,15555,494],{},[278,15557,15558,15560,15564],{},[10,15559,500],{},[10,15561,15562],{},[303,15563,505],{},[278,15565,15566,15572,15580,15582],{},[10,15567,15568,513,15570,517],{},[63,15569,512],{},[63,15571,516],{},[10,15573,520,15574,523,15576,527,15578,531],{},[63,15575,512],{},[303,15577,526],{},[303,15579,530],{},[10,15581,534],{},[10,15583,15584,540],{},[303,15585,539],{},[278,15587,15588,15590],{},[10,15589,545],{},[278,15591,15592,15596],{},[10,15593,550,15594,554],{},[303,15595,553],{},[10,15597,557],{},[278,15599,15600,15604],{},[10,15601,562,15602],{},[303,15603,565],{},[10,15605,15606],{},[26,15607],{"alt":570,"src":571},[278,15609,15610,15612],{},[10,15611,576],{},[10,15613,15614],{},[26,15615],{"alt":570,"src":581},[337,15617,585],{"id":584},[10,15619,588,15620,592,15622,596],{},[63,15621,591],{},[63,15623,595],{},[56,15625,15626],{"className":599,"code":600,"language":601,"meta":61,"style":61},[63,15627,15628],{"__ignoreMap":61},[66,15629,15630,15632],{"class":68,"line":69},[66,15631,60],{"class":608},[66,15633,612],{"class":611},[10,15635,615],{},[56,15637,15639],{"className":15638,"code":619,"language":152,"meta":61},[150],[63,15640,619],{"__ignoreMap":61},[10,15642,15643],{},[26,15644],{"alt":570,"src":626},[10,15646,629],{},[56,15648,15649],{"className":599,"code":632,"language":601,"meta":61,"style":61},[63,15650,15651],{"__ignoreMap":61},[66,15652,15653,15655,15657,15659],{"class":68,"line":69},[66,15654,60],{"class":608},[66,15656,641],{"class":611},[66,15658,645],{"class":644},[66,15660,612],{"class":611},[10,15662,650,15663,653,15665,657],{},[63,15664,60],{},[63,15666,656],{},[56,15668,15669],{"className":599,"code":660,"language":601,"meta":61,"style":61},[63,15670,15671,15677],{"__ignoreMap":61},[66,15672,15673,15675],{"class":68,"line":69},[66,15674,516],{"class":608},[66,15676,612],{"class":611},[66,15678,15679,15681,15683,15685],{"class":68,"line":75},[66,15680,516],{"class":608},[66,15682,641],{"class":611},[66,15684,645],{"class":644},[66,15686,612],{"class":611},[14,15688,682],{"id":681},[337,15690,686],{"id":685},[10,15692,689],{},[56,15694,15695],{"className":599,"code":692,"language":601,"meta":61,"style":61},[63,15696,15697],{"__ignoreMap":61},[66,15698,15699,15701],{"class":68,"line":69},[66,15700,699],{"class":608},[66,15702,612],{"class":611},[10,15704,704,15705,708],{},[63,15706,707],{},[337,15708,712],{"id":711},[10,15710,343,15711,720,15714,207,15716,727],{},[345,15712,719],{"href":717,"rel":15713},[349],[303,15715,723],{},[63,15717,726],{},[10,15719,730,15720,734],{},[63,15721,733],{},[337,15723,738],{"id":737},[10,15725,741],{},[56,15727,15728],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,15729,15730,15736],{"__ignoreMap":61},[66,15731,15732,15734],{"class":68,"line":69},[66,15733,699],{"class":608},[66,15735,612],{"class":611},[66,15737,15738,15740,15742,15744],{"class":68,"line":75},[66,15739,699],{"class":608},[66,15741,641],{"class":611},[66,15743,645],{"class":644},[66,15745,612],{"class":611},[10,15747,765,15748,768],{},[63,15749,699],{},[14,15751,772],{"id":771},[10,15753,775],{},[337,15755,779],{"id":778},[10,15757,782],{},[56,15759,15760],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,15761,15762,15768],{"__ignoreMap":61},[66,15763,15764,15766],{"class":68,"line":69},[66,15765,699],{"class":608},[66,15767,612],{"class":611},[66,15769,15770,15772,15774,15776],{"class":68,"line":75},[66,15771,699],{"class":608},[66,15773,641],{"class":611},[66,15775,645],{"class":644},[66,15777,612],{"class":611},[10,15779,805],{},[337,15781,809],{"id":808},[10,15783,812],{},[56,15785,15786],{"className":599,"code":815,"language":601,"meta":61,"style":61},[63,15787,15788,15796],{"__ignoreMap":61},[66,15789,15790,15792,15794],{"class":68,"line":69},[66,15791,822],{"class":608},[66,15793,825],{"class":644},[66,15795,828],{"class":644},[66,15797,15798,15800,15802,15804,15806,15808],{"class":68,"line":75},[66,15799,822],{"class":608},[66,15801,825],{"class":644},[66,15803,837],{"class":644},[66,15805,840],{"class":644},[66,15807,843],{"class":644},[66,15809,846],{"class":644},[10,15811,849],{},[56,15813,15814],{"className":599,"code":852,"language":601,"meta":61,"style":61},[63,15815,15816],{"__ignoreMap":61},[66,15817,15818,15820,15822,15824,15826],{"class":68,"line":69},[66,15819,822],{"class":608},[66,15821,861],{"class":644},[66,15823,837],{"class":644},[66,15825,840],{"class":644},[66,15827,868],{"class":644},[10,15829,871],{},[56,15831,15832],{"className":599,"code":874,"language":601,"meta":61,"style":61},[63,15833,15834],{"__ignoreMap":61},[66,15835,15836,15838,15840,15842,15844],{"class":68,"line":69},[66,15837,822],{"class":608},[66,15839,883],{"class":644},[66,15841,886],{"class":611},[66,15843,889],{"class":644},[66,15845,892],{"class":644},[10,15847,15848,897],{},[63,15849,822],{},[337,15851,901],{"id":900},[10,15853,904],{},[56,15855,15856],{"className":599,"code":744,"language":601,"meta":61,"style":61},[63,15857,15858,15864],{"__ignoreMap":61},[66,15859,15860,15862],{"class":68,"line":69},[66,15861,699],{"class":608},[66,15863,612],{"class":611},[66,15865,15866,15868,15870,15872],{"class":68,"line":75},[66,15867,699],{"class":608},[66,15869,641],{"class":611},[66,15871,645],{"class":644},[66,15873,612],{"class":611},[10,15875,927],{},[14,15877,930],{"id":930},[337,15879,934],{"id":933},[10,15881,937,15882,941],{},[63,15883,940],{},[162,15885,15886,15890,15892],{},[40,15887,946,15888,949],{},[63,15889,656],{},[40,15891,952],{},[40,15893,955],{},[10,15895,958],{},[337,15897,962],{"id":961},[10,15899,965],{},[56,15901,15902],{"className":599,"code":692,"language":601,"meta":61,"style":61},[63,15903,15904],{"__ignoreMap":61},[66,15905,15906,15908],{"class":68,"line":69},[66,15907,699],{"class":608},[66,15909,612],{"class":611},[10,15911,978,15912,981,15914,984,15916,207],{},[63,15913,699],{},[63,15915,60],{},[63,15917,699],{},[337,15919,990],{"id":989},[10,15921,993],{},[56,15923,15924],{"className":599,"code":996,"language":601,"meta":61,"style":61},[63,15925,15926],{"__ignoreMap":61},[66,15927,15928,15930,15932,15934],{"class":68,"line":69},[66,15929,699],{"class":608},[66,15931,641],{"class":611},[66,15933,645],{"class":644},[66,15935,612],{"class":611},[10,15937,1011,15938,1014,15940,1017,15942,1020,15944,1024],{},[63,15939,699],{},[63,15941,60],{},[63,15943,516],{},[63,15945,1023],{},[221,15947,1027],{},{"title":61,"searchDepth":75,"depth":75,"links":15949},[15950,15951,15952,15957,15962,15967],{"id":257,"depth":75,"text":257},{"id":273,"depth":75,"text":273},{"id":334,"depth":75,"text":335,"children":15953},[15954,15955,15956],{"id":339,"depth":81,"text":340},{"id":399,"depth":81,"text":400},{"id":584,"depth":81,"text":585},{"id":681,"depth":75,"text":682,"children":15958},[15959,15960,15961],{"id":685,"depth":81,"text":686},{"id":711,"depth":81,"text":712},{"id":737,"depth":81,"text":738},{"id":771,"depth":75,"text":772,"children":15963},[15964,15965,15966],{"id":778,"depth":81,"text":779},{"id":808,"depth":81,"text":809},{"id":900,"depth":81,"text":901},{"id":930,"depth":75,"text":930,"children":15968},[15969,15970,15971],{"id":933,"depth":81,"text":934},{"id":961,"depth":81,"text":962},{"id":989,"depth":81,"text":990},{},{"title":252,"description":61},[234,1060,1061],1786973366397]