[{"data":1,"prerenderedAt":15987},["ShallowReactive",2],{"post-python-debug-logging-testing":3,"sidebar-posts":262,"post-related-source":9178},{"id":4,"title":5,"body":6,"category":247,"cover":248,"description":12,"extension":249,"meta":250,"navigation":84,"path":251,"pinned":252,"publishedAt":253,"seo":254,"slug":255,"stem":256,"summary":257,"tags":258,"updatedAt":253,"visible":84,"__hash__":261},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8,"toc":235},"minimark",[9,13,17,20,23,30,33,36,49,52,55,155,158,166,169,172,184,188,191,197,200,203,211,214,222,225,228,231],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[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\u002F39-debug-test.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","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","python","",[63,64,65,73,79,86,92,97,103,109,115,120,126,132,138,143,149],"code",{"__ignoreMap":61},[66,67,70],"span",{"class":68,"line":69},"line",1,[66,71,72],{},"import logging\n",[66,74,76],{"class":68,"line":75},2,[66,77,78],{},"import unittest\n",[66,80,82],{"class":68,"line":81},3,[66,83,85],{"emptyLinePlaceholder":84},true,"\n",[66,87,89],{"class":68,"line":88},4,[66,90,91],{},"logging.basicConfig(level=logging.INFO)\n",[66,93,95],{"class":68,"line":94},5,[66,96,85],{"emptyLinePlaceholder":84},[66,98,100],{"class":68,"line":99},6,[66,101,102],{},"def clamp_progress(value):\n",[66,104,106],{"class":68,"line":105},7,[66,107,108],{},"    logging.info(\"检查进度：%s\", value)\n",[66,110,112],{"class":68,"line":111},8,[66,113,114],{},"    return max(0, min(100, value))\n",[66,116,118],{"class":68,"line":117},9,[66,119,85],{"emptyLinePlaceholder":84},[66,121,123],{"class":68,"line":122},10,[66,124,125],{},"class ProgressTest(unittest.TestCase):\n",[66,127,129],{"class":68,"line":128},11,[66,130,131],{},"    def test_upper_limit(self):\n",[66,133,135],{"class":68,"line":134},12,[66,136,137],{},"        self.assertEqual(clamp_progress(120), 100)\n",[66,139,141],{"class":68,"line":140},13,[66,142,85],{"emptyLinePlaceholder":84},[66,144,146],{"class":68,"line":145},14,[66,147,148],{},"if __name__ == \"__main__\":\n",[66,150,152],{"class":68,"line":151},15,[66,153,154],{},"    unittest.main()\n",[10,156,157],{},"预期结果：",[56,159,164],{"className":160,"code":162,"language":163,"meta":61},[161],"language-text","测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n","text",[63,165,162],{"__ignoreMap":61},[10,167,168],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,170,171],{"id":171},"按执行顺序拆开看",[173,174,175,181],"ol",{},[40,176,177,180],{},[63,178,179],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[40,182,183],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[185,186,187],"h3",{"id":187},"再看一个具体细节",[10,189,190],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,192,193],{},[26,194],{"alt":195,"src":196},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,198,199],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,201,202],{"id":202},"初学者容易混淆的地方",[37,204,205,208],{},[40,206,207],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[40,209,210],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,212,213],{"id":213},"练习",[173,215,216,219],{},[40,217,218],{},"为负数进度增加测试。",[40,220,221],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,223,224],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,226,227],{"id":227},"本篇边界",[10,229,230],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,233,234],"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":236},[237,238,239,240,241,244,245,246],{"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":171,"depth":75,"text":171,"children":242},[243],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",false,"2026-08-17",{"title":5,"description":12},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[247,259,260],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",[263,1076,1413,1547,1699,1878,2066,2231,2415,2596,2788,3019,3203,3380,3537,3708,3873,4087,4315,4497,4661,4850,5038,5193,5353,5550,5747,5959,6126,6369,6550,6755,6950,7134,7335,7623,7815,8044,8239,8459,8698,8861],{"id":264,"title":265,"body":266,"category":247,"cover":248,"description":61,"extension":249,"meta":1065,"navigation":84,"path":1066,"pinned":252,"publishedAt":1067,"seo":1068,"slug":1069,"stem":1070,"summary":1071,"tags":1072,"updatedAt":1067,"visible":84,"__hash__":1075},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":267,"toc":1041},[268,271,274,277,284,287,290,329,345,349,353,364,369,375,393,399,404,410,414,460,463,469,475,478,509,554,571,585,595,599,610,626,629,635,640,643,661,671,692,696,700,703,715,722,726,741,748,752,755,776,782,786,789,793,796,816,819,823,826,860,863,882,885,906,911,915,918,938,941,944,948,955,969,972,976,979,989,1000,1004,1007,1022,1038],[14,269,270],{"id":270},"引言",[10,272,273],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,275,276],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,278,279,280,283],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[63,281,282],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,285,286],{"id":286},"扫盲",[10,288,289],{},"那么这里有几个概念：",[291,292,293,296],"blockquote",{},[10,294,295],{},"为什么需要安装python解释器？",[291,297,298,309,312,320,323],{},[10,299,300,301,304,305,308],{},"我们写的代码，电脑其实看不懂，电脑只认识",[63,302,303],{},"0","和",[63,306,307],{},"1","组成的机器指令。",[10,310,311],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,313,314,315,319],{},"这样，我们就能用",[316,317,318],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,321,322],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,324,325],{},[26,326],{"alt":327,"src":328},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[291,330,331,334],{},[10,332,333],{},"pip又是什么？",[291,335,336,339],{},[10,337,338],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,340,341],{},[26,342],{"alt":343,"src":344},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,346,348],{"id":347},"windows-安装","Windows 安装",[185,350,352],{"id":351},"_1-下载官方安装程序","1. 下载官方安装程序",[10,354,355,356,363],{},"打开 ",[357,358,362],"a",{"href":359,"rel":360},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[361],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[291,365,366],{},[10,367,368],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,370,371],{},[26,372],{"alt":373,"src":374},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[37,376,377,384,390],{},[40,378,379,380,383],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[316,381,382],{},"Windows installer (64-bit)","。",[40,385,386,387,383],{},"搭载 ARM 处理器的 Windows 设备选择 ",[316,388,389],{},"Windows installer (ARM64)",[40,391,392],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,394,395],{},[26,396],{"alt":397,"src":398},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[291,400,401],{},[10,402,403],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,405,406],{},[26,407],{"alt":408,"src":409},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[185,411,413],{"id":412},"_2-安装并加入-path","2. 安装并加入 PATH",[291,415,416,421,428,453],{},[291,417,418],{},[10,419,420],{},"PATH 环境变量",[10,422,423,424,427],{},"Windows 有一个特殊的变量叫 ",[316,425,426],{},"PATH","，它里面存了一串文件夹路径，比如：",[56,429,431],{"className":58,"code":430,"language":60,"meta":61,"style":61},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[63,432,433,438,443,448],{"__ignoreMap":61},[66,434,435],{"class":68,"line":69},[66,436,437],{},"D:\\Python313\\\n",[66,439,440],{"class":68,"line":75},[66,441,442],{},"D:\\Python313\\Scripts\\\n",[66,444,445],{"class":68,"line":81},[66,446,447],{},"C:\\Windows\\System32\\\n",[66,449,450],{"class":68,"line":88},[66,451,452],{},"...\n",[10,454,455,456,459],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[316,457,458],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,461,462],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,464,465,466,468],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[63,467,60],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,470,471],{},[26,472],{"alt":473,"src":474},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,476,477],{},"对安装界面最底部的两个勾选项分别解释 :",[291,479,480,483,488],{},[10,481,482],{},"Add python.exe to PATH",[10,484,485],{},[316,486,487],{},"把 Python 添加到系统环境变量",[291,489,490,496,502],{},[10,491,492,493,495],{},"勾选后，你可以在命令行任意位置直接输入 ",[63,494,60],{}," 就能运行",[10,497,498,499,501],{},"不勾选的话，命令行输入 ",[63,500,60],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,503,504,505,508],{},"必须",[316,506,507],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[291,510,511,514,519],{},[10,512,513],{},"Use admin privileges when installing py.exe",[10,515,516],{},[316,517,518],{},"使用管理员权限安装 py.exe（Python 启动器）",[291,520,521,531,545,548],{},[10,522,523,526,527,530],{},[63,524,525],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[63,528,529],{},"py"," 来启动 Python。",[10,532,533,534,536,537,540,541,544],{},"勾选后，",[63,535,525],{}," 会安装到",[316,538,539],{},"系统级目录","，电脑上",[316,542,543],{},"所有用户账户","都能用",[10,546,547],{},"不勾选，只有当前用户能用",[10,549,550,553],{},[316,551,552],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[291,555,556,559],{},[10,557,558],{},"操作建议",[291,560,561,568],{},[10,562,563,564,567],{},"两个都勾上之后，再点 ",[316,565,566],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,569,570],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[291,572,573,579],{},[10,574,575,576],{},"Python 安装的",[316,577,578],{},"可选功能页",[10,580,581],{},[26,582],{"alt":583,"src":584},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[291,586,587,590],{},[10,588,589],{},"高级选项页",[10,591,592],{},[26,593],{"alt":583,"src":594},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[185,596,598],{"id":597},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,600,601,602,605,606,609],{},"按 ",[63,603,604],{},"Win + R","，输入 ",[63,607,608],{},"cmd"," 并回车，然后执行：",[56,611,615],{"className":612,"code":613,"language":614,"meta":61,"style":61},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[63,616,617],{"__ignoreMap":61},[66,618,619,622],{"class":68,"line":69},[66,620,60],{"class":621},"svObZ",[66,623,625],{"class":624},"sDLfK"," --version\n",[10,627,628],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[56,630,633],{"className":631,"code":632,"language":163,"meta":61},[161],"Python 3.x.x\n",[63,634,632],{"__ignoreMap":61},[10,636,637],{},[26,638],{"alt":583,"src":639},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,641,642],{},"继续检查 pip：",[56,644,646],{"className":612,"code":645,"language":614,"meta":61,"style":61},"python -m pip --version\n",[63,647,648],{"__ignoreMap":61},[66,649,650,652,655,659],{"class":68,"line":69},[66,651,60],{"class":621},[66,653,654],{"class":624}," -m",[66,656,658],{"class":657},"sU2Wk"," pip",[66,660,625],{"class":624},[10,662,663,664,666,667,670],{},"如果 ",[63,665,60],{}," 无法识别，但 ",[63,668,669],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[56,672,674],{"className":612,"code":673,"language":614,"meta":61,"style":61},"py --version\npy -m pip --version\n",[63,675,676,682],{"__ignoreMap":61},[66,677,678,680],{"class":68,"line":69},[66,679,529],{"class":621},[66,681,625],{"class":624},[66,683,684,686,688,690],{"class":68,"line":75},[66,685,529],{"class":621},[66,687,654],{"class":624},[66,689,658],{"class":657},[66,691,625],{"class":624},[14,693,695],{"id":694},"macos-安装","macOS 安装",[185,697,699],{"id":698},"_1-先检查现有环境","1. 先检查现有环境",[10,701,702],{},"打开“终端”应用，执行：",[56,704,706],{"className":612,"code":705,"language":614,"meta":61,"style":61},"python3 --version\n",[63,707,708],{"__ignoreMap":61},[66,709,710,713],{"class":68,"line":69},[66,711,712],{"class":621},"python3",[66,714,625],{"class":624},[10,716,717,718,721],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[63,719,720],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[185,723,725],{"id":724},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,727,355,728,733,734,383,737,740],{},[357,729,732],{"href":730,"rel":731},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[361],"Python macOS 下载页","，下载当前稳定版的 ",[316,735,736],{},"macOS 64-bit universal2 installer",[63,738,739],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,742,743,744,747],{},"下载完成后打开 ",[63,745,746],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[185,749,751],{"id":750},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,753,754],{},"安装完成后重新打开终端，执行：",[56,756,758],{"className":612,"code":757,"language":614,"meta":61,"style":61},"python3 --version\npython3 -m pip --version\n",[63,759,760,766],{"__ignoreMap":61},[66,761,762,764],{"class":68,"line":69},[66,763,712],{"class":621},[66,765,625],{"class":624},[66,767,768,770,772,774],{"class":68,"line":75},[66,769,712],{"class":621},[66,771,654],{"class":624},[66,773,658],{"class":657},[66,775,625],{"class":624},[10,777,778,779,781],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[63,780,712],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,783,785],{"id":784},"linux-安装","Linux 安装",[10,787,788],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[185,790,792],{"id":791},"_1-检查是否已经安装","1. 检查是否已经安装",[10,794,795],{},"打开终端，执行：",[56,797,798],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,799,800,806],{"__ignoreMap":61},[66,801,802,804],{"class":68,"line":69},[66,803,712],{"class":621},[66,805,625],{"class":624},[66,807,808,810,812,814],{"class":68,"line":75},[66,809,712],{"class":621},[66,811,654],{"class":624},[66,813,658],{"class":657},[66,815,625],{"class":624},[10,817,818],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[185,820,822],{"id":821},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,824,825],{},"Ubuntu 或 Debian：",[56,827,829],{"className":612,"code":828,"language":614,"meta":61,"style":61},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[63,830,831,842],{"__ignoreMap":61},[66,832,833,836,839],{"class":68,"line":69},[66,834,835],{"class":621},"sudo",[66,837,838],{"class":657}," apt",[66,840,841],{"class":657}," update\n",[66,843,844,846,848,851,854,857],{"class":68,"line":75},[66,845,835],{"class":621},[66,847,838],{"class":657},[66,849,850],{"class":657}," install",[66,852,853],{"class":657}," python3",[66,855,856],{"class":657}," python3-pip",[66,858,859],{"class":657}," python3-venv\n",[10,861,862],{},"Fedora：",[56,864,866],{"className":612,"code":865,"language":614,"meta":61,"style":61},"sudo dnf install python3 python3-pip\n",[63,867,868],{"__ignoreMap":61},[66,869,870,872,875,877,879],{"class":68,"line":69},[66,871,835],{"class":621},[66,873,874],{"class":657}," dnf",[66,876,850],{"class":657},[66,878,853],{"class":657},[66,880,881],{"class":657}," python3-pip\n",[10,883,884],{},"Arch Linux：",[56,886,888],{"className":612,"code":887,"language":614,"meta":61,"style":61},"sudo pacman -S python python-pip\n",[63,889,890],{"__ignoreMap":61},[66,891,892,894,897,900,903],{"class":68,"line":69},[66,893,835],{"class":621},[66,895,896],{"class":657}," pacman",[66,898,899],{"class":624}," -S",[66,901,902],{"class":657}," python",[66,904,905],{"class":657}," python-pip\n",[10,907,908,910],{},[63,909,835],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[185,912,914],{"id":913},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,916,917],{},"安装结束后执行：",[56,919,920],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,921,922,928],{"__ignoreMap":61},[66,923,924,926],{"class":68,"line":69},[66,925,712],{"class":621},[66,927,625],{"class":624},[66,929,930,932,934,936],{"class":68,"line":75},[66,931,712],{"class":621},[66,933,654],{"class":624},[66,935,658],{"class":657},[66,937,625],{"class":624},[10,939,940],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,942,943],{"id":943},"常见问题",[185,945,947],{"id":946},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,949,950,951,954],{},"先关闭当前命令提示符并重新打开，再执行 ",[63,952,953],{},"python --version","。如果仍然失败，按下面的顺序检查：",[173,956,957,963,966],{},[40,958,959,960,962],{},"执行 ",[63,961,669],{},"，确认 Python Launcher 是否可用。",[40,964,965],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[40,967,968],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,970,971],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[185,973,975],{"id":974},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,977,978],{},"先尝试：",[56,980,981],{"className":612,"code":705,"language":614,"meta":61,"style":61},[63,982,983],{"__ignoreMap":61},[66,984,985,987],{"class":68,"line":69},[66,986,712],{"class":621},[66,988,625],{"class":624},[10,990,991,992,994,995,997,998,383],{},"在这两个系统中，只有 ",[63,993,712],{}," 命令而没有 ",[63,996,60],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[63,999,712],{},[185,1001,1003],{"id":1002},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,1005,1006],{},"先使用模块方式检查：",[56,1008,1010],{"className":612,"code":1009,"language":614,"meta":61,"style":61},"python3 -m pip --version\n",[63,1011,1012],{"__ignoreMap":61},[66,1013,1014,1016,1018,1020],{"class":68,"line":69},[66,1015,712],{"class":621},[66,1017,654],{"class":624},[66,1019,658],{"class":657},[66,1021,625],{"class":624},[10,1023,1024,1025,1027,1028,1030,1031,1033,1034,1037],{},"Windows 用户将命令中的 ",[63,1026,712],{}," 换成 ",[63,1029,60],{}," 或 ",[63,1032,529],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[63,1035,1036],{},"python3-pip","；不要直接使用其他系统的安装命令。",[232,1039,1040],{},"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":1042},[1043,1044,1045,1050,1055,1060],{"id":270,"depth":75,"text":270},{"id":286,"depth":75,"text":286},{"id":347,"depth":75,"text":348,"children":1046},[1047,1048,1049],{"id":351,"depth":81,"text":352},{"id":412,"depth":81,"text":413},{"id":597,"depth":81,"text":598},{"id":694,"depth":75,"text":695,"children":1051},[1052,1053,1054],{"id":698,"depth":81,"text":699},{"id":724,"depth":81,"text":725},{"id":750,"depth":81,"text":751},{"id":784,"depth":75,"text":785,"children":1056},[1057,1058,1059],{"id":791,"depth":81,"text":792},{"id":821,"depth":81,"text":822},{"id":913,"depth":81,"text":914},{"id":943,"depth":75,"text":943,"children":1061},[1062,1063,1064],{"id":946,"depth":81,"text":947},{"id":974,"depth":81,"text":975},{"id":1002,"depth":81,"text":1003},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":265,"description":61},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[247,1073,1074],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1077,"title":1078,"body":1079,"category":247,"cover":1086,"description":61,"extension":249,"meta":1402,"navigation":84,"path":1403,"pinned":252,"publishedAt":1404,"seo":1405,"slug":1406,"stem":1407,"summary":1408,"tags":1409,"updatedAt":1404,"visible":84,"__hash__":1412},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1080,"toc":1387},[1081,1087,1090,1093,1097,1100,1124,1127,1133,1136,1139,1173,1183,1187,1194,1197,1222,1225,1237,1240,1244,1247,1250,1253,1256,1259,1262,1265,1289,1292,1295,1301,1304,1307,1310,1314,1320,1323,1349,1352,1356,1359,1362,1366,1369,1372,1375,1378,1381,1384],[10,1082,1083],{},[26,1084],{"alt":1085,"src":1086},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1088,1089],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1091,1092],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1094,1096],{"id":1095},"python-代码是什么样的","Python 代码是什么样的",[10,1098,1099],{},"下面是一段简单的 Python 代码：",[56,1101,1103],{"className":58,"code":1102,"language":60,"meta":61,"style":61},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[63,1104,1105,1110,1115,1119],{"__ignoreMap":61},[66,1106,1107],{"class":68,"line":69},[66,1108,1109],{},"name = \"Python\"\n",[66,1111,1112],{"class":68,"line":75},[66,1113,1114],{},"year = 2026\n",[66,1116,1117],{"class":68,"line":81},[66,1118,85],{"emptyLinePlaceholder":84},[66,1120,1121],{"class":68,"line":88},[66,1122,1123],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1125,1126],{},"运行结果：",[56,1128,1131],{"className":1129,"code":1130,"language":163,"meta":61},[161],"正在学习 Python，当前年份是 2026\n",[63,1132,1130],{"__ignoreMap":61},[10,1134,1135],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1137,1138],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[56,1140,1142],{"className":58,"code":1141,"language":60,"meta":61,"style":61},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[63,1143,1144,1149,1153,1158,1163,1168],{"__ignoreMap":61},[66,1145,1146],{"class":68,"line":69},[66,1147,1148],{},"score = 85\n",[66,1150,1151],{"class":68,"line":75},[66,1152,85],{"emptyLinePlaceholder":84},[66,1154,1155],{"class":68,"line":81},[66,1156,1157],{},"if score >= 60:\n",[66,1159,1160],{"class":68,"line":88},[66,1161,1162],{},"    print(\"成绩合格\")\n",[66,1164,1165],{"class":68,"line":94},[66,1166,1167],{},"else:\n",[66,1169,1170],{"class":68,"line":99},[66,1171,1172],{},"    print(\"需要继续学习\")\n",[10,1174,1175,1178,1179,1182],{},[63,1176,1177],{},"if"," 和 ",[63,1180,1181],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1184,1186],{"id":1185},"python-如何运行代码","Python 如何运行代码",[10,1188,1189,1190,1193],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[63,1191,1192],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1195,1196],{},"交互式环境适合快速验证一个表达式：",[56,1198,1200],{"className":58,"code":1199,"language":60,"meta":61,"style":61},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[63,1201,1202,1207,1212,1217],{"__ignoreMap":61},[66,1203,1204],{"class":68,"line":69},[66,1205,1206],{},">>> 10 + 20\n",[66,1208,1209],{"class":68,"line":75},[66,1210,1211],{},"30\n",[66,1213,1214],{"class":68,"line":81},[66,1215,1216],{},">>> \"Python\".lower()\n",[66,1218,1219],{"class":68,"line":88},[66,1220,1221],{},"'python'\n",[10,1223,1224],{},"需要保存和重复运行的程序，则可以写入文件：",[56,1226,1228],{"className":612,"code":1227,"language":614,"meta":61,"style":61},"python3 hello.py\n",[63,1229,1230],{"__ignoreMap":61},[66,1231,1232,1234],{"class":68,"line":69},[66,1233,712],{"class":621},[66,1235,1236],{"class":657}," hello.py\n",[10,1238,1239],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1241,1243],{"id":1242},"python-的特点","Python 的特点",[185,1245,1246],{"id":1246},"语法相对简洁",[10,1248,1249],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[185,1251,1252],{"id":1252},"支持多种编程方式",[10,1254,1255],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[185,1257,1258],{"id":1258},"标准库比较完整",[10,1260,1261],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1263,1264],{},"例如，获取当前时间：",[56,1266,1268],{"className":58,"code":1267,"language":60,"meta":61,"style":61},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[63,1269,1270,1275,1279,1284],{"__ignoreMap":61},[66,1271,1272],{"class":68,"line":69},[66,1273,1274],{},"from datetime import datetime\n",[66,1276,1277],{"class":68,"line":75},[66,1278,85],{"emptyLinePlaceholder":84},[66,1280,1281],{"class":68,"line":81},[66,1282,1283],{},"now = datetime.now()\n",[66,1285,1286],{"class":68,"line":88},[66,1287,1288],{},"print(now)\n",[10,1290,1291],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[185,1293,1294],{"id":1294},"第三方工具丰富",[10,1296,1297,1298,1300],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[63,1299,282],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1302,1303],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[185,1305,1306],{"id":1306},"支持多个操作系统",[10,1308,1309],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1311,1313],{"id":1312},"python-可以做什么","Python 可以做什么",[10,1315,1316],{},[26,1317],{"alt":1318,"src":1319},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1321,1322],{},"Python 的应用范围比较广，常见方向包括：",[37,1324,1325,1328,1331,1334,1337,1340,1343,1346],{},[40,1326,1327],{},"编写自动化脚本，批量处理文件和重复任务；",[40,1329,1330],{},"开发网站后端和 API 服务；",[40,1332,1333],{},"进行数据清洗、统计分析和图表展示；",[40,1335,1336],{},"编写网络爬虫和信息采集工具；",[40,1338,1339],{},"开发自动化测试程序；",[40,1341,1342],{},"进行机器学习和人工智能开发；",[40,1344,1345],{},"编写运维、监控和辅助开发工具；",[40,1347,1348],{},"开发部分桌面应用和插件。",[10,1350,1351],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1353,1355],{"id":1354},"python-的发展","Python 的发展",[10,1357,1358],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1360,1361],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1363,1365],{"id":1364},"python-也有局限","Python 也有局限",[10,1367,1368],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1370,1371],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1373,1374],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1376,1377],{"id":1377},"写在最后",[10,1379,1380],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1382,1383],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[232,1385,1386],{},"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":1388},[1389,1390,1391,1398,1399,1400,1401],{"id":1095,"depth":75,"text":1096},{"id":1185,"depth":75,"text":1186},{"id":1242,"depth":75,"text":1243,"children":1392},[1393,1394,1395,1396,1397],{"id":1246,"depth":81,"text":1246},{"id":1252,"depth":81,"text":1252},{"id":1258,"depth":81,"text":1258},{"id":1294,"depth":81,"text":1294},{"id":1306,"depth":81,"text":1306},{"id":1312,"depth":75,"text":1313},{"id":1354,"depth":75,"text":1355},{"id":1364,"depth":75,"text":1365},{"id":1377,"depth":75,"text":1377},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1078,"description":61},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[247,1410,1411],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1414,"title":1415,"body":1416,"category":247,"cover":248,"description":1420,"extension":249,"meta":1538,"navigation":84,"path":1539,"pinned":252,"publishedAt":253,"seo":1540,"slug":1541,"stem":1542,"summary":1543,"tags":1544,"updatedAt":253,"visible":84,"__hash__":1546},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1417,"toc":1528},[1418,1421,1423,1426,1428,1434,1439,1441,1455,1457,1459,1468,1470,1476,1478,1480,1496,1498,1509,1511,1519,1521,1523,1526],[10,1419,1420],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1422,16],{"id":16},[10,1424,1425],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1427,22],{"id":22},[10,1429,1430],{},[26,1431],{"alt":1432,"src":1433},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1435,1436,1438],{},[63,1437,1192],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1440,35],{"id":35},[37,1442,1443,1449,1452],{},[40,1444,1445,1446,1448],{},"源代码是人编写的文本，通常保存在 ",[63,1447,1192],{}," 文件中。",[40,1450,1451],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[40,1453,1454],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1456,51],{"id":51},[10,1458,54],{},[56,1460,1462],{"className":58,"code":1461,"language":60,"meta":61,"style":61},"print(\"你好，Python\")\n",[63,1463,1464],{"__ignoreMap":61},[66,1465,1466],{"class":68,"line":69},[66,1467,1461],{},[10,1469,157],{},[56,1471,1474],{"className":1472,"code":1473,"language":163,"meta":61},[161],"你好，Python\n",[63,1475,1473],{"__ignoreMap":61},[10,1477,168],{},[14,1479,171],{"id":171},[173,1481,1482,1489],{},[40,1483,1484,1485,1488],{},"终端启动解释器后，解释器读取 ",[63,1486,1487],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[40,1490,1491,1492,1495],{},"字符串对象先准备好，再交给 ",[63,1493,1494],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1497,202],{"id":202},[37,1499,1500,1503],{},[40,1501,1502],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[40,1504,1505,1506,1508],{},"认为 ",[63,1507,1192],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1510,213],{"id":213},[173,1512,1513,1516],{},[40,1514,1515],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[40,1517,1518],{},"把示例文字改成自己的学习目标并重新运行。",[10,1520,224],{},[14,1522,227],{"id":227},[10,1524,1525],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,1527,234],{},{"title":61,"searchDepth":75,"depth":75,"links":1529},[1530,1531,1532,1533,1534,1535,1536,1537],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1415,"description":1420},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[247,1410,1545],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1548,"title":1549,"body":1550,"category":247,"cover":248,"description":1554,"extension":249,"meta":1690,"navigation":84,"path":1691,"pinned":252,"publishedAt":253,"seo":1692,"slug":1693,"stem":1694,"summary":1695,"tags":1696,"updatedAt":253,"visible":84,"__hash__":1698},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1551,"toc":1680},[1552,1555,1557,1560,1562,1568,1574,1576,1591,1593,1596,1616,1618,1624,1626,1628,1641,1643,1657,1659,1670,1672,1674,1677],[10,1553,1554],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1556,16],{"id":16},[10,1558,1559],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1561,22],{"id":22},[10,1563,1564],{},[26,1565],{"alt":1566,"src":1567},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1569,1570,1571,1573],{},"终端收到 ",[63,1572,712],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1575,35],{"id":35},[37,1577,1578,1581,1584],{},[40,1579,1580],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[40,1582,1583],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[40,1585,1586,1587,1590],{},"检查 pip 时使用 ",[63,1588,1589],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1592,51],{"id":51},[10,1594,1595],{},"在 macOS 终端执行：",[56,1597,1598],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,1599,1600,1606],{"__ignoreMap":61},[66,1601,1602,1604],{"class":68,"line":69},[66,1603,712],{"class":621},[66,1605,625],{"class":624},[66,1607,1608,1610,1612,1614],{"class":68,"line":75},[66,1609,712],{"class":621},[66,1611,654],{"class":624},[66,1613,658],{"class":657},[66,1615,625],{"class":624},[10,1617,157],{},[56,1619,1622],{"className":1620,"code":1621,"language":163,"meta":61},[161],"Python 3.14.x\npip 版本信息与安装路径\n",[63,1623,1621],{"__ignoreMap":61},[10,1625,168],{},[14,1627,171],{"id":171},[173,1629,1630,1636],{},[40,1631,1632,1635],{},[63,1633,1634],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[40,1637,1638,1640],{},[63,1639,720],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1642,202],{"id":202},[37,1644,1645,1651],{},[40,1646,1647,1648,1650],{},"看到系统已有 ",[63,1649,712],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[40,1652,1653,1654,1656],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[63,1655,712],{},"，不修改系统自带工具。",[14,1658,213],{"id":213},[173,1660,1661,1667],{},[40,1662,959,1663,1666],{},[63,1664,1665],{},"which python3","，记录当前解释器路径。",[40,1668,1669],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1671,224],{},[14,1673,227],{"id":227},[10,1675,1676],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,1678,1679],{},"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":1681},[1682,1683,1684,1685,1686,1687,1688,1689],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1549,"description":1554},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[247,1697,1073],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1700,"title":1701,"body":1702,"category":247,"cover":248,"description":1867,"extension":249,"meta":1868,"navigation":84,"path":1869,"pinned":252,"publishedAt":253,"seo":1870,"slug":1871,"stem":1872,"summary":1873,"tags":1874,"updatedAt":253,"visible":84,"__hash__":1877},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1703,"toc":1857},[1704,1710,1712,1715,1717,1723,1726,1728,1752,1754,1756,1783,1785,1791,1793,1795,1813,1815,1829,1831,1845,1847,1849,1855],[10,1705,1706,1707,1709],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[63,1708,1192],{}," 脚本。",[14,1711,16],{"id":16},[10,1713,1714],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1716,22],{"id":22},[10,1718,1719],{},[26,1720],{"alt":1721,"src":1722},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1724,1725],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1727,35],{"id":35},[37,1729,1730,1739,1746],{},[40,1731,1732,1733,1735,1736,383],{},"在终端输入 ",[63,1734,712],{}," 进入 REPL，提示符通常是 ",[63,1737,1738],{},">>>",[40,1740,1741,1742,1745],{},"输入 ",[63,1743,1744],{},"exit()"," 或按 Control-D 退出 REPL。",[40,1747,1748,1749,1751],{},"需要保存、复查或多次运行的代码应写入 ",[63,1750,1192],{}," 文件。",[14,1753,51],{"id":51},[10,1755,54],{},[56,1757,1761],{"className":1758,"code":1759,"language":1760,"meta":61,"style":61},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[63,1762,1763,1768,1773,1778],{"__ignoreMap":61},[66,1764,1765],{"class":68,"line":69},[66,1766,1767],{},">>> 2 + 3\n",[66,1769,1770],{"class":68,"line":75},[66,1771,1772],{},"5\n",[66,1774,1775],{"class":68,"line":81},[66,1776,1777],{},">>> \"python\".upper()\n",[66,1779,1780],{"class":68,"line":88},[66,1781,1782],{},"'PYTHON'\n",[10,1784,157],{},[56,1786,1789],{"className":1787,"code":1788,"language":163,"meta":61},[161],"REPL 会直接显示表达式结果\n",[63,1790,1788],{"__ignoreMap":61},[10,1792,168],{},[14,1794,171],{"id":171},[173,1796,1797,1807],{},[40,1798,1799,1800,1803,1804,383],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[63,1801,1802],{},"2 + 3"," 能直接看到 ",[63,1805,1806],{},"5",[40,1808,1809,1810,1812],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[63,1811,1494],{}," 才会写到标准输出。",[14,1814,202],{"id":202},[37,1816,1817,1826],{},[40,1818,1819,1820,1822,1823,1825],{},"把提示符 ",[63,1821,1738],{}," 复制进 ",[63,1824,1192],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[40,1827,1828],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1830,213],{"id":213},[173,1832,1833,1839],{},[40,1834,1835,1836,383],{},"在 REPL 计算 ",[63,1837,1838],{},"12 * 8",[40,1840,1841,1842,1844],{},"把同一表达式写入脚本；观察脚本中不调用 ",[63,1843,1494],{}," 时是否显示结果。",[10,1846,224],{},[14,1848,227],{"id":227},[10,1850,1851,1852,1854],{},"本篇目标是根据任务选择 REPL 或 ",[63,1853,1192],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,1856,234],{},{"title":61,"searchDepth":75,"depth":75,"links":1858},[1859,1860,1861,1862,1863,1864,1865,1866],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1701,"description":1867},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[247,1875,1876],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1879,"title":1880,"body":1881,"category":247,"cover":248,"description":1885,"extension":249,"meta":2056,"navigation":84,"path":2057,"pinned":252,"publishedAt":253,"seo":2058,"slug":2059,"stem":2060,"summary":2061,"tags":2062,"updatedAt":253,"visible":84,"__hash__":2065},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1882,"toc":2046},[1883,1886,1888,1891,1893,1899,1905,1907,1925,1927,1929,1974,1976,1982,1984,1986,2008,2010,2022,2024,2036,2038,2040,2043],[10,1884,1885],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1887,16],{"id":16},[10,1889,1890],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1892,22],{"id":22},[10,1894,1895],{},[26,1896],{"alt":1897,"src":1898},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1900,1901,1904],{},[63,1902,1903],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1906,35],{"id":35},[37,1908,1909,1912,1922],{},[40,1910,1911],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[40,1913,1914,1917,1918,1921],{},[63,1915,1916],{},"pwd"," 显示当前目录，",[63,1919,1920],{},"ls"," 显示目录里的文件。",[40,1923,1924],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1926,51],{"id":51},[10,1928,1595],{},[56,1930,1932],{"className":612,"code":1931,"language":614,"meta":61,"style":61},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[63,1933,1934,1942,1949,1954,1968],{"__ignoreMap":61},[66,1935,1936,1939],{"class":68,"line":69},[66,1937,1938],{"class":621},"mkdir",[66,1940,1941],{"class":657}," python-study\n",[66,1943,1944,1947],{"class":68,"line":75},[66,1945,1946],{"class":624},"cd",[66,1948,1941],{"class":657},[66,1950,1951],{"class":68,"line":81},[66,1952,1953],{"class":624},"pwd\n",[66,1955,1956,1959,1962,1966],{"class":68,"line":88},[66,1957,1958],{"class":624},"printf",[66,1960,1961],{"class":657}," 'print(\"项目已经运行\")\\n'",[66,1963,1965],{"class":1964},"snl16"," >",[66,1967,1236],{"class":657},[66,1969,1970,1972],{"class":68,"line":94},[66,1971,712],{"class":621},[66,1973,1236],{"class":657},[10,1975,157],{},[56,1977,1980],{"className":1978,"code":1979,"language":163,"meta":61},[161],"项目已经运行\n",[63,1981,1979],{"__ignoreMap":61},[10,1983,168],{},[14,1985,171],{"id":171},[173,1987,1988,1999],{},[40,1989,1990,1992,1993,1995,1996,1998],{},[63,1991,1938],{}," 创建目录，",[63,1994,1946],{}," 改变终端当前目录，",[63,1997,1916],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[40,2000,2001,2003,2004,2007],{},[63,2002,1903],{}," 会在当前目录寻找 ",[63,2005,2006],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,2009,202],{"id":202},[37,2011,2012,2019],{},[40,2013,2014,2015,1178,2017,383],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[63,2016,1916],{},[63,2018,1920],{},[40,2020,2021],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2023,213],{"id":213},[173,2025,2026,2033],{},[40,2027,2028,2029,2032],{},"新建 ",[63,2030,2031],{},"lesson01.py"," 并输出课程编号。",[40,2034,2035],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2037,224],{},[14,2039,227],{"id":227},[10,2041,2042],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,2044,2045],{},"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":2047},[2048,2049,2050,2051,2052,2053,2054,2055],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1880,"description":1885},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[247,2063,2064],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2067,"title":2068,"body":2069,"category":247,"cover":248,"description":2073,"extension":249,"meta":2221,"navigation":84,"path":2222,"pinned":252,"publishedAt":253,"seo":2223,"slug":2224,"stem":2225,"summary":2226,"tags":2227,"updatedAt":253,"visible":84,"__hash__":2230},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2070,"toc":2211},[2071,2074,2076,2079,2081,2087,2098,2100,2120,2122,2124,2144,2146,2152,2154,2156,2175,2177,2185,2187,2202,2204,2206,2209],[10,2072,2073],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2075,16],{"id":16},[10,2077,2078],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2080,22],{"id":22},[10,2082,2083],{},[26,2084],{"alt":2085,"src":2086},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2088,2089,2090,383,2092,2095,2096,383],{},"Python 先计算表达式，再把得到的对象交给 ",[63,2091,1494],{},[63,2093,2094],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[63,2097,1802],{},[14,2099,35],{"id":35},[37,2101,2102,2108,2117],{},[40,2103,2104,2107],{},[63,2105,2106],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[40,2109,2110,2113,2114,383],{},[63,2111,2112],{},"7 + 5"," 是表达式，运行时先求值得到 ",[63,2115,2116],{},"12",[40,2118,2119],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2121,51],{"id":51},[10,2123,54],{},[56,2125,2127],{"className":58,"code":2126,"language":60,"meta":61,"style":61},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[63,2128,2129,2134,2139],{"__ignoreMap":61},[66,2130,2131],{"class":68,"line":69},[66,2132,2133],{},"print(42)\n",[66,2135,2136],{"class":68,"line":75},[66,2137,2138],{},"print(7 + 5)\n",[66,2140,2141],{"class":68,"line":81},[66,2142,2143],{},"print(\"Python 基础课\")\n",[10,2145,157],{},[56,2147,2150],{"className":2148,"code":2149,"language":163,"meta":61},[161],"42\n12\nPython 基础课\n",[63,2151,2149],{"__ignoreMap":61},[10,2153,168],{},[14,2155,171],{"id":171},[173,2157,2158,2166],{},[40,2159,2160,2163,2164,383],{},[63,2161,2162],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[63,2165,2116],{},[40,2167,2168,2170,2171,2174],{},[63,2169,1494],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[63,2172,2173],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2176,202],{"id":202},[37,2178,2179,2182],{},[40,2180,2181],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[40,2183,2184],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2186,213],{"id":213},[173,2188,2189,2192],{},[40,2190,2191],{},"分别输出一个整数、一个小数和一段文本。",[40,2193,2194,2195,2197,2198,2201],{},"比较 ",[63,2196,2094],{}," 与 ",[63,2199,2200],{},"print(\"2 + 3\")"," 的结果。",[10,2203,224],{},[14,2205,227],{"id":227},[10,2207,2208],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,2210,234],{},{"title":61,"searchDepth":75,"depth":75,"links":2212},[2213,2214,2215,2216,2217,2218,2219,2220],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2068,"description":2073},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[247,2228,2229],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2232,"title":2233,"body":2234,"category":247,"cover":248,"description":2238,"extension":249,"meta":2405,"navigation":84,"path":2406,"pinned":252,"publishedAt":253,"seo":2407,"slug":2408,"stem":2409,"summary":2410,"tags":2411,"updatedAt":253,"visible":84,"__hash__":2414},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2235,"toc":2395},[2236,2239,2241,2244,2246,2252,2255,2257,2283,2285,2287,2315,2317,2323,2325,2327,2351,2353,2369,2371,2386,2388,2390,2393],[10,2237,2238],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2240,16],{"id":16},[10,2242,2243],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2245,22],{"id":22},[10,2247,2248],{},[26,2249],{"alt":2250,"src":2251},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2253,2254],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2256,35],{"id":35},[37,2258,2259,2262,2272],{},[40,2260,2261],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[40,2263,2264,2265,2197,2268,2271],{},"变量名区分大小写，",[63,2266,2267],{},"score",[63,2269,2270],{},"Score"," 是两个名字。",[40,2273,2274,2275,2278,2279,2282],{},"使用能表达含义的名称；不要用 ",[63,2276,2277],{},"list","、",[63,2280,2281],{},"str"," 等内置名称作为普通变量名。",[14,2284,51],{"id":51},[10,2286,54],{},[56,2288,2290],{"className":58,"code":2289,"language":60,"meta":61,"style":61},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[63,2291,2292,2297,2302,2306,2311],{"__ignoreMap":61},[66,2293,2294],{"class":68,"line":69},[66,2295,2296],{},"score = 90\n",[66,2298,2299],{"class":68,"line":75},[66,2300,2301],{},"print(score)\n",[66,2303,2304],{"class":68,"line":81},[66,2305,85],{"emptyLinePlaceholder":84},[66,2307,2308],{"class":68,"line":88},[66,2309,2310],{},"score = 95\n",[66,2312,2313],{"class":68,"line":94},[66,2314,2301],{},[10,2316,157],{},[56,2318,2321],{"className":2319,"code":2320,"language":163,"meta":61},[161],"90\n95\n",[63,2322,2320],{"__ignoreMap":61},[10,2324,168],{},[14,2326,171],{"id":171},[173,2328,2329,2338],{},[40,2330,959,2331,2334,2335,2337],{},[63,2332,2333],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[63,2336,2267],{}," 再绑定到它。",[40,2339,959,2340,2343,2344,2347,2348,383],{},[63,2341,2342],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[63,2345,2346],{},"90"," 没有被改造成 ",[63,2349,2350],{},"95",[14,2352,202],{"id":202},[37,2354,2355,2358],{},[40,2356,2357],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[40,2359,2360,2361,2278,2363,2278,2365,2368],{},"使用 ",[63,2362,2277],{},[63,2364,2281],{},[63,2366,2367],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2370,213],{"id":213},[173,2372,2373,2383],{},[40,2374,2375,2376,1178,2379,2382],{},"创建 ",[63,2377,2378],{},"course_name",[63,2380,2381],{},"lesson_count"," 两个变量并输出。",[40,2384,2385],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2387,224],{},[14,2389,227],{"id":227},[10,2391,2392],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,2394,234],{},{"title":61,"searchDepth":75,"depth":75,"links":2396},[2397,2398,2399,2400,2401,2402,2403,2404],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2233,"description":2238},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[247,2412,2413],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2416,"title":2417,"body":2418,"category":247,"cover":248,"description":2422,"extension":249,"meta":2586,"navigation":84,"path":2587,"pinned":252,"publishedAt":253,"seo":2588,"slug":2589,"stem":2590,"summary":2591,"tags":2592,"updatedAt":253,"visible":84,"__hash__":2595},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2419,"toc":2576},[2420,2423,2425,2428,2430,2436,2439,2441,2470,2472,2474,2518,2520,2526,2528,2530,2544,2546,2557,2559,2567,2569,2571,2574],[10,2421,2422],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2424,16],{"id":16},[10,2426,2427],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2429,22],{"id":22},[10,2431,2432],{},[26,2433],{"alt":2434,"src":2435},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2437,2438],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2440,35],{"id":35},[37,2442,2443,2453,2467],{},[40,2444,2445,2448,2449,2452],{},[63,2446,2447],{},"int"," 表示整数，",[63,2450,2451],{},"float"," 表示浮点数。",[40,2454,2455,2458,2459,2462,2463,2466],{},[63,2456,2457],{},"\u002F"," 总是进行真除法；",[63,2460,2461],{},"\u002F\u002F"," 是向下取整除法，",[63,2464,2465],{},"%"," 得到余数。",[40,2468,2469],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2471,51],{"id":51},[10,2473,54],{},[56,2475,2477],{"className":58,"code":2476,"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,2478,2479,2484,2489,2494,2498,2503,2508,2513],{"__ignoreMap":61},[66,2480,2481],{"class":68,"line":69},[66,2482,2483],{},"price = 25\n",[66,2485,2486],{"class":68,"line":75},[66,2487,2488],{},"count = 4\n",[66,2490,2491],{"class":68,"line":81},[66,2492,2493],{},"discount = 0.9\n",[66,2495,2496],{"class":68,"line":88},[66,2497,85],{"emptyLinePlaceholder":84},[66,2499,2500],{"class":68,"line":94},[66,2501,2502],{},"total = price * count * discount\n",[66,2504,2505],{"class":68,"line":99},[66,2506,2507],{},"average = total \u002F count\n",[66,2509,2510],{"class":68,"line":105},[66,2511,2512],{},"print(total)\n",[66,2514,2515],{"class":68,"line":111},[66,2516,2517],{},"print(average)\n",[10,2519,157],{},[56,2521,2524],{"className":2522,"code":2523,"language":163,"meta":61},[161],"90.0\n22.5\n",[63,2525,2523],{"__ignoreMap":61},[10,2527,168],{},[14,2529,171],{"id":171},[173,2531,2532,2538],{},[40,2533,2534,2537],{},[63,2535,2536],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[40,2539,2540,2543],{},[63,2541,2542],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2545,202],{"id":202},[37,2547,2548,2554],{},[40,2549,2550,2551,383],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[63,2552,2553],{},"decimal.Decimal",[40,2555,2556],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2558,213],{"id":213},[173,2560,2561,2564],{},[40,2562,2563],{},"计算 137 除以 10 的商和余数。",[40,2565,2566],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2568,224],{},[14,2570,227],{"id":227},[10,2572,2573],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,2575,234],{},{"title":61,"searchDepth":75,"depth":75,"links":2577},[2578,2579,2580,2581,2582,2583,2584,2585],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2417,"description":2422},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[247,2593,2594],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2597,"title":2598,"body":2599,"category":247,"cover":248,"description":2603,"extension":249,"meta":2778,"navigation":84,"path":2779,"pinned":252,"publishedAt":253,"seo":2780,"slug":2781,"stem":2782,"summary":2783,"tags":2784,"updatedAt":253,"visible":84,"__hash__":2787},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2600,"toc":2766},[2601,2604,2606,2609,2611,2617,2627,2629,2640,2642,2644,2674,2676,2682,2684,2686,2716,2718,2721,2727,2730,2732,2740,2742,2757,2759,2761,2764],[10,2602,2603],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2605,16],{"id":16},[10,2607,2608],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2610,22],{"id":22},[10,2612,2613],{},[26,2614],{"alt":2615,"src":2616},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2618,2619,2620,2623,2624,383],{},"切片 ",[63,2621,2622],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[63,2625,2626],{},"stop - start",[14,2628,35],{"id":35},[37,2630,2631,2634,2637],{},[40,2632,2633],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[40,2635,2636],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[40,2638,2639],{},"切片会创建新的字符串，不会修改原字符串。",[14,2641,51],{"id":51},[10,2643,54],{},[56,2645,2647],{"className":58,"code":2646,"language":60,"meta":61,"style":61},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[63,2648,2649,2654,2659,2664,2669],{"__ignoreMap":61},[66,2650,2651],{"class":68,"line":69},[66,2652,2653],{},"language = \"Python\"\n",[66,2655,2656],{"class":68,"line":75},[66,2657,2658],{},"print(language[0])\n",[66,2660,2661],{"class":68,"line":81},[66,2662,2663],{},"print(language[-1])\n",[66,2665,2666],{"class":68,"line":88},[66,2667,2668],{},"print(language[0:3])\n",[66,2670,2671],{"class":68,"line":94},[66,2672,2673],{},"print(language + \" 3.14\")\n",[10,2675,157],{},[56,2677,2680],{"className":2678,"code":2679,"language":163,"meta":61},[161],"P\nn\nPyt\nPython 3.14\n",[63,2681,2679],{"__ignoreMap":61},[10,2683,168],{},[14,2685,171],{"id":171},[173,2687,2688,2702],{},[40,2689,2690,2691,2693,2694,2697,2698,2701],{},"字符串 ",[63,2692,247],{}," 的正索引从 ",[63,2695,2696],{},"P"," 的 0 开始，负索引从末尾 ",[63,2699,2700],{},"n"," 的 -1 开始。",[40,2703,2704,2707,2708,2711,2712,2715],{},[63,2705,2706],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[63,2709,2710],{},"Pyt","；索引 3 的 ",[63,2713,2714],{},"h"," 不在结果中。",[185,2717,187],{"id":187},[10,2719,2720],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2722,2723],{},[26,2724],{"alt":2725,"src":2726},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2728,2729],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2731,202],{"id":202},[37,2733,2734,2737],{},[40,2735,2736],{},"把第一个字符写成索引 1，造成整体偏移一位。",[40,2738,2739],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2741,213],{"id":213},[173,2743,2744,2754],{},[40,2745,2746,2747,2750,2751,383],{},"从 ",[63,2748,2749],{},"\"programming\""," 中切出 ",[63,2752,2753],{},"\"gram\"",[40,2755,2756],{},"使用负索引取得字符串倒数第二个字符。",[10,2758,224],{},[14,2760,227],{"id":227},[10,2762,2763],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,2765,234],{},{"title":61,"searchDepth":75,"depth":75,"links":2767},[2768,2769,2770,2771,2772,2775,2776,2777],{"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":171,"depth":75,"text":171,"children":2773},[2774],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2598,"description":2603},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[247,2785,2786],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2789,"title":2790,"body":2791,"category":247,"cover":248,"description":2795,"extension":249,"meta":3009,"navigation":84,"path":3010,"pinned":252,"publishedAt":253,"seo":3011,"slug":3012,"stem":3013,"summary":3014,"tags":3015,"updatedAt":253,"visible":84,"__hash__":3018},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2792,"toc":2997},[2793,2796,2798,2801,2803,2809,2819,2821,2854,2856,2858,2902,2904,2910,2912,2914,2935,2937,2940,2946,2954,2956,2970,2972,2988,2990,2992,2995],[10,2794,2795],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2797,16],{"id":16},[10,2799,2800],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2802,22],{"id":22},[10,2804,2805],{},[26,2806],{"alt":2807,"src":2808},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2810,2811,2812,1030,2815,2818],{},"比较表达式先产生 ",[63,2813,2814],{},"True",[63,2816,2817],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2820,35],{"id":35},[37,2822,2823,2837,2851],{},[40,2824,2825,2828,2829,2832,2833,2836],{},[63,2826,2827],{},"=="," 判断是否相等，",[63,2830,2831],{},"!="," 判断是否不等；单个 ",[63,2834,2835],{},"="," 是赋值。",[40,2838,2839,2842,2843,2846,2847,2850],{},[63,2840,2841],{},"and"," 要求两侧都为真，",[63,2844,2845],{},"or"," 只需一侧为真，",[63,2848,2849],{},"not"," 取反。",[40,2852,2853],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2855,51],{"id":51},[10,2857,54],{},[56,2859,2861],{"className":58,"code":2860,"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,2862,2863,2868,2873,2877,2882,2887,2892,2897],{"__ignoreMap":61},[66,2864,2865],{"class":68,"line":69},[66,2866,2867],{},"age = 20\n",[66,2869,2870],{"class":68,"line":75},[66,2871,2872],{},"has_ticket = True\n",[66,2874,2875],{"class":68,"line":81},[66,2876,85],{"emptyLinePlaceholder":84},[66,2878,2879],{"class":68,"line":88},[66,2880,2881],{},"is_adult = age >= 18\n",[66,2883,2884],{"class":68,"line":94},[66,2885,2886],{},"can_enter = is_adult and has_ticket\n",[66,2888,2889],{"class":68,"line":99},[66,2890,2891],{},"print(is_adult)\n",[66,2893,2894],{"class":68,"line":105},[66,2895,2896],{},"print(can_enter)\n",[66,2898,2899],{"class":68,"line":111},[66,2900,2901],{},"print(not has_ticket)\n",[10,2903,157],{},[56,2905,2908],{"className":2906,"code":2907,"language":163,"meta":61},[161],"True\nTrue\nFalse\n",[63,2909,2907],{"__ignoreMap":61},[10,2911,168],{},[14,2913,171],{"id":171},[173,2915,2916,2926],{},[40,2917,2918,2921,2922,2925],{},[63,2919,2920],{},"age >= 18"," 先产生布尔值并绑定给 ",[63,2923,2924],{},"is_adult","，这一步没有任何分支跳转。",[40,2927,2928,2931,2932,2934],{},[63,2929,2930],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[63,2933,2849],{}," 只对紧随其后的值取反。",[185,2936,187],{"id":187},[10,2938,2939],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2941,2942],{},[26,2943],{"alt":2944,"src":2945},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2947,2948,2950,2951,2953],{},[63,2949,2841],{}," 只有“真、真”得到真；",[63,2952,2845],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2955,202],{"id":202},[37,2957,2958,2967],{},[40,2959,2960,2961,2963,2964,2966],{},"用单个等号判断相等。",[63,2962,2835],{}," 是赋值，",[63,2965,2827],{}," 才是相等比较。",[40,2968,2969],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,2971,213],{"id":213},[173,2973,2974,2981],{},[40,2975,2976,2977,2980],{},"判断数字 ",[63,2978,2979],{},"15"," 是否同时大于 10 且小于 20。",[40,2982,2983,2984,2987],{},"分别修改年龄和票据状态，记录 ",[63,2985,2986],{},"can_enter"," 的四种组合结果。",[10,2989,224],{},[14,2991,227],{"id":227},[10,2993,2994],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,2996,234],{},{"title":61,"searchDepth":75,"depth":75,"links":2998},[2999,3000,3001,3002,3003,3006,3007,3008],{"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":171,"depth":75,"text":171,"children":3004},[3005],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2790,"description":2795},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[247,3016,3017],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3020,"title":3021,"body":3022,"category":247,"cover":248,"description":3026,"extension":249,"meta":3194,"navigation":84,"path":3195,"pinned":252,"publishedAt":253,"seo":3196,"slug":3197,"stem":3198,"summary":3199,"tags":3200,"updatedAt":253,"visible":84,"__hash__":3202},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3023,"toc":3184},[3024,3027,3029,3032,3034,3040,3058,3060,3073,3075,3077,3111,3113,3119,3121,3123,3145,3147,3159,3161,3175,3177,3179,3182],[10,3025,3026],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3028,16],{"id":16},[10,3030,3031],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3033,22],{"id":22},[10,3035,3036],{},[26,3037],{"alt":3038,"src":3039},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3041,3042,3045,3046,3049,3050,3053,3054,3057],{},[63,3043,3044],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[63,3047,3048],{},"18","，程序首先得到的也是 ",[63,3051,3052],{},"\"18\"","，需要 ",[63,3055,3056],{},"int()"," 后才能按整数参与计算。",[14,3059,35],{"id":35},[37,3061,3062,3065,3070],{},[40,3063,3064],{},"提示文字应告诉用户需要输入什么。",[40,3066,3067,3069],{},[63,3068,3056],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[40,3071,3072],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3074,51],{"id":51},[10,3076,54],{},[56,3078,3080],{"className":58,"code":3079,"language":60,"meta":61,"style":61},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[63,3081,3082,3087,3092,3097,3101,3106],{"__ignoreMap":61},[66,3083,3084],{"class":68,"line":69},[66,3085,3086],{},"name = input(\"请输入姓名：\")\n",[66,3088,3089],{"class":68,"line":75},[66,3090,3091],{},"age_text = input(\"请输入年龄：\")\n",[66,3093,3094],{"class":68,"line":81},[66,3095,3096],{},"age = int(age_text)\n",[66,3098,3099],{"class":68,"line":88},[66,3100,85],{"emptyLinePlaceholder":84},[66,3102,3103],{"class":68,"line":94},[66,3104,3105],{},"print(\"你好，\" + name)\n",[66,3107,3108],{"class":68,"line":99},[66,3109,3110],{},"print(age + 1)\n",[10,3112,157],{},[56,3114,3117],{"className":3115,"code":3116,"language":163,"meta":61},[161],"根据输入显示姓名，并输出下一年的年龄\n",[63,3118,3116],{"__ignoreMap":61},[10,3120,168],{},[14,3122,171],{"id":171},[173,3124,3125,3135],{},[40,3126,3127,3128,3130,3131,3134],{},"两次 ",[63,3129,3044],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[63,3132,3133],{},"age_text"," 用来提醒这仍是文本。",[40,3136,3137,3140,3141,3144],{},[63,3138,3139],{},"int(age_text)"," 创建整数对象，后面的 ",[63,3142,3143],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3146,202],{"id":202},[37,3148,3149,3156],{},[40,3150,3151,3152,3155],{},"直接计算 ",[63,3153,3154],{},"input(...) + 1","，忽略输入结果是字符串。",[40,3157,3158],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3160,213],{"id":213},[173,3162,3163,3166],{},[40,3164,3165],{},"接收两个整数并输出它们的和。",[40,3167,1741,3168,3171,3172,3174],{},[63,3169,3170],{},"18.5"," 给 ",[63,3173,3056],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3176,224],{},[14,3178,227],{"id":227},[10,3180,3181],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,3183,234],{},{"title":61,"searchDepth":75,"depth":75,"links":3185},[3186,3187,3188,3189,3190,3191,3192,3193],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3021,"description":3026},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[247,2367,3201],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3204,"title":3205,"body":3206,"category":247,"cover":248,"description":3210,"extension":249,"meta":3370,"navigation":84,"path":3371,"pinned":252,"publishedAt":253,"seo":3372,"slug":3373,"stem":3374,"summary":3375,"tags":3376,"updatedAt":253,"visible":84,"__hash__":3379},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3207,"toc":3360},[3208,3211,3213,3216,3218,3224,3231,3233,3247,3249,3251,3290,3292,3298,3300,3302,3321,3323,3338,3340,3351,3353,3355,3358],[10,3209,3210],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3212,16],{"id":16},[10,3214,3215],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3217,22],{"id":22},[10,3219,3220],{},[26,3221],{"alt":3222,"src":3223},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3225,3226,3227,3230],{},"列表为元素维护从 0 开始的位置索引。修改 ",[63,3228,3229],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3232,35],{"id":35},[37,3234,3235,3238,3241],{},[40,3236,3237],{},"列表使用方括号，元素之间用逗号分隔。",[40,3239,3240],{},"列表可变，可以替换、追加和删除元素。",[40,3242,3243,3244,383],{},"访问不存在的索引会产生 ",[63,3245,3246],{},"IndexError",[14,3248,51],{"id":51},[10,3250,54],{},[56,3252,3254],{"className":58,"code":3253,"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,3255,3256,3261,3266,3270,3275,3280,3285],{"__ignoreMap":61},[66,3257,3258],{"class":68,"line":69},[66,3259,3260],{},"scores = [82, 90, 76]\n",[66,3262,3263],{"class":68,"line":75},[66,3264,3265],{},"print(scores[0])\n",[66,3267,3268],{"class":68,"line":81},[66,3269,85],{"emptyLinePlaceholder":84},[66,3271,3272],{"class":68,"line":88},[66,3273,3274],{},"scores[1] = 95\n",[66,3276,3277],{"class":68,"line":94},[66,3278,3279],{},"scores.append(88)\n",[66,3281,3282],{"class":68,"line":99},[66,3283,3284],{},"print(scores)\n",[66,3286,3287],{"class":68,"line":105},[66,3288,3289],{},"print(len(scores))\n",[10,3291,157],{},[56,3293,3296],{"className":3294,"code":3295,"language":163,"meta":61},[161],"82\n[82, 95, 76, 88]\n4\n",[63,3297,3295],{"__ignoreMap":61},[10,3299,168],{},[14,3301,171],{"id":171},[173,3303,3304,3307],{},[40,3305,3306],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[40,3308,3309,3312,3313,3316,3317,3320],{},[63,3310,3311],{},"scores[1] = 95"," 替换第二个位置，",[63,3314,3315],{},"append(88)"," 在末尾增加新位置，",[63,3318,3319],{},"len()"," 因而从 3 变为 4。",[14,3322,202],{"id":202},[37,3324,3325,3335],{},[40,3326,3327,3328,3331,3332,383],{},"访问 ",[63,3329,3330],{},"scores[len(scores)]","。最后一个合法正索引是 ",[63,3333,3334],{},"len(scores) - 1",[40,3336,3337],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3339,213],{"id":213},[173,3341,3342,3345],{},[40,3343,3344],{},"建立三项学习任务列表，再追加第四项。",[40,3346,3347,3348,3350],{},"修改第二项，并用 ",[63,3349,3319],{}," 检查元素数量。",[10,3352,224],{},[14,3354,227],{"id":227},[10,3356,3357],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,3359,234],{},{"title":61,"searchDepth":75,"depth":75,"links":3361},[3362,3363,3364,3365,3366,3367,3368,3369],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3205,"description":3210},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[247,3377,3378],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3381,"title":3382,"body":3383,"category":247,"cover":248,"description":3387,"extension":249,"meta":3528,"navigation":84,"path":3529,"pinned":252,"publishedAt":253,"seo":3530,"slug":3531,"stem":3532,"summary":3533,"tags":3534,"updatedAt":253,"visible":84,"__hash__":3536},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3384,"toc":3518},[3385,3388,3390,3393,3395,3401,3404,3406,3417,3419,3421,3455,3457,3463,3465,3467,3481,3483,3495,3497,3509,3511,3513,3516],[10,3386,3387],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3389,16],{"id":16},[10,3391,3392],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3394,22],{"id":22},[10,3396,3397],{},[26,3398],{"alt":3399,"src":3400},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3402,3403],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3405,35],{"id":35},[37,3407,3408,3411,3414],{},[40,3409,3410],{},"元组常用来表达固定数量、固定含义的一组值。",[40,3412,3413],{},"只有一个元素的元组必须保留尾随逗号。",[40,3415,3416],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3418,51],{"id":51},[10,3420,54],{},[56,3422,3424],{"className":58,"code":3423,"language":60,"meta":61,"style":61},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[63,3425,3426,3431,3436,3441,3445,3450],{"__ignoreMap":61},[66,3427,3428],{"class":68,"line":69},[66,3429,3430],{},"point = (120, 80)\n",[66,3432,3433],{"class":68,"line":75},[66,3434,3435],{},"print(point[0])\n",[66,3437,3438],{"class":68,"line":81},[66,3439,3440],{},"print(point[1])\n",[66,3442,3443],{"class":68,"line":88},[66,3444,85],{"emptyLinePlaceholder":84},[66,3446,3447],{"class":68,"line":94},[66,3448,3449],{},"single = (5,)\n",[66,3451,3452],{"class":68,"line":99},[66,3453,3454],{},"print(single)\n",[10,3456,157],{},[56,3458,3461],{"className":3459,"code":3460,"language":163,"meta":61},[161],"120\n80\n(5,)\n",[63,3462,3460],{"__ignoreMap":61},[10,3464,168],{},[14,3466,171],{"id":171},[173,3468,3469,3475],{},[40,3470,3471,3474],{},[63,3472,3473],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[40,3476,3477,3480],{},[63,3478,3479],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3482,202],{"id":202},[37,3484,3485,3492],{},[40,3486,3487,3488,3491],{},"把 ",[63,3489,3490],{},"(5)"," 当作元组，实际它仍是整数。",[40,3493,3494],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3496,213],{"id":213},[173,3498,3499,3502],{},[40,3500,3501],{},"用元组表示宽度和高度。",[40,3503,2194,3504,2197,3506,3508],{},[63,3505,3490],{},[63,3507,3479],{}," 的类型。",[10,3510,224],{},[14,3512,227],{"id":227},[10,3514,3515],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,3517,234],{},{"title":61,"searchDepth":75,"depth":75,"links":3519},[3520,3521,3522,3523,3524,3525,3526,3527],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3382,"description":3387},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[247,3535,3378],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3538,"title":3539,"body":3540,"category":247,"cover":248,"description":3544,"extension":249,"meta":3699,"navigation":84,"path":3700,"pinned":252,"publishedAt":253,"seo":3701,"slug":3702,"stem":3703,"summary":3704,"tags":3705,"updatedAt":253,"visible":84,"__hash__":3707},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3541,"toc":3689},[3542,3545,3547,3550,3552,3558,3568,3570,3584,3586,3588,3622,3624,3630,3632,3634,3649,3651,3670,3672,3680,3682,3684,3687],[10,3543,3544],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3546,16],{"id":16},[10,3548,3549],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3551,22],{"id":22},[10,3553,3554],{},[26,3555],{"alt":3556,"src":3557},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3559,3560,3561,3564,3565,3567],{},"字典通过键定位值，不使用连续位置表达含义。",[63,3562,3563],{},"student[\"score\"]"," 读取的是键 ",[63,3566,2267],{}," 对应的值，而不是“第几个元素”。",[14,3569,35],{"id":35},[37,3571,3572,3575,3581],{},[40,3573,3574],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[40,3576,2360,3577,3580],{},[63,3578,3579],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[40,3582,3583],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3585,51],{"id":51},[10,3587,54],{},[56,3589,3591],{"className":58,"code":3590,"language":60,"meta":61,"style":61},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[63,3592,3593,3598,3603,3607,3612,3617],{"__ignoreMap":61},[66,3594,3595],{"class":68,"line":69},[66,3596,3597],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[66,3599,3600],{"class":68,"line":75},[66,3601,3602],{},"print(student[\"name\"])\n",[66,3604,3605],{"class":68,"line":81},[66,3606,85],{"emptyLinePlaceholder":84},[66,3608,3609],{"class":68,"line":88},[66,3610,3611],{},"student[\"score\"] = 95\n",[66,3613,3614],{"class":68,"line":94},[66,3615,3616],{},"student[\"city\"] = \"郑州\"\n",[66,3618,3619],{"class":68,"line":99},[66,3620,3621],{},"print(student)\n",[10,3623,157],{},[56,3625,3628],{"className":3626,"code":3627,"language":163,"meta":61},[161],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[63,3629,3627],{"__ignoreMap":61},[10,3631,168],{},[14,3633,171],{"id":171},[173,3635,3636,3639],{},[40,3637,3638],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[40,3640,3641,3642,3644,3645,3648],{},"给已有键 ",[63,3643,2267],{}," 赋值会更新映射，给新键 ",[63,3646,3647],{},"city"," 赋值会增加映射。",[14,3650,202],{"id":202},[37,3652,3653,3660],{},[40,3654,3655,3656,3659],{},"按位置理解字典并尝试 ",[63,3657,3658],{},"student[0]","，而实际键是字符串。",[40,3661,3662,3663,3666,3667,383],{},"直接读取不确定存在的键并忽略 ",[63,3664,3665],{},"KeyError","；后续可根据场景使用成员检查或 ",[63,3668,3669],{},"get()",[14,3671,213],{"id":213},[173,3673,3674,3677],{},[40,3675,3676],{},"建立一本书的标题、作者和页数字典。",[40,3678,3679],{},"添加分类键，再修改页数。",[10,3681,224],{},[14,3683,227],{"id":227},[10,3685,3686],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,3688,234],{},{"title":61,"searchDepth":75,"depth":75,"links":3690},[3691,3692,3693,3694,3695,3696,3697,3698],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3539,"description":3544},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[247,3706,3378],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3709,"title":3710,"body":3711,"category":247,"cover":248,"description":3715,"extension":249,"meta":3864,"navigation":84,"path":3865,"pinned":252,"publishedAt":253,"seo":3866,"slug":3867,"stem":3868,"summary":3869,"tags":3870,"updatedAt":253,"visible":84,"__hash__":3872},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3712,"toc":3854},[3713,3716,3718,3721,3723,3729,3732,3734,3753,3755,3757,3791,3793,3799,3801,3803,3818,3820,3832,3834,3845,3847,3849,3852],[10,3714,3715],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3717,16],{"id":16},[10,3719,3720],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3722,22],{"id":22},[10,3724,3725],{},[26,3726],{"alt":3727,"src":3728},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3730,3731],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3733,35],{"id":35},[37,3735,3736,3739,3742],{},[40,3737,3738],{},"集合中的元素不重复。",[40,3740,3741],{},"集合是无序容器，不要依赖打印顺序或索引。",[40,3743,3744,3745,3748,3749,3752],{},"创建空集合必须写 ",[63,3746,3747],{},"set()","；",[63,3750,3751],{},"{}"," 创建的是空字典。",[14,3754,51],{"id":51},[10,3756,54],{},[56,3758,3760],{"className":58,"code":3759,"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,3761,3762,3767,3772,3776,3781,3786],{"__ignoreMap":61},[66,3763,3764],{"class":68,"line":69},[66,3765,3766],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[66,3768,3769],{"class":68,"line":75},[66,3770,3771],{},"right = {\"Python\", \"Docker\"}\n",[66,3773,3774],{"class":68,"line":81},[66,3775,85],{"emptyLinePlaceholder":84},[66,3777,3778],{"class":68,"line":88},[66,3779,3780],{},"print(left & right)\n",[66,3782,3783],{"class":68,"line":94},[66,3784,3785],{},"print(left | right)\n",[66,3787,3788],{"class":68,"line":99},[66,3789,3790],{},"print(\"Git\" in left)\n",[10,3792,157],{},[56,3794,3797],{"className":3795,"code":3796,"language":163,"meta":61},[161],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[63,3798,3796],{"__ignoreMap":61},[10,3800,168],{},[14,3802,171],{"id":171},[173,3804,3805,3808],{},[40,3806,3807],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[40,3809,3810,3813,3814,3817],{},[63,3811,3812],{},"&"," 计算交集，",[63,3815,3816],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3819,202],{"id":202},[37,3821,3822,3829],{},[40,3823,2360,3824,3826,3827,383],{},[63,3825,3751],{}," 创建空集合，实际得到空字典；空集合应写 ",[63,3828,3747],{},[40,3830,3831],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3833,213],{"id":213},[173,3835,3836,3842],{},[40,3837,3838,3839,3841],{},"把包含重复标签的列表交给 ",[63,3840,3747],{}," 去重。",[40,3843,3844],{},"计算两组课程标签的交集和差集。",[10,3846,224],{},[14,3848,227],{"id":227},[10,3850,3851],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,3853,234],{},{"title":61,"searchDepth":75,"depth":75,"links":3855},[3856,3857,3858,3859,3860,3861,3862,3863],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3710,"description":3715},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[247,3871,3378],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3874,"title":3875,"body":3876,"category":247,"cover":248,"description":3880,"extension":249,"meta":4077,"navigation":84,"path":4078,"pinned":252,"publishedAt":253,"seo":4079,"slug":4080,"stem":4081,"summary":4082,"tags":4083,"updatedAt":253,"visible":84,"__hash__":4086},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3877,"toc":4065},[3878,3881,3883,3886,3888,3894,3904,3906,3923,3925,3927,3976,3978,3984,3986,3988,4010,4012,4015,4021,4024,4026,4039,4041,4056,4058,4060,4063],[10,3879,3880],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3882,16],{"id":16},[10,3884,3885],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3887,22],{"id":22},[10,3889,3890],{},[26,3891],{"alt":3892,"src":3893},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3895,3896,3899,3900,3903],{},[63,3897,3898],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[63,3901,3902],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3905,35],{"id":35},[37,3907,3908,3917,3920],{},[40,3909,3910,3912,3913,3916],{},[63,3911,2827],{}," 比较内容是否相等，",[63,3914,3915],{},"is"," 比较是否为同一个对象。",[40,3918,3919],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[40,3921,3922],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3924,51],{"id":51},[10,3926,54],{},[56,3928,3930],{"className":58,"code":3929,"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,3931,3932,3937,3942,3947,3951,3956,3961,3966,3971],{"__ignoreMap":61},[66,3933,3934],{"class":68,"line":69},[66,3935,3936],{},"tasks = [\"变量\", \"字符串\"]\n",[66,3938,3939],{"class":68,"line":75},[66,3940,3941],{},"shared = tasks\n",[66,3943,3944],{"class":68,"line":81},[66,3945,3946],{},"backup = tasks.copy()\n",[66,3948,3949],{"class":68,"line":88},[66,3950,85],{"emptyLinePlaceholder":84},[66,3952,3953],{"class":68,"line":94},[66,3954,3955],{},"tasks.append(\"列表\")\n",[66,3957,3958],{"class":68,"line":99},[66,3959,3960],{},"print(shared)\n",[66,3962,3963],{"class":68,"line":105},[66,3964,3965],{},"print(backup)\n",[66,3967,3968],{"class":68,"line":111},[66,3969,3970],{},"print(tasks is shared)\n",[66,3972,3973],{"class":68,"line":117},[66,3974,3975],{},"print(tasks is backup)\n",[10,3977,157],{},[56,3979,3982],{"className":3980,"code":3981,"language":163,"meta":61},[161],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[63,3983,3981],{"__ignoreMap":61},[10,3985,168],{},[14,3987,171],{"id":171},[173,3989,3990,3996],{},[40,3991,3992,3995],{},[63,3993,3994],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[40,3997,3998,4001,4002,4005,4006,4009],{},[63,3999,4000],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[63,4003,4004],{},"shared"," 能观察到变化，",[63,4007,4008],{},"backup"," 不会。",[185,4011,187],{"id":187},[10,4013,4014],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4016,4017],{},[26,4018],{"alt":4019,"src":4020},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4022,4023],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4025,202],{"id":202},[37,4027,4028,4036],{},[40,4029,4030,4031,4033,4034,383],{},"用 ",[63,4032,2827],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[63,4035,3915],{},[40,4037,4038],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4040,213],{"id":213},[173,4042,4043,4046],{},[40,4044,4045],{},"让两个变量引用同一个字典并修改其中一个。",[40,4047,2360,4048,4051,4052,1178,4054,383],{},[63,4049,4050],{},"copy()"," 创建外层副本，再比较 ",[63,4053,3915],{},[63,4055,2827],{},[10,4057,224],{},[14,4059,227],{"id":227},[10,4061,4062],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,4064,234],{},{"title":61,"searchDepth":75,"depth":75,"links":4066},[4067,4068,4069,4070,4071,4074,4075,4076],{"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":171,"depth":75,"text":171,"children":4072},[4073],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3875,"description":3880},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[247,4084,4085],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4088,"title":4089,"body":4090,"category":247,"cover":248,"description":4094,"extension":249,"meta":4306,"navigation":84,"path":4307,"pinned":252,"publishedAt":253,"seo":4308,"slug":4309,"stem":4310,"summary":4311,"tags":4312,"updatedAt":253,"visible":84,"__hash__":4314},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4091,"toc":4293},[4092,4095,4097,4100,4102,4108,4118,4120,4131,4133,4135,4187,4189,4195,4197,4199,4217,4219,4222,4228,4236,4239,4242,4248,4254,4256,4274,4276,4284,4286,4288,4291],[10,4093,4094],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4096,16],{"id":16},[10,4098,4099],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4101,22],{"id":22},[10,4103,4104],{},[26,4105],{"alt":4106,"src":4107},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4109,4110,2278,4112,2278,4115,4117],{},[63,4111,1177],{},[63,4113,4114],{},"elif",[63,4116,1181],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4119,35],{"id":35},[37,4121,4122,4125,4128],{},[40,4123,4124],{},"冒号表示接下来开始一个代码块。",[40,4126,4127],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[40,4129,4130],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4132,51],{"id":51},[10,4134,54],{},[56,4136,4138],{"className":58,"code":4137,"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,4139,4140,4145,4149,4154,4159,4164,4169,4173,4178,4182],{"__ignoreMap":61},[66,4141,4142],{"class":68,"line":69},[66,4143,4144],{},"score = int(input(\"请输入分数：\"))\n",[66,4146,4147],{"class":68,"line":75},[66,4148,85],{"emptyLinePlaceholder":84},[66,4150,4151],{"class":68,"line":81},[66,4152,4153],{},"if score >= 90:\n",[66,4155,4156],{"class":68,"line":88},[66,4157,4158],{},"    level = \"优秀\"\n",[66,4160,4161],{"class":68,"line":94},[66,4162,4163],{},"elif score >= 60:\n",[66,4165,4166],{"class":68,"line":99},[66,4167,4168],{},"    level = \"合格\"\n",[66,4170,4171],{"class":68,"line":105},[66,4172,1167],{},[66,4174,4175],{"class":68,"line":111},[66,4176,4177],{},"    level = \"需要继续学习\"\n",[66,4179,4180],{"class":68,"line":117},[66,4181,85],{"emptyLinePlaceholder":84},[66,4183,4184],{"class":68,"line":122},[66,4185,4186],{},"print(level)\n",[10,4188,157],{},[56,4190,4193],{"className":4191,"code":4192,"language":163,"meta":61},[161],"输入 85 时输出：合格\n",[63,4194,4192],{"__ignoreMap":61},[10,4196,168],{},[14,4198,171],{"id":171},[173,4200,4201,4208],{},[40,4202,4203,4204,4207],{},"输入先转换为整数，程序从 ",[63,4205,4206],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[40,4209,4210,4213,4214,4216],{},[63,4211,4212],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[63,4215,1181],{}," 被跳过；最终三个分支只会选择一个。",[185,4218,187],{"id":187},[10,4220,4221],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4223,4224],{},[26,4225],{"alt":4226,"src":4227},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4229,4230,4232,4233,4235],{},[63,4231,4206],{}," 必须放在 ",[63,4234,4212],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[185,4237,187],{"id":4238},"再看一个具体细节-1",[10,4240,4241],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4243,4244],{},[26,4245],{"alt":4246,"src":4247},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4249,4250,4251,4253],{},"同一缩进层级属于同一个代码块；回到 ",[63,4252,1177],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4255,202],{"id":202},[37,4257,4258,4264],{},[40,4259,4260,4261,4263],{},"先写 ",[63,4262,4212],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[40,4265,4266,4267,4269,4270,4273],{},"混用多个独立 ",[63,4268,1177],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[63,4271,4272],{},"if\u002Felif\u002Felse"," 链。",[14,4275,213],{"id":213},[173,4277,4278,4281],{},[40,4279,4280],{},"根据温度输出“冷、适中、热”三个等级。",[40,4282,4283],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4285,224],{},[14,4287,227],{"id":227},[10,4289,4290],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,4292,234],{},{"title":61,"searchDepth":75,"depth":75,"links":4294},[4295,4296,4297,4298,4299,4303,4304,4305],{"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":171,"depth":75,"text":171,"children":4300},[4301,4302],{"id":187,"depth":81,"text":187},{"id":4238,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4089,"description":4094},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[247,1177,4313],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4316,"title":4317,"body":4318,"category":247,"cover":248,"description":4322,"extension":249,"meta":4488,"navigation":84,"path":4489,"pinned":252,"publishedAt":253,"seo":4490,"slug":4491,"stem":4492,"summary":4493,"tags":4494,"updatedAt":253,"visible":84,"__hash__":4496},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4319,"toc":4476},[4320,4323,4325,4328,4330,4336,4342,4344,4359,4361,4363,4401,4403,4409,4411,4413,4428,4430,4433,4439,4445,4447,4455,4457,4467,4469,4471,4474],[10,4321,4322],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4324,16],{"id":16},[10,4326,4327],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4329,22],{"id":22},[10,4331,4332],{},[26,4333],{"alt":4334,"src":4335},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4337,4338,4341],{},[63,4339,4340],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4343,35],{"id":35},[37,4345,4346,4349,4352],{},[40,4347,4348],{},"进入循环前先准备参与条件判断的状态。",[40,4350,4351],{},"循环体中必须有机会让条件变为假。",[40,4353,4354,4355,4358],{},"能够预先确定遍历对象时，后续介绍的 ",[63,4356,4357],{},"for"," 通常更直接。",[14,4360,51],{"id":51},[10,4362,54],{},[56,4364,4366],{"className":58,"code":4365,"language":60,"meta":61,"style":61},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[63,4367,4368,4373,4377,4382,4387,4392,4396],{"__ignoreMap":61},[66,4369,4370],{"class":68,"line":69},[66,4371,4372],{},"count = 1\n",[66,4374,4375],{"class":68,"line":75},[66,4376,85],{"emptyLinePlaceholder":84},[66,4378,4379],{"class":68,"line":81},[66,4380,4381],{},"while count \u003C= 3:\n",[66,4383,4384],{"class":68,"line":88},[66,4385,4386],{},"    print(\"第\", count, \"次练习\")\n",[66,4388,4389],{"class":68,"line":94},[66,4390,4391],{},"    count = count + 1\n",[66,4393,4394],{"class":68,"line":99},[66,4395,85],{"emptyLinePlaceholder":84},[66,4397,4398],{"class":68,"line":105},[66,4399,4400],{},"print(\"练习结束\")\n",[10,4402,157],{},[56,4404,4407],{"className":4405,"code":4406,"language":163,"meta":61},[161],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[63,4408,4406],{"__ignoreMap":61},[10,4410,168],{},[14,4412,171],{"id":171},[173,4414,4415,4422],{},[40,4416,4417,4418,4421],{},"进入循环前 ",[63,4419,4420],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[40,4423,4424,4425,4427],{},"循环体末尾把 ",[63,4426,4420],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[185,4429,187],{"id":187},[10,4431,4432],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4434,4435],{},[26,4436],{"alt":4437,"src":4438},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4440,4441,4442,4444],{},"第4次检查时 ",[63,4443,4420],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4446,202],{"id":202},[37,4448,4449,4452],{},[40,4450,4451],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[40,4453,4454],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4456,213],{"id":213},[173,4458,4459,4464],{},[40,4460,2360,4461,4463],{},[63,4462,4340],{}," 输出 1 到 5。",[40,4465,4466],{},"计算 1 到 10 的累加和。",[10,4468,224],{},[14,4470,227],{"id":227},[10,4472,4473],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,4475,234],{},{"title":61,"searchDepth":75,"depth":75,"links":4477},[4478,4479,4480,4481,4482,4485,4486,4487],{"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":171,"depth":75,"text":171,"children":4483},[4484],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4317,"description":4322},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[247,4340,4495],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4498,"title":4499,"body":4500,"category":247,"cover":248,"description":4504,"extension":249,"meta":4652,"navigation":84,"path":4653,"pinned":252,"publishedAt":253,"seo":4654,"slug":4655,"stem":4656,"summary":4657,"tags":4658,"updatedAt":253,"visible":84,"__hash__":4660},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4501,"toc":4642},[4502,4505,4507,4510,4512,4518,4523,4525,4539,4541,4543,4581,4583,4589,4591,4593,4610,4612,4620,4622,4633,4635,4637,4640],[10,4503,4504],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4506,16],{"id":16},[10,4508,4509],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4511,22],{"id":22},[10,4513,4514],{},[26,4515],{"alt":4516,"src":4517},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4519,4520,4522],{},[63,4521,4357],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4524,35],{"id":35},[37,4526,4527,4533,4536],{},[40,4528,4529,4532],{},[63,4530,4531],{},"range(1, 4)"," 包含 1，不包含 4。",[40,4534,4535],{},"只需要元素时直接遍历元素，不必手工维护索引。",[40,4537,4538],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4540,51],{"id":51},[10,4542,54],{},[56,4544,4546],{"className":58,"code":4545,"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,4547,4548,4553,4557,4562,4567,4571,4576],{"__ignoreMap":61},[66,4549,4550],{"class":68,"line":69},[66,4551,4552],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[66,4554,4555],{"class":68,"line":75},[66,4556,85],{"emptyLinePlaceholder":84},[66,4558,4559],{"class":68,"line":81},[66,4560,4561],{},"for course in courses:\n",[66,4563,4564],{"class":68,"line":88},[66,4565,4566],{},"    print(course)\n",[66,4568,4569],{"class":68,"line":94},[66,4570,85],{"emptyLinePlaceholder":84},[66,4572,4573],{"class":68,"line":99},[66,4574,4575],{},"for number in range(1, 4):\n",[66,4577,4578],{"class":68,"line":105},[66,4579,4580],{},"    print(number)\n",[10,4582,157],{},[56,4584,4587],{"className":4585,"code":4586,"language":163,"meta":61},[161],"变量\n字符串\n列表\n1\n2\n3\n",[63,4588,4586],{"__ignoreMap":61},[10,4590,168],{},[14,4592,171],{"id":171},[173,4594,4595,4605],{},[40,4596,4597,4598,4600,4601,4604],{},"第一个 ",[63,4599,4357],{}," 依次从列表取得字符串，循环变量 ",[63,4602,4603],{},"course"," 每轮重新绑定。",[40,4606,4607,4609],{},[63,4608,4531],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4611,202],{"id":202},[37,4613,4614,4617],{},[40,4615,4616],{},"只需要元素却手工维护索引，增加越界风险。",[40,4618,4619],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4621,213],{"id":213},[173,4623,4624,4627],{},[40,4625,4626],{},"逐项输出一个字符串中的字符。",[40,4628,2360,4629,4632],{},[63,4630,4631],{},"range()"," 输出 2、4、6、8。",[10,4634,224],{},[14,4636,227],{"id":227},[10,4638,4639],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,4641,234],{},{"title":61,"searchDepth":75,"depth":75,"links":4643},[4644,4645,4646,4647,4648,4649,4650,4651],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4499,"description":4504},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[247,4357,4659],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4662,"title":4663,"body":4664,"category":247,"cover":248,"description":4668,"extension":249,"meta":4842,"navigation":84,"path":4843,"pinned":252,"publishedAt":253,"seo":4844,"slug":4845,"stem":4846,"summary":4847,"tags":4848,"updatedAt":253,"visible":84,"__hash__":4849},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4665,"toc":4832},[4666,4669,4671,4674,4676,4682,4692,4694,4713,4715,4717,4769,4771,4777,4779,4781,4795,4797,4813,4815,4823,4825,4827,4830],[10,4667,4668],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4670,16],{"id":16},[10,4672,4673],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4675,22],{"id":22},[10,4677,4678],{},[26,4679],{"alt":4680,"src":4681},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4683,4684,4687,4688,4691],{},[63,4685,4686],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[63,4689,4690],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4693,35],{"id":35},[37,4695,4696,4699,4707],{},[40,4697,4698],{},"先写普通循环，再在确有需要时加入流程控制语句。",[40,4700,4701,4703,4704,4706],{},[63,4702,4686],{}," 前要确认不会跳过 ",[63,4705,4340],{}," 循环中的状态更新。",[40,4708,4709,4710,4712],{},"多层嵌套中 ",[63,4711,4690],{}," 只结束它所在的最内层循环。",[14,4714,51],{"id":51},[10,4716,54],{},[56,4718,4720],{"className":58,"code":4719,"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,4721,4722,4727,4731,4736,4741,4746,4751,4756,4760,4764],{"__ignoreMap":61},[66,4723,4724],{"class":68,"line":69},[66,4725,4726],{},"numbers = [3, -1, 0, 8, 12]\n",[66,4728,4729],{"class":68,"line":75},[66,4730,85],{"emptyLinePlaceholder":84},[66,4732,4733],{"class":68,"line":81},[66,4734,4735],{},"for number in numbers:\n",[66,4737,4738],{"class":68,"line":88},[66,4739,4740],{},"    if number \u003C 0:\n",[66,4742,4743],{"class":68,"line":94},[66,4744,4745],{},"        continue\n",[66,4747,4748],{"class":68,"line":99},[66,4749,4750],{},"    if number == 0:\n",[66,4752,4753],{"class":68,"line":105},[66,4754,4755],{},"        break\n",[66,4757,4758],{"class":68,"line":111},[66,4759,4580],{},[66,4761,4762],{"class":68,"line":117},[66,4763,85],{"emptyLinePlaceholder":84},[66,4765,4766],{"class":68,"line":122},[66,4767,4768],{},"print(\"循环结束\")\n",[10,4770,157],{},[56,4772,4775],{"className":4773,"code":4774,"language":163,"meta":61},[161],"3\n循环结束\n",[63,4776,4774],{"__ignoreMap":61},[10,4778,168],{},[14,4780,171],{"id":171},[173,4782,4783,4789],{},[40,4784,4785,4786,4788],{},"遇到 -1 时 ",[63,4787,4686],{}," 立即结束本轮，后面的判断和输出都不执行。",[40,4790,4791,4792,4794],{},"遇到 0 时 ",[63,4793,4690],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4796,202],{"id":202},[37,4798,4799,4804],{},[40,4800,3487,4801,4803],{},[63,4802,4686],{}," 当作结束循环，实际它只跳到下一轮。",[40,4805,4806,4807,4809,4810,4812],{},"在 ",[63,4808,4340],{}," 中把状态更新放在可能被 ",[63,4811,4686],{}," 跳过的位置，造成无限循环。",[14,4814,213],{"id":213},[173,4816,4817,4820],{},[40,4818,4819],{},"跳过列表中的空字符串并输出其他内容。",[40,4821,4822],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4824,224],{},[14,4826,227],{"id":227},[10,4828,4829],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,4831,234],{},{"title":61,"searchDepth":75,"depth":75,"links":4833},[4834,4835,4836,4837,4838,4839,4840,4841],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4663,"description":4668},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[247,4690,4686],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4851,"title":4852,"body":4853,"category":247,"cover":248,"description":4857,"extension":249,"meta":5028,"navigation":84,"path":5029,"pinned":252,"publishedAt":253,"seo":5030,"slug":5031,"stem":5032,"summary":5033,"tags":5034,"updatedAt":253,"visible":84,"__hash__":5037},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4854,"toc":5016},[4855,4858,4860,4863,4865,4871,4874,4876,4900,4902,4904,4938,4940,4946,4948,4950,4967,4969,4972,4978,4981,4983,4997,4999,5007,5009,5011,5014],[10,4856,4857],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4859,16],{"id":16},[10,4861,4862],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4864,22],{"id":22},[10,4866,4867],{},[26,4868],{"alt":4869,"src":4870},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4872,4873],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4875,35],{"id":35},[37,4877,4878,4881,4884],{},[40,4879,4880],{},"每增加一层嵌套，阅读成本都会上升。",[40,4882,4883],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[40,4885,4886,4887,2278,4890,4893,4894,2278,4897,383],{},"变量名使用 ",[63,4888,4889],{},"row",[63,4891,4892],{},"cell"," 等层级含义，避免全部写成 ",[63,4895,4896],{},"i",[63,4898,4899],{},"j",[14,4901,51],{"id":51},[10,4903,54],{},[56,4905,4907],{"className":58,"code":4906,"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,4908,4909,4914,4918,4923,4928,4933],{"__ignoreMap":61},[66,4910,4911],{"class":68,"line":69},[66,4912,4913],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[66,4915,4916],{"class":68,"line":75},[66,4917,85],{"emptyLinePlaceholder":84},[66,4919,4920],{"class":68,"line":81},[66,4921,4922],{},"for row in table:\n",[66,4924,4925],{"class":68,"line":88},[66,4926,4927],{},"    for cell in row:\n",[66,4929,4930],{"class":68,"line":94},[66,4931,4932],{},"        print(cell)\n",[66,4934,4935],{"class":68,"line":99},[66,4936,4937],{},"    print(\"一行结束\")\n",[10,4939,157],{},[56,4941,4944],{"className":4942,"code":4943,"language":163,"meta":61},[161],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[63,4945,4943],{"__ignoreMap":61},[10,4947,168],{},[14,4949,171],{"id":171},[173,4951,4952,4964],{},[40,4953,4954,4955,4957,4958,1178,4961,383],{},"外层变量 ",[63,4956,4889],{}," 先引用第一行列表，内层才依次处理 ",[63,4959,4960],{},"A1",[63,4962,4963],{},"A2",[40,4965,4966],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[185,4968,187],{"id":187},[10,4970,4971],{},"二维列表的输出顺序可以展开成一条时间线。",[10,4973,4974],{},[26,4975],{"alt":4976,"src":4977},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,4979,4980],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,4982,202],{"id":202},[37,4984,4985,4994],{},[40,4986,4987,4988,1030,4991,4993],{},"把两层循环变量都叫 ",[63,4989,4990],{},"item",[63,4992,4896],{},"，难以确认当前层级。",[40,4995,4996],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,4998,213],{"id":213},[173,5000,5001,5004],{},[40,5002,5003],{},"打印一个 2×3 数字表。",[40,5005,5006],{},"在内层增加条件，只输出大于 3 的元素。",[10,5008,224],{},[14,5010,227],{"id":227},[10,5012,5013],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,5015,234],{},{"title":61,"searchDepth":75,"depth":75,"links":5017},[5018,5019,5020,5021,5022,5025,5026,5027],{"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":171,"depth":75,"text":171,"children":5023},[5024],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4852,"description":4857},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[247,5035,5036],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5039,"title":5040,"body":5041,"category":247,"cover":248,"description":5045,"extension":249,"meta":5183,"navigation":84,"path":5184,"pinned":252,"publishedAt":253,"seo":5185,"slug":5186,"stem":5187,"summary":5188,"tags":5189,"updatedAt":253,"visible":84,"__hash__":5192},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5042,"toc":5173},[5043,5046,5048,5051,5053,5059,5062,5064,5075,5077,5079,5117,5119,5125,5127,5129,5141,5143,5154,5156,5164,5166,5168,5171],[10,5044,5045],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5047,16],{"id":16},[10,5049,5050],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5052,22],{"id":22},[10,5054,5055],{},[26,5056],{"alt":5057,"src":5058},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5060,5061],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5063,35],{"id":35},[37,5065,5066,5069,5072],{},[40,5067,5068],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[40,5070,5071],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[40,5073,5074],{},"推导式创建新列表，不修改输入列表。",[14,5076,51],{"id":51},[10,5078,54],{},[56,5080,5082],{"className":58,"code":5081,"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,5083,5084,5089,5093,5098,5103,5107,5112],{"__ignoreMap":61},[66,5085,5086],{"class":68,"line":69},[66,5087,5088],{},"numbers = [1, 2, 3, 4, 5]\n",[66,5090,5091],{"class":68,"line":75},[66,5092,85],{"emptyLinePlaceholder":84},[66,5094,5095],{"class":68,"line":81},[66,5096,5097],{},"squares = [number * number for number in numbers]\n",[66,5099,5100],{"class":68,"line":88},[66,5101,5102],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[66,5104,5105],{"class":68,"line":94},[66,5106,85],{"emptyLinePlaceholder":84},[66,5108,5109],{"class":68,"line":99},[66,5110,5111],{},"print(squares)\n",[66,5113,5114],{"class":68,"line":105},[66,5115,5116],{},"print(even_squares)\n",[10,5118,157],{},[56,5120,5123],{"className":5121,"code":5122,"language":163,"meta":61},[161],"[1, 4, 9, 16, 25]\n[4, 16]\n",[63,5124,5122],{"__ignoreMap":61},[10,5126,168],{},[14,5128,171],{"id":171},[173,5130,5131,5134],{},[40,5132,5133],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[40,5135,5136,5137,5140],{},"第二条先用 ",[63,5138,5139],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5142,202],{"id":202},[37,5144,5145,5151],{},[40,5146,5147,5148,5150],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[63,5149,4357],{}," 开始找输入。",[40,5152,5153],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5155,213],{"id":213},[173,5157,5158,5161],{},[40,5159,5160],{},"把字符串列表转换为长度列表。",[40,5162,5163],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5165,224],{},[14,5167,227],{"id":227},[10,5169,5170],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,5172,234],{},{"title":61,"searchDepth":75,"depth":75,"links":5174},[5175,5176,5177,5178,5179,5180,5181,5182],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5040,"description":5045},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[247,5190,5191],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5194,"title":5195,"body":5196,"category":247,"cover":248,"description":5200,"extension":249,"meta":5343,"navigation":84,"path":5344,"pinned":252,"publishedAt":253,"seo":5345,"slug":5346,"stem":5347,"summary":5348,"tags":5349,"updatedAt":253,"visible":84,"__hash__":5352},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5197,"toc":5333},[5198,5201,5203,5206,5208,5214,5217,5219,5230,5232,5234,5273,5275,5281,5283,5285,5300,5302,5310,5312,5324,5326,5328,5331],[10,5199,5200],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5202,16],{"id":16},[10,5204,5205],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5207,22],{"id":22},[10,5209,5210],{},[26,5211],{"alt":5212,"src":5213},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5215,5216],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5218,35],{"id":35},[37,5220,5221,5224,5227],{},[40,5222,5223],{},"函数名描述动作，使用小写字母和下划线。",[40,5225,5226],{},"函数定义要先执行，之后才能调用。",[40,5228,5229],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5231,51],{"id":51},[10,5233,54],{},[56,5235,5237],{"className":58,"code":5236,"language":60,"meta":61,"style":61},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[63,5238,5239,5244,5249,5254,5258,5263,5268],{"__ignoreMap":61},[66,5240,5241],{"class":68,"line":69},[66,5242,5243],{},"def show_progress():\n",[66,5245,5246],{"class":68,"line":75},[66,5247,5248],{},"    print(\"正在学习函数\")\n",[66,5250,5251],{"class":68,"line":81},[66,5252,5253],{},"    print(\"本节完成 50%\")\n",[66,5255,5256],{"class":68,"line":88},[66,5257,85],{"emptyLinePlaceholder":84},[66,5259,5260],{"class":68,"line":94},[66,5261,5262],{},"print(\"调用前\")\n",[66,5264,5265],{"class":68,"line":99},[66,5266,5267],{},"show_progress()\n",[66,5269,5270],{"class":68,"line":105},[66,5271,5272],{},"print(\"调用后\")\n",[10,5274,157],{},[56,5276,5279],{"className":5277,"code":5278,"language":163,"meta":61},[161],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[63,5280,5278],{"__ignoreMap":61},[10,5282,168],{},[14,5284,171],{"id":171},[173,5286,5287,5293],{},[40,5288,959,5289,5292],{},[63,5290,5291],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[40,5294,5295,5296,5299],{},"运行到 ",[63,5297,5298],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5301,202],{"id":202},[37,5303,5304,5307],{},[40,5305,5306],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[40,5308,5309],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5311,213],{"id":213},[173,5313,5314,5321],{},[40,5315,5316,5317,5320],{},"定义 ",[63,5318,5319],{},"show_plan()"," 输出两行学习计划。",[40,5322,5323],{},"连续调用同一个函数两次，观察执行顺序。",[10,5325,224],{},[14,5327,227],{"id":227},[10,5329,5330],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,5332,234],{},{"title":61,"searchDepth":75,"depth":75,"links":5334},[5335,5336,5337,5338,5339,5340,5341,5342],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5195,"description":5200},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[247,5350,5351],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5354,"title":5355,"body":5356,"category":247,"cover":248,"description":5360,"extension":249,"meta":5540,"navigation":84,"path":5541,"pinned":252,"publishedAt":253,"seo":5542,"slug":5543,"stem":5544,"summary":5545,"tags":5546,"updatedAt":253,"visible":84,"__hash__":5549},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5357,"toc":5528},[5358,5361,5363,5366,5368,5374,5381,5383,5400,5402,5404,5438,5440,5446,5448,5450,5471,5473,5476,5482,5492,5494,5509,5511,5519,5521,5523,5526],[10,5359,5360],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5362,16],{"id":16},[10,5364,5365],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5367,22],{"id":22},[10,5369,5370],{},[26,5371],{"alt":5372,"src":5373},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5375,5376,5377,5380],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[63,5378,5379],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5382,35],{"id":35},[37,5384,5385,5388,5391],{},[40,5386,5387],{},"形参出现在函数定义中，实参出现在函数调用中。",[40,5389,5390],{},"局部变量默认只在函数内部可见。",[40,5392,5393,5394,5396,5397,383],{},"没有显式 ",[63,5395,5379],{}," 的函数会返回 ",[63,5398,5399],{},"None",[14,5401,51],{"id":51},[10,5403,54],{},[56,5405,5407],{"className":58,"code":5406,"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,5408,5409,5414,5419,5424,5428,5433],{"__ignoreMap":61},[66,5410,5411],{"class":68,"line":69},[66,5412,5413],{},"def calculate_total(price, count):\n",[66,5415,5416],{"class":68,"line":75},[66,5417,5418],{},"    total = price * count\n",[66,5420,5421],{"class":68,"line":81},[66,5422,5423],{},"    return total\n",[66,5425,5426],{"class":68,"line":88},[66,5427,85],{"emptyLinePlaceholder":84},[66,5429,5430],{"class":68,"line":94},[66,5431,5432],{},"result = calculate_total(25, 4)\n",[66,5434,5435],{"class":68,"line":99},[66,5436,5437],{},"print(result)\n",[10,5439,157],{},[56,5441,5444],{"className":5442,"code":5443,"language":163,"meta":61},[161],"100\n",[63,5445,5443],{"__ignoreMap":61},[10,5447,168],{},[14,5449,171],{"id":171},[173,5451,5452,5461],{},[40,5453,5454,5455,2278,5458,5460],{},"调用时 25 和 4 分别绑定到 ",[63,5456,5457],{},"price",[63,5459,4420],{},"，它们只在本次函数调用的局部范围中使用。",[40,5462,5463,5466,5467,5470],{},[63,5464,5465],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[63,5468,5469],{},"result"," 并输出。",[185,5472,187],{"id":187},[10,5474,5475],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5477,5478],{},[26,5479],{"alt":5480,"src":5481},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5483,5484,2278,5486,1178,5488,5491],{},[63,5485,5457],{},[63,5487,4420],{},[63,5489,5490],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5493,202],{"id":202},[37,5495,5496,5503],{},[40,5497,5498,5499,5502],{},"在函数内部只 ",[63,5500,5501],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[40,5504,5505,5506,5508],{},"试图在函数外直接访问局部变量 ",[63,5507,5490],{},"，它的名字只在调用期间的局部作用域存在。",[14,5510,213],{"id":213},[173,5512,5513,5516],{},[40,5514,5515],{},"编写计算长方形面积的函数。",[40,5517,5518],{},"让函数返回结果后在调用方加上单位再输出。",[10,5520,224],{},[14,5522,227],{"id":227},[10,5524,5525],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,5527,234],{},{"title":61,"searchDepth":75,"depth":75,"links":5529},[5530,5531,5532,5533,5534,5537,5538,5539],{"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":171,"depth":75,"text":171,"children":5535},[5536],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5355,"description":5360},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[247,5547,5548],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5551,"title":5552,"body":5553,"category":247,"cover":248,"description":5557,"extension":249,"meta":5737,"navigation":84,"path":5738,"pinned":252,"publishedAt":253,"seo":5739,"slug":5740,"stem":5741,"summary":5742,"tags":5743,"updatedAt":253,"visible":84,"__hash__":5746},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5554,"toc":5725},[5555,5558,5560,5563,5565,5571,5574,5576,5593,5595,5597,5649,5651,5657,5659,5661,5679,5681,5684,5690,5693,5695,5706,5708,5716,5718,5720,5723],[10,5556,5557],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5559,16],{"id":16},[10,5561,5562],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5564,22],{"id":22},[10,5566,5567],{},[26,5568],{"alt":5569,"src":5570},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5572,5573],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5575,35],{"id":35},[37,5577,5578,5581,5587],{},[40,5579,5580],{},"必需参数应放在有默认值的参数之前。",[40,5582,5583,5586],{},[63,5584,5585],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[40,5588,5589,5592],{},[63,5590,5591],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5594,51],{"id":51},[10,5596,54],{},[56,5598,5600],{"className":58,"code":5599,"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,5601,5602,5607,5612,5616,5621,5626,5630,5635,5640,5644],{"__ignoreMap":61},[66,5603,5604],{"class":68,"line":69},[66,5605,5606],{},"def build_title(name, level=\"基础\"):\n",[66,5608,5609],{"class":68,"line":75},[66,5610,5611],{},"    return name + \"｜\" + level\n",[66,5613,5614],{"class":68,"line":81},[66,5615,85],{"emptyLinePlaceholder":84},[66,5617,5618],{"class":68,"line":88},[66,5619,5620],{},"print(build_title(\"Python\"))\n",[66,5622,5623],{"class":68,"line":94},[66,5624,5625],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[66,5627,5628],{"class":68,"line":99},[66,5629,85],{"emptyLinePlaceholder":84},[66,5631,5632],{"class":68,"line":105},[66,5633,5634],{},"def total(*numbers):\n",[66,5636,5637],{"class":68,"line":111},[66,5638,5639],{},"    return sum(numbers)\n",[66,5641,5642],{"class":68,"line":117},[66,5643,85],{"emptyLinePlaceholder":84},[66,5645,5646],{"class":68,"line":122},[66,5647,5648],{},"print(total(10, 20, 30))\n",[10,5650,157],{},[56,5652,5655],{"className":5653,"code":5654,"language":163,"meta":61},[161],"Python｜基础\n异常处理｜进阶\n60\n",[63,5656,5654],{"__ignoreMap":61},[10,5658,168],{},[14,5660,171],{"id":171},[173,5662,5663,5670],{},[40,5664,5665,5666,5669],{},"第一次调用只提供必需参数，",[63,5667,5668],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[40,5671,5672,5675,5676,383],{},[63,5673,5674],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[63,5677,5678],{},"sum()",[185,5680,187],{"id":187},[10,5682,5683],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5685,5686],{},[26,5687],{"alt":5688,"src":5689},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5691,5692],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5694,202],{"id":202},[37,5696,5697,5703],{},[40,5698,5699,5700,5702],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[63,5701,5399],{}," 再在函数内创建。",[40,5704,5705],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5707,213],{"id":213},[173,5709,5710,5713],{},[40,5711,5712],{},"给问候函数增加默认称呼。",[40,5714,5715],{},"编写接收任意数量分数并返回总分的函数。",[10,5717,224],{},[14,5719,227],{"id":227},[10,5721,5722],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,5724,234],{},{"title":61,"searchDepth":75,"depth":75,"links":5726},[5727,5728,5729,5730,5731,5734,5735,5736],{"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":171,"depth":75,"text":171,"children":5732},[5733],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5552,"description":5557},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[247,5744,5745],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5748,"title":5749,"body":5750,"category":247,"cover":248,"description":5754,"extension":249,"meta":5949,"navigation":84,"path":5950,"pinned":252,"publishedAt":253,"seo":5951,"slug":5952,"stem":5953,"summary":5954,"tags":5955,"updatedAt":253,"visible":84,"__hash__":5958},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5751,"toc":5937},[5752,5755,5757,5760,5762,5768,5771,5773,5790,5792,5794,5855,5857,5863,5865,5867,5894,5896,5899,5905,5908,5910,5918,5920,5928,5930,5932,5935],[10,5753,5754],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5756,16],{"id":16},[10,5758,5759],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5761,22],{"id":22},[10,5763,5764],{},[26,5765],{"alt":5766,"src":5767},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5769,5770],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5772,35],{"id":35},[37,5774,5775,5778,5781],{},[40,5776,5777],{},"函数内部赋值默认创建局部变量。",[40,5779,5780],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[40,5782,5783,2197,5786,5789],{},[63,5784,5785],{},"global",[63,5787,5788],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5791,51],{"id":51},[10,5793,54],{},[56,5795,5797],{"className":58,"code":5796,"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,5798,5799,5804,5808,5813,5818,5822,5827,5832,5837,5841,5846,5850],{"__ignoreMap":61},[66,5800,5801],{"class":68,"line":69},[66,5802,5803],{},"course = \"Python\"\n",[66,5805,5806],{"class":68,"line":75},[66,5807,85],{"emptyLinePlaceholder":84},[66,5809,5810],{"class":68,"line":81},[66,5811,5812],{},"def outer():\n",[66,5814,5815],{"class":68,"line":88},[66,5816,5817],{},"    level = \"基础\"\n",[66,5819,5820],{"class":68,"line":94},[66,5821,85],{"emptyLinePlaceholder":84},[66,5823,5824],{"class":68,"line":99},[66,5825,5826],{},"    def show():\n",[66,5828,5829],{"class":68,"line":105},[66,5830,5831],{},"        lesson = \"作用域\"\n",[66,5833,5834],{"class":68,"line":111},[66,5835,5836],{},"        print(course, level, lesson)\n",[66,5838,5839],{"class":68,"line":117},[66,5840,85],{"emptyLinePlaceholder":84},[66,5842,5843],{"class":68,"line":122},[66,5844,5845],{},"    show()\n",[66,5847,5848],{"class":68,"line":128},[66,5849,85],{"emptyLinePlaceholder":84},[66,5851,5852],{"class":68,"line":134},[66,5853,5854],{},"outer()\n",[10,5856,157],{},[56,5858,5861],{"className":5859,"code":5860,"language":163,"meta":61},[161],"Python 基础 作用域\n",[63,5862,5860],{"__ignoreMap":61},[10,5864,168],{},[14,5866,171],{"id":171},[173,5868,5869,5886],{},[40,5870,5871,5874,5875,5878,5879,5881,5882,5885],{},[63,5872,5873],{},"show()"," 中查找 ",[63,5876,5877],{},"lesson"," 时先在局部找到，查找 ",[63,5880,5668],{}," 时到外层 ",[63,5883,5884],{},"outer()"," 找到。",[40,5887,5888,5890,5891,5893],{},[63,5889,4603],{}," 在局部和外层都不存在，继续到模块全局找到；",[63,5892,2229],{}," 最后在内置作用域找到。",[185,5895,187],{"id":187},[10,5897,5898],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5900,5901],{},[26,5902],{"alt":5903,"src":5904},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5906,5907],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5909,202],{"id":202},[37,5911,5912,5915],{},[40,5913,5914],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[40,5916,5917],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5919,213],{"id":213},[173,5921,5922,5925],{},[40,5923,5924],{},"在内外层定义同名变量，观察最近作用域优先。",[40,5926,5927],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5929,224],{},[14,5931,227],{"id":227},[10,5933,5934],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,5936,234],{},{"title":61,"searchDepth":75,"depth":75,"links":5938},[5939,5940,5941,5942,5943,5946,5947,5948],{"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":171,"depth":75,"text":171,"children":5944},[5945],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5749,"description":5754},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[247,5956,5957],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5960,"title":5961,"body":5962,"category":247,"cover":248,"description":5966,"extension":249,"meta":6116,"navigation":84,"path":6117,"pinned":252,"publishedAt":253,"seo":6118,"slug":6119,"stem":6120,"summary":6121,"tags":6122,"updatedAt":253,"visible":84,"__hash__":6125},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5963,"toc":6106},[5964,5967,5969,5972,5974,5980,5983,5985,6004,6006,6008,6042,6044,6050,6052,6054,6069,6071,6083,6085,6097,6099,6101,6104],[10,5965,5966],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,5968,16],{"id":16},[10,5970,5971],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5973,22],{"id":22},[10,5975,5976],{},[26,5977],{"alt":5978,"src":5979},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,5981,5982],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,5984,35],{"id":35},[37,5986,5987,5990,5993],{},[40,5988,5989],{},"文档字符串紧跟在函数定义后的第一条语句。",[40,5991,5992],{},"注解表达接口意图，不代替输入校验和测试。",[40,5994,5995,5996,2278,5998,2278,6000,6003],{},"基础注解优先使用 ",[63,5997,2281],{},[63,5999,2447],{},[63,6001,6002],{},"list[str]"," 等直接写法。",[14,6005,51],{"id":51},[10,6007,54],{},[56,6009,6011],{"className":58,"code":6010,"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,6012,6013,6018,6023,6028,6032,6037],{"__ignoreMap":61},[66,6014,6015],{"class":68,"line":69},[66,6016,6017],{},"def format_score(name: str, score: int) -> str:\n",[66,6019,6020],{"class":68,"line":75},[66,6021,6022],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[66,6024,6025],{"class":68,"line":81},[66,6026,6027],{},"    return name + \"：\" + str(score)\n",[66,6029,6030],{"class":68,"line":88},[66,6031,85],{"emptyLinePlaceholder":84},[66,6033,6034],{"class":68,"line":94},[66,6035,6036],{},"print(format_score(\"小郑\", 95))\n",[66,6038,6039],{"class":68,"line":99},[66,6040,6041],{},"print(format_score.__doc__)\n",[10,6043,157],{},[56,6045,6048],{"className":6046,"code":6047,"language":163,"meta":61},[161],"小郑：95\n返回带姓名的分数文本。\n",[63,6049,6047],{"__ignoreMap":61},[10,6051,168],{},[14,6053,171],{"id":171},[173,6055,6056,6066],{},[40,6057,6058,6059,6062,6063,6065],{},"函数签名说明 ",[63,6060,6061],{},"name"," 预期为字符串、",[63,6064,2267],{}," 预期为整数，返回值预期为字符串。",[40,6067,6068],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6070,202],{"id":202},[37,6072,6073,6080],{},[40,6074,6075,6076,6079],{},"认为加了 ",[63,6077,6078],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[40,6081,6082],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6084,213],{"id":213},[173,6086,6087,6090],{},[40,6088,6089],{},"为面积函数补充参数和返回值注解。",[40,6091,6092,6093,6096],{},"通过 ",[63,6094,6095],{},"函数名.__doc__"," 查看文档字符串。",[10,6098,224],{},[14,6100,227],{"id":227},[10,6102,6103],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,6105,234],{},{"title":61,"searchDepth":75,"depth":75,"links":6107},[6108,6109,6110,6111,6112,6113,6114,6115],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5961,"description":5966},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[247,6123,6124],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6127,"title":6128,"body":6129,"category":247,"cover":248,"description":6133,"extension":249,"meta":6359,"navigation":84,"path":6360,"pinned":252,"publishedAt":253,"seo":6361,"slug":6362,"stem":6363,"summary":6364,"tags":6365,"updatedAt":253,"visible":84,"__hash__":6368},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6130,"toc":6347},[6131,6134,6136,6142,6144,6150,6161,6163,6181,6183,6190,6218,6225,6244,6253,6255,6261,6263,6265,6288,6290,6293,6299,6305,6307,6323,6325,6338,6340,6342,6345],[10,6132,6133],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6135,16],{"id":16},[10,6137,6138,6139,6141],{},"本篇只处理“模块、import 与 ",[316,6140,6061],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6143,22],{"id":22},[10,6145,6146],{},[26,6147],{"alt":6148,"src":6149},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6151,6152,6153,6156,6157,6160],{},"同一个文件直接运行时 ",[63,6154,6155],{},"__name__"," 等于 ",[63,6158,6159],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6162,35],{"id":35},[37,6164,6165,6171,6174],{},[40,6166,6167,6168,6170],{},"一个 ",[63,6169,1192],{}," 文件就是一个模块。",[40,6172,6173],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[40,6175,6176,6177,6180],{},"避免使用 ",[63,6178,6179],{},"from module import *","，它会让名字来源不清楚。",[14,6182,51],{"id":51},[10,6184,6185,6186,6189],{},"先在同一个目录中创建两个文件。把函数放进 ",[63,6187,6188],{},"calculator.py","：",[56,6191,6193],{"className":58,"code":6192,"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,6194,6195,6200,6205,6209,6213],{"__ignoreMap":61},[66,6196,6197],{"class":68,"line":69},[66,6198,6199],{},"def add(left, right):\n",[66,6201,6202],{"class":68,"line":75},[66,6203,6204],{},"    return left + right\n",[66,6206,6207],{"class":68,"line":81},[66,6208,85],{"emptyLinePlaceholder":84},[66,6210,6211],{"class":68,"line":88},[66,6212,148],{},[66,6214,6215],{"class":68,"line":94},[66,6216,6217],{},"    print(add(2, 3))\n",[10,6219,6220,6221,6224],{},"再创建 ",[63,6222,6223],{},"app.py","，从模块中导入函数：",[56,6226,6228],{"className":58,"code":6227,"language":60,"meta":61,"style":61},"from calculator import add\n\nprint(add(10, 20))\n",[63,6229,6230,6235,6239],{"__ignoreMap":61},[66,6231,6232],{"class":68,"line":69},[66,6233,6234],{},"from calculator import add\n",[66,6236,6237],{"class":68,"line":75},[66,6238,85],{"emptyLinePlaceholder":84},[66,6240,6241],{"class":68,"line":81},[66,6242,6243],{},"print(add(10, 20))\n",[10,6245,6246,6247,1178,6250,383],{},"分别执行 ",[63,6248,6249],{},"python3 calculator.py",[63,6251,6252],{},"python3 app.py",[10,6254,157],{},[56,6256,6259],{"className":6257,"code":6258,"language":163,"meta":61},[161],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[63,6260,6258],{"__ignoreMap":61},[10,6262,168],{},[14,6264,171],{"id":171},[173,6266,6267,6277],{},[40,6268,6269,6270,6272,6273,6276],{},"直接运行 ",[63,6271,6188],{}," 时，模块名是 ",[63,6274,6275],{},"__main__","，入口代码输出 5。",[40,6278,6279,6281,6282,6284,6285,6287],{},[63,6280,6223],{}," 导入模块时，",[63,6283,6188],{}," 的函数定义会执行，但入口判断为假；随后 ",[63,6286,6223],{}," 调用函数输出 30。",[185,6289,187],{"id":187},[10,6291,6292],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6294,6295],{},[26,6296],{"alt":6297,"src":6298},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6300,6301,6302,6304],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[63,6303,6275],{}," 保护下的演示代码。",[14,6306,202],{"id":202},[37,6308,6309,6316],{},[40,6310,6311,6312,1178,6314,383],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[63,6313,6188],{},[63,6315,6223],{},[40,6317,6318,6319,6322],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[63,6320,6321],{},"json.py","，导致导入目标被遮蔽。",[14,6324,213],{"id":213},[173,6326,6327,6333],{},[40,6328,2375,6329,6332],{},[63,6330,6331],{},"text_tools.py"," 并导出一个格式化函数。",[40,6334,6335,6336,383],{},"分别直接运行模块和从另一个脚本导入，输出 ",[63,6337,6155],{},[10,6339,224],{},[14,6341,227],{"id":227},[10,6343,6344],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,6346,234],{},{"title":61,"searchDepth":75,"depth":75,"links":6348},[6349,6350,6351,6352,6353,6356,6357,6358],{"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":171,"depth":75,"text":171,"children":6354},[6355],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6128,"description":6133},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[247,6366,6367],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6370,"title":6371,"body":6372,"category":247,"cover":248,"description":6376,"extension":249,"meta":6541,"navigation":84,"path":6542,"pinned":252,"publishedAt":253,"seo":6543,"slug":6544,"stem":6545,"summary":6546,"tags":6547,"updatedAt":253,"visible":84,"__hash__":6549},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6373,"toc":6531},[6374,6377,6379,6382,6384,6390,6393,6395,6409,6411,6413,6459,6461,6467,6469,6471,6497,6499,6509,6511,6522,6524,6526,6529],[10,6375,6376],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6378,16],{"id":16},[10,6380,6381],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6383,22],{"id":22},[10,6385,6386],{},[26,6387],{"alt":6388,"src":6389},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6391,6392],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6394,35],{"id":35},[37,6396,6397,6403,6406],{},[40,6398,6399,6402],{},[63,6400,6401],{},".venv"," 是常见目录名，不应提交到 Git。",[40,6404,6405],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[40,6407,6408],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6410,51],{"id":51},[10,6412,1595],{},[56,6414,6416],{"className":612,"code":6415,"language":614,"meta":61,"style":61},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[63,6417,6418,6430,6438,6444,6454],{"__ignoreMap":61},[66,6419,6420,6422,6424,6427],{"class":68,"line":69},[66,6421,712],{"class":621},[66,6423,654],{"class":624},[66,6425,6426],{"class":657}," venv",[66,6428,6429],{"class":657}," .venv\n",[66,6431,6432,6435],{"class":68,"line":75},[66,6433,6434],{"class":624},"source",[66,6436,6437],{"class":657}," .venv\u002Fbin\u002Factivate\n",[66,6439,6440,6442],{"class":68,"line":81},[66,6441,60],{"class":621},[66,6443,625],{"class":624},[66,6445,6446,6448,6450,6452],{"class":68,"line":88},[66,6447,60],{"class":621},[66,6449,654],{"class":624},[66,6451,658],{"class":657},[66,6453,625],{"class":624},[66,6455,6456],{"class":68,"line":94},[66,6457,6458],{"class":621},"deactivate\n",[10,6460,157],{},[56,6462,6465],{"className":6463,"code":6464,"language":163,"meta":61},[161],"Python 和 pip 的路径应指向当前项目的 .venv\n",[63,6466,6464],{"__ignoreMap":61},[10,6468,168],{},[14,6470,171],{"id":171},[173,6472,6473,6482],{},[40,6474,6475,6478,6479,6481],{},[63,6476,6477],{},"venv"," 根据当前 ",[63,6480,712],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[40,6483,6484,6485,2197,6487,6490,6491,3748,6493,6496],{},"激活后 ",[63,6486,60],{},[63,6488,6489],{},"python -m pip"," 优先指向 ",[63,6492,6401],{},[63,6494,6495],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6498,202],{"id":202},[37,6500,6501,6504],{},[40,6502,6503],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[40,6505,3487,6506,6508],{},[63,6507,6401],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6510,213],{"id":213},[173,6512,6513,6519],{},[40,6514,6515,6516,383],{},"创建虚拟环境并记录激活前后的 ",[63,6517,6518],{},"which python",[40,6520,6521],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6523,224],{},[14,6525,227],{"id":227},[10,6527,6528],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,6530,1679],{},{"title":61,"searchDepth":75,"depth":75,"links":6532},[6533,6534,6535,6536,6537,6538,6539,6540],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6371,"description":6376},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[247,6548,282],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6551,"title":6552,"body":6553,"category":247,"cover":248,"description":6557,"extension":249,"meta":6745,"navigation":84,"path":6746,"pinned":252,"publishedAt":253,"seo":6747,"slug":6748,"stem":6749,"summary":6750,"tags":6751,"updatedAt":253,"visible":84,"__hash__":6754},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6554,"toc":6735},[6555,6558,6560,6563,6565,6571,6580,6582,6606,6608,6610,6663,6665,6671,6673,6675,6691,6693,6712,6714,6726,6728,6730,6733],[10,6556,6557],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6559,16],{"id":16},[10,6561,6562],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6564,22],{"id":22},[10,6566,6567],{},[26,6568],{"alt":6569,"src":6570},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6572,6573,6576,6577,6579],{},[63,6574,6575],{},"Path"," 使用 ",[63,6578,2457],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6581,35],{"id":35},[37,6583,6584,6587,6599],{},[40,6585,6586],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[40,6588,6589,2278,6592,2278,6595,6598],{},[63,6590,6591],{},"exists()",[63,6593,6594],{},"is_file()",[63,6596,6597],{},"is_dir()"," 检查真实文件系统状态。",[40,6600,6601,6602,6605],{},"创建目录前明确目标；",[63,6603,6604],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6607,51],{"id":51},[10,6609,54],{},[56,6611,6613],{"className":58,"code":6612,"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,6614,6615,6620,6624,6629,6634,6639,6643,6648,6653,6658],{"__ignoreMap":61},[66,6616,6617],{"class":68,"line":69},[66,6618,6619],{},"from pathlib import Path\n",[66,6621,6622],{"class":68,"line":75},[66,6623,85],{"emptyLinePlaceholder":84},[66,6625,6626],{"class":68,"line":81},[66,6627,6628],{},"project = Path.cwd()\n",[66,6630,6631],{"class":68,"line":88},[66,6632,6633],{},"data_dir = project \u002F \"data\"\n",[66,6635,6636],{"class":68,"line":94},[66,6637,6638],{},"file_path = data_dir \u002F \"records.json\"\n",[66,6640,6641],{"class":68,"line":99},[66,6642,85],{"emptyLinePlaceholder":84},[66,6644,6645],{"class":68,"line":105},[66,6646,6647],{},"print(project)\n",[66,6649,6650],{"class":68,"line":111},[66,6651,6652],{},"print(file_path.name)\n",[66,6654,6655],{"class":68,"line":117},[66,6656,6657],{},"print(file_path.suffix)\n",[66,6659,6660],{"class":68,"line":122},[66,6661,6662],{},"print(file_path.exists())\n",[10,6664,157],{},[56,6666,6669],{"className":6667,"code":6668,"language":163,"meta":61},[161],"显示当前项目路径、records.json、.json 和存在状态\n",[63,6670,6668],{"__ignoreMap":61},[10,6672,168],{},[14,6674,171],{"id":171},[173,6676,6677,6683],{},[40,6678,6679,6682],{},[63,6680,6681],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[40,6684,2360,6685,6687,6688,6690],{},[63,6686,2457],{}," 组合路径片段只创建新的 ",[63,6689,6575],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6692,202],{"id":202},[37,6694,6695,6703],{},[40,6696,3487,6697,6699,6700,6702],{},[63,6698,6575],{}," 对象存在当成真实文件存在，仍需调用 ",[63,6701,6591],{}," 等方法确认。",[40,6704,6705,6706,1030,6708,6711],{},"手工拼接 ",[63,6707,2457],{},[63,6709,6710],{},"\\"," 分隔符，降低跨平台可读性。",[14,6713,213],{"id":213},[173,6715,6716,6723],{},[40,6717,6718,6719,6722],{},"组合 ",[63,6720,6721],{},"output\u002Freport.txt"," 路径但先不创建文件。",[40,6724,6725],{},"输出路径的父目录、文件名和扩展名。",[10,6727,224],{},[14,6729,227],{"id":227},[10,6731,6732],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,6734,234],{},{"title":61,"searchDepth":75,"depth":75,"links":6736},[6737,6738,6739,6740,6741,6742,6743,6744],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6552,"description":6557},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[247,6752,6753],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6756,"title":6757,"body":6758,"category":247,"cover":248,"description":6762,"extension":249,"meta":6940,"navigation":84,"path":6941,"pinned":252,"publishedAt":253,"seo":6942,"slug":6943,"stem":6944,"summary":6945,"tags":6946,"updatedAt":253,"visible":84,"__hash__":6949},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6759,"toc":6930},[6760,6763,6765,6768,6770,6776,6779,6781,6809,6811,6813,6870,6872,6878,6880,6882,6893,6895,6908,6910,6921,6923,6925,6928],[10,6761,6762],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6764,16],{"id":16},[10,6766,6767],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6769,22],{"id":22},[10,6771,6772],{},[26,6773],{"alt":6774,"src":6775},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6777,6778],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6780,35],{"id":35},[37,6782,6783,6789,6798],{},[40,6784,6785,6788],{},[63,6786,6787],{},"w"," 模式会截断原文件，写入前必须确认目标。",[40,6790,6791,6794,6795,383],{},[63,6792,6793],{},"r"," 模式读取不存在文件会产生 ",[63,6796,6797],{},"FileNotFoundError",[40,6799,6800,6801,6804,6805,6808],{},"本篇显式调用 ",[63,6802,6803],{},"close()","；第 34 篇会用 ",[63,6806,6807],{},"with"," 更可靠地管理关闭动作。",[14,6810,51],{"id":51},[10,6812,54],{},[56,6814,6816],{"className":58,"code":6815,"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,6817,6818,6822,6826,6831,6836,6841,6846,6850,6855,6860,6865],{"__ignoreMap":61},[66,6819,6820],{"class":68,"line":69},[66,6821,6619],{},[66,6823,6824],{"class":68,"line":75},[66,6825,85],{"emptyLinePlaceholder":84},[66,6827,6828],{"class":68,"line":81},[66,6829,6830],{},"file_path = Path(\"notes.txt\")\n",[66,6832,6833],{"class":68,"line":88},[66,6834,6835],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[66,6837,6838],{"class":68,"line":94},[66,6839,6840],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[66,6842,6843],{"class":68,"line":99},[66,6844,6845],{},"writer.close()\n",[66,6847,6848],{"class":68,"line":105},[66,6849,85],{"emptyLinePlaceholder":84},[66,6851,6852],{"class":68,"line":111},[66,6853,6854],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[66,6856,6857],{"class":68,"line":117},[66,6858,6859],{},"content = reader.read()\n",[66,6861,6862],{"class":68,"line":122},[66,6863,6864],{},"reader.close()\n",[66,6866,6867],{"class":68,"line":128},[66,6868,6869],{},"print(content)\n",[10,6871,157],{},[56,6873,6876],{"className":6874,"code":6875,"language":163,"meta":61},[161],"变量\n循环\n函数\n",[63,6877,6875],{"__ignoreMap":61},[10,6879,168],{},[14,6881,171],{"id":171},[173,6883,6884,6890],{},[40,6885,6886,6887,6889],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[63,6888,6803],{}," 确保缓冲内容交给文件系统。",[40,6891,6892],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6894,202],{"id":202},[37,6896,6897,6902],{},[40,6898,2360,6899,6901],{},[63,6900,6787],{}," 模式打开重要文件却未确认覆盖风险。",[40,6903,6904,6905,383],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[63,6906,6907],{},"encoding=\"utf-8\"",[14,6909,213],{"id":213},[173,6911,6912,6915],{},[40,6913,6914],{},"写入三行学习记录并读取。",[40,6916,6917,6918,6920],{},"改用 ",[63,6919,357],{}," 模式追加一行，确认原内容仍保留。",[10,6922,224],{},[14,6924,227],{"id":227},[10,6926,6927],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,6929,234],{},{"title":61,"searchDepth":75,"depth":75,"links":6931},[6932,6933,6934,6935,6936,6937,6938,6939],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6757,"description":6762},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[247,6947,6948],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6951,"title":6952,"body":6953,"category":247,"cover":248,"description":6957,"extension":249,"meta":7124,"navigation":84,"path":7125,"pinned":252,"publishedAt":253,"seo":7126,"slug":7127,"stem":7128,"summary":7129,"tags":7130,"updatedAt":253,"visible":84,"__hash__":7133},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6954,"toc":7114},[6955,6958,6960,6963,6965,6971,6981,6983,6997,6999,7001,7061,7063,7069,7071,7073,7085,7087,7095,7097,7105,7107,7109,7112],[10,6956,6957],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6959,16],{"id":16},[10,6961,6962],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6964,22],{"id":22},[10,6966,6967],{},[26,6968],{"alt":6969,"src":6970},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,6972,6973,6976,6977,6980],{},[63,6974,6975],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[63,6978,6979],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,6982,35],{"id":35},[37,6984,6985,6988,6994],{},[40,6986,6987],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[40,6989,6990,6993],{},[63,6991,6992],{},"ensure_ascii=False"," 让中文以可读字符写入。",[40,6995,6996],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,6998,51],{"id":51},[10,7000,54],{},[56,7002,7004],{"className":58,"code":7003,"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,7005,7006,7011,7015,7020,7024,7029,7034,7038,7042,7047,7052,7056],{"__ignoreMap":61},[66,7007,7008],{"class":68,"line":69},[66,7009,7010],{},"import json\n",[66,7012,7013],{"class":68,"line":75},[66,7014,85],{"emptyLinePlaceholder":84},[66,7016,7017],{"class":68,"line":81},[66,7018,7019],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[66,7021,7022],{"class":68,"line":88},[66,7023,85],{"emptyLinePlaceholder":84},[66,7025,7026],{"class":68,"line":94},[66,7027,7028],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[66,7030,7031],{"class":68,"line":99},[66,7032,7033],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[66,7035,7036],{"class":68,"line":105},[66,7037,6845],{},[66,7039,7040],{"class":68,"line":111},[66,7041,85],{"emptyLinePlaceholder":84},[66,7043,7044],{"class":68,"line":117},[66,7045,7046],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[66,7048,7049],{"class":68,"line":122},[66,7050,7051],{},"loaded = json.load(reader)\n",[66,7053,7054],{"class":68,"line":128},[66,7055,6864],{},[66,7057,7058],{"class":68,"line":134},[66,7059,7060],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7062,157],{},[56,7064,7067],{"className":7065,"code":7066,"language":163,"meta":61},[161],"Python 60\n",[63,7068,7066],{"__ignoreMap":61},[10,7070,168],{},[14,7072,171],{"id":171},[173,7074,7075,7080],{},[40,7076,7077,7079],{},[63,7078,6975],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[40,7081,7082,7084],{},[63,7083,6979],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7086,202],{"id":202},[37,7088,7089,7092],{},[40,7090,7091],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[40,7093,7094],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7096,213],{"id":213},[173,7098,7099,7102],{},[40,7100,7101],{},"保存包含两条学习记录的列表。",[40,7103,7104],{},"读取后修改进度，再重新写回文件。",[10,7106,224],{},[14,7108,227],{"id":227},[10,7110,7111],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,7113,234],{},{"title":61,"searchDepth":75,"depth":75,"links":7115},[7116,7117,7118,7119,7120,7121,7122,7123],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6952,"description":6957},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[247,7131,7132],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7135,"title":7136,"body":7137,"category":247,"cover":248,"description":7141,"extension":249,"meta":7325,"navigation":84,"path":7326,"pinned":252,"publishedAt":253,"seo":7327,"slug":7328,"stem":7329,"summary":7330,"tags":7331,"updatedAt":253,"visible":84,"__hash__":7334},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7138,"toc":7315},[7139,7142,7144,7147,7149,7155,7161,7163,7185,7187,7189,7252,7254,7260,7262,7264,7280,7282,7296,7298,7306,7308,7310,7313],[10,7140,7141],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7143,16],{"id":16},[10,7145,7146],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7148,22],{"id":22},[10,7150,7151],{},[26,7152],{"alt":7153,"src":7154},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7156,7157,7160],{},[63,7158,7159],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7162,35],{"id":35},[37,7164,7165,7175,7182],{},[40,7166,2360,7167,7170,7171,7174],{},[63,7168,7169],{},"newline=\"\""," 让 ",[63,7172,7173],{},"csv"," 模块正确处理换行。",[40,7176,7177,7178,7181],{},"字段顺序由 ",[63,7179,7180],{},"fieldnames"," 决定，字典键需要与字段名一致。",[40,7183,7184],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7186,51],{"id":51},[10,7188,54],{},[56,7190,7192],{"className":58,"code":7191,"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,7193,7194,7199,7203,7208,7213,7218,7223,7228,7232,7237,7242,7247],{"__ignoreMap":61},[66,7195,7196],{"class":68,"line":69},[66,7197,7198],{},"import csv\n",[66,7200,7201],{"class":68,"line":75},[66,7202,85],{"emptyLinePlaceholder":84},[66,7204,7205],{"class":68,"line":81},[66,7206,7207],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[66,7209,7210],{"class":68,"line":88},[66,7211,7212],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[66,7214,7215],{"class":68,"line":94},[66,7216,7217],{},"writer.writeheader()\n",[66,7219,7220],{"class":68,"line":99},[66,7221,7222],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[66,7224,7225],{"class":68,"line":105},[66,7226,7227],{},"writer_file.close()\n",[66,7229,7230],{"class":68,"line":111},[66,7231,85],{"emptyLinePlaceholder":84},[66,7233,7234],{"class":68,"line":117},[66,7235,7236],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[66,7238,7239],{"class":68,"line":122},[66,7240,7241],{},"for row in csv.DictReader(reader_file):\n",[66,7243,7244],{"class":68,"line":128},[66,7245,7246],{},"    print(row[\"name\"], row[\"score\"])\n",[66,7248,7249],{"class":68,"line":134},[66,7250,7251],{},"reader_file.close()\n",[10,7253,157],{},[56,7255,7258],{"className":7256,"code":7257,"language":163,"meta":61},[161],"小郑 95\n",[63,7259,7257],{"__ignoreMap":61},[10,7261,168],{},[14,7263,171],{"id":171},[173,7265,7266,7275],{},[40,7267,7268,7271,7272,7274],{},[63,7269,7270],{},"DictWriter"," 按 ",[63,7273,7180],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[40,7276,7277,7279],{},[63,7278,7159],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7281,202],{"id":202},[37,7283,7284,7287],{},[40,7285,7286],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[40,7288,7289,7290,7292,7293,7295],{},"在 macOS 以外环境忽略 ",[63,7291,7169],{}," 可能出现额外空行；统一交给 ",[63,7294,7173],{}," 模块管理换行。",[14,7297,213],{"id":213},[173,7299,7300,7303],{},[40,7301,7302],{},"写入三名学习者的课程和分数。",[40,7304,7305],{},"读取 CSV 后把分数字符串转换为整数。",[10,7307,224],{},[14,7309,227],{"id":227},[10,7311,7312],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,7314,234],{},{"title":61,"searchDepth":75,"depth":75,"links":7316},[7317,7318,7319,7320,7321,7322,7323,7324],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7136,"description":7141},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[247,7332,7333],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7336,"title":7337,"body":7338,"category":247,"cover":248,"description":7342,"extension":249,"meta":7613,"navigation":84,"path":7614,"pinned":252,"publishedAt":253,"seo":7615,"slug":7616,"stem":7617,"summary":7618,"tags":7619,"updatedAt":253,"visible":84,"__hash__":7622},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7339,"toc":7600},[7340,7343,7345,7348,7350,7356,7367,7369,7386,7388,7390,7463,7465,7471,7473,7475,7500,7502,7511,7517,7528,7530,7536,7542,7551,7553,7568,7570,7591,7593,7595,7598],[10,7341,7342],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7344,16],{"id":16},[10,7346,7347],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7349,22],{"id":22},[10,7351,7352],{},[26,7353],{"alt":7354,"src":7355},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7357,7358,7359,7362,7363,7366],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[63,7360,7361],{},"except","；无论是否异常，",[63,7364,7365],{},"finally"," 都会在离开结构前执行。",[14,7368,35],{"id":35},[37,7370,7371,7377,7383],{},[40,7372,7373,7374,7376],{},"只捕获能够处理的具体异常，不使用空的 ",[63,7375,7361],{}," 吞掉全部错误。",[40,7378,7379,7382],{},[63,7380,7381],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[40,7384,7385],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7387,51],{"id":51},[10,7389,54],{},[56,7391,7393],{"className":58,"code":7392,"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,7394,7395,7400,7405,7410,7415,7420,7424,7429,7434,7439,7444,7448,7453,7458],{"__ignoreMap":61},[66,7396,7397],{"class":68,"line":69},[66,7398,7399],{},"def parse_age(text):\n",[66,7401,7402],{"class":68,"line":75},[66,7403,7404],{},"    age = int(text)\n",[66,7406,7407],{"class":68,"line":81},[66,7408,7409],{},"    if age \u003C 0:\n",[66,7411,7412],{"class":68,"line":88},[66,7413,7414],{},"        raise ValueError(\"年龄不能为负数\")\n",[66,7416,7417],{"class":68,"line":94},[66,7418,7419],{},"    return age\n",[66,7421,7422],{"class":68,"line":99},[66,7423,85],{"emptyLinePlaceholder":84},[66,7425,7426],{"class":68,"line":105},[66,7427,7428],{},"try:\n",[66,7430,7431],{"class":68,"line":111},[66,7432,7433],{},"    age = parse_age(\"18\")\n",[66,7435,7436],{"class":68,"line":117},[66,7437,7438],{},"except ValueError as error:\n",[66,7440,7441],{"class":68,"line":122},[66,7442,7443],{},"    print(\"输入错误：\", error)\n",[66,7445,7446],{"class":68,"line":128},[66,7447,1167],{},[66,7449,7450],{"class":68,"line":134},[66,7451,7452],{},"    print(\"年龄：\", age)\n",[66,7454,7455],{"class":68,"line":140},[66,7456,7457],{},"finally:\n",[66,7459,7460],{"class":68,"line":145},[66,7461,7462],{},"    print(\"处理结束\")\n",[10,7464,157],{},[56,7466,7469],{"className":7467,"code":7468,"language":163,"meta":61},[161],"年龄： 18\n处理结束\n",[63,7470,7468],{"__ignoreMap":61},[10,7472,168],{},[14,7474,171],{"id":171},[173,7476,7477,7489],{},[40,7478,7479,7481,7482,7484,7485,7488],{},[63,7480,3056],{}," 或主动 ",[63,7483,7381],{}," 都可能产生 ",[63,7486,7487],{},"ValueError","，控制流立即离开当前正常路径。",[40,7490,7491,7492,7494,7495,7497,7498,383],{},"有异常时进入匹配的 ",[63,7493,7361],{},"；没有异常时执行 ",[63,7496,1181],{},"；两种情况最后都会执行 ",[63,7499,7365],{},[185,7501,187],{"id":187},[10,7503,7504,2278,7506,1178,7508,7510],{},[63,7505,7361],{},[63,7507,1181],{},[63,7509,7365],{}," 的职责不同，不能只看它们出现的顺序。",[10,7512,7513],{},[26,7514],{"alt":7515,"src":7516},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7518,7519,7521,7522,7524,7525,7527],{},[63,7520,7361],{}," 处理匹配异常，",[63,7523,1181],{}," 只在无异常时运行，",[63,7526,7365],{}," 负责两条路径都需要的清理动作。",[185,7529,187],{"id":4238},[10,7531,7532,7535],{},[63,7533,7534],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7537,7538],{},[26,7539],{"alt":7540,"src":7541},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7543,7544,7545,7547,7548,7550],{},"只把可能产生预期异常的操作放进 ",[63,7546,7534],{},"，后续正常业务放进 ",[63,7549,1181],{},"，错误边界会更清楚。",[14,7552,202],{"id":202},[37,7554,7555,7562],{},[40,7556,7557,7558,7561],{},"使用裸 ",[63,7559,7560],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[40,7563,7564,7565,7567],{},"把整个程序包在一个巨大 ",[63,7566,7534],{}," 中，无法判断究竟哪一步允许失败。",[14,7569,213],{"id":213},[173,7571,7572,7585],{},[40,7573,7574,7575,7578,7579,1178,7582,383],{},"让 ",[63,7576,7577],{},"parse_age"," 分别处理 ",[63,7580,7581],{},"\"abc\"",[63,7583,7584],{},"\"-1\"",[40,7586,7587,7588,7590],{},"为文件读取捕获 ",[63,7589,6797],{}," 并给出清晰提示。",[10,7592,224],{},[14,7594,227],{"id":227},[10,7596,7597],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,7599,234],{},{"title":61,"searchDepth":75,"depth":75,"links":7601},[7602,7603,7604,7605,7606,7610,7611,7612],{"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":171,"depth":75,"text":171,"children":7607},[7608,7609],{"id":187,"depth":81,"text":187},{"id":4238,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7337,"description":7342},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[247,7620,7621],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7624,"title":7625,"body":7626,"category":247,"cover":248,"description":7630,"extension":249,"meta":7806,"navigation":84,"path":7807,"pinned":252,"publishedAt":253,"seo":7808,"slug":7809,"stem":7810,"summary":7811,"tags":7812,"updatedAt":253,"visible":84,"__hash__":7814},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7627,"toc":7796},[7628,7631,7633,7636,7638,7644,7650,7652,7668,7670,7672,7726,7728,7734,7736,7738,7751,7753,7766,7768,7787,7789,7791,7794],[10,7629,7630],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7632,16],{"id":16},[10,7634,7635],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7637,22],{"id":22},[10,7639,7640],{},[26,7641],{"alt":7642,"src":7643},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7645,7646,7647,7649],{},"进入 ",[63,7648,6807],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7651,35],{"id":35},[37,7653,7654,7659,7665],{},[40,7655,7656,7658],{},[63,7657,6807],{}," 把资源获取和释放配成一个清晰边界。",[40,7660,7661,7664],{},[63,7662,7663],{},"as file"," 得到的是上下文返回的资源对象。",[40,7666,7667],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7669,51],{"id":51},[10,7671,54],{},[56,7673,7675],{"className":58,"code":7674,"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,7676,7677,7681,7685,7689,7693,7698,7703,7707,7712,7717,7721],{"__ignoreMap":61},[66,7678,7679],{"class":68,"line":69},[66,7680,6619],{},[66,7682,7683],{"class":68,"line":75},[66,7684,85],{"emptyLinePlaceholder":84},[66,7686,7687],{"class":68,"line":81},[66,7688,6830],{},[66,7690,7691],{"class":68,"line":88},[66,7692,85],{"emptyLinePlaceholder":84},[66,7694,7695],{"class":68,"line":94},[66,7696,7697],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[66,7699,7700],{"class":68,"line":99},[66,7701,7702],{},"    file.write(\"上下文管理器\\n\")\n",[66,7704,7705],{"class":68,"line":105},[66,7706,85],{"emptyLinePlaceholder":84},[66,7708,7709],{"class":68,"line":111},[66,7710,7711],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[66,7713,7714],{"class":68,"line":117},[66,7715,7716],{},"    print(file.read())\n",[66,7718,7719],{"class":68,"line":122},[66,7720,85],{"emptyLinePlaceholder":84},[66,7722,7723],{"class":68,"line":128},[66,7724,7725],{},"print(file.closed)\n",[10,7727,157],{},[56,7729,7732],{"className":7730,"code":7731,"language":163,"meta":61},[161],"上下文管理器\n\nTrue\n",[63,7733,7731],{"__ignoreMap":61},[10,7735,168],{},[14,7737,171],{"id":171},[173,7739,7740,7748],{},[40,7741,7646,7742,7744,7745,383],{},[63,7743,6807],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[63,7746,7747],{},"file",[40,7749,7750],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7752,202],{"id":202},[37,7754,7755,7760],{},[40,7756,4806,7757,7759],{},[63,7758,6807],{}," 代码块外继续读写已经关闭的文件对象。",[40,7761,7762,7763,7765],{},"误以为 ",[63,7764,6807],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7767,213],{"id":213},[173,7769,7770,7779],{},[40,7771,7772,7773,7776,7777,383],{},"把第 30 篇的手动 ",[63,7774,7775],{},"open\u002Fclose"," 改写为 ",[63,7778,6807],{},[40,7780,4806,7781,7783,7784,383],{},[63,7782,6807],{}," 块后检查 ",[63,7785,7786],{},"file.closed",[10,7788,224],{},[14,7790,227],{"id":227},[10,7792,7793],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,7795,234],{},{"title":61,"searchDepth":75,"depth":75,"links":7797},[7798,7799,7800,7801,7802,7803,7804,7805],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7625,"description":7630},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[247,6807,7813],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7816,"title":7817,"body":7818,"category":247,"cover":248,"description":7822,"extension":249,"meta":8034,"navigation":84,"path":8035,"pinned":252,"publishedAt":253,"seo":8036,"slug":8037,"stem":8038,"summary":8039,"tags":8040,"updatedAt":253,"visible":84,"__hash__":8043},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7819,"toc":8022},[7820,7823,7825,7828,7830,7836,7839,7841,7858,7860,7862,7930,7932,7938,7940,7942,7967,7969,7972,7978,7987,7989,8000,8002,8013,8015,8017,8020],[10,7821,7822],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7824,16],{"id":16},[10,7826,7827],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7829,22],{"id":22},[10,7831,7832],{},[26,7833],{"alt":7834,"src":7835},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7837,7838],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7840,35],{"id":35},[37,7842,7843,7849,7855],{},[40,7844,7845,7848],{},[63,7846,7847],{},"self"," 表示当前实例，由方法调用自动传入。",[40,7850,7851,7854],{},[63,7852,7853],{},"__init__"," 在实例创建过程中初始化属性。",[40,7856,7857],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7859,51],{"id":51},[10,7861,54],{},[56,7863,7865],{"className":58,"code":7864,"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,7866,7867,7872,7877,7882,7887,7891,7896,7901,7906,7911,7915,7920,7925],{"__ignoreMap":61},[66,7868,7869],{"class":68,"line":69},[66,7870,7871],{},"class LearningRecord:\n",[66,7873,7874],{"class":68,"line":75},[66,7875,7876],{},"    def __init__(self, course, progress=0):\n",[66,7878,7879],{"class":68,"line":81},[66,7880,7881],{},"        self.course = course\n",[66,7883,7884],{"class":68,"line":88},[66,7885,7886],{},"        self.progress = progress\n",[66,7888,7889],{"class":68,"line":94},[66,7890,85],{"emptyLinePlaceholder":84},[66,7892,7893],{"class":68,"line":99},[66,7894,7895],{},"    def advance(self, amount):\n",[66,7897,7898],{"class":68,"line":105},[66,7899,7900],{},"        self.progress = self.progress + amount\n",[66,7902,7903],{"class":68,"line":111},[66,7904,7905],{},"        if self.progress > 100:\n",[66,7907,7908],{"class":68,"line":117},[66,7909,7910],{},"            self.progress = 100\n",[66,7912,7913],{"class":68,"line":122},[66,7914,85],{"emptyLinePlaceholder":84},[66,7916,7917],{"class":68,"line":128},[66,7918,7919],{},"record = LearningRecord(\"Python\", 40)\n",[66,7921,7922],{"class":68,"line":134},[66,7923,7924],{},"record.advance(15)\n",[66,7926,7927],{"class":68,"line":140},[66,7928,7929],{},"print(record.course, record.progress)\n",[10,7931,157],{},[56,7933,7936],{"className":7934,"code":7935,"language":163,"meta":61},[161],"Python 55\n",[63,7937,7935],{"__ignoreMap":61},[10,7939,168],{},[14,7941,171],{"id":171},[173,7943,7944,7954],{},[40,7945,7946,7947,7950,7951,7953],{},"调用 ",[63,7948,7949],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[63,7952,7853],{}," 把课程和进度保存在该实例属性中。",[40,7955,7956,7959,7960,7963,7964,7966],{},[63,7957,7958],{},"record.advance(15)"," 自动把 ",[63,7961,7962],{},"record"," 作为 ",[63,7965,7847],{},"，方法更新同一实例的进度并限制上限。",[185,7968,187],{"id":187},[10,7970,7971],{},"类是共同定义，实例则各自保存状态。",[10,7973,7974],{},[26,7975],{"alt":7976,"src":7977},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7979,7980,7981,1178,7983,7986],{},"两个实例共享同一套方法定义，但 ",[63,7982,4603],{},[63,7984,7985],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,7988,202],{"id":202},[37,7990,7991,7997],{},[40,7992,7993,7994,7996],{},"调用实例方法时手工再传一次 ",[63,7995,7847],{},"。通过实例调用时 Python 会自动绑定。",[40,7998,7999],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,8001,213],{"id":213},[173,8003,8004,8010],{},[40,8005,5316,8006,8009],{},[63,8007,8008],{},"Book"," 类，保存标题和阅读页数。",[40,8011,8012],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,8014,224],{},[14,8016,227],{"id":227},[10,8018,8019],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,8021,234],{},{"title":61,"searchDepth":75,"depth":75,"links":8023},[8024,8025,8026,8027,8028,8031,8032,8033],{"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":171,"depth":75,"text":171,"children":8029},[8030],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7817,"description":7822},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[247,8041,8042],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":8045,"title":8046,"body":8047,"category":247,"cover":248,"description":8051,"extension":249,"meta":8229,"navigation":84,"path":8230,"pinned":252,"publishedAt":253,"seo":8231,"slug":8232,"stem":8233,"summary":8234,"tags":8235,"updatedAt":253,"visible":84,"__hash__":8238},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8048,"toc":8219},[8049,8052,8054,8057,8059,8065,8068,8070,8081,8083,8085,8152,8154,8160,8162,8164,8183,8185,8193,8195,8210,8212,8214,8217],[10,8050,8051],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,8053,16],{"id":16},[10,8055,8056],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8058,22],{"id":22},[10,8060,8061],{},[26,8062],{"alt":8063,"src":8064},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8066,8067],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8069,35],{"id":35},[37,8071,8072,8075,8078],{},[40,8073,8074],{},"封装让对象通过方法维护自己的有效状态。",[40,8076,8077],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[40,8079,8080],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8082,51],{"id":51},[10,8084,54],{},[56,8086,8088],{"className":58,"code":8087,"language":60,"meta":61,"style":61},"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",[63,8089,8090,8095,8100,8105,8109,8114,8119,8124,8128,8133,8138,8142,8147],{"__ignoreMap":61},[66,8091,8092],{"class":68,"line":69},[66,8093,8094],{},"class Storage:\n",[66,8096,8097],{"class":68,"line":75},[66,8098,8099],{},"    def save(self, text):\n",[66,8101,8102],{"class":68,"line":81},[66,8103,8104],{},"        print(\"保存：\", text)\n",[66,8106,8107],{"class":68,"line":88},[66,8108,85],{"emptyLinePlaceholder":84},[66,8110,8111],{"class":68,"line":94},[66,8112,8113],{},"class LearningService:\n",[66,8115,8116],{"class":68,"line":99},[66,8117,8118],{},"    def __init__(self, storage):\n",[66,8120,8121],{"class":68,"line":105},[66,8122,8123],{},"        self.storage = storage\n",[66,8125,8126],{"class":68,"line":111},[66,8127,85],{"emptyLinePlaceholder":84},[66,8129,8130],{"class":68,"line":117},[66,8131,8132],{},"    def finish_lesson(self, title):\n",[66,8134,8135],{"class":68,"line":122},[66,8136,8137],{},"        self.storage.save(title)\n",[66,8139,8140],{"class":68,"line":128},[66,8141,85],{"emptyLinePlaceholder":84},[66,8143,8144],{"class":68,"line":134},[66,8145,8146],{},"service = LearningService(Storage())\n",[66,8148,8149],{"class":68,"line":140},[66,8150,8151],{},"service.finish_lesson(\"异常处理\")\n",[10,8153,157],{},[56,8155,8158],{"className":8156,"code":8157,"language":163,"meta":61},[161],"保存： 异常处理\n",[63,8159,8157],{"__ignoreMap":61},[10,8161,168],{},[14,8163,171],{"id":171},[173,8165,8166,8176],{},[40,8167,8168,8171,8172,8175],{},[63,8169,8170],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[63,8173,8174],{},"save()"," 的协作对象。",[40,8177,8178,8179,8182],{},"调用业务方法时，服务把保存动作委托给 ",[63,8180,8181],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8184,202],{"id":202},[37,8186,8187,8190],{},[40,8188,8189],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[40,8191,8192],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8194,213],{"id":213},[173,8196,8197,8207],{},[40,8198,8199,8200,8203,8204,383],{},"用组合让 ",[63,8201,8202],{},"OrderService"," 使用一个 ",[63,8205,8206],{},"Notifier",[40,8208,8209],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8211,224],{},[14,8213,227],{"id":227},[10,8215,8216],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,8218,234],{},{"title":61,"searchDepth":75,"depth":75,"links":8220},[8221,8222,8223,8224,8225,8226,8227,8228],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":8046,"description":8051},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[247,8236,8237],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8240,"title":8241,"body":8242,"category":247,"cover":248,"description":8246,"extension":249,"meta":8449,"navigation":84,"path":8450,"pinned":252,"publishedAt":253,"seo":8451,"slug":8452,"stem":8453,"summary":8454,"tags":8455,"updatedAt":253,"visible":84,"__hash__":8458},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8243,"toc":8437},[8244,8247,8249,8252,8254,8260,8267,8269,8294,8296,8298,8350,8352,8358,8360,8362,8383,8385,8391,8397,8403,8405,8413,8415,8428,8430,8432,8435],[10,8245,8246],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8248,16],{"id":16},[10,8250,8251],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8253,22],{"id":22},[10,8255,8256],{},[26,8257],{"alt":8258,"src":8259},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8261,8262,8263,8266],{},"生成器运行到 ",[63,8264,8265],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8268,35],{"id":35},[37,8270,8271,8281,8291],{},[40,8272,8273,8276,8277,8280],{},[63,8274,8275],{},"iter()"," 从可迭代对象取得迭代器，",[63,8278,8279],{},"next()"," 请求下一个值。",[40,8282,8283,8284,8287,8288,8290],{},"没有更多值时迭代器抛出 ",[63,8285,8286],{},"StopIteration","，",[63,8289,4357],{}," 会自动处理。",[40,8292,8293],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8295,51],{"id":51},[10,8297,54],{},[56,8299,8301],{"className":58,"code":8300,"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,8302,8303,8308,8313,8318,8323,8328,8332,8337,8342,8346],{"__ignoreMap":61},[66,8304,8305],{"class":68,"line":69},[66,8306,8307],{},"def countdown(start):\n",[66,8309,8310],{"class":68,"line":75},[66,8311,8312],{},"    current = start\n",[66,8314,8315],{"class":68,"line":81},[66,8316,8317],{},"    while current > 0:\n",[66,8319,8320],{"class":68,"line":88},[66,8321,8322],{},"        yield current\n",[66,8324,8325],{"class":68,"line":94},[66,8326,8327],{},"        current = current - 1\n",[66,8329,8330],{"class":68,"line":99},[66,8331,85],{"emptyLinePlaceholder":84},[66,8333,8334],{"class":68,"line":105},[66,8335,8336],{},"iterator = countdown(3)\n",[66,8338,8339],{"class":68,"line":111},[66,8340,8341],{},"print(next(iterator))\n",[66,8343,8344],{"class":68,"line":117},[66,8345,8341],{},[66,8347,8348],{"class":68,"line":122},[66,8349,8341],{},[10,8351,157],{},[56,8353,8356],{"className":8354,"code":8355,"language":163,"meta":61},[161],"3\n2\n1\n",[63,8357,8355],{"__ignoreMap":61},[10,8359,168],{},[14,8361,171],{"id":171},[173,8363,8364,8370],{},[40,8365,7946,8366,8369],{},[63,8367,8368],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[40,8371,8372,8373,8375,8376,8378,8379,8382],{},"每次 ",[63,8374,8279],{}," 运行到下一个 ",[63,8377,8265],{}," 并暂停，局部变量 ",[63,8380,8381],{},"current"," 和执行位置被保留。",[185,8384,187],{"id":187},[10,8386,8387,8388,8390],{},"生成器的暂停位置可以展开成多次 ",[63,8389,8279],{}," 的时间线。",[10,8392,8393],{},[26,8394],{"alt":8395,"src":8396},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8398,8399,8400,8402],{},"每次请求只推进到下一个 ",[63,8401,8265],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8404,202],{"id":202},[37,8406,8407,8410],{},[40,8408,8409],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[40,8411,8412],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8414,213],{"id":213},[173,8416,8417,8420],{},[40,8418,8419],{},"编写产生 1 到指定上限偶数的生成器。",[40,8421,4030,8422,8424,8425,8427],{},[63,8423,4357],{}," 遍历生成器，比较手动 ",[63,8426,8279],{}," 的差异。",[10,8429,224],{},[14,8431,227],{"id":227},[10,8433,8434],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,8436,234],{},{"title":61,"searchDepth":75,"depth":75,"links":8438},[8439,8440,8441,8442,8443,8446,8447,8448],{"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":171,"depth":75,"text":171,"children":8444},[8445],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8241,"description":8246},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[247,8456,8457],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8460,"title":8461,"body":8462,"category":247,"cover":248,"description":8466,"extension":249,"meta":8689,"navigation":84,"path":8690,"pinned":252,"publishedAt":253,"seo":8691,"slug":8692,"stem":8693,"summary":8694,"tags":8695,"updatedAt":253,"visible":84,"__hash__":8697},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8463,"toc":8677},[8464,8467,8469,8472,8474,8480,8483,8485,8505,8507,8509,8590,8592,8598,8600,8602,8624,8626,8629,8635,8642,8644,8654,8656,8668,8670,8672,8675],[10,8465,8466],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8468,16],{"id":16},[10,8470,8471],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8473,22],{"id":22},[10,8475,8476],{},[26,8477],{"alt":8478,"src":8479},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8481,8482],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8484,35],{"id":35},[37,8486,8487,8496,8499],{},[40,8488,8489,8492,8493,383],{},[63,8490,8491],{},"@trace"," 等价于 ",[63,8494,8495],{},"add = trace(add)",[40,8497,8498],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[40,8500,8501,8504],{},[63,8502,8503],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8506,51],{"id":51},[10,8508,54],{},[56,8510,8512],{"className":58,"code":8511,"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,8513,8514,8519,8523,8528,8533,8538,8543,8548,8553,8558,8563,8567,8572,8576,8580,8584],{"__ignoreMap":61},[66,8515,8516],{"class":68,"line":69},[66,8517,8518],{},"from functools import wraps\n",[66,8520,8521],{"class":68,"line":75},[66,8522,85],{"emptyLinePlaceholder":84},[66,8524,8525],{"class":68,"line":81},[66,8526,8527],{},"def trace(function):\n",[66,8529,8530],{"class":68,"line":88},[66,8531,8532],{},"    @wraps(function)\n",[66,8534,8535],{"class":68,"line":94},[66,8536,8537],{},"    def wrapper(*args, **kwargs):\n",[66,8539,8540],{"class":68,"line":99},[66,8541,8542],{},"        print(\"开始：\", function.__name__)\n",[66,8544,8545],{"class":68,"line":105},[66,8546,8547],{},"        result = function(*args, **kwargs)\n",[66,8549,8550],{"class":68,"line":111},[66,8551,8552],{},"        print(\"结束：\", function.__name__)\n",[66,8554,8555],{"class":68,"line":117},[66,8556,8557],{},"        return result\n",[66,8559,8560],{"class":68,"line":122},[66,8561,8562],{},"    return wrapper\n",[66,8564,8565],{"class":68,"line":128},[66,8566,85],{"emptyLinePlaceholder":84},[66,8568,8569],{"class":68,"line":134},[66,8570,8571],{},"@trace\n",[66,8573,8574],{"class":68,"line":140},[66,8575,6199],{},[66,8577,8578],{"class":68,"line":145},[66,8579,6204],{},[66,8581,8582],{"class":68,"line":151},[66,8583,85],{"emptyLinePlaceholder":84},[66,8585,8587],{"class":68,"line":8586},16,[66,8588,8589],{},"print(add(2, 3))\n",[10,8591,157],{},[56,8593,8596],{"className":8594,"code":8595,"language":163,"meta":61},[161],"开始： add\n结束： add\n5\n",[63,8597,8595],{"__ignoreMap":61},[10,8599,168],{},[14,8601,171],{"id":171},[173,8603,8604,8621],{},[40,8605,8606,8607,8610,8611,8614,8615,8618,8619,383],{},"解释器执行定义时，把原 ",[63,8608,8609],{},"add"," 函数交给 ",[63,8612,8613],{},"trace","，返回的 ",[63,8616,8617],{},"wrapper"," 重新绑定到名字 ",[63,8620,8609],{},[40,8622,8623],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[185,8625,187],{"id":187},[10,8627,8628],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8630,8631],{},[26,8632],{"alt":8633,"src":8634},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8636,8637,8639,8640,383],{},[63,8638,8491],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[63,8641,8495],{},[14,8643,202],{"id":202},[37,8645,8646,8651],{},[40,8647,8648,8649,383],{},"包装函数忘记返回原函数结果，调用方得到 ",[63,8650,5399],{},[40,8652,8653],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8655,213],{"id":213},[173,8657,8658,8661],{},[40,8659,8660],{},"编写只记录调用次数的简单装饰器。",[40,8662,8663,8664,8667],{},"删除包装函数的 ",[63,8665,8666],{},"return result","，观察调用方得到什么。",[10,8669,224],{},[14,8671,227],{"id":227},[10,8673,8674],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,8676,234],{},{"title":61,"searchDepth":75,"depth":75,"links":8678},[8679,8680,8681,8682,8683,8686,8687,8688],{"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":171,"depth":75,"text":171,"children":8684},[8685],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8461,"description":8466},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[247,8696,5350],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":4,"title":5,"body":8699,"category":247,"cover":248,"description":12,"extension":249,"meta":8858,"navigation":84,"path":251,"pinned":252,"publishedAt":253,"seo":8859,"slug":255,"stem":256,"summary":257,"tags":8860,"updatedAt":253,"visible":84,"__hash__":261},{"type":7,"value":8700,"toc":8846},[8701,8703,8705,8707,8709,8713,8715,8717,8725,8727,8729,8793,8795,8800,8802,8804,8812,8814,8816,8820,8822,8824,8830,8832,8838,8840,8842,8844],[10,8702,12],{},[14,8704,16],{"id":16},[10,8706,19],{},[14,8708,22],{"id":22},[10,8710,8711],{},[26,8712],{"alt":28,"src":29},[10,8714,32],{},[14,8716,35],{"id":35},[37,8718,8719,8721,8723],{},[40,8720,42],{},[40,8722,45],{},[40,8724,48],{},[14,8726,51],{"id":51},[10,8728,54],{},[56,8730,8731],{"className":58,"code":59,"language":60,"meta":61,"style":61},[63,8732,8733,8737,8741,8745,8749,8753,8757,8761,8765,8769,8773,8777,8781,8785,8789],{"__ignoreMap":61},[66,8734,8735],{"class":68,"line":69},[66,8736,72],{},[66,8738,8739],{"class":68,"line":75},[66,8740,78],{},[66,8742,8743],{"class":68,"line":81},[66,8744,85],{"emptyLinePlaceholder":84},[66,8746,8747],{"class":68,"line":88},[66,8748,91],{},[66,8750,8751],{"class":68,"line":94},[66,8752,85],{"emptyLinePlaceholder":84},[66,8754,8755],{"class":68,"line":99},[66,8756,102],{},[66,8758,8759],{"class":68,"line":105},[66,8760,108],{},[66,8762,8763],{"class":68,"line":111},[66,8764,114],{},[66,8766,8767],{"class":68,"line":117},[66,8768,85],{"emptyLinePlaceholder":84},[66,8770,8771],{"class":68,"line":122},[66,8772,125],{},[66,8774,8775],{"class":68,"line":128},[66,8776,131],{},[66,8778,8779],{"class":68,"line":134},[66,8780,137],{},[66,8782,8783],{"class":68,"line":140},[66,8784,85],{"emptyLinePlaceholder":84},[66,8786,8787],{"class":68,"line":145},[66,8788,148],{},[66,8790,8791],{"class":68,"line":151},[66,8792,154],{},[10,8794,157],{},[56,8796,8798],{"className":8797,"code":162,"language":163,"meta":61},[161],[63,8799,162],{"__ignoreMap":61},[10,8801,168],{},[14,8803,171],{"id":171},[173,8805,8806,8810],{},[40,8807,8808,180],{},[63,8809,179],{},[40,8811,183],{},[185,8813,187],{"id":187},[10,8815,190],{},[10,8817,8818],{},[26,8819],{"alt":195,"src":196},[10,8821,199],{},[14,8823,202],{"id":202},[37,8825,8826,8828],{},[40,8827,207],{},[40,8829,210],{},[14,8831,213],{"id":213},[173,8833,8834,8836],{},[40,8835,218],{},[40,8837,221],{},[10,8839,224],{},[14,8841,227],{"id":227},[10,8843,230],{},[232,8845,234],{},{"title":61,"searchDepth":75,"depth":75,"links":8847},[8848,8849,8850,8851,8852,8855,8856,8857],{"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":171,"depth":75,"text":171,"children":8853},[8854],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5,"description":12},[247,259,260],{"id":8862,"title":8863,"body":8864,"category":247,"cover":248,"description":8868,"extension":249,"meta":9168,"navigation":84,"path":9169,"pinned":252,"publishedAt":253,"seo":9170,"slug":9171,"stem":9172,"summary":9173,"tags":9174,"updatedAt":253,"visible":84,"__hash__":9177},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8865,"toc":9155},[8866,8869,8871,8874,8876,8882,8885,8887,8902,8904,8906,9053,9055,9061,9063,9065,9078,9080,9083,9089,9092,9094,9097,9103,9110,9112,9123,9125,9146,9148,9150,9153],[10,8867,8868],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8870,16],{"id":16},[10,8872,8873],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8875,22],{"id":22},[10,8877,8878],{},[26,8879],{"alt":8880,"src":8881},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8883,8884],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8886,35],{"id":35},[37,8888,8889,8892,8895],{},[40,8890,8891],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[40,8893,8894],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[40,8896,8897,8898,8901],{},"实际扩展前先为 ",[63,8899,8900],{},"add()"," 和存储边界补充测试。",[14,8903,51],{"id":51},[10,8905,54],{},[56,8907,8909],{"className":58,"code":8908,"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,8910,8911,8915,8919,8923,8928,8933,8938,8943,8947,8952,8957,8962,8967,8972,8976,8981,8986,8992,8997,9003,9008,9013,9019,9025,9031,9036,9042,9047],{"__ignoreMap":61},[66,8912,8913],{"class":68,"line":69},[66,8914,7010],{},[66,8916,8917],{"class":68,"line":75},[66,8918,6619],{},[66,8920,8921],{"class":68,"line":81},[66,8922,85],{"emptyLinePlaceholder":84},[66,8924,8925],{"class":68,"line":88},[66,8926,8927],{},"class LearningRecords:\n",[66,8929,8930],{"class":68,"line":94},[66,8931,8932],{},"    def __init__(self, file_path):\n",[66,8934,8935],{"class":68,"line":99},[66,8936,8937],{},"        self.file_path = Path(file_path)\n",[66,8939,8940],{"class":68,"line":105},[66,8941,8942],{},"        self.items = []\n",[66,8944,8945],{"class":68,"line":111},[66,8946,85],{"emptyLinePlaceholder":84},[66,8948,8949],{"class":68,"line":117},[66,8950,8951],{},"    def add(self, title):\n",[66,8953,8954],{"class":68,"line":122},[66,8955,8956],{},"        title = title.strip()\n",[66,8958,8959],{"class":68,"line":128},[66,8960,8961],{},"        if not title:\n",[66,8963,8964],{"class":68,"line":134},[66,8965,8966],{},"            raise ValueError(\"课程名称不能为空\")\n",[66,8968,8969],{"class":68,"line":140},[66,8970,8971],{},"        self.items.append({\"title\": title, \"done\": False})\n",[66,8973,8974],{"class":68,"line":145},[66,8975,85],{"emptyLinePlaceholder":84},[66,8977,8978],{"class":68,"line":151},[66,8979,8980],{},"    def save(self):\n",[66,8982,8983],{"class":68,"line":8586},[66,8984,8985],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[66,8987,8989],{"class":68,"line":8988},17,[66,8990,8991],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[66,8993,8995],{"class":68,"line":8994},18,[66,8996,85],{"emptyLinePlaceholder":84},[66,8998,9000],{"class":68,"line":8999},19,[66,9001,9002],{},"records = LearningRecords(\"learning-records.json\")\n",[66,9004,9006],{"class":68,"line":9005},20,[66,9007,85],{"emptyLinePlaceholder":84},[66,9009,9011],{"class":68,"line":9010},21,[66,9012,7428],{},[66,9014,9016],{"class":68,"line":9015},22,[66,9017,9018],{},"    title = input(\"输入已学习课程：\")\n",[66,9020,9022],{"class":68,"line":9021},23,[66,9023,9024],{},"    records.add(title)\n",[66,9026,9028],{"class":68,"line":9027},24,[66,9029,9030],{},"    records.save()\n",[66,9032,9034],{"class":68,"line":9033},25,[66,9035,7438],{},[66,9037,9039],{"class":68,"line":9038},26,[66,9040,9041],{},"    print(\"无法保存：\", error)\n",[66,9043,9045],{"class":68,"line":9044},27,[66,9046,1167],{},[66,9048,9050],{"class":68,"line":9049},28,[66,9051,9052],{},"    print(\"已保存 1 条学习记录\")\n",[10,9054,157],{},[56,9056,9059],{"className":9057,"code":9058,"language":163,"meta":61},[161],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[63,9060,9058],{"__ignoreMap":61},[10,9062,168],{},[14,9064,171],{"id":171},[173,9066,9067,9073],{},[40,9068,9069,9070,9072],{},"输入层取得课程名后，",[63,9071,8900],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[40,9074,9075,9077],{},[63,9076,8174],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[185,9079,187],{"id":187},[10,9081,9082],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9084,9085],{},[26,9086],{"alt":9087,"src":9088},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9090,9091],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[185,9093,187],{"id":4238},[10,9095,9096],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9098,9099],{},[26,9100],{"alt":9101,"src":9102},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9104,9105,9106,9109],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[63,9107,9108],{},"load()"," 把文件状态恢复到内存。",[14,9111,202],{"id":202},[37,9113,9114,9117],{},[40,9115,9116],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[40,9118,9119,9120,9122],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[63,9121,9108],{}," 是下一项必要扩展。",[14,9124,213],{"id":213},[173,9126,9127,9133,9136],{},[40,9128,9129,9130,9132],{},"增加 ",[63,9131,9108],{},"，文件不存在时从空列表开始。",[40,9134,9135],{},"增加按序号标记完成的功能，并校验序号范围。",[40,9137,9138,9139,9142,9143,9145],{},"把输入循环放进 ",[63,9140,9141],{},"main()","，通过 ",[63,9144,6155],{}," 控制程序入口。",[10,9147,224],{},[14,9149,227],{"id":227},[10,9151,9152],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[232,9154,234],{},{"title":61,"searchDepth":75,"depth":75,"links":9156},[9157,9158,9159,9160,9161,9165,9166,9167],{"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":171,"depth":75,"text":171,"children":9162},[9163,9164],{"id":187,"depth":81,"text":187},{"id":4238,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8863,"description":8868},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[247,9175,9176],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9179,9282,9401,9532,9675,9800,9937,10074,10215,10384,10521,10654,10777,10906,11033,11196,11372,11513,11642,11791,11934,12055,12178,12327,12480,12645,12772,12953,13096,13253,13404,13551,13706,13924,14079,14254,14405,14572,14759,14922,15164,15404],{"id":1414,"title":1415,"body":9180,"category":247,"cover":248,"description":1420,"extension":249,"meta":9279,"navigation":84,"path":1539,"pinned":252,"publishedAt":253,"seo":9280,"slug":1541,"stem":1542,"summary":1543,"tags":9281,"updatedAt":253,"visible":84,"__hash__":1546},{"type":7,"value":9181,"toc":9269},[9182,9184,9186,9188,9190,9194,9198,9200,9210,9212,9214,9222,9224,9229,9231,9233,9243,9245,9253,9255,9261,9263,9265,9267],[10,9183,1420],{},[14,9185,16],{"id":16},[10,9187,1425],{},[14,9189,22],{"id":22},[10,9191,9192],{},[26,9193],{"alt":1432,"src":1433},[10,9195,9196,1438],{},[63,9197,1192],{},[14,9199,35],{"id":35},[37,9201,9202,9206,9208],{},[40,9203,1445,9204,1448],{},[63,9205,1192],{},[40,9207,1451],{},[40,9209,1454],{},[14,9211,51],{"id":51},[10,9213,54],{},[56,9215,9216],{"className":58,"code":1461,"language":60,"meta":61,"style":61},[63,9217,9218],{"__ignoreMap":61},[66,9219,9220],{"class":68,"line":69},[66,9221,1461],{},[10,9223,157],{},[56,9225,9227],{"className":9226,"code":1473,"language":163,"meta":61},[161],[63,9228,1473],{"__ignoreMap":61},[10,9230,168],{},[14,9232,171],{"id":171},[173,9234,9235,9239],{},[40,9236,1484,9237,1488],{},[63,9238,1487],{},[40,9240,1491,9241,1495],{},[63,9242,1494],{},[14,9244,202],{"id":202},[37,9246,9247,9249],{},[40,9248,1502],{},[40,9250,1505,9251,1508],{},[63,9252,1192],{},[14,9254,213],{"id":213},[173,9256,9257,9259],{},[40,9258,1515],{},[40,9260,1518],{},[10,9262,224],{},[14,9264,227],{"id":227},[10,9266,1525],{},[232,9268,234],{},{"title":61,"searchDepth":75,"depth":75,"links":9270},[9271,9272,9273,9274,9275,9276,9277,9278],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":1415,"description":1420},[247,1410,1545],{"id":1548,"title":1549,"body":9283,"category":247,"cover":248,"description":1554,"extension":249,"meta":9398,"navigation":84,"path":1691,"pinned":252,"publishedAt":253,"seo":9399,"slug":1693,"stem":1694,"summary":1695,"tags":9400,"updatedAt":253,"visible":84,"__hash__":1698},{"type":7,"value":9284,"toc":9388},[9285,9287,9289,9291,9293,9297,9301,9303,9313,9315,9317,9337,9339,9344,9346,9348,9358,9360,9370,9372,9380,9382,9384,9386],[10,9286,1554],{},[14,9288,16],{"id":16},[10,9290,1559],{},[14,9292,22],{"id":22},[10,9294,9295],{},[26,9296],{"alt":1566,"src":1567},[10,9298,1570,9299,1573],{},[63,9300,712],{},[14,9302,35],{"id":35},[37,9304,9305,9307,9309],{},[40,9306,1580],{},[40,9308,1583],{},[40,9310,1586,9311,1590],{},[63,9312,1589],{},[14,9314,51],{"id":51},[10,9316,1595],{},[56,9318,9319],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,9320,9321,9327],{"__ignoreMap":61},[66,9322,9323,9325],{"class":68,"line":69},[66,9324,712],{"class":621},[66,9326,625],{"class":624},[66,9328,9329,9331,9333,9335],{"class":68,"line":75},[66,9330,712],{"class":621},[66,9332,654],{"class":624},[66,9334,658],{"class":657},[66,9336,625],{"class":624},[10,9338,157],{},[56,9340,9342],{"className":9341,"code":1621,"language":163,"meta":61},[161],[63,9343,1621],{"__ignoreMap":61},[10,9345,168],{},[14,9347,171],{"id":171},[173,9349,9350,9354],{},[40,9351,9352,1635],{},[63,9353,1634],{},[40,9355,9356,1640],{},[63,9357,720],{},[14,9359,202],{"id":202},[37,9361,9362,9366],{},[40,9363,1647,9364,1650],{},[63,9365,712],{},[40,9367,1653,9368,1656],{},[63,9369,712],{},[14,9371,213],{"id":213},[173,9373,9374,9378],{},[40,9375,959,9376,1666],{},[63,9377,1665],{},[40,9379,1669],{},[10,9381,224],{},[14,9383,227],{"id":227},[10,9385,1676],{},[232,9387,1679],{},{"title":61,"searchDepth":75,"depth":75,"links":9389},[9390,9391,9392,9393,9394,9395,9396,9397],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":1549,"description":1554},[247,1697,1073],{"id":1700,"title":1701,"body":9402,"category":247,"cover":248,"description":1867,"extension":249,"meta":9529,"navigation":84,"path":1869,"pinned":252,"publishedAt":253,"seo":9530,"slug":1871,"stem":1872,"summary":1873,"tags":9531,"updatedAt":253,"visible":84,"__hash__":1877},{"type":7,"value":9403,"toc":9519},[9404,9408,9410,9412,9414,9418,9420,9422,9438,9440,9442,9462,9464,9469,9471,9473,9485,9487,9497,9499,9509,9511,9513,9517],[10,9405,1706,9406,1709],{},[63,9407,1192],{},[14,9409,16],{"id":16},[10,9411,1714],{},[14,9413,22],{"id":22},[10,9415,9416],{},[26,9417],{"alt":1721,"src":1722},[10,9419,1725],{},[14,9421,35],{"id":35},[37,9423,9424,9430,9434],{},[40,9425,1732,9426,1735,9428,383],{},[63,9427,712],{},[63,9429,1738],{},[40,9431,1741,9432,1745],{},[63,9433,1744],{},[40,9435,1748,9436,1751],{},[63,9437,1192],{},[14,9439,51],{"id":51},[10,9441,54],{},[56,9443,9444],{"className":1758,"code":1759,"language":1760,"meta":61,"style":61},[63,9445,9446,9450,9454,9458],{"__ignoreMap":61},[66,9447,9448],{"class":68,"line":69},[66,9449,1767],{},[66,9451,9452],{"class":68,"line":75},[66,9453,1772],{},[66,9455,9456],{"class":68,"line":81},[66,9457,1777],{},[66,9459,9460],{"class":68,"line":88},[66,9461,1782],{},[10,9463,157],{},[56,9465,9467],{"className":9466,"code":1788,"language":163,"meta":61},[161],[63,9468,1788],{"__ignoreMap":61},[10,9470,168],{},[14,9472,171],{"id":171},[173,9474,9475,9481],{},[40,9476,1799,9477,1803,9479,383],{},[63,9478,1802],{},[63,9480,1806],{},[40,9482,1809,9483,1812],{},[63,9484,1494],{},[14,9486,202],{"id":202},[37,9488,9489,9495],{},[40,9490,1819,9491,1822,9493,1825],{},[63,9492,1738],{},[63,9494,1192],{},[40,9496,1828],{},[14,9498,213],{"id":213},[173,9500,9501,9505],{},[40,9502,1835,9503,383],{},[63,9504,1838],{},[40,9506,1841,9507,1844],{},[63,9508,1494],{},[10,9510,224],{},[14,9512,227],{"id":227},[10,9514,1851,9515,1854],{},[63,9516,1192],{},[232,9518,234],{},{"title":61,"searchDepth":75,"depth":75,"links":9520},[9521,9522,9523,9524,9525,9526,9527,9528],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":1701,"description":1867},[247,1875,1876],{"id":1879,"title":1880,"body":9533,"category":247,"cover":248,"description":1885,"extension":249,"meta":9672,"navigation":84,"path":2057,"pinned":252,"publishedAt":253,"seo":9673,"slug":2059,"stem":2060,"summary":2061,"tags":9674,"updatedAt":253,"visible":84,"__hash__":2065},{"type":7,"value":9534,"toc":9662},[9535,9537,9539,9541,9543,9547,9551,9553,9565,9567,9569,9605,9607,9612,9614,9616,9632,9634,9644,9646,9654,9656,9658,9660],[10,9536,1885],{},[14,9538,16],{"id":16},[10,9540,1890],{},[14,9542,22],{"id":22},[10,9544,9545],{},[26,9546],{"alt":1897,"src":1898},[10,9548,9549,1904],{},[63,9550,1903],{},[14,9552,35],{"id":35},[37,9554,9555,9557,9563],{},[40,9556,1911],{},[40,9558,9559,1917,9561,1921],{},[63,9560,1916],{},[63,9562,1920],{},[40,9564,1924],{},[14,9566,51],{"id":51},[10,9568,1595],{},[56,9570,9571],{"className":612,"code":1931,"language":614,"meta":61,"style":61},[63,9572,9573,9579,9585,9589,9599],{"__ignoreMap":61},[66,9574,9575,9577],{"class":68,"line":69},[66,9576,1938],{"class":621},[66,9578,1941],{"class":657},[66,9580,9581,9583],{"class":68,"line":75},[66,9582,1946],{"class":624},[66,9584,1941],{"class":657},[66,9586,9587],{"class":68,"line":81},[66,9588,1953],{"class":624},[66,9590,9591,9593,9595,9597],{"class":68,"line":88},[66,9592,1958],{"class":624},[66,9594,1961],{"class":657},[66,9596,1965],{"class":1964},[66,9598,1236],{"class":657},[66,9600,9601,9603],{"class":68,"line":94},[66,9602,712],{"class":621},[66,9604,1236],{"class":657},[10,9606,157],{},[56,9608,9610],{"className":9609,"code":1979,"language":163,"meta":61},[161],[63,9611,1979],{"__ignoreMap":61},[10,9613,168],{},[14,9615,171],{"id":171},[173,9617,9618,9626],{},[40,9619,9620,1992,9622,1995,9624,1998],{},[63,9621,1938],{},[63,9623,1946],{},[63,9625,1916],{},[40,9627,9628,2003,9630,2007],{},[63,9629,1903],{},[63,9631,2006],{},[14,9633,202],{"id":202},[37,9635,9636,9642],{},[40,9637,2014,9638,1178,9640,383],{},[63,9639,1916],{},[63,9641,1920],{},[40,9643,2021],{},[14,9645,213],{"id":213},[173,9647,9648,9652],{},[40,9649,2028,9650,2032],{},[63,9651,2031],{},[40,9653,2035],{},[10,9655,224],{},[14,9657,227],{"id":227},[10,9659,2042],{},[232,9661,2045],{},{"title":61,"searchDepth":75,"depth":75,"links":9663},[9664,9665,9666,9667,9668,9669,9670,9671],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":1880,"description":1885},[247,2063,2064],{"id":2067,"title":2068,"body":9676,"category":247,"cover":248,"description":2073,"extension":249,"meta":9797,"navigation":84,"path":2222,"pinned":252,"publishedAt":253,"seo":9798,"slug":2224,"stem":2225,"summary":2226,"tags":9799,"updatedAt":253,"visible":84,"__hash__":2230},{"type":7,"value":9677,"toc":9787},[9678,9680,9682,9684,9686,9690,9698,9700,9714,9716,9718,9734,9736,9741,9743,9745,9759,9761,9767,9769,9779,9781,9783,9785],[10,9679,2073],{},[14,9681,16],{"id":16},[10,9683,2078],{},[14,9685,22],{"id":22},[10,9687,9688],{},[26,9689],{"alt":2085,"src":2086},[10,9691,2089,9692,383,9694,2095,9696,383],{},[63,9693,1494],{},[63,9695,2094],{},[63,9697,1802],{},[14,9699,35],{"id":35},[37,9701,9702,9706,9712],{},[40,9703,9704,2107],{},[63,9705,2106],{},[40,9707,9708,2113,9710,383],{},[63,9709,2112],{},[63,9711,2116],{},[40,9713,2119],{},[14,9715,51],{"id":51},[10,9717,54],{},[56,9719,9720],{"className":58,"code":2126,"language":60,"meta":61,"style":61},[63,9721,9722,9726,9730],{"__ignoreMap":61},[66,9723,9724],{"class":68,"line":69},[66,9725,2133],{},[66,9727,9728],{"class":68,"line":75},[66,9729,2138],{},[66,9731,9732],{"class":68,"line":81},[66,9733,2143],{},[10,9735,157],{},[56,9737,9739],{"className":9738,"code":2149,"language":163,"meta":61},[161],[63,9740,2149],{"__ignoreMap":61},[10,9742,168],{},[14,9744,171],{"id":171},[173,9746,9747,9753],{},[40,9748,9749,2163,9751,383],{},[63,9750,2162],{},[63,9752,2116],{},[40,9754,9755,2170,9757,2174],{},[63,9756,1494],{},[63,9758,2173],{},[14,9760,202],{"id":202},[37,9762,9763,9765],{},[40,9764,2181],{},[40,9766,2184],{},[14,9768,213],{"id":213},[173,9770,9771,9773],{},[40,9772,2191],{},[40,9774,2194,9775,2197,9777,2201],{},[63,9776,2094],{},[63,9778,2200],{},[10,9780,224],{},[14,9782,227],{"id":227},[10,9784,2208],{},[232,9786,234],{},{"title":61,"searchDepth":75,"depth":75,"links":9788},[9789,9790,9791,9792,9793,9794,9795,9796],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":2068,"description":2073},[247,2228,2229],{"id":2232,"title":2233,"body":9801,"category":247,"cover":248,"description":2238,"extension":249,"meta":9934,"navigation":84,"path":2406,"pinned":252,"publishedAt":253,"seo":9935,"slug":2408,"stem":2409,"summary":2410,"tags":9936,"updatedAt":253,"visible":84,"__hash__":2414},{"type":7,"value":9802,"toc":9924},[9803,9805,9807,9809,9811,9815,9817,9819,9835,9837,9839,9863,9865,9870,9872,9874,9890,9892,9904,9906,9916,9918,9920,9922],[10,9804,2238],{},[14,9806,16],{"id":16},[10,9808,2243],{},[14,9810,22],{"id":22},[10,9812,9813],{},[26,9814],{"alt":2250,"src":2251},[10,9816,2254],{},[14,9818,35],{"id":35},[37,9820,9821,9823,9829],{},[40,9822,2261],{},[40,9824,2264,9825,2197,9827,2271],{},[63,9826,2267],{},[63,9828,2270],{},[40,9830,2274,9831,2278,9833,2282],{},[63,9832,2277],{},[63,9834,2281],{},[14,9836,51],{"id":51},[10,9838,54],{},[56,9840,9841],{"className":58,"code":2289,"language":60,"meta":61,"style":61},[63,9842,9843,9847,9851,9855,9859],{"__ignoreMap":61},[66,9844,9845],{"class":68,"line":69},[66,9846,2296],{},[66,9848,9849],{"class":68,"line":75},[66,9850,2301],{},[66,9852,9853],{"class":68,"line":81},[66,9854,85],{"emptyLinePlaceholder":84},[66,9856,9857],{"class":68,"line":88},[66,9858,2310],{},[66,9860,9861],{"class":68,"line":94},[66,9862,2301],{},[10,9864,157],{},[56,9866,9868],{"className":9867,"code":2320,"language":163,"meta":61},[161],[63,9869,2320],{"__ignoreMap":61},[10,9871,168],{},[14,9873,171],{"id":171},[173,9875,9876,9882],{},[40,9877,959,9878,2334,9880,2337],{},[63,9879,2333],{},[63,9881,2267],{},[40,9883,959,9884,2343,9886,2347,9888,383],{},[63,9885,2342],{},[63,9887,2346],{},[63,9889,2350],{},[14,9891,202],{"id":202},[37,9893,9894,9896],{},[40,9895,2357],{},[40,9897,2360,9898,2278,9900,2278,9902,2368],{},[63,9899,2277],{},[63,9901,2281],{},[63,9903,2367],{},[14,9905,213],{"id":213},[173,9907,9908,9914],{},[40,9909,2375,9910,1178,9912,2382],{},[63,9911,2378],{},[63,9913,2381],{},[40,9915,2385],{},[10,9917,224],{},[14,9919,227],{"id":227},[10,9921,2392],{},[232,9923,234],{},{"title":61,"searchDepth":75,"depth":75,"links":9925},[9926,9927,9928,9929,9930,9931,9932,9933],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":2233,"description":2238},[247,2412,2413],{"id":2416,"title":2417,"body":9938,"category":247,"cover":248,"description":2422,"extension":249,"meta":10071,"navigation":84,"path":2587,"pinned":252,"publishedAt":253,"seo":10072,"slug":2589,"stem":2590,"summary":2591,"tags":10073,"updatedAt":253,"visible":84,"__hash__":2595},{"type":7,"value":9939,"toc":10061},[9940,9942,9944,9946,9948,9952,9954,9956,9974,9976,9978,10014,10016,10021,10023,10025,10035,10037,10045,10047,10053,10055,10057,10059],[10,9941,2422],{},[14,9943,16],{"id":16},[10,9945,2427],{},[14,9947,22],{"id":22},[10,9949,9950],{},[26,9951],{"alt":2434,"src":2435},[10,9953,2438],{},[14,9955,35],{"id":35},[37,9957,9958,9964,9972],{},[40,9959,9960,2448,9962,2452],{},[63,9961,2447],{},[63,9963,2451],{},[40,9965,9966,2458,9968,2462,9970,2466],{},[63,9967,2457],{},[63,9969,2461],{},[63,9971,2465],{},[40,9973,2469],{},[14,9975,51],{"id":51},[10,9977,54],{},[56,9979,9980],{"className":58,"code":2476,"language":60,"meta":61,"style":61},[63,9981,9982,9986,9990,9994,9998,10002,10006,10010],{"__ignoreMap":61},[66,9983,9984],{"class":68,"line":69},[66,9985,2483],{},[66,9987,9988],{"class":68,"line":75},[66,9989,2488],{},[66,9991,9992],{"class":68,"line":81},[66,9993,2493],{},[66,9995,9996],{"class":68,"line":88},[66,9997,85],{"emptyLinePlaceholder":84},[66,9999,10000],{"class":68,"line":94},[66,10001,2502],{},[66,10003,10004],{"class":68,"line":99},[66,10005,2507],{},[66,10007,10008],{"class":68,"line":105},[66,10009,2512],{},[66,10011,10012],{"class":68,"line":111},[66,10013,2517],{},[10,10015,157],{},[56,10017,10019],{"className":10018,"code":2523,"language":163,"meta":61},[161],[63,10020,2523],{"__ignoreMap":61},[10,10022,168],{},[14,10024,171],{"id":171},[173,10026,10027,10031],{},[40,10028,10029,2537],{},[63,10030,2536],{},[40,10032,10033,2543],{},[63,10034,2542],{},[14,10036,202],{"id":202},[37,10038,10039,10043],{},[40,10040,2550,10041,383],{},[63,10042,2553],{},[40,10044,2556],{},[14,10046,213],{"id":213},[173,10048,10049,10051],{},[40,10050,2563],{},[40,10052,2566],{},[10,10054,224],{},[14,10056,227],{"id":227},[10,10058,2573],{},[232,10060,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10062},[10063,10064,10065,10066,10067,10068,10069,10070],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":2417,"description":2422},[247,2593,2594],{"id":2597,"title":2598,"body":10075,"category":247,"cover":248,"description":2603,"extension":249,"meta":10212,"navigation":84,"path":2779,"pinned":252,"publishedAt":253,"seo":10213,"slug":2781,"stem":2782,"summary":2783,"tags":10214,"updatedAt":253,"visible":84,"__hash__":2787},{"type":7,"value":10076,"toc":10200},[10077,10079,10081,10083,10085,10089,10095,10097,10105,10107,10109,10133,10135,10140,10142,10144,10162,10164,10166,10170,10172,10174,10180,10182,10192,10194,10196,10198],[10,10078,2603],{},[14,10080,16],{"id":16},[10,10082,2608],{},[14,10084,22],{"id":22},[10,10086,10087],{},[26,10088],{"alt":2615,"src":2616},[10,10090,2619,10091,2623,10093,383],{},[63,10092,2622],{},[63,10094,2626],{},[14,10096,35],{"id":35},[37,10098,10099,10101,10103],{},[40,10100,2633],{},[40,10102,2636],{},[40,10104,2639],{},[14,10106,51],{"id":51},[10,10108,54],{},[56,10110,10111],{"className":58,"code":2646,"language":60,"meta":61,"style":61},[63,10112,10113,10117,10121,10125,10129],{"__ignoreMap":61},[66,10114,10115],{"class":68,"line":69},[66,10116,2653],{},[66,10118,10119],{"class":68,"line":75},[66,10120,2658],{},[66,10122,10123],{"class":68,"line":81},[66,10124,2663],{},[66,10126,10127],{"class":68,"line":88},[66,10128,2668],{},[66,10130,10131],{"class":68,"line":94},[66,10132,2673],{},[10,10134,157],{},[56,10136,10138],{"className":10137,"code":2679,"language":163,"meta":61},[161],[63,10139,2679],{"__ignoreMap":61},[10,10141,168],{},[14,10143,171],{"id":171},[173,10145,10146,10154],{},[40,10147,2690,10148,2693,10150,2697,10152,2701],{},[63,10149,247],{},[63,10151,2696],{},[63,10153,2700],{},[40,10155,10156,2707,10158,2711,10160,2715],{},[63,10157,2706],{},[63,10159,2710],{},[63,10161,2714],{},[185,10163,187],{"id":187},[10,10165,2720],{},[10,10167,10168],{},[26,10169],{"alt":2725,"src":2726},[10,10171,2729],{},[14,10173,202],{"id":202},[37,10175,10176,10178],{},[40,10177,2736],{},[40,10179,2739],{},[14,10181,213],{"id":213},[173,10183,10184,10190],{},[40,10185,2746,10186,2750,10188,383],{},[63,10187,2749],{},[63,10189,2753],{},[40,10191,2756],{},[10,10193,224],{},[14,10195,227],{"id":227},[10,10197,2763],{},[232,10199,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10201},[10202,10203,10204,10205,10206,10209,10210,10211],{"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":171,"depth":75,"text":171,"children":10207},[10208],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":2598,"description":2603},[247,2785,2786],{"id":2789,"title":2790,"body":10216,"category":247,"cover":248,"description":2795,"extension":249,"meta":10381,"navigation":84,"path":3010,"pinned":252,"publishedAt":253,"seo":10382,"slug":3012,"stem":3013,"summary":3014,"tags":10383,"updatedAt":253,"visible":84,"__hash__":3018},{"type":7,"value":10217,"toc":10369},[10218,10220,10222,10224,10226,10230,10236,10238,10258,10260,10262,10298,10300,10305,10307,10309,10323,10325,10327,10331,10337,10339,10349,10351,10361,10363,10365,10367],[10,10219,2795],{},[14,10221,16],{"id":16},[10,10223,2800],{},[14,10225,22],{"id":22},[10,10227,10228],{},[26,10229],{"alt":2807,"src":2808},[10,10231,2811,10232,1030,10234,2818],{},[63,10233,2814],{},[63,10235,2817],{},[14,10237,35],{"id":35},[37,10239,10240,10248,10256],{},[40,10241,10242,2828,10244,2832,10246,2836],{},[63,10243,2827],{},[63,10245,2831],{},[63,10247,2835],{},[40,10249,10250,2842,10252,2846,10254,2850],{},[63,10251,2841],{},[63,10253,2845],{},[63,10255,2849],{},[40,10257,2853],{},[14,10259,51],{"id":51},[10,10261,54],{},[56,10263,10264],{"className":58,"code":2860,"language":60,"meta":61,"style":61},[63,10265,10266,10270,10274,10278,10282,10286,10290,10294],{"__ignoreMap":61},[66,10267,10268],{"class":68,"line":69},[66,10269,2867],{},[66,10271,10272],{"class":68,"line":75},[66,10273,2872],{},[66,10275,10276],{"class":68,"line":81},[66,10277,85],{"emptyLinePlaceholder":84},[66,10279,10280],{"class":68,"line":88},[66,10281,2881],{},[66,10283,10284],{"class":68,"line":94},[66,10285,2886],{},[66,10287,10288],{"class":68,"line":99},[66,10289,2891],{},[66,10291,10292],{"class":68,"line":105},[66,10293,2896],{},[66,10295,10296],{"class":68,"line":111},[66,10297,2901],{},[10,10299,157],{},[56,10301,10303],{"className":10302,"code":2907,"language":163,"meta":61},[161],[63,10304,2907],{"__ignoreMap":61},[10,10306,168],{},[14,10308,171],{"id":171},[173,10310,10311,10317],{},[40,10312,10313,2921,10315,2925],{},[63,10314,2920],{},[63,10316,2924],{},[40,10318,10319,2931,10321,2934],{},[63,10320,2930],{},[63,10322,2849],{},[185,10324,187],{"id":187},[10,10326,2939],{},[10,10328,10329],{},[26,10330],{"alt":2944,"src":2945},[10,10332,10333,2950,10335,2953],{},[63,10334,2841],{},[63,10336,2845],{},[14,10338,202],{"id":202},[37,10340,10341,10347],{},[40,10342,2960,10343,2963,10345,2966],{},[63,10344,2835],{},[63,10346,2827],{},[40,10348,2969],{},[14,10350,213],{"id":213},[173,10352,10353,10357],{},[40,10354,2976,10355,2980],{},[63,10356,2979],{},[40,10358,2983,10359,2987],{},[63,10360,2986],{},[10,10362,224],{},[14,10364,227],{"id":227},[10,10366,2994],{},[232,10368,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10370},[10371,10372,10373,10374,10375,10378,10379,10380],{"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":171,"depth":75,"text":171,"children":10376},[10377],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":2790,"description":2795},[247,3016,3017],{"id":3020,"title":3021,"body":10385,"category":247,"cover":248,"description":3026,"extension":249,"meta":10518,"navigation":84,"path":3195,"pinned":252,"publishedAt":253,"seo":10519,"slug":3197,"stem":3198,"summary":3199,"tags":10520,"updatedAt":253,"visible":84,"__hash__":3202},{"type":7,"value":10386,"toc":10508},[10387,10389,10391,10393,10395,10399,10409,10411,10421,10423,10425,10453,10455,10460,10462,10464,10478,10480,10488,10490,10500,10502,10504,10506],[10,10388,3026],{},[14,10390,16],{"id":16},[10,10392,3031],{},[14,10394,22],{"id":22},[10,10396,10397],{},[26,10398],{"alt":3038,"src":3039},[10,10400,10401,3045,10403,3049,10405,3053,10407,3057],{},[63,10402,3044],{},[63,10404,3048],{},[63,10406,3052],{},[63,10408,3056],{},[14,10410,35],{"id":35},[37,10412,10413,10415,10419],{},[40,10414,3064],{},[40,10416,10417,3069],{},[63,10418,3056],{},[40,10420,3072],{},[14,10422,51],{"id":51},[10,10424,54],{},[56,10426,10427],{"className":58,"code":3079,"language":60,"meta":61,"style":61},[63,10428,10429,10433,10437,10441,10445,10449],{"__ignoreMap":61},[66,10430,10431],{"class":68,"line":69},[66,10432,3086],{},[66,10434,10435],{"class":68,"line":75},[66,10436,3091],{},[66,10438,10439],{"class":68,"line":81},[66,10440,3096],{},[66,10442,10443],{"class":68,"line":88},[66,10444,85],{"emptyLinePlaceholder":84},[66,10446,10447],{"class":68,"line":94},[66,10448,3105],{},[66,10450,10451],{"class":68,"line":99},[66,10452,3110],{},[10,10454,157],{},[56,10456,10458],{"className":10457,"code":3116,"language":163,"meta":61},[161],[63,10459,3116],{"__ignoreMap":61},[10,10461,168],{},[14,10463,171],{"id":171},[173,10465,10466,10472],{},[40,10467,3127,10468,3130,10470,3134],{},[63,10469,3044],{},[63,10471,3133],{},[40,10473,10474,3140,10476,3144],{},[63,10475,3139],{},[63,10477,3143],{},[14,10479,202],{"id":202},[37,10481,10482,10486],{},[40,10483,3151,10484,3155],{},[63,10485,3154],{},[40,10487,3158],{},[14,10489,213],{"id":213},[173,10491,10492,10494],{},[40,10493,3165],{},[40,10495,1741,10496,3171,10498,3174],{},[63,10497,3170],{},[63,10499,3056],{},[10,10501,224],{},[14,10503,227],{"id":227},[10,10505,3181],{},[232,10507,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10509},[10510,10511,10512,10513,10514,10515,10516,10517],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":3021,"description":3026},[247,2367,3201],{"id":3204,"title":3205,"body":10522,"category":247,"cover":248,"description":3210,"extension":249,"meta":10651,"navigation":84,"path":3371,"pinned":252,"publishedAt":253,"seo":10652,"slug":3373,"stem":3374,"summary":3375,"tags":10653,"updatedAt":253,"visible":84,"__hash__":3379},{"type":7,"value":10523,"toc":10641},[10524,10526,10528,10530,10532,10536,10540,10542,10552,10554,10556,10588,10590,10595,10597,10599,10611,10613,10623,10625,10633,10635,10637,10639],[10,10525,3210],{},[14,10527,16],{"id":16},[10,10529,3215],{},[14,10531,22],{"id":22},[10,10533,10534],{},[26,10535],{"alt":3222,"src":3223},[10,10537,3226,10538,3230],{},[63,10539,3229],{},[14,10541,35],{"id":35},[37,10543,10544,10546,10548],{},[40,10545,3237],{},[40,10547,3240],{},[40,10549,3243,10550,383],{},[63,10551,3246],{},[14,10553,51],{"id":51},[10,10555,54],{},[56,10557,10558],{"className":58,"code":3253,"language":60,"meta":61,"style":61},[63,10559,10560,10564,10568,10572,10576,10580,10584],{"__ignoreMap":61},[66,10561,10562],{"class":68,"line":69},[66,10563,3260],{},[66,10565,10566],{"class":68,"line":75},[66,10567,3265],{},[66,10569,10570],{"class":68,"line":81},[66,10571,85],{"emptyLinePlaceholder":84},[66,10573,10574],{"class":68,"line":88},[66,10575,3274],{},[66,10577,10578],{"class":68,"line":94},[66,10579,3279],{},[66,10581,10582],{"class":68,"line":99},[66,10583,3284],{},[66,10585,10586],{"class":68,"line":105},[66,10587,3289],{},[10,10589,157],{},[56,10591,10593],{"className":10592,"code":3295,"language":163,"meta":61},[161],[63,10594,3295],{"__ignoreMap":61},[10,10596,168],{},[14,10598,171],{"id":171},[173,10600,10601,10603],{},[40,10602,3306],{},[40,10604,10605,3312,10607,3316,10609,3320],{},[63,10606,3311],{},[63,10608,3315],{},[63,10610,3319],{},[14,10612,202],{"id":202},[37,10614,10615,10621],{},[40,10616,3327,10617,3331,10619,383],{},[63,10618,3330],{},[63,10620,3334],{},[40,10622,3337],{},[14,10624,213],{"id":213},[173,10626,10627,10629],{},[40,10628,3344],{},[40,10630,3347,10631,3350],{},[63,10632,3319],{},[10,10634,224],{},[14,10636,227],{"id":227},[10,10638,3357],{},[232,10640,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10642},[10643,10644,10645,10646,10647,10648,10649,10650],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":3205,"description":3210},[247,3377,3378],{"id":3381,"title":3382,"body":10655,"category":247,"cover":248,"description":3387,"extension":249,"meta":10774,"navigation":84,"path":3529,"pinned":252,"publishedAt":253,"seo":10775,"slug":3531,"stem":3532,"summary":3533,"tags":10776,"updatedAt":253,"visible":84,"__hash__":3536},{"type":7,"value":10656,"toc":10764},[10657,10659,10661,10663,10665,10669,10671,10673,10681,10683,10685,10713,10715,10720,10722,10724,10734,10736,10744,10746,10756,10758,10760,10762],[10,10658,3387],{},[14,10660,16],{"id":16},[10,10662,3392],{},[14,10664,22],{"id":22},[10,10666,10667],{},[26,10668],{"alt":3399,"src":3400},[10,10670,3403],{},[14,10672,35],{"id":35},[37,10674,10675,10677,10679],{},[40,10676,3410],{},[40,10678,3413],{},[40,10680,3416],{},[14,10682,51],{"id":51},[10,10684,54],{},[56,10686,10687],{"className":58,"code":3423,"language":60,"meta":61,"style":61},[63,10688,10689,10693,10697,10701,10705,10709],{"__ignoreMap":61},[66,10690,10691],{"class":68,"line":69},[66,10692,3430],{},[66,10694,10695],{"class":68,"line":75},[66,10696,3435],{},[66,10698,10699],{"class":68,"line":81},[66,10700,3440],{},[66,10702,10703],{"class":68,"line":88},[66,10704,85],{"emptyLinePlaceholder":84},[66,10706,10707],{"class":68,"line":94},[66,10708,3449],{},[66,10710,10711],{"class":68,"line":99},[66,10712,3454],{},[10,10714,157],{},[56,10716,10718],{"className":10717,"code":3460,"language":163,"meta":61},[161],[63,10719,3460],{"__ignoreMap":61},[10,10721,168],{},[14,10723,171],{"id":171},[173,10725,10726,10730],{},[40,10727,10728,3474],{},[63,10729,3473],{},[40,10731,10732,3480],{},[63,10733,3479],{},[14,10735,202],{"id":202},[37,10737,10738,10742],{},[40,10739,3487,10740,3491],{},[63,10741,3490],{},[40,10743,3494],{},[14,10745,213],{"id":213},[173,10747,10748,10750],{},[40,10749,3501],{},[40,10751,2194,10752,2197,10754,3508],{},[63,10753,3490],{},[63,10755,3479],{},[10,10757,224],{},[14,10759,227],{"id":227},[10,10761,3515],{},[232,10763,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10765},[10766,10767,10768,10769,10770,10771,10772,10773],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":3382,"description":3387},[247,3535,3378],{"id":3538,"title":3539,"body":10778,"category":247,"cover":248,"description":3544,"extension":249,"meta":10903,"navigation":84,"path":3700,"pinned":252,"publishedAt":253,"seo":10904,"slug":3702,"stem":3703,"summary":3704,"tags":10905,"updatedAt":253,"visible":84,"__hash__":3707},{"type":7,"value":10779,"toc":10893},[10780,10782,10784,10786,10788,10792,10798,10800,10810,10812,10814,10842,10844,10849,10851,10853,10863,10865,10877,10879,10885,10887,10889,10891],[10,10781,3544],{},[14,10783,16],{"id":16},[10,10785,3549],{},[14,10787,22],{"id":22},[10,10789,10790],{},[26,10791],{"alt":3556,"src":3557},[10,10793,3560,10794,3564,10796,3567],{},[63,10795,3563],{},[63,10797,2267],{},[14,10799,35],{"id":35},[37,10801,10802,10804,10808],{},[40,10803,3574],{},[40,10805,2360,10806,3580],{},[63,10807,3579],{},[40,10809,3583],{},[14,10811,51],{"id":51},[10,10813,54],{},[56,10815,10816],{"className":58,"code":3590,"language":60,"meta":61,"style":61},[63,10817,10818,10822,10826,10830,10834,10838],{"__ignoreMap":61},[66,10819,10820],{"class":68,"line":69},[66,10821,3597],{},[66,10823,10824],{"class":68,"line":75},[66,10825,3602],{},[66,10827,10828],{"class":68,"line":81},[66,10829,85],{"emptyLinePlaceholder":84},[66,10831,10832],{"class":68,"line":88},[66,10833,3611],{},[66,10835,10836],{"class":68,"line":94},[66,10837,3616],{},[66,10839,10840],{"class":68,"line":99},[66,10841,3621],{},[10,10843,157],{},[56,10845,10847],{"className":10846,"code":3627,"language":163,"meta":61},[161],[63,10848,3627],{"__ignoreMap":61},[10,10850,168],{},[14,10852,171],{"id":171},[173,10854,10855,10857],{},[40,10856,3638],{},[40,10858,3641,10859,3644,10861,3648],{},[63,10860,2267],{},[63,10862,3647],{},[14,10864,202],{"id":202},[37,10866,10867,10871],{},[40,10868,3655,10869,3659],{},[63,10870,3658],{},[40,10872,3662,10873,3666,10875,383],{},[63,10874,3665],{},[63,10876,3669],{},[14,10878,213],{"id":213},[173,10880,10881,10883],{},[40,10882,3676],{},[40,10884,3679],{},[10,10886,224],{},[14,10888,227],{"id":227},[10,10890,3686],{},[232,10892,234],{},{"title":61,"searchDepth":75,"depth":75,"links":10894},[10895,10896,10897,10898,10899,10900,10901,10902],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":3539,"description":3544},[247,3706,3378],{"id":3709,"title":3710,"body":10907,"category":247,"cover":248,"description":3715,"extension":249,"meta":11030,"navigation":84,"path":3865,"pinned":252,"publishedAt":253,"seo":11031,"slug":3867,"stem":3868,"summary":3869,"tags":11032,"updatedAt":253,"visible":84,"__hash__":3872},{"type":7,"value":10908,"toc":11020},[10909,10911,10913,10915,10917,10921,10923,10925,10937,10939,10941,10969,10971,10976,10978,10980,10990,10992,11002,11004,11012,11014,11016,11018],[10,10910,3715],{},[14,10912,16],{"id":16},[10,10914,3720],{},[14,10916,22],{"id":22},[10,10918,10919],{},[26,10920],{"alt":3727,"src":3728},[10,10922,3731],{},[14,10924,35],{"id":35},[37,10926,10927,10929,10931],{},[40,10928,3738],{},[40,10930,3741],{},[40,10932,3744,10933,3748,10935,3752],{},[63,10934,3747],{},[63,10936,3751],{},[14,10938,51],{"id":51},[10,10940,54],{},[56,10942,10943],{"className":58,"code":3759,"language":60,"meta":61,"style":61},[63,10944,10945,10949,10953,10957,10961,10965],{"__ignoreMap":61},[66,10946,10947],{"class":68,"line":69},[66,10948,3766],{},[66,10950,10951],{"class":68,"line":75},[66,10952,3771],{},[66,10954,10955],{"class":68,"line":81},[66,10956,85],{"emptyLinePlaceholder":84},[66,10958,10959],{"class":68,"line":88},[66,10960,3780],{},[66,10962,10963],{"class":68,"line":94},[66,10964,3785],{},[66,10966,10967],{"class":68,"line":99},[66,10968,3790],{},[10,10970,157],{},[56,10972,10974],{"className":10973,"code":3796,"language":163,"meta":61},[161],[63,10975,3796],{"__ignoreMap":61},[10,10977,168],{},[14,10979,171],{"id":171},[173,10981,10982,10984],{},[40,10983,3807],{},[40,10985,10986,3813,10988,3817],{},[63,10987,3812],{},[63,10989,3816],{},[14,10991,202],{"id":202},[37,10993,10994,11000],{},[40,10995,2360,10996,3826,10998,383],{},[63,10997,3751],{},[63,10999,3747],{},[40,11001,3831],{},[14,11003,213],{"id":213},[173,11005,11006,11010],{},[40,11007,3838,11008,3841],{},[63,11009,3747],{},[40,11011,3844],{},[10,11013,224],{},[14,11015,227],{"id":227},[10,11017,3851],{},[232,11019,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11021},[11022,11023,11024,11025,11026,11027,11028,11029],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":3710,"description":3715},[247,3871,3378],{"id":3874,"title":3875,"body":11034,"category":247,"cover":248,"description":3880,"extension":249,"meta":11193,"navigation":84,"path":4078,"pinned":252,"publishedAt":253,"seo":11194,"slug":4080,"stem":4081,"summary":4082,"tags":11195,"updatedAt":253,"visible":84,"__hash__":4086},{"type":7,"value":11035,"toc":11181},[11036,11038,11040,11042,11044,11048,11054,11056,11068,11070,11072,11112,11114,11119,11121,11123,11137,11139,11141,11145,11147,11149,11159,11161,11173,11175,11177,11179],[10,11037,3880],{},[14,11039,16],{"id":16},[10,11041,3885],{},[14,11043,22],{"id":22},[10,11045,11046],{},[26,11047],{"alt":3892,"src":3893},[10,11049,11050,3899,11052,3903],{},[63,11051,3898],{},[63,11053,3902],{},[14,11055,35],{"id":35},[37,11057,11058,11064,11066],{},[40,11059,11060,3912,11062,3916],{},[63,11061,2827],{},[63,11063,3915],{},[40,11065,3919],{},[40,11067,3922],{},[14,11069,51],{"id":51},[10,11071,54],{},[56,11073,11074],{"className":58,"code":3929,"language":60,"meta":61,"style":61},[63,11075,11076,11080,11084,11088,11092,11096,11100,11104,11108],{"__ignoreMap":61},[66,11077,11078],{"class":68,"line":69},[66,11079,3936],{},[66,11081,11082],{"class":68,"line":75},[66,11083,3941],{},[66,11085,11086],{"class":68,"line":81},[66,11087,3946],{},[66,11089,11090],{"class":68,"line":88},[66,11091,85],{"emptyLinePlaceholder":84},[66,11093,11094],{"class":68,"line":94},[66,11095,3955],{},[66,11097,11098],{"class":68,"line":99},[66,11099,3960],{},[66,11101,11102],{"class":68,"line":105},[66,11103,3965],{},[66,11105,11106],{"class":68,"line":111},[66,11107,3970],{},[66,11109,11110],{"class":68,"line":117},[66,11111,3975],{},[10,11113,157],{},[56,11115,11117],{"className":11116,"code":3981,"language":163,"meta":61},[161],[63,11118,3981],{"__ignoreMap":61},[10,11120,168],{},[14,11122,171],{"id":171},[173,11124,11125,11129],{},[40,11126,11127,3995],{},[63,11128,3994],{},[40,11130,11131,4001,11133,4005,11135,4009],{},[63,11132,4000],{},[63,11134,4004],{},[63,11136,4008],{},[185,11138,187],{"id":187},[10,11140,4014],{},[10,11142,11143],{},[26,11144],{"alt":4019,"src":4020},[10,11146,4023],{},[14,11148,202],{"id":202},[37,11150,11151,11157],{},[40,11152,4030,11153,4033,11155,383],{},[63,11154,2827],{},[63,11156,3915],{},[40,11158,4038],{},[14,11160,213],{"id":213},[173,11162,11163,11165],{},[40,11164,4045],{},[40,11166,2360,11167,4051,11169,1178,11171,383],{},[63,11168,4050],{},[63,11170,3915],{},[63,11172,2827],{},[10,11174,224],{},[14,11176,227],{"id":227},[10,11178,4062],{},[232,11180,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11182},[11183,11184,11185,11186,11187,11190,11191,11192],{"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":171,"depth":75,"text":171,"children":11188},[11189],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":3875,"description":3880},[247,4084,4085],{"id":4088,"title":4089,"body":11197,"category":247,"cover":248,"description":4094,"extension":249,"meta":11369,"navigation":84,"path":4307,"pinned":252,"publishedAt":253,"seo":11370,"slug":4309,"stem":4310,"summary":4311,"tags":11371,"updatedAt":253,"visible":84,"__hash__":4314},{"type":7,"value":11198,"toc":11356},[11199,11201,11203,11205,11207,11211,11219,11221,11229,11231,11233,11277,11279,11284,11286,11288,11300,11302,11304,11308,11314,11316,11318,11322,11326,11328,11340,11342,11348,11350,11352,11354],[10,11200,4094],{},[14,11202,16],{"id":16},[10,11204,4099],{},[14,11206,22],{"id":22},[10,11208,11209],{},[26,11210],{"alt":4106,"src":4107},[10,11212,11213,2278,11215,2278,11217,4117],{},[63,11214,1177],{},[63,11216,4114],{},[63,11218,1181],{},[14,11220,35],{"id":35},[37,11222,11223,11225,11227],{},[40,11224,4124],{},[40,11226,4127],{},[40,11228,4130],{},[14,11230,51],{"id":51},[10,11232,54],{},[56,11234,11235],{"className":58,"code":4137,"language":60,"meta":61,"style":61},[63,11236,11237,11241,11245,11249,11253,11257,11261,11265,11269,11273],{"__ignoreMap":61},[66,11238,11239],{"class":68,"line":69},[66,11240,4144],{},[66,11242,11243],{"class":68,"line":75},[66,11244,85],{"emptyLinePlaceholder":84},[66,11246,11247],{"class":68,"line":81},[66,11248,4153],{},[66,11250,11251],{"class":68,"line":88},[66,11252,4158],{},[66,11254,11255],{"class":68,"line":94},[66,11256,4163],{},[66,11258,11259],{"class":68,"line":99},[66,11260,4168],{},[66,11262,11263],{"class":68,"line":105},[66,11264,1167],{},[66,11266,11267],{"class":68,"line":111},[66,11268,4177],{},[66,11270,11271],{"class":68,"line":117},[66,11272,85],{"emptyLinePlaceholder":84},[66,11274,11275],{"class":68,"line":122},[66,11276,4186],{},[10,11278,157],{},[56,11280,11282],{"className":11281,"code":4192,"language":163,"meta":61},[161],[63,11283,4192],{"__ignoreMap":61},[10,11285,168],{},[14,11287,171],{"id":171},[173,11289,11290,11294],{},[40,11291,4203,11292,4207],{},[63,11293,4206],{},[40,11295,11296,4213,11298,4216],{},[63,11297,4212],{},[63,11299,1181],{},[185,11301,187],{"id":187},[10,11303,4221],{},[10,11305,11306],{},[26,11307],{"alt":4226,"src":4227},[10,11309,11310,4232,11312,4235],{},[63,11311,4206],{},[63,11313,4212],{},[185,11315,187],{"id":4238},[10,11317,4241],{},[10,11319,11320],{},[26,11321],{"alt":4246,"src":4247},[10,11323,4250,11324,4253],{},[63,11325,1177],{},[14,11327,202],{"id":202},[37,11329,11330,11334],{},[40,11331,4260,11332,4263],{},[63,11333,4212],{},[40,11335,4266,11336,4269,11338,4273],{},[63,11337,1177],{},[63,11339,4272],{},[14,11341,213],{"id":213},[173,11343,11344,11346],{},[40,11345,4280],{},[40,11347,4283],{},[10,11349,224],{},[14,11351,227],{"id":227},[10,11353,4290],{},[232,11355,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11357},[11358,11359,11360,11361,11362,11366,11367,11368],{"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":171,"depth":75,"text":171,"children":11363},[11364,11365],{"id":187,"depth":81,"text":187},{"id":4238,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":4089,"description":4094},[247,1177,4313],{"id":4316,"title":4317,"body":11373,"category":247,"cover":248,"description":4322,"extension":249,"meta":11510,"navigation":84,"path":4489,"pinned":252,"publishedAt":253,"seo":11511,"slug":4491,"stem":4492,"summary":4493,"tags":11512,"updatedAt":253,"visible":84,"__hash__":4496},{"type":7,"value":11374,"toc":11498},[11375,11377,11379,11381,11383,11387,11391,11393,11403,11405,11407,11439,11441,11446,11448,11450,11460,11462,11464,11468,11472,11474,11480,11482,11490,11492,11494,11496],[10,11376,4322],{},[14,11378,16],{"id":16},[10,11380,4327],{},[14,11382,22],{"id":22},[10,11384,11385],{},[26,11386],{"alt":4334,"src":4335},[10,11388,11389,4341],{},[63,11390,4340],{},[14,11392,35],{"id":35},[37,11394,11395,11397,11399],{},[40,11396,4348],{},[40,11398,4351],{},[40,11400,4354,11401,4358],{},[63,11402,4357],{},[14,11404,51],{"id":51},[10,11406,54],{},[56,11408,11409],{"className":58,"code":4365,"language":60,"meta":61,"style":61},[63,11410,11411,11415,11419,11423,11427,11431,11435],{"__ignoreMap":61},[66,11412,11413],{"class":68,"line":69},[66,11414,4372],{},[66,11416,11417],{"class":68,"line":75},[66,11418,85],{"emptyLinePlaceholder":84},[66,11420,11421],{"class":68,"line":81},[66,11422,4381],{},[66,11424,11425],{"class":68,"line":88},[66,11426,4386],{},[66,11428,11429],{"class":68,"line":94},[66,11430,4391],{},[66,11432,11433],{"class":68,"line":99},[66,11434,85],{"emptyLinePlaceholder":84},[66,11436,11437],{"class":68,"line":105},[66,11438,4400],{},[10,11440,157],{},[56,11442,11444],{"className":11443,"code":4406,"language":163,"meta":61},[161],[63,11445,4406],{"__ignoreMap":61},[10,11447,168],{},[14,11449,171],{"id":171},[173,11451,11452,11456],{},[40,11453,4417,11454,4421],{},[63,11455,4420],{},[40,11457,4424,11458,4427],{},[63,11459,4420],{},[185,11461,187],{"id":187},[10,11463,4432],{},[10,11465,11466],{},[26,11467],{"alt":4437,"src":4438},[10,11469,4441,11470,4444],{},[63,11471,4420],{},[14,11473,202],{"id":202},[37,11475,11476,11478],{},[40,11477,4451],{},[40,11479,4454],{},[14,11481,213],{"id":213},[173,11483,11484,11488],{},[40,11485,2360,11486,4463],{},[63,11487,4340],{},[40,11489,4466],{},[10,11491,224],{},[14,11493,227],{"id":227},[10,11495,4473],{},[232,11497,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11499},[11500,11501,11502,11503,11504,11507,11508,11509],{"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":171,"depth":75,"text":171,"children":11505},[11506],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":4317,"description":4322},[247,4340,4495],{"id":4498,"title":4499,"body":11514,"category":247,"cover":248,"description":4504,"extension":249,"meta":11639,"navigation":84,"path":4653,"pinned":252,"publishedAt":253,"seo":11640,"slug":4655,"stem":4656,"summary":4657,"tags":11641,"updatedAt":253,"visible":84,"__hash__":4660},{"type":7,"value":11515,"toc":11629},[11516,11518,11520,11522,11524,11528,11532,11534,11544,11546,11548,11580,11582,11587,11589,11591,11603,11605,11611,11613,11621,11623,11625,11627],[10,11517,4504],{},[14,11519,16],{"id":16},[10,11521,4509],{},[14,11523,22],{"id":22},[10,11525,11526],{},[26,11527],{"alt":4516,"src":4517},[10,11529,11530,4522],{},[63,11531,4357],{},[14,11533,35],{"id":35},[37,11535,11536,11540,11542],{},[40,11537,11538,4532],{},[63,11539,4531],{},[40,11541,4535],{},[40,11543,4538],{},[14,11545,51],{"id":51},[10,11547,54],{},[56,11549,11550],{"className":58,"code":4545,"language":60,"meta":61,"style":61},[63,11551,11552,11556,11560,11564,11568,11572,11576],{"__ignoreMap":61},[66,11553,11554],{"class":68,"line":69},[66,11555,4552],{},[66,11557,11558],{"class":68,"line":75},[66,11559,85],{"emptyLinePlaceholder":84},[66,11561,11562],{"class":68,"line":81},[66,11563,4561],{},[66,11565,11566],{"class":68,"line":88},[66,11567,4566],{},[66,11569,11570],{"class":68,"line":94},[66,11571,85],{"emptyLinePlaceholder":84},[66,11573,11574],{"class":68,"line":99},[66,11575,4575],{},[66,11577,11578],{"class":68,"line":105},[66,11579,4580],{},[10,11581,157],{},[56,11583,11585],{"className":11584,"code":4586,"language":163,"meta":61},[161],[63,11586,4586],{"__ignoreMap":61},[10,11588,168],{},[14,11590,171],{"id":171},[173,11592,11593,11599],{},[40,11594,4597,11595,4600,11597,4604],{},[63,11596,4357],{},[63,11598,4603],{},[40,11600,11601,4609],{},[63,11602,4531],{},[14,11604,202],{"id":202},[37,11606,11607,11609],{},[40,11608,4616],{},[40,11610,4619],{},[14,11612,213],{"id":213},[173,11614,11615,11617],{},[40,11616,4626],{},[40,11618,2360,11619,4632],{},[63,11620,4631],{},[10,11622,224],{},[14,11624,227],{"id":227},[10,11626,4639],{},[232,11628,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11630},[11631,11632,11633,11634,11635,11636,11637,11638],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":4499,"description":4504},[247,4357,4659],{"id":4662,"title":4663,"body":11643,"category":247,"cover":248,"description":4668,"extension":249,"meta":11788,"navigation":84,"path":4843,"pinned":252,"publishedAt":253,"seo":11789,"slug":4845,"stem":4846,"summary":4847,"tags":11790,"updatedAt":253,"visible":84,"__hash__":4849},{"type":7,"value":11644,"toc":11778},[11645,11647,11649,11651,11653,11657,11663,11665,11679,11681,11683,11727,11729,11734,11736,11738,11748,11750,11762,11764,11770,11772,11774,11776],[10,11646,4668],{},[14,11648,16],{"id":16},[10,11650,4673],{},[14,11652,22],{"id":22},[10,11654,11655],{},[26,11656],{"alt":4680,"src":4681},[10,11658,11659,4687,11661,4691],{},[63,11660,4686],{},[63,11662,4690],{},[14,11664,35],{"id":35},[37,11666,11667,11669,11675],{},[40,11668,4698],{},[40,11670,11671,4703,11673,4706],{},[63,11672,4686],{},[63,11674,4340],{},[40,11676,4709,11677,4712],{},[63,11678,4690],{},[14,11680,51],{"id":51},[10,11682,54],{},[56,11684,11685],{"className":58,"code":4719,"language":60,"meta":61,"style":61},[63,11686,11687,11691,11695,11699,11703,11707,11711,11715,11719,11723],{"__ignoreMap":61},[66,11688,11689],{"class":68,"line":69},[66,11690,4726],{},[66,11692,11693],{"class":68,"line":75},[66,11694,85],{"emptyLinePlaceholder":84},[66,11696,11697],{"class":68,"line":81},[66,11698,4735],{},[66,11700,11701],{"class":68,"line":88},[66,11702,4740],{},[66,11704,11705],{"class":68,"line":94},[66,11706,4745],{},[66,11708,11709],{"class":68,"line":99},[66,11710,4750],{},[66,11712,11713],{"class":68,"line":105},[66,11714,4755],{},[66,11716,11717],{"class":68,"line":111},[66,11718,4580],{},[66,11720,11721],{"class":68,"line":117},[66,11722,85],{"emptyLinePlaceholder":84},[66,11724,11725],{"class":68,"line":122},[66,11726,4768],{},[10,11728,157],{},[56,11730,11732],{"className":11731,"code":4774,"language":163,"meta":61},[161],[63,11733,4774],{"__ignoreMap":61},[10,11735,168],{},[14,11737,171],{"id":171},[173,11739,11740,11744],{},[40,11741,4785,11742,4788],{},[63,11743,4686],{},[40,11745,4791,11746,4794],{},[63,11747,4690],{},[14,11749,202],{"id":202},[37,11751,11752,11756],{},[40,11753,3487,11754,4803],{},[63,11755,4686],{},[40,11757,4806,11758,4809,11760,4812],{},[63,11759,4340],{},[63,11761,4686],{},[14,11763,213],{"id":213},[173,11765,11766,11768],{},[40,11767,4819],{},[40,11769,4822],{},[10,11771,224],{},[14,11773,227],{"id":227},[10,11775,4829],{},[232,11777,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11779},[11780,11781,11782,11783,11784,11785,11786,11787],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":4663,"description":4668},[247,4690,4686],{"id":4851,"title":4852,"body":11792,"category":247,"cover":248,"description":4857,"extension":249,"meta":11931,"navigation":84,"path":5029,"pinned":252,"publishedAt":253,"seo":11932,"slug":5031,"stem":5032,"summary":5033,"tags":11933,"updatedAt":253,"visible":84,"__hash__":5037},{"type":7,"value":11793,"toc":11919},[11794,11796,11798,11800,11802,11806,11808,11810,11826,11828,11830,11858,11860,11865,11867,11869,11881,11883,11885,11889,11891,11893,11903,11905,11911,11913,11915,11917],[10,11795,4857],{},[14,11797,16],{"id":16},[10,11799,4862],{},[14,11801,22],{"id":22},[10,11803,11804],{},[26,11805],{"alt":4869,"src":4870},[10,11807,4873],{},[14,11809,35],{"id":35},[37,11811,11812,11814,11816],{},[40,11813,4880],{},[40,11815,4883],{},[40,11817,4886,11818,2278,11820,4893,11822,2278,11824,383],{},[63,11819,4889],{},[63,11821,4892],{},[63,11823,4896],{},[63,11825,4899],{},[14,11827,51],{"id":51},[10,11829,54],{},[56,11831,11832],{"className":58,"code":4906,"language":60,"meta":61,"style":61},[63,11833,11834,11838,11842,11846,11850,11854],{"__ignoreMap":61},[66,11835,11836],{"class":68,"line":69},[66,11837,4913],{},[66,11839,11840],{"class":68,"line":75},[66,11841,85],{"emptyLinePlaceholder":84},[66,11843,11844],{"class":68,"line":81},[66,11845,4922],{},[66,11847,11848],{"class":68,"line":88},[66,11849,4927],{},[66,11851,11852],{"class":68,"line":94},[66,11853,4932],{},[66,11855,11856],{"class":68,"line":99},[66,11857,4937],{},[10,11859,157],{},[56,11861,11863],{"className":11862,"code":4943,"language":163,"meta":61},[161],[63,11864,4943],{"__ignoreMap":61},[10,11866,168],{},[14,11868,171],{"id":171},[173,11870,11871,11879],{},[40,11872,4954,11873,4957,11875,1178,11877,383],{},[63,11874,4889],{},[63,11876,4960],{},[63,11878,4963],{},[40,11880,4966],{},[185,11882,187],{"id":187},[10,11884,4971],{},[10,11886,11887],{},[26,11888],{"alt":4976,"src":4977},[10,11890,4980],{},[14,11892,202],{"id":202},[37,11894,11895,11901],{},[40,11896,4987,11897,1030,11899,4993],{},[63,11898,4990],{},[63,11900,4896],{},[40,11902,4996],{},[14,11904,213],{"id":213},[173,11906,11907,11909],{},[40,11908,5003],{},[40,11910,5006],{},[10,11912,224],{},[14,11914,227],{"id":227},[10,11916,5013],{},[232,11918,234],{},{"title":61,"searchDepth":75,"depth":75,"links":11920},[11921,11922,11923,11924,11925,11928,11929,11930],{"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":171,"depth":75,"text":171,"children":11926},[11927],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":4852,"description":4857},[247,5035,5036],{"id":5039,"title":5040,"body":11935,"category":247,"cover":248,"description":5045,"extension":249,"meta":12052,"navigation":84,"path":5184,"pinned":252,"publishedAt":253,"seo":12053,"slug":5186,"stem":5187,"summary":5188,"tags":12054,"updatedAt":253,"visible":84,"__hash__":5192},{"type":7,"value":11936,"toc":12042},[11937,11939,11941,11943,11945,11949,11951,11953,11961,11963,11965,11997,11999,12004,12006,12008,12016,12018,12026,12028,12034,12036,12038,12040],[10,11938,5045],{},[14,11940,16],{"id":16},[10,11942,5050],{},[14,11944,22],{"id":22},[10,11946,11947],{},[26,11948],{"alt":5057,"src":5058},[10,11950,5061],{},[14,11952,35],{"id":35},[37,11954,11955,11957,11959],{},[40,11956,5068],{},[40,11958,5071],{},[40,11960,5074],{},[14,11962,51],{"id":51},[10,11964,54],{},[56,11966,11967],{"className":58,"code":5081,"language":60,"meta":61,"style":61},[63,11968,11969,11973,11977,11981,11985,11989,11993],{"__ignoreMap":61},[66,11970,11971],{"class":68,"line":69},[66,11972,5088],{},[66,11974,11975],{"class":68,"line":75},[66,11976,85],{"emptyLinePlaceholder":84},[66,11978,11979],{"class":68,"line":81},[66,11980,5097],{},[66,11982,11983],{"class":68,"line":88},[66,11984,5102],{},[66,11986,11987],{"class":68,"line":94},[66,11988,85],{"emptyLinePlaceholder":84},[66,11990,11991],{"class":68,"line":99},[66,11992,5111],{},[66,11994,11995],{"class":68,"line":105},[66,11996,5116],{},[10,11998,157],{},[56,12000,12002],{"className":12001,"code":5122,"language":163,"meta":61},[161],[63,12003,5122],{"__ignoreMap":61},[10,12005,168],{},[14,12007,171],{"id":171},[173,12009,12010,12012],{},[40,12011,5133],{},[40,12013,5136,12014,5140],{},[63,12015,5139],{},[14,12017,202],{"id":202},[37,12019,12020,12024],{},[40,12021,5147,12022,5150],{},[63,12023,4357],{},[40,12025,5153],{},[14,12027,213],{"id":213},[173,12029,12030,12032],{},[40,12031,5160],{},[40,12033,5163],{},[10,12035,224],{},[14,12037,227],{"id":227},[10,12039,5170],{},[232,12041,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12043},[12044,12045,12046,12047,12048,12049,12050,12051],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5040,"description":5045},[247,5190,5191],{"id":5194,"title":5195,"body":12056,"category":247,"cover":248,"description":5200,"extension":249,"meta":12175,"navigation":84,"path":5344,"pinned":252,"publishedAt":253,"seo":12176,"slug":5346,"stem":5347,"summary":5348,"tags":12177,"updatedAt":253,"visible":84,"__hash__":5352},{"type":7,"value":12057,"toc":12165},[12058,12060,12062,12064,12066,12070,12072,12074,12082,12084,12086,12118,12120,12125,12127,12129,12139,12141,12147,12149,12157,12159,12161,12163],[10,12059,5200],{},[14,12061,16],{"id":16},[10,12063,5205],{},[14,12065,22],{"id":22},[10,12067,12068],{},[26,12069],{"alt":5212,"src":5213},[10,12071,5216],{},[14,12073,35],{"id":35},[37,12075,12076,12078,12080],{},[40,12077,5223],{},[40,12079,5226],{},[40,12081,5229],{},[14,12083,51],{"id":51},[10,12085,54],{},[56,12087,12088],{"className":58,"code":5236,"language":60,"meta":61,"style":61},[63,12089,12090,12094,12098,12102,12106,12110,12114],{"__ignoreMap":61},[66,12091,12092],{"class":68,"line":69},[66,12093,5243],{},[66,12095,12096],{"class":68,"line":75},[66,12097,5248],{},[66,12099,12100],{"class":68,"line":81},[66,12101,5253],{},[66,12103,12104],{"class":68,"line":88},[66,12105,85],{"emptyLinePlaceholder":84},[66,12107,12108],{"class":68,"line":94},[66,12109,5262],{},[66,12111,12112],{"class":68,"line":99},[66,12113,5267],{},[66,12115,12116],{"class":68,"line":105},[66,12117,5272],{},[10,12119,157],{},[56,12121,12123],{"className":12122,"code":5278,"language":163,"meta":61},[161],[63,12124,5278],{"__ignoreMap":61},[10,12126,168],{},[14,12128,171],{"id":171},[173,12130,12131,12135],{},[40,12132,959,12133,5292],{},[63,12134,5291],{},[40,12136,5295,12137,5299],{},[63,12138,5298],{},[14,12140,202],{"id":202},[37,12142,12143,12145],{},[40,12144,5306],{},[40,12146,5309],{},[14,12148,213],{"id":213},[173,12150,12151,12155],{},[40,12152,5316,12153,5320],{},[63,12154,5319],{},[40,12156,5323],{},[10,12158,224],{},[14,12160,227],{"id":227},[10,12162,5330],{},[232,12164,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12166},[12167,12168,12169,12170,12171,12172,12173,12174],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5195,"description":5200},[247,5350,5351],{"id":5354,"title":5355,"body":12179,"category":247,"cover":248,"description":5360,"extension":249,"meta":12324,"navigation":84,"path":5541,"pinned":252,"publishedAt":253,"seo":12325,"slug":5543,"stem":5544,"summary":5545,"tags":12326,"updatedAt":253,"visible":84,"__hash__":5549},{"type":7,"value":12180,"toc":12312},[12181,12183,12185,12187,12189,12193,12197,12199,12211,12213,12215,12243,12245,12250,12252,12254,12268,12270,12272,12276,12284,12286,12296,12298,12304,12306,12308,12310],[10,12182,5360],{},[14,12184,16],{"id":16},[10,12186,5365],{},[14,12188,22],{"id":22},[10,12190,12191],{},[26,12192],{"alt":5372,"src":5373},[10,12194,5376,12195,5380],{},[63,12196,5379],{},[14,12198,35],{"id":35},[37,12200,12201,12203,12205],{},[40,12202,5387],{},[40,12204,5390],{},[40,12206,5393,12207,5396,12209,383],{},[63,12208,5379],{},[63,12210,5399],{},[14,12212,51],{"id":51},[10,12214,54],{},[56,12216,12217],{"className":58,"code":5406,"language":60,"meta":61,"style":61},[63,12218,12219,12223,12227,12231,12235,12239],{"__ignoreMap":61},[66,12220,12221],{"class":68,"line":69},[66,12222,5413],{},[66,12224,12225],{"class":68,"line":75},[66,12226,5418],{},[66,12228,12229],{"class":68,"line":81},[66,12230,5423],{},[66,12232,12233],{"class":68,"line":88},[66,12234,85],{"emptyLinePlaceholder":84},[66,12236,12237],{"class":68,"line":94},[66,12238,5432],{},[66,12240,12241],{"class":68,"line":99},[66,12242,5437],{},[10,12244,157],{},[56,12246,12248],{"className":12247,"code":5443,"language":163,"meta":61},[161],[63,12249,5443],{"__ignoreMap":61},[10,12251,168],{},[14,12253,171],{"id":171},[173,12255,12256,12262],{},[40,12257,5454,12258,2278,12260,5460],{},[63,12259,5457],{},[63,12261,4420],{},[40,12263,12264,5466,12266,5470],{},[63,12265,5465],{},[63,12267,5469],{},[185,12269,187],{"id":187},[10,12271,5475],{},[10,12273,12274],{},[26,12275],{"alt":5480,"src":5481},[10,12277,12278,2278,12280,1178,12282,5491],{},[63,12279,5457],{},[63,12281,4420],{},[63,12283,5490],{},[14,12285,202],{"id":202},[37,12287,12288,12292],{},[40,12289,5498,12290,5502],{},[63,12291,5501],{},[40,12293,5505,12294,5508],{},[63,12295,5490],{},[14,12297,213],{"id":213},[173,12299,12300,12302],{},[40,12301,5515],{},[40,12303,5518],{},[10,12305,224],{},[14,12307,227],{"id":227},[10,12309,5525],{},[232,12311,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12313},[12314,12315,12316,12317,12318,12321,12322,12323],{"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":171,"depth":75,"text":171,"children":12319},[12320],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5355,"description":5360},[247,5547,5548],{"id":5551,"title":5552,"body":12328,"category":247,"cover":248,"description":5557,"extension":249,"meta":12477,"navigation":84,"path":5738,"pinned":252,"publishedAt":253,"seo":12478,"slug":5740,"stem":5741,"summary":5742,"tags":12479,"updatedAt":253,"visible":84,"__hash__":5746},{"type":7,"value":12329,"toc":12465},[12330,12332,12334,12336,12338,12342,12344,12346,12358,12360,12362,12406,12408,12413,12415,12417,12429,12431,12433,12437,12439,12441,12449,12451,12457,12459,12461,12463],[10,12331,5557],{},[14,12333,16],{"id":16},[10,12335,5562],{},[14,12337,22],{"id":22},[10,12339,12340],{},[26,12341],{"alt":5569,"src":5570},[10,12343,5573],{},[14,12345,35],{"id":35},[37,12347,12348,12350,12354],{},[40,12349,5580],{},[40,12351,12352,5586],{},[63,12353,5585],{},[40,12355,12356,5592],{},[63,12357,5591],{},[14,12359,51],{"id":51},[10,12361,54],{},[56,12363,12364],{"className":58,"code":5599,"language":60,"meta":61,"style":61},[63,12365,12366,12370,12374,12378,12382,12386,12390,12394,12398,12402],{"__ignoreMap":61},[66,12367,12368],{"class":68,"line":69},[66,12369,5606],{},[66,12371,12372],{"class":68,"line":75},[66,12373,5611],{},[66,12375,12376],{"class":68,"line":81},[66,12377,85],{"emptyLinePlaceholder":84},[66,12379,12380],{"class":68,"line":88},[66,12381,5620],{},[66,12383,12384],{"class":68,"line":94},[66,12385,5625],{},[66,12387,12388],{"class":68,"line":99},[66,12389,85],{"emptyLinePlaceholder":84},[66,12391,12392],{"class":68,"line":105},[66,12393,5634],{},[66,12395,12396],{"class":68,"line":111},[66,12397,5639],{},[66,12399,12400],{"class":68,"line":117},[66,12401,85],{"emptyLinePlaceholder":84},[66,12403,12404],{"class":68,"line":122},[66,12405,5648],{},[10,12407,157],{},[56,12409,12411],{"className":12410,"code":5654,"language":163,"meta":61},[161],[63,12412,5654],{"__ignoreMap":61},[10,12414,168],{},[14,12416,171],{"id":171},[173,12418,12419,12423],{},[40,12420,5665,12421,5669],{},[63,12422,5668],{},[40,12424,12425,5675,12427,383],{},[63,12426,5674],{},[63,12428,5678],{},[185,12430,187],{"id":187},[10,12432,5683],{},[10,12434,12435],{},[26,12436],{"alt":5688,"src":5689},[10,12438,5692],{},[14,12440,202],{"id":202},[37,12442,12443,12447],{},[40,12444,5699,12445,5702],{},[63,12446,5399],{},[40,12448,5705],{},[14,12450,213],{"id":213},[173,12452,12453,12455],{},[40,12454,5712],{},[40,12456,5715],{},[10,12458,224],{},[14,12460,227],{"id":227},[10,12462,5722],{},[232,12464,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12466},[12467,12468,12469,12470,12471,12474,12475,12476],{"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":171,"depth":75,"text":171,"children":12472},[12473],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5552,"description":5557},[247,5744,5745],{"id":5748,"title":5749,"body":12481,"category":247,"cover":248,"description":5754,"extension":249,"meta":12642,"navigation":84,"path":5950,"pinned":252,"publishedAt":253,"seo":12643,"slug":5952,"stem":5953,"summary":5954,"tags":12644,"updatedAt":253,"visible":84,"__hash__":5958},{"type":7,"value":12482,"toc":12630},[12483,12485,12487,12489,12491,12495,12497,12499,12511,12513,12515,12567,12569,12574,12576,12578,12596,12598,12600,12604,12606,12608,12614,12616,12622,12624,12626,12628],[10,12484,5754],{},[14,12486,16],{"id":16},[10,12488,5759],{},[14,12490,22],{"id":22},[10,12492,12493],{},[26,12494],{"alt":5766,"src":5767},[10,12496,5770],{},[14,12498,35],{"id":35},[37,12500,12501,12503,12505],{},[40,12502,5777],{},[40,12504,5780],{},[40,12506,12507,2197,12509,5789],{},[63,12508,5785],{},[63,12510,5788],{},[14,12512,51],{"id":51},[10,12514,54],{},[56,12516,12517],{"className":58,"code":5796,"language":60,"meta":61,"style":61},[63,12518,12519,12523,12527,12531,12535,12539,12543,12547,12551,12555,12559,12563],{"__ignoreMap":61},[66,12520,12521],{"class":68,"line":69},[66,12522,5803],{},[66,12524,12525],{"class":68,"line":75},[66,12526,85],{"emptyLinePlaceholder":84},[66,12528,12529],{"class":68,"line":81},[66,12530,5812],{},[66,12532,12533],{"class":68,"line":88},[66,12534,5817],{},[66,12536,12537],{"class":68,"line":94},[66,12538,85],{"emptyLinePlaceholder":84},[66,12540,12541],{"class":68,"line":99},[66,12542,5826],{},[66,12544,12545],{"class":68,"line":105},[66,12546,5831],{},[66,12548,12549],{"class":68,"line":111},[66,12550,5836],{},[66,12552,12553],{"class":68,"line":117},[66,12554,85],{"emptyLinePlaceholder":84},[66,12556,12557],{"class":68,"line":122},[66,12558,5845],{},[66,12560,12561],{"class":68,"line":128},[66,12562,85],{"emptyLinePlaceholder":84},[66,12564,12565],{"class":68,"line":134},[66,12566,5854],{},[10,12568,157],{},[56,12570,12572],{"className":12571,"code":5860,"language":163,"meta":61},[161],[63,12573,5860],{"__ignoreMap":61},[10,12575,168],{},[14,12577,171],{"id":171},[173,12579,12580,12590],{},[40,12581,12582,5874,12584,5878,12586,5881,12588,5885],{},[63,12583,5873],{},[63,12585,5877],{},[63,12587,5668],{},[63,12589,5884],{},[40,12591,12592,5890,12594,5893],{},[63,12593,4603],{},[63,12595,2229],{},[185,12597,187],{"id":187},[10,12599,5898],{},[10,12601,12602],{},[26,12603],{"alt":5903,"src":5904},[10,12605,5907],{},[14,12607,202],{"id":202},[37,12609,12610,12612],{},[40,12611,5914],{},[40,12613,5917],{},[14,12615,213],{"id":213},[173,12617,12618,12620],{},[40,12619,5924],{},[40,12621,5927],{},[10,12623,224],{},[14,12625,227],{"id":227},[10,12627,5934],{},[232,12629,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12631},[12632,12633,12634,12635,12636,12639,12640,12641],{"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":171,"depth":75,"text":171,"children":12637},[12638],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5749,"description":5754},[247,5956,5957],{"id":5960,"title":5961,"body":12646,"category":247,"cover":248,"description":5966,"extension":249,"meta":12769,"navigation":84,"path":6117,"pinned":252,"publishedAt":253,"seo":12770,"slug":6119,"stem":6120,"summary":6121,"tags":12771,"updatedAt":253,"visible":84,"__hash__":6125},{"type":7,"value":12647,"toc":12759},[12648,12650,12652,12654,12656,12660,12662,12664,12678,12680,12682,12710,12712,12717,12719,12721,12731,12733,12741,12743,12751,12753,12755,12757],[10,12649,5966],{},[14,12651,16],{"id":16},[10,12653,5971],{},[14,12655,22],{"id":22},[10,12657,12658],{},[26,12659],{"alt":5978,"src":5979},[10,12661,5982],{},[14,12663,35],{"id":35},[37,12665,12666,12668,12670],{},[40,12667,5989],{},[40,12669,5992],{},[40,12671,5995,12672,2278,12674,2278,12676,6003],{},[63,12673,2281],{},[63,12675,2447],{},[63,12677,6002],{},[14,12679,51],{"id":51},[10,12681,54],{},[56,12683,12684],{"className":58,"code":6010,"language":60,"meta":61,"style":61},[63,12685,12686,12690,12694,12698,12702,12706],{"__ignoreMap":61},[66,12687,12688],{"class":68,"line":69},[66,12689,6017],{},[66,12691,12692],{"class":68,"line":75},[66,12693,6022],{},[66,12695,12696],{"class":68,"line":81},[66,12697,6027],{},[66,12699,12700],{"class":68,"line":88},[66,12701,85],{"emptyLinePlaceholder":84},[66,12703,12704],{"class":68,"line":94},[66,12705,6036],{},[66,12707,12708],{"class":68,"line":99},[66,12709,6041],{},[10,12711,157],{},[56,12713,12715],{"className":12714,"code":6047,"language":163,"meta":61},[161],[63,12716,6047],{"__ignoreMap":61},[10,12718,168],{},[14,12720,171],{"id":171},[173,12722,12723,12729],{},[40,12724,6058,12725,6062,12727,6065],{},[63,12726,6061],{},[63,12728,2267],{},[40,12730,6068],{},[14,12732,202],{"id":202},[37,12734,12735,12739],{},[40,12736,6075,12737,6079],{},[63,12738,6078],{},[40,12740,6082],{},[14,12742,213],{"id":213},[173,12744,12745,12747],{},[40,12746,6089],{},[40,12748,6092,12749,6096],{},[63,12750,6095],{},[10,12752,224],{},[14,12754,227],{"id":227},[10,12756,6103],{},[232,12758,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12760},[12761,12762,12763,12764,12765,12766,12767,12768],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5961,"description":5966},[247,6123,6124],{"id":6127,"title":6128,"body":12773,"category":247,"cover":248,"description":6133,"extension":249,"meta":12950,"navigation":84,"path":6360,"pinned":252,"publishedAt":253,"seo":12951,"slug":6362,"stem":6363,"summary":6364,"tags":12952,"updatedAt":253,"visible":84,"__hash__":6368},{"type":7,"value":12774,"toc":12938},[12775,12777,12779,12783,12785,12789,12795,12797,12809,12811,12815,12839,12843,12859,12865,12867,12872,12874,12876,12892,12894,12896,12900,12904,12906,12918,12920,12930,12932,12934,12936],[10,12776,6133],{},[14,12778,16],{"id":16},[10,12780,6138,12781,6141],{},[316,12782,6061],{},[14,12784,22],{"id":22},[10,12786,12787],{},[26,12788],{"alt":6148,"src":6149},[10,12790,6152,12791,6156,12793,6160],{},[63,12792,6155],{},[63,12794,6159],{},[14,12796,35],{"id":35},[37,12798,12799,12803,12805],{},[40,12800,6167,12801,6170],{},[63,12802,1192],{},[40,12804,6173],{},[40,12806,6176,12807,6180],{},[63,12808,6179],{},[14,12810,51],{"id":51},[10,12812,6185,12813,6189],{},[63,12814,6188],{},[56,12816,12817],{"className":58,"code":6192,"language":60,"meta":61,"style":61},[63,12818,12819,12823,12827,12831,12835],{"__ignoreMap":61},[66,12820,12821],{"class":68,"line":69},[66,12822,6199],{},[66,12824,12825],{"class":68,"line":75},[66,12826,6204],{},[66,12828,12829],{"class":68,"line":81},[66,12830,85],{"emptyLinePlaceholder":84},[66,12832,12833],{"class":68,"line":88},[66,12834,148],{},[66,12836,12837],{"class":68,"line":94},[66,12838,6217],{},[10,12840,6220,12841,6224],{},[63,12842,6223],{},[56,12844,12845],{"className":58,"code":6227,"language":60,"meta":61,"style":61},[63,12846,12847,12851,12855],{"__ignoreMap":61},[66,12848,12849],{"class":68,"line":69},[66,12850,6234],{},[66,12852,12853],{"class":68,"line":75},[66,12854,85],{"emptyLinePlaceholder":84},[66,12856,12857],{"class":68,"line":81},[66,12858,6243],{},[10,12860,6246,12861,1178,12863,383],{},[63,12862,6249],{},[63,12864,6252],{},[10,12866,157],{},[56,12868,12870],{"className":12869,"code":6258,"language":163,"meta":61},[161],[63,12871,6258],{"__ignoreMap":61},[10,12873,168],{},[14,12875,171],{"id":171},[173,12877,12878,12884],{},[40,12879,6269,12880,6272,12882,6276],{},[63,12881,6188],{},[63,12883,6275],{},[40,12885,12886,6281,12888,6284,12890,6287],{},[63,12887,6223],{},[63,12889,6188],{},[63,12891,6223],{},[185,12893,187],{"id":187},[10,12895,6292],{},[10,12897,12898],{},[26,12899],{"alt":6297,"src":6298},[10,12901,6301,12902,6304],{},[63,12903,6275],{},[14,12905,202],{"id":202},[37,12907,12908,12914],{},[40,12909,6311,12910,1178,12912,383],{},[63,12911,6188],{},[63,12913,6223],{},[40,12915,6318,12916,6322],{},[63,12917,6321],{},[14,12919,213],{"id":213},[173,12921,12922,12926],{},[40,12923,2375,12924,6332],{},[63,12925,6331],{},[40,12927,6335,12928,383],{},[63,12929,6155],{},[10,12931,224],{},[14,12933,227],{"id":227},[10,12935,6344],{},[232,12937,234],{},{"title":61,"searchDepth":75,"depth":75,"links":12939},[12940,12941,12942,12943,12944,12947,12948,12949],{"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":171,"depth":75,"text":171,"children":12945},[12946],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":6128,"description":6133},[247,6366,6367],{"id":6370,"title":6371,"body":12954,"category":247,"cover":248,"description":6376,"extension":249,"meta":13093,"navigation":84,"path":6542,"pinned":252,"publishedAt":253,"seo":13094,"slug":6544,"stem":6545,"summary":6546,"tags":13095,"updatedAt":253,"visible":84,"__hash__":6549},{"type":7,"value":12955,"toc":13083},[12956,12958,12960,12962,12964,12968,12970,12972,12982,12984,12986,13026,13028,13033,13035,13037,13055,13057,13065,13067,13075,13077,13079,13081],[10,12957,6376],{},[14,12959,16],{"id":16},[10,12961,6381],{},[14,12963,22],{"id":22},[10,12965,12966],{},[26,12967],{"alt":6388,"src":6389},[10,12969,6392],{},[14,12971,35],{"id":35},[37,12973,12974,12978,12980],{},[40,12975,12976,6402],{},[63,12977,6401],{},[40,12979,6405],{},[40,12981,6408],{},[14,12983,51],{"id":51},[10,12985,1595],{},[56,12987,12988],{"className":612,"code":6415,"language":614,"meta":61,"style":61},[63,12989,12990,13000,13006,13012,13022],{"__ignoreMap":61},[66,12991,12992,12994,12996,12998],{"class":68,"line":69},[66,12993,712],{"class":621},[66,12995,654],{"class":624},[66,12997,6426],{"class":657},[66,12999,6429],{"class":657},[66,13001,13002,13004],{"class":68,"line":75},[66,13003,6434],{"class":624},[66,13005,6437],{"class":657},[66,13007,13008,13010],{"class":68,"line":81},[66,13009,60],{"class":621},[66,13011,625],{"class":624},[66,13013,13014,13016,13018,13020],{"class":68,"line":88},[66,13015,60],{"class":621},[66,13017,654],{"class":624},[66,13019,658],{"class":657},[66,13021,625],{"class":624},[66,13023,13024],{"class":68,"line":94},[66,13025,6458],{"class":621},[10,13027,157],{},[56,13029,13031],{"className":13030,"code":6464,"language":163,"meta":61},[161],[63,13032,6464],{"__ignoreMap":61},[10,13034,168],{},[14,13036,171],{"id":171},[173,13038,13039,13045],{},[40,13040,13041,6478,13043,6481],{},[63,13042,6477],{},[63,13044,712],{},[40,13046,6484,13047,2197,13049,6490,13051,3748,13053,6496],{},[63,13048,60],{},[63,13050,6489],{},[63,13052,6401],{},[63,13054,6495],{},[14,13056,202],{"id":202},[37,13058,13059,13061],{},[40,13060,6503],{},[40,13062,3487,13063,6508],{},[63,13064,6401],{},[14,13066,213],{"id":213},[173,13068,13069,13073],{},[40,13070,6515,13071,383],{},[63,13072,6518],{},[40,13074,6521],{},[10,13076,224],{},[14,13078,227],{"id":227},[10,13080,6528],{},[232,13082,1679],{},{"title":61,"searchDepth":75,"depth":75,"links":13084},[13085,13086,13087,13088,13089,13090,13091,13092],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":6371,"description":6376},[247,6548,282],{"id":6551,"title":6552,"body":13097,"category":247,"cover":248,"description":6557,"extension":249,"meta":13250,"navigation":84,"path":6746,"pinned":252,"publishedAt":253,"seo":13251,"slug":6748,"stem":6749,"summary":6750,"tags":13252,"updatedAt":253,"visible":84,"__hash__":6754},{"type":7,"value":13098,"toc":13240},[13099,13101,13103,13105,13107,13111,13117,13119,13135,13137,13139,13183,13185,13190,13192,13194,13206,13208,13222,13224,13232,13234,13236,13238],[10,13100,6557],{},[14,13102,16],{"id":16},[10,13104,6562],{},[14,13106,22],{"id":22},[10,13108,13109],{},[26,13110],{"alt":6569,"src":6570},[10,13112,13113,6576,13115,6579],{},[63,13114,6575],{},[63,13116,2457],{},[14,13118,35],{"id":35},[37,13120,13121,13123,13131],{},[40,13122,6586],{},[40,13124,13125,2278,13127,2278,13129,6598],{},[63,13126,6591],{},[63,13128,6594],{},[63,13130,6597],{},[40,13132,6601,13133,6605],{},[63,13134,6604],{},[14,13136,51],{"id":51},[10,13138,54],{},[56,13140,13141],{"className":58,"code":6612,"language":60,"meta":61,"style":61},[63,13142,13143,13147,13151,13155,13159,13163,13167,13171,13175,13179],{"__ignoreMap":61},[66,13144,13145],{"class":68,"line":69},[66,13146,6619],{},[66,13148,13149],{"class":68,"line":75},[66,13150,85],{"emptyLinePlaceholder":84},[66,13152,13153],{"class":68,"line":81},[66,13154,6628],{},[66,13156,13157],{"class":68,"line":88},[66,13158,6633],{},[66,13160,13161],{"class":68,"line":94},[66,13162,6638],{},[66,13164,13165],{"class":68,"line":99},[66,13166,85],{"emptyLinePlaceholder":84},[66,13168,13169],{"class":68,"line":105},[66,13170,6647],{},[66,13172,13173],{"class":68,"line":111},[66,13174,6652],{},[66,13176,13177],{"class":68,"line":117},[66,13178,6657],{},[66,13180,13181],{"class":68,"line":122},[66,13182,6662],{},[10,13184,157],{},[56,13186,13188],{"className":13187,"code":6668,"language":163,"meta":61},[161],[63,13189,6668],{"__ignoreMap":61},[10,13191,168],{},[14,13193,171],{"id":171},[173,13195,13196,13200],{},[40,13197,13198,6682],{},[63,13199,6681],{},[40,13201,2360,13202,6687,13204,6690],{},[63,13203,2457],{},[63,13205,6575],{},[14,13207,202],{"id":202},[37,13209,13210,13216],{},[40,13211,3487,13212,6699,13214,6702],{},[63,13213,6575],{},[63,13215,6591],{},[40,13217,6705,13218,1030,13220,6711],{},[63,13219,2457],{},[63,13221,6710],{},[14,13223,213],{"id":213},[173,13225,13226,13230],{},[40,13227,6718,13228,6722],{},[63,13229,6721],{},[40,13231,6725],{},[10,13233,224],{},[14,13235,227],{"id":227},[10,13237,6732],{},[232,13239,234],{},{"title":61,"searchDepth":75,"depth":75,"links":13241},[13242,13243,13244,13245,13246,13247,13248,13249],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":6552,"description":6557},[247,6752,6753],{"id":6756,"title":6757,"body":13254,"category":247,"cover":248,"description":6762,"extension":249,"meta":13401,"navigation":84,"path":6941,"pinned":252,"publishedAt":253,"seo":13402,"slug":6943,"stem":6944,"summary":6945,"tags":13403,"updatedAt":253,"visible":84,"__hash__":6949},{"type":7,"value":13255,"toc":13391},[13256,13258,13260,13262,13264,13268,13270,13272,13290,13292,13294,13342,13344,13349,13351,13353,13361,13363,13373,13375,13383,13385,13387,13389],[10,13257,6762],{},[14,13259,16],{"id":16},[10,13261,6767],{},[14,13263,22],{"id":22},[10,13265,13266],{},[26,13267],{"alt":6774,"src":6775},[10,13269,6778],{},[14,13271,35],{"id":35},[37,13273,13274,13278,13284],{},[40,13275,13276,6788],{},[63,13277,6787],{},[40,13279,13280,6794,13282,383],{},[63,13281,6793],{},[63,13283,6797],{},[40,13285,6800,13286,6804,13288,6808],{},[63,13287,6803],{},[63,13289,6807],{},[14,13291,51],{"id":51},[10,13293,54],{},[56,13295,13296],{"className":58,"code":6815,"language":60,"meta":61,"style":61},[63,13297,13298,13302,13306,13310,13314,13318,13322,13326,13330,13334,13338],{"__ignoreMap":61},[66,13299,13300],{"class":68,"line":69},[66,13301,6619],{},[66,13303,13304],{"class":68,"line":75},[66,13305,85],{"emptyLinePlaceholder":84},[66,13307,13308],{"class":68,"line":81},[66,13309,6830],{},[66,13311,13312],{"class":68,"line":88},[66,13313,6835],{},[66,13315,13316],{"class":68,"line":94},[66,13317,6840],{},[66,13319,13320],{"class":68,"line":99},[66,13321,6845],{},[66,13323,13324],{"class":68,"line":105},[66,13325,85],{"emptyLinePlaceholder":84},[66,13327,13328],{"class":68,"line":111},[66,13329,6854],{},[66,13331,13332],{"class":68,"line":117},[66,13333,6859],{},[66,13335,13336],{"class":68,"line":122},[66,13337,6864],{},[66,13339,13340],{"class":68,"line":128},[66,13341,6869],{},[10,13343,157],{},[56,13345,13347],{"className":13346,"code":6875,"language":163,"meta":61},[161],[63,13348,6875],{"__ignoreMap":61},[10,13350,168],{},[14,13352,171],{"id":171},[173,13354,13355,13359],{},[40,13356,6886,13357,6889],{},[63,13358,6803],{},[40,13360,6892],{},[14,13362,202],{"id":202},[37,13364,13365,13369],{},[40,13366,2360,13367,6901],{},[63,13368,6787],{},[40,13370,6904,13371,383],{},[63,13372,6907],{},[14,13374,213],{"id":213},[173,13376,13377,13379],{},[40,13378,6914],{},[40,13380,6917,13381,6920],{},[63,13382,357],{},[10,13384,224],{},[14,13386,227],{"id":227},[10,13388,6927],{},[232,13390,234],{},{"title":61,"searchDepth":75,"depth":75,"links":13392},[13393,13394,13395,13396,13397,13398,13399,13400],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":6757,"description":6762},[247,6947,6948],{"id":6951,"title":6952,"body":13405,"category":247,"cover":248,"description":6957,"extension":249,"meta":13548,"navigation":84,"path":7125,"pinned":252,"publishedAt":253,"seo":13549,"slug":7127,"stem":7128,"summary":7129,"tags":13550,"updatedAt":253,"visible":84,"__hash__":7133},{"type":7,"value":13406,"toc":13538},[13407,13409,13411,13413,13415,13419,13425,13427,13437,13439,13441,13493,13495,13500,13502,13504,13514,13516,13522,13524,13530,13532,13534,13536],[10,13408,6957],{},[14,13410,16],{"id":16},[10,13412,6962],{},[14,13414,22],{"id":22},[10,13416,13417],{},[26,13418],{"alt":6969,"src":6970},[10,13420,13421,6976,13423,6980],{},[63,13422,6975],{},[63,13424,6979],{},[14,13426,35],{"id":35},[37,13428,13429,13431,13435],{},[40,13430,6987],{},[40,13432,13433,6993],{},[63,13434,6992],{},[40,13436,6996],{},[14,13438,51],{"id":51},[10,13440,54],{},[56,13442,13443],{"className":58,"code":7003,"language":60,"meta":61,"style":61},[63,13444,13445,13449,13453,13457,13461,13465,13469,13473,13477,13481,13485,13489],{"__ignoreMap":61},[66,13446,13447],{"class":68,"line":69},[66,13448,7010],{},[66,13450,13451],{"class":68,"line":75},[66,13452,85],{"emptyLinePlaceholder":84},[66,13454,13455],{"class":68,"line":81},[66,13456,7019],{},[66,13458,13459],{"class":68,"line":88},[66,13460,85],{"emptyLinePlaceholder":84},[66,13462,13463],{"class":68,"line":94},[66,13464,7028],{},[66,13466,13467],{"class":68,"line":99},[66,13468,7033],{},[66,13470,13471],{"class":68,"line":105},[66,13472,6845],{},[66,13474,13475],{"class":68,"line":111},[66,13476,85],{"emptyLinePlaceholder":84},[66,13478,13479],{"class":68,"line":117},[66,13480,7046],{},[66,13482,13483],{"class":68,"line":122},[66,13484,7051],{},[66,13486,13487],{"class":68,"line":128},[66,13488,6864],{},[66,13490,13491],{"class":68,"line":134},[66,13492,7060],{},[10,13494,157],{},[56,13496,13498],{"className":13497,"code":7066,"language":163,"meta":61},[161],[63,13499,7066],{"__ignoreMap":61},[10,13501,168],{},[14,13503,171],{"id":171},[173,13505,13506,13510],{},[40,13507,13508,7079],{},[63,13509,6975],{},[40,13511,13512,7084],{},[63,13513,6979],{},[14,13515,202],{"id":202},[37,13517,13518,13520],{},[40,13519,7091],{},[40,13521,7094],{},[14,13523,213],{"id":213},[173,13525,13526,13528],{},[40,13527,7101],{},[40,13529,7104],{},[10,13531,224],{},[14,13533,227],{"id":227},[10,13535,7111],{},[232,13537,234],{},{"title":61,"searchDepth":75,"depth":75,"links":13539},[13540,13541,13542,13543,13544,13545,13546,13547],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":6952,"description":6957},[247,7131,7132],{"id":7135,"title":7136,"body":13552,"category":247,"cover":248,"description":7141,"extension":249,"meta":13703,"navigation":84,"path":7326,"pinned":252,"publishedAt":253,"seo":13704,"slug":7328,"stem":7329,"summary":7330,"tags":13705,"updatedAt":253,"visible":84,"__hash__":7334},{"type":7,"value":13553,"toc":13693},[13554,13556,13558,13560,13562,13566,13570,13572,13586,13588,13590,13642,13644,13649,13651,13653,13665,13667,13677,13679,13685,13687,13689,13691],[10,13555,7141],{},[14,13557,16],{"id":16},[10,13559,7146],{},[14,13561,22],{"id":22},[10,13563,13564],{},[26,13565],{"alt":7153,"src":7154},[10,13567,13568,7160],{},[63,13569,7159],{},[14,13571,35],{"id":35},[37,13573,13574,13580,13584],{},[40,13575,2360,13576,7170,13578,7174],{},[63,13577,7169],{},[63,13579,7173],{},[40,13581,7177,13582,7181],{},[63,13583,7180],{},[40,13585,7184],{},[14,13587,51],{"id":51},[10,13589,54],{},[56,13591,13592],{"className":58,"code":7191,"language":60,"meta":61,"style":61},[63,13593,13594,13598,13602,13606,13610,13614,13618,13622,13626,13630,13634,13638],{"__ignoreMap":61},[66,13595,13596],{"class":68,"line":69},[66,13597,7198],{},[66,13599,13600],{"class":68,"line":75},[66,13601,85],{"emptyLinePlaceholder":84},[66,13603,13604],{"class":68,"line":81},[66,13605,7207],{},[66,13607,13608],{"class":68,"line":88},[66,13609,7212],{},[66,13611,13612],{"class":68,"line":94},[66,13613,7217],{},[66,13615,13616],{"class":68,"line":99},[66,13617,7222],{},[66,13619,13620],{"class":68,"line":105},[66,13621,7227],{},[66,13623,13624],{"class":68,"line":111},[66,13625,85],{"emptyLinePlaceholder":84},[66,13627,13628],{"class":68,"line":117},[66,13629,7236],{},[66,13631,13632],{"class":68,"line":122},[66,13633,7241],{},[66,13635,13636],{"class":68,"line":128},[66,13637,7246],{},[66,13639,13640],{"class":68,"line":134},[66,13641,7251],{},[10,13643,157],{},[56,13645,13647],{"className":13646,"code":7257,"language":163,"meta":61},[161],[63,13648,7257],{"__ignoreMap":61},[10,13650,168],{},[14,13652,171],{"id":171},[173,13654,13655,13661],{},[40,13656,13657,7271,13659,7274],{},[63,13658,7270],{},[63,13660,7180],{},[40,13662,13663,7279],{},[63,13664,7159],{},[14,13666,202],{"id":202},[37,13668,13669,13671],{},[40,13670,7286],{},[40,13672,7289,13673,7292,13675,7295],{},[63,13674,7169],{},[63,13676,7173],{},[14,13678,213],{"id":213},[173,13680,13681,13683],{},[40,13682,7302],{},[40,13684,7305],{},[10,13686,224],{},[14,13688,227],{"id":227},[10,13690,7312],{},[232,13692,234],{},{"title":61,"searchDepth":75,"depth":75,"links":13694},[13695,13696,13697,13698,13699,13700,13701,13702],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":7136,"description":7141},[247,7332,7333],{"id":7336,"title":7337,"body":13707,"category":247,"cover":248,"description":7342,"extension":249,"meta":13921,"navigation":84,"path":7614,"pinned":252,"publishedAt":253,"seo":13922,"slug":7616,"stem":7617,"summary":7618,"tags":13923,"updatedAt":253,"visible":84,"__hash__":7622},{"type":7,"value":13708,"toc":13908},[13709,13711,13713,13715,13717,13721,13727,13729,13741,13743,13745,13805,13807,13812,13814,13816,13834,13836,13844,13848,13856,13858,13862,13866,13872,13874,13884,13886,13900,13902,13904,13906],[10,13710,7342],{},[14,13712,16],{"id":16},[10,13714,7347],{},[14,13716,22],{"id":22},[10,13718,13719],{},[26,13720],{"alt":7354,"src":7355},[10,13722,7358,13723,7362,13725,7366],{},[63,13724,7361],{},[63,13726,7365],{},[14,13728,35],{"id":35},[37,13730,13731,13735,13739],{},[40,13732,7373,13733,7376],{},[63,13734,7361],{},[40,13736,13737,7382],{},[63,13738,7381],{},[40,13740,7385],{},[14,13742,51],{"id":51},[10,13744,54],{},[56,13746,13747],{"className":58,"code":7392,"language":60,"meta":61,"style":61},[63,13748,13749,13753,13757,13761,13765,13769,13773,13777,13781,13785,13789,13793,13797,13801],{"__ignoreMap":61},[66,13750,13751],{"class":68,"line":69},[66,13752,7399],{},[66,13754,13755],{"class":68,"line":75},[66,13756,7404],{},[66,13758,13759],{"class":68,"line":81},[66,13760,7409],{},[66,13762,13763],{"class":68,"line":88},[66,13764,7414],{},[66,13766,13767],{"class":68,"line":94},[66,13768,7419],{},[66,13770,13771],{"class":68,"line":99},[66,13772,85],{"emptyLinePlaceholder":84},[66,13774,13775],{"class":68,"line":105},[66,13776,7428],{},[66,13778,13779],{"class":68,"line":111},[66,13780,7433],{},[66,13782,13783],{"class":68,"line":117},[66,13784,7438],{},[66,13786,13787],{"class":68,"line":122},[66,13788,7443],{},[66,13790,13791],{"class":68,"line":128},[66,13792,1167],{},[66,13794,13795],{"class":68,"line":134},[66,13796,7452],{},[66,13798,13799],{"class":68,"line":140},[66,13800,7457],{},[66,13802,13803],{"class":68,"line":145},[66,13804,7462],{},[10,13806,157],{},[56,13808,13810],{"className":13809,"code":7468,"language":163,"meta":61},[161],[63,13811,7468],{"__ignoreMap":61},[10,13813,168],{},[14,13815,171],{"id":171},[173,13817,13818,13826],{},[40,13819,13820,7481,13822,7484,13824,7488],{},[63,13821,3056],{},[63,13823,7381],{},[63,13825,7487],{},[40,13827,7491,13828,7494,13830,7497,13832,383],{},[63,13829,7361],{},[63,13831,1181],{},[63,13833,7365],{},[185,13835,187],{"id":187},[10,13837,13838,2278,13840,1178,13842,7510],{},[63,13839,7361],{},[63,13841,1181],{},[63,13843,7365],{},[10,13845,13846],{},[26,13847],{"alt":7515,"src":7516},[10,13849,13850,7521,13852,7524,13854,7527],{},[63,13851,7361],{},[63,13853,1181],{},[63,13855,7365],{},[185,13857,187],{"id":4238},[10,13859,13860,7535],{},[63,13861,7534],{},[10,13863,13864],{},[26,13865],{"alt":7540,"src":7541},[10,13867,7544,13868,7547,13870,7550],{},[63,13869,7534],{},[63,13871,1181],{},[14,13873,202],{"id":202},[37,13875,13876,13880],{},[40,13877,7557,13878,7561],{},[63,13879,7560],{},[40,13881,7564,13882,7567],{},[63,13883,7534],{},[14,13885,213],{"id":213},[173,13887,13888,13896],{},[40,13889,7574,13890,7578,13892,1178,13894,383],{},[63,13891,7577],{},[63,13893,7581],{},[63,13895,7584],{},[40,13897,7587,13898,7590],{},[63,13899,6797],{},[10,13901,224],{},[14,13903,227],{"id":227},[10,13905,7597],{},[232,13907,234],{},{"title":61,"searchDepth":75,"depth":75,"links":13909},[13910,13911,13912,13913,13914,13918,13919,13920],{"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":171,"depth":75,"text":171,"children":13915},[13916,13917],{"id":187,"depth":81,"text":187},{"id":4238,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":7337,"description":7342},[247,7620,7621],{"id":7624,"title":7625,"body":13925,"category":247,"cover":248,"description":7630,"extension":249,"meta":14076,"navigation":84,"path":7807,"pinned":252,"publishedAt":253,"seo":14077,"slug":7809,"stem":7810,"summary":7811,"tags":14078,"updatedAt":253,"visible":84,"__hash__":7814},{"type":7,"value":13926,"toc":14066},[13927,13929,13931,13933,13935,13939,13943,13945,13957,13959,13961,14009,14011,14016,14018,14020,14030,14032,14042,14044,14058,14060,14062,14064],[10,13928,7630],{},[14,13930,16],{"id":16},[10,13932,7635],{},[14,13934,22],{"id":22},[10,13936,13937],{},[26,13938],{"alt":7642,"src":7643},[10,13940,7646,13941,7649],{},[63,13942,6807],{},[14,13944,35],{"id":35},[37,13946,13947,13951,13955],{},[40,13948,13949,7658],{},[63,13950,6807],{},[40,13952,13953,7664],{},[63,13954,7663],{},[40,13956,7667],{},[14,13958,51],{"id":51},[10,13960,54],{},[56,13962,13963],{"className":58,"code":7674,"language":60,"meta":61,"style":61},[63,13964,13965,13969,13973,13977,13981,13985,13989,13993,13997,14001,14005],{"__ignoreMap":61},[66,13966,13967],{"class":68,"line":69},[66,13968,6619],{},[66,13970,13971],{"class":68,"line":75},[66,13972,85],{"emptyLinePlaceholder":84},[66,13974,13975],{"class":68,"line":81},[66,13976,6830],{},[66,13978,13979],{"class":68,"line":88},[66,13980,85],{"emptyLinePlaceholder":84},[66,13982,13983],{"class":68,"line":94},[66,13984,7697],{},[66,13986,13987],{"class":68,"line":99},[66,13988,7702],{},[66,13990,13991],{"class":68,"line":105},[66,13992,85],{"emptyLinePlaceholder":84},[66,13994,13995],{"class":68,"line":111},[66,13996,7711],{},[66,13998,13999],{"class":68,"line":117},[66,14000,7716],{},[66,14002,14003],{"class":68,"line":122},[66,14004,85],{"emptyLinePlaceholder":84},[66,14006,14007],{"class":68,"line":128},[66,14008,7725],{},[10,14010,157],{},[56,14012,14014],{"className":14013,"code":7731,"language":163,"meta":61},[161],[63,14015,7731],{"__ignoreMap":61},[10,14017,168],{},[14,14019,171],{"id":171},[173,14021,14022,14028],{},[40,14023,7646,14024,7744,14026,383],{},[63,14025,6807],{},[63,14027,7747],{},[40,14029,7750],{},[14,14031,202],{"id":202},[37,14033,14034,14038],{},[40,14035,4806,14036,7759],{},[63,14037,6807],{},[40,14039,7762,14040,7765],{},[63,14041,6807],{},[14,14043,213],{"id":213},[173,14045,14046,14052],{},[40,14047,7772,14048,7776,14050,383],{},[63,14049,7775],{},[63,14051,6807],{},[40,14053,4806,14054,7783,14056,383],{},[63,14055,6807],{},[63,14057,7786],{},[10,14059,224],{},[14,14061,227],{"id":227},[10,14063,7793],{},[232,14065,234],{},{"title":61,"searchDepth":75,"depth":75,"links":14067},[14068,14069,14070,14071,14072,14073,14074,14075],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":7625,"description":7630},[247,6807,7813],{"id":7816,"title":7817,"body":14080,"category":247,"cover":248,"description":7822,"extension":249,"meta":14251,"navigation":84,"path":8035,"pinned":252,"publishedAt":253,"seo":14252,"slug":8037,"stem":8038,"summary":8039,"tags":14253,"updatedAt":253,"visible":84,"__hash__":8043},{"type":7,"value":14081,"toc":14239},[14082,14084,14086,14088,14090,14094,14096,14098,14110,14112,14114,14170,14172,14177,14179,14181,14197,14199,14201,14205,14211,14213,14221,14223,14231,14233,14235,14237],[10,14083,7822],{},[14,14085,16],{"id":16},[10,14087,7827],{},[14,14089,22],{"id":22},[10,14091,14092],{},[26,14093],{"alt":7834,"src":7835},[10,14095,7838],{},[14,14097,35],{"id":35},[37,14099,14100,14104,14108],{},[40,14101,14102,7848],{},[63,14103,7847],{},[40,14105,14106,7854],{},[63,14107,7853],{},[40,14109,7857],{},[14,14111,51],{"id":51},[10,14113,54],{},[56,14115,14116],{"className":58,"code":7864,"language":60,"meta":61,"style":61},[63,14117,14118,14122,14126,14130,14134,14138,14142,14146,14150,14154,14158,14162,14166],{"__ignoreMap":61},[66,14119,14120],{"class":68,"line":69},[66,14121,7871],{},[66,14123,14124],{"class":68,"line":75},[66,14125,7876],{},[66,14127,14128],{"class":68,"line":81},[66,14129,7881],{},[66,14131,14132],{"class":68,"line":88},[66,14133,7886],{},[66,14135,14136],{"class":68,"line":94},[66,14137,85],{"emptyLinePlaceholder":84},[66,14139,14140],{"class":68,"line":99},[66,14141,7895],{},[66,14143,14144],{"class":68,"line":105},[66,14145,7900],{},[66,14147,14148],{"class":68,"line":111},[66,14149,7905],{},[66,14151,14152],{"class":68,"line":117},[66,14153,7910],{},[66,14155,14156],{"class":68,"line":122},[66,14157,85],{"emptyLinePlaceholder":84},[66,14159,14160],{"class":68,"line":128},[66,14161,7919],{},[66,14163,14164],{"class":68,"line":134},[66,14165,7924],{},[66,14167,14168],{"class":68,"line":140},[66,14169,7929],{},[10,14171,157],{},[56,14173,14175],{"className":14174,"code":7935,"language":163,"meta":61},[161],[63,14176,7935],{"__ignoreMap":61},[10,14178,168],{},[14,14180,171],{"id":171},[173,14182,14183,14189],{},[40,14184,7946,14185,7950,14187,7953],{},[63,14186,7949],{},[63,14188,7853],{},[40,14190,14191,7959,14193,7963,14195,7966],{},[63,14192,7958],{},[63,14194,7962],{},[63,14196,7847],{},[185,14198,187],{"id":187},[10,14200,7971],{},[10,14202,14203],{},[26,14204],{"alt":7976,"src":7977},[10,14206,7980,14207,1178,14209,7986],{},[63,14208,4603],{},[63,14210,7985],{},[14,14212,202],{"id":202},[37,14214,14215,14219],{},[40,14216,7993,14217,7996],{},[63,14218,7847],{},[40,14220,7999],{},[14,14222,213],{"id":213},[173,14224,14225,14229],{},[40,14226,5316,14227,8009],{},[63,14228,8008],{},[40,14230,8012],{},[10,14232,224],{},[14,14234,227],{"id":227},[10,14236,8019],{},[232,14238,234],{},{"title":61,"searchDepth":75,"depth":75,"links":14240},[14241,14242,14243,14244,14245,14248,14249,14250],{"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":171,"depth":75,"text":171,"children":14246},[14247],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":7817,"description":7822},[247,8041,8042],{"id":8045,"title":8046,"body":14255,"category":247,"cover":248,"description":8051,"extension":249,"meta":14402,"navigation":84,"path":8230,"pinned":252,"publishedAt":253,"seo":14403,"slug":8232,"stem":8233,"summary":8234,"tags":14404,"updatedAt":253,"visible":84,"__hash__":8238},{"type":7,"value":14256,"toc":14392},[14257,14259,14261,14263,14265,14269,14271,14273,14281,14283,14285,14341,14343,14348,14350,14352,14364,14366,14372,14374,14384,14386,14388,14390],[10,14258,8051],{},[14,14260,16],{"id":16},[10,14262,8056],{},[14,14264,22],{"id":22},[10,14266,14267],{},[26,14268],{"alt":8063,"src":8064},[10,14270,8067],{},[14,14272,35],{"id":35},[37,14274,14275,14277,14279],{},[40,14276,8074],{},[40,14278,8077],{},[40,14280,8080],{},[14,14282,51],{"id":51},[10,14284,54],{},[56,14286,14287],{"className":58,"code":8087,"language":60,"meta":61,"style":61},[63,14288,14289,14293,14297,14301,14305,14309,14313,14317,14321,14325,14329,14333,14337],{"__ignoreMap":61},[66,14290,14291],{"class":68,"line":69},[66,14292,8094],{},[66,14294,14295],{"class":68,"line":75},[66,14296,8099],{},[66,14298,14299],{"class":68,"line":81},[66,14300,8104],{},[66,14302,14303],{"class":68,"line":88},[66,14304,85],{"emptyLinePlaceholder":84},[66,14306,14307],{"class":68,"line":94},[66,14308,8113],{},[66,14310,14311],{"class":68,"line":99},[66,14312,8118],{},[66,14314,14315],{"class":68,"line":105},[66,14316,8123],{},[66,14318,14319],{"class":68,"line":111},[66,14320,85],{"emptyLinePlaceholder":84},[66,14322,14323],{"class":68,"line":117},[66,14324,8132],{},[66,14326,14327],{"class":68,"line":122},[66,14328,8137],{},[66,14330,14331],{"class":68,"line":128},[66,14332,85],{"emptyLinePlaceholder":84},[66,14334,14335],{"class":68,"line":134},[66,14336,8146],{},[66,14338,14339],{"class":68,"line":140},[66,14340,8151],{},[10,14342,157],{},[56,14344,14346],{"className":14345,"code":8157,"language":163,"meta":61},[161],[63,14347,8157],{"__ignoreMap":61},[10,14349,168],{},[14,14351,171],{"id":171},[173,14353,14354,14360],{},[40,14355,14356,8171,14358,8175],{},[63,14357,8170],{},[63,14359,8174],{},[40,14361,8178,14362,8182],{},[63,14363,8181],{},[14,14365,202],{"id":202},[37,14367,14368,14370],{},[40,14369,8189],{},[40,14371,8192],{},[14,14373,213],{"id":213},[173,14375,14376,14382],{},[40,14377,8199,14378,8203,14380,383],{},[63,14379,8202],{},[63,14381,8206],{},[40,14383,8209],{},[10,14385,224],{},[14,14387,227],{"id":227},[10,14389,8216],{},[232,14391,234],{},{"title":61,"searchDepth":75,"depth":75,"links":14393},[14394,14395,14396,14397,14398,14399,14400,14401],{"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":171,"depth":75,"text":171},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":8046,"description":8051},[247,8236,8237],{"id":8240,"title":8241,"body":14406,"category":247,"cover":248,"description":8246,"extension":249,"meta":14569,"navigation":84,"path":8450,"pinned":252,"publishedAt":253,"seo":14570,"slug":8452,"stem":8453,"summary":8454,"tags":14571,"updatedAt":253,"visible":84,"__hash__":8458},{"type":7,"value":14407,"toc":14557},[14408,14410,14412,14414,14416,14420,14424,14426,14442,14444,14446,14490,14492,14497,14499,14501,14515,14517,14521,14525,14529,14531,14537,14539,14549,14551,14553,14555],[10,14409,8246],{},[14,14411,16],{"id":16},[10,14413,8251],{},[14,14415,22],{"id":22},[10,14417,14418],{},[26,14419],{"alt":8258,"src":8259},[10,14421,8262,14422,8266],{},[63,14423,8265],{},[14,14425,35],{"id":35},[37,14427,14428,14434,14440],{},[40,14429,14430,8276,14432,8280],{},[63,14431,8275],{},[63,14433,8279],{},[40,14435,8283,14436,8287,14438,8290],{},[63,14437,8286],{},[63,14439,4357],{},[40,14441,8293],{},[14,14443,51],{"id":51},[10,14445,54],{},[56,14447,14448],{"className":58,"code":8300,"language":60,"meta":61,"style":61},[63,14449,14450,14454,14458,14462,14466,14470,14474,14478,14482,14486],{"__ignoreMap":61},[66,14451,14452],{"class":68,"line":69},[66,14453,8307],{},[66,14455,14456],{"class":68,"line":75},[66,14457,8312],{},[66,14459,14460],{"class":68,"line":81},[66,14461,8317],{},[66,14463,14464],{"class":68,"line":88},[66,14465,8322],{},[66,14467,14468],{"class":68,"line":94},[66,14469,8327],{},[66,14471,14472],{"class":68,"line":99},[66,14473,85],{"emptyLinePlaceholder":84},[66,14475,14476],{"class":68,"line":105},[66,14477,8336],{},[66,14479,14480],{"class":68,"line":111},[66,14481,8341],{},[66,14483,14484],{"class":68,"line":117},[66,14485,8341],{},[66,14487,14488],{"class":68,"line":122},[66,14489,8341],{},[10,14491,157],{},[56,14493,14495],{"className":14494,"code":8355,"language":163,"meta":61},[161],[63,14496,8355],{"__ignoreMap":61},[10,14498,168],{},[14,14500,171],{"id":171},[173,14502,14503,14507],{},[40,14504,7946,14505,8369],{},[63,14506,8368],{},[40,14508,8372,14509,8375,14511,8378,14513,8382],{},[63,14510,8279],{},[63,14512,8265],{},[63,14514,8381],{},[185,14516,187],{"id":187},[10,14518,8387,14519,8390],{},[63,14520,8279],{},[10,14522,14523],{},[26,14524],{"alt":8395,"src":8396},[10,14526,8399,14527,8402],{},[63,14528,8265],{},[14,14530,202],{"id":202},[37,14532,14533,14535],{},[40,14534,8409],{},[40,14536,8412],{},[14,14538,213],{"id":213},[173,14540,14541,14543],{},[40,14542,8419],{},[40,14544,4030,14545,8424,14547,8427],{},[63,14546,4357],{},[63,14548,8279],{},[10,14550,224],{},[14,14552,227],{"id":227},[10,14554,8434],{},[232,14556,234],{},{"title":61,"searchDepth":75,"depth":75,"links":14558},[14559,14560,14561,14562,14563,14566,14567,14568],{"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":171,"depth":75,"text":171,"children":14564},[14565],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":8241,"description":8246},[247,8456,8457],{"id":8460,"title":8461,"body":14573,"category":247,"cover":248,"description":8466,"extension":249,"meta":14756,"navigation":84,"path":8690,"pinned":252,"publishedAt":253,"seo":14757,"slug":8692,"stem":8693,"summary":8694,"tags":14758,"updatedAt":253,"visible":84,"__hash__":8697},{"type":7,"value":14574,"toc":14744},[14575,14577,14579,14581,14583,14587,14589,14591,14605,14607,14609,14677,14679,14684,14686,14688,14702,14704,14706,14710,14716,14718,14726,14728,14736,14738,14740,14742],[10,14576,8466],{},[14,14578,16],{"id":16},[10,14580,8471],{},[14,14582,22],{"id":22},[10,14584,14585],{},[26,14586],{"alt":8478,"src":8479},[10,14588,8482],{},[14,14590,35],{"id":35},[37,14592,14593,14599,14601],{},[40,14594,14595,8492,14597,383],{},[63,14596,8491],{},[63,14598,8495],{},[40,14600,8498],{},[40,14602,14603,8504],{},[63,14604,8503],{},[14,14606,51],{"id":51},[10,14608,54],{},[56,14610,14611],{"className":58,"code":8511,"language":60,"meta":61,"style":61},[63,14612,14613,14617,14621,14625,14629,14633,14637,14641,14645,14649,14653,14657,14661,14665,14669,14673],{"__ignoreMap":61},[66,14614,14615],{"class":68,"line":69},[66,14616,8518],{},[66,14618,14619],{"class":68,"line":75},[66,14620,85],{"emptyLinePlaceholder":84},[66,14622,14623],{"class":68,"line":81},[66,14624,8527],{},[66,14626,14627],{"class":68,"line":88},[66,14628,8532],{},[66,14630,14631],{"class":68,"line":94},[66,14632,8537],{},[66,14634,14635],{"class":68,"line":99},[66,14636,8542],{},[66,14638,14639],{"class":68,"line":105},[66,14640,8547],{},[66,14642,14643],{"class":68,"line":111},[66,14644,8552],{},[66,14646,14647],{"class":68,"line":117},[66,14648,8557],{},[66,14650,14651],{"class":68,"line":122},[66,14652,8562],{},[66,14654,14655],{"class":68,"line":128},[66,14656,85],{"emptyLinePlaceholder":84},[66,14658,14659],{"class":68,"line":134},[66,14660,8571],{},[66,14662,14663],{"class":68,"line":140},[66,14664,6199],{},[66,14666,14667],{"class":68,"line":145},[66,14668,6204],{},[66,14670,14671],{"class":68,"line":151},[66,14672,85],{"emptyLinePlaceholder":84},[66,14674,14675],{"class":68,"line":8586},[66,14676,8589],{},[10,14678,157],{},[56,14680,14682],{"className":14681,"code":8595,"language":163,"meta":61},[161],[63,14683,8595],{"__ignoreMap":61},[10,14685,168],{},[14,14687,171],{"id":171},[173,14689,14690,14700],{},[40,14691,8606,14692,8610,14694,8614,14696,8618,14698,383],{},[63,14693,8609],{},[63,14695,8613],{},[63,14697,8617],{},[63,14699,8609],{},[40,14701,8623],{},[185,14703,187],{"id":187},[10,14705,8628],{},[10,14707,14708],{},[26,14709],{"alt":8633,"src":8634},[10,14711,14712,8639,14714,383],{},[63,14713,8491],{},[63,14715,8495],{},[14,14717,202],{"id":202},[37,14719,14720,14724],{},[40,14721,8648,14722,383],{},[63,14723,5399],{},[40,14725,8653],{},[14,14727,213],{"id":213},[173,14729,14730,14732],{},[40,14731,8660],{},[40,14733,8663,14734,8667],{},[63,14735,8666],{},[10,14737,224],{},[14,14739,227],{"id":227},[10,14741,8674],{},[232,14743,234],{},{"title":61,"searchDepth":75,"depth":75,"links":14745},[14746,14747,14748,14749,14750,14753,14754,14755],{"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":171,"depth":75,"text":171,"children":14751},[14752],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":8461,"description":8466},[247,8696,5350],{"id":4,"title":5,"body":14760,"category":247,"cover":248,"description":12,"extension":249,"meta":14919,"navigation":84,"path":251,"pinned":252,"publishedAt":253,"seo":14920,"slug":255,"stem":256,"summary":257,"tags":14921,"updatedAt":253,"visible":84,"__hash__":261},{"type":7,"value":14761,"toc":14907},[14762,14764,14766,14768,14770,14774,14776,14778,14786,14788,14790,14854,14856,14861,14863,14865,14873,14875,14877,14881,14883,14885,14891,14893,14899,14901,14903,14905],[10,14763,12],{},[14,14765,16],{"id":16},[10,14767,19],{},[14,14769,22],{"id":22},[10,14771,14772],{},[26,14773],{"alt":28,"src":29},[10,14775,32],{},[14,14777,35],{"id":35},[37,14779,14780,14782,14784],{},[40,14781,42],{},[40,14783,45],{},[40,14785,48],{},[14,14787,51],{"id":51},[10,14789,54],{},[56,14791,14792],{"className":58,"code":59,"language":60,"meta":61,"style":61},[63,14793,14794,14798,14802,14806,14810,14814,14818,14822,14826,14830,14834,14838,14842,14846,14850],{"__ignoreMap":61},[66,14795,14796],{"class":68,"line":69},[66,14797,72],{},[66,14799,14800],{"class":68,"line":75},[66,14801,78],{},[66,14803,14804],{"class":68,"line":81},[66,14805,85],{"emptyLinePlaceholder":84},[66,14807,14808],{"class":68,"line":88},[66,14809,91],{},[66,14811,14812],{"class":68,"line":94},[66,14813,85],{"emptyLinePlaceholder":84},[66,14815,14816],{"class":68,"line":99},[66,14817,102],{},[66,14819,14820],{"class":68,"line":105},[66,14821,108],{},[66,14823,14824],{"class":68,"line":111},[66,14825,114],{},[66,14827,14828],{"class":68,"line":117},[66,14829,85],{"emptyLinePlaceholder":84},[66,14831,14832],{"class":68,"line":122},[66,14833,125],{},[66,14835,14836],{"class":68,"line":128},[66,14837,131],{},[66,14839,14840],{"class":68,"line":134},[66,14841,137],{},[66,14843,14844],{"class":68,"line":140},[66,14845,85],{"emptyLinePlaceholder":84},[66,14847,14848],{"class":68,"line":145},[66,14849,148],{},[66,14851,14852],{"class":68,"line":151},[66,14853,154],{},[10,14855,157],{},[56,14857,14859],{"className":14858,"code":162,"language":163,"meta":61},[161],[63,14860,162],{"__ignoreMap":61},[10,14862,168],{},[14,14864,171],{"id":171},[173,14866,14867,14871],{},[40,14868,14869,180],{},[63,14870,179],{},[40,14872,183],{},[185,14874,187],{"id":187},[10,14876,190],{},[10,14878,14879],{},[26,14880],{"alt":195,"src":196},[10,14882,199],{},[14,14884,202],{"id":202},[37,14886,14887,14889],{},[40,14888,207],{},[40,14890,210],{},[14,14892,213],{"id":213},[173,14894,14895,14897],{},[40,14896,218],{},[40,14898,221],{},[10,14900,224],{},[14,14902,227],{"id":227},[10,14904,230],{},[232,14906,234],{},{"title":61,"searchDepth":75,"depth":75,"links":14908},[14909,14910,14911,14912,14913,14916,14917,14918],{"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":171,"depth":75,"text":171,"children":14914},[14915],{"id":187,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":5,"description":12},[247,259,260],{"id":8862,"title":8863,"body":14923,"category":247,"cover":248,"description":8868,"extension":249,"meta":15161,"navigation":84,"path":9169,"pinned":252,"publishedAt":253,"seo":15162,"slug":9171,"stem":9172,"summary":9173,"tags":15163,"updatedAt":253,"visible":84,"__hash__":9177},{"type":7,"value":14924,"toc":15148},[14925,14927,14929,14931,14933,14937,14939,14941,14951,14953,14955,15071,15073,15078,15080,15082,15092,15094,15096,15100,15102,15104,15106,15110,15114,15116,15124,15126,15140,15142,15144,15146],[10,14926,8868],{},[14,14928,16],{"id":16},[10,14930,8873],{},[14,14932,22],{"id":22},[10,14934,14935],{},[26,14936],{"alt":8880,"src":8881},[10,14938,8884],{},[14,14940,35],{"id":35},[37,14942,14943,14945,14947],{},[40,14944,8891],{},[40,14946,8894],{},[40,14948,8897,14949,8901],{},[63,14950,8900],{},[14,14952,51],{"id":51},[10,14954,54],{},[56,14956,14957],{"className":58,"code":8908,"language":60,"meta":61,"style":61},[63,14958,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,15059,15063,15067],{"__ignoreMap":61},[66,14960,14961],{"class":68,"line":69},[66,14962,7010],{},[66,14964,14965],{"class":68,"line":75},[66,14966,6619],{},[66,14968,14969],{"class":68,"line":81},[66,14970,85],{"emptyLinePlaceholder":84},[66,14972,14973],{"class":68,"line":88},[66,14974,8927],{},[66,14976,14977],{"class":68,"line":94},[66,14978,8932],{},[66,14980,14981],{"class":68,"line":99},[66,14982,8937],{},[66,14984,14985],{"class":68,"line":105},[66,14986,8942],{},[66,14988,14989],{"class":68,"line":111},[66,14990,85],{"emptyLinePlaceholder":84},[66,14992,14993],{"class":68,"line":117},[66,14994,8951],{},[66,14996,14997],{"class":68,"line":122},[66,14998,8956],{},[66,15000,15001],{"class":68,"line":128},[66,15002,8961],{},[66,15004,15005],{"class":68,"line":134},[66,15006,8966],{},[66,15008,15009],{"class":68,"line":140},[66,15010,8971],{},[66,15012,15013],{"class":68,"line":145},[66,15014,85],{"emptyLinePlaceholder":84},[66,15016,15017],{"class":68,"line":151},[66,15018,8980],{},[66,15020,15021],{"class":68,"line":8586},[66,15022,8985],{},[66,15024,15025],{"class":68,"line":8988},[66,15026,8991],{},[66,15028,15029],{"class":68,"line":8994},[66,15030,85],{"emptyLinePlaceholder":84},[66,15032,15033],{"class":68,"line":8999},[66,15034,9002],{},[66,15036,15037],{"class":68,"line":9005},[66,15038,85],{"emptyLinePlaceholder":84},[66,15040,15041],{"class":68,"line":9010},[66,15042,7428],{},[66,15044,15045],{"class":68,"line":9015},[66,15046,9018],{},[66,15048,15049],{"class":68,"line":9021},[66,15050,9024],{},[66,15052,15053],{"class":68,"line":9027},[66,15054,9030],{},[66,15056,15057],{"class":68,"line":9033},[66,15058,7438],{},[66,15060,15061],{"class":68,"line":9038},[66,15062,9041],{},[66,15064,15065],{"class":68,"line":9044},[66,15066,1167],{},[66,15068,15069],{"class":68,"line":9049},[66,15070,9052],{},[10,15072,157],{},[56,15074,15076],{"className":15075,"code":9058,"language":163,"meta":61},[161],[63,15077,9058],{"__ignoreMap":61},[10,15079,168],{},[14,15081,171],{"id":171},[173,15083,15084,15088],{},[40,15085,9069,15086,9072],{},[63,15087,8900],{},[40,15089,15090,9077],{},[63,15091,8174],{},[185,15093,187],{"id":187},[10,15095,9082],{},[10,15097,15098],{},[26,15099],{"alt":9087,"src":9088},[10,15101,9091],{},[185,15103,187],{"id":4238},[10,15105,9096],{},[10,15107,15108],{},[26,15109],{"alt":9101,"src":9102},[10,15111,9105,15112,9109],{},[63,15113,9108],{},[14,15115,202],{"id":202},[37,15117,15118,15120],{},[40,15119,9116],{},[40,15121,9119,15122,9122],{},[63,15123,9108],{},[14,15125,213],{"id":213},[173,15127,15128,15132,15134],{},[40,15129,9129,15130,9132],{},[63,15131,9108],{},[40,15133,9135],{},[40,15135,9138,15136,9142,15138,9145],{},[63,15137,9141],{},[63,15139,6155],{},[10,15141,224],{},[14,15143,227],{"id":227},[10,15145,9152],{},[232,15147,234],{},{"title":61,"searchDepth":75,"depth":75,"links":15149},[15150,15151,15152,15153,15154,15158,15159,15160],{"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":171,"depth":75,"text":171,"children":15155},[15156,15157],{"id":187,"depth":81,"text":187},{"id":4238,"depth":81,"text":187},{"id":202,"depth":75,"text":202},{"id":213,"depth":75,"text":213},{"id":227,"depth":75,"text":227},{},{"title":8863,"description":8868},[247,9175,9176],{"id":1077,"title":1078,"body":15165,"category":247,"cover":1086,"description":61,"extension":249,"meta":15401,"navigation":84,"path":1403,"pinned":252,"publishedAt":1404,"seo":15402,"slug":1406,"stem":1407,"summary":1408,"tags":15403,"updatedAt":1404,"visible":84,"__hash__":1412},{"type":7,"value":15166,"toc":15386},[15167,15171,15173,15175,15177,15179,15199,15201,15206,15208,15210,15238,15244,15246,15250,15252,15272,15274,15284,15286,15288,15290,15292,15294,15296,15298,15300,15302,15322,15324,15326,15330,15332,15334,15336,15338,15342,15344,15362,15364,15366,15368,15370,15372,15374,15376,15378,15380,15382,15384],[10,15168,15169],{},[26,15170],{"alt":1085,"src":1086},[10,15172,1089],{},[10,15174,1092],{},[14,15176,1096],{"id":1095},[10,15178,1099],{},[56,15180,15181],{"className":58,"code":1102,"language":60,"meta":61,"style":61},[63,15182,15183,15187,15191,15195],{"__ignoreMap":61},[66,15184,15185],{"class":68,"line":69},[66,15186,1109],{},[66,15188,15189],{"class":68,"line":75},[66,15190,1114],{},[66,15192,15193],{"class":68,"line":81},[66,15194,85],{"emptyLinePlaceholder":84},[66,15196,15197],{"class":68,"line":88},[66,15198,1123],{},[10,15200,1126],{},[56,15202,15204],{"className":15203,"code":1130,"language":163,"meta":61},[161],[63,15205,1130],{"__ignoreMap":61},[10,15207,1135],{},[10,15209,1138],{},[56,15211,15212],{"className":58,"code":1141,"language":60,"meta":61,"style":61},[63,15213,15214,15218,15222,15226,15230,15234],{"__ignoreMap":61},[66,15215,15216],{"class":68,"line":69},[66,15217,1148],{},[66,15219,15220],{"class":68,"line":75},[66,15221,85],{"emptyLinePlaceholder":84},[66,15223,15224],{"class":68,"line":81},[66,15225,1157],{},[66,15227,15228],{"class":68,"line":88},[66,15229,1162],{},[66,15231,15232],{"class":68,"line":94},[66,15233,1167],{},[66,15235,15236],{"class":68,"line":99},[66,15237,1172],{},[10,15239,15240,1178,15242,1182],{},[63,15241,1177],{},[63,15243,1181],{},[14,15245,1186],{"id":1185},[10,15247,1189,15248,1193],{},[63,15249,1192],{},[10,15251,1196],{},[56,15253,15254],{"className":58,"code":1199,"language":60,"meta":61,"style":61},[63,15255,15256,15260,15264,15268],{"__ignoreMap":61},[66,15257,15258],{"class":68,"line":69},[66,15259,1206],{},[66,15261,15262],{"class":68,"line":75},[66,15263,1211],{},[66,15265,15266],{"class":68,"line":81},[66,15267,1216],{},[66,15269,15270],{"class":68,"line":88},[66,15271,1221],{},[10,15273,1224],{},[56,15275,15276],{"className":612,"code":1227,"language":614,"meta":61,"style":61},[63,15277,15278],{"__ignoreMap":61},[66,15279,15280,15282],{"class":68,"line":69},[66,15281,712],{"class":621},[66,15283,1236],{"class":657},[10,15285,1239],{},[14,15287,1243],{"id":1242},[185,15289,1246],{"id":1246},[10,15291,1249],{},[185,15293,1252],{"id":1252},[10,15295,1255],{},[185,15297,1258],{"id":1258},[10,15299,1261],{},[10,15301,1264],{},[56,15303,15304],{"className":58,"code":1267,"language":60,"meta":61,"style":61},[63,15305,15306,15310,15314,15318],{"__ignoreMap":61},[66,15307,15308],{"class":68,"line":69},[66,15309,1274],{},[66,15311,15312],{"class":68,"line":75},[66,15313,85],{"emptyLinePlaceholder":84},[66,15315,15316],{"class":68,"line":81},[66,15317,1283],{},[66,15319,15320],{"class":68,"line":88},[66,15321,1288],{},[10,15323,1291],{},[185,15325,1294],{"id":1294},[10,15327,1297,15328,1300],{},[63,15329,282],{},[10,15331,1303],{},[185,15333,1306],{"id":1306},[10,15335,1309],{},[14,15337,1313],{"id":1312},[10,15339,15340],{},[26,15341],{"alt":1318,"src":1319},[10,15343,1322],{},[37,15345,15346,15348,15350,15352,15354,15356,15358,15360],{},[40,15347,1327],{},[40,15349,1330],{},[40,15351,1333],{},[40,15353,1336],{},[40,15355,1339],{},[40,15357,1342],{},[40,15359,1345],{},[40,15361,1348],{},[10,15363,1351],{},[14,15365,1355],{"id":1354},[10,15367,1358],{},[10,15369,1361],{},[14,15371,1365],{"id":1364},[10,15373,1368],{},[10,15375,1371],{},[10,15377,1374],{},[14,15379,1377],{"id":1377},[10,15381,1380],{},[10,15383,1383],{},[232,15385,1386],{},{"title":61,"searchDepth":75,"depth":75,"links":15387},[15388,15389,15390,15397,15398,15399,15400],{"id":1095,"depth":75,"text":1096},{"id":1185,"depth":75,"text":1186},{"id":1242,"depth":75,"text":1243,"children":15391},[15392,15393,15394,15395,15396],{"id":1246,"depth":81,"text":1246},{"id":1252,"depth":81,"text":1252},{"id":1258,"depth":81,"text":1258},{"id":1294,"depth":81,"text":1294},{"id":1306,"depth":81,"text":1306},{"id":1312,"depth":75,"text":1313},{"id":1354,"depth":75,"text":1355},{"id":1364,"depth":75,"text":1365},{"id":1377,"depth":75,"text":1377},{},{"title":1078,"description":61},[247,1410,1411],{"id":264,"title":265,"body":15405,"category":247,"cover":248,"description":61,"extension":249,"meta":15984,"navigation":84,"path":1066,"pinned":252,"publishedAt":1067,"seo":15985,"slug":1069,"stem":1070,"summary":1071,"tags":15986,"updatedAt":1067,"visible":84,"__hash__":1075},{"type":7,"value":15406,"toc":15960},[15407,15409,15411,15413,15417,15419,15421,15445,15457,15459,15461,15466,15470,15474,15486,15490,15494,15498,15500,15534,15536,15540,15544,15546,15568,15598,15610,15620,15628,15630,15636,15646,15648,15653,15657,15659,15673,15679,15699,15701,15703,15705,15715,15719,15721,15730,15734,15736,15738,15758,15762,15764,15766,15768,15770,15790,15792,15794,15796,15822,15824,15840,15842,15858,15862,15864,15866,15886,15888,15890,15892,15896,15906,15908,15910,15912,15922,15930,15932,15934,15948,15958],[14,15408,270],{"id":270},[10,15410,273],{},[10,15412,276],{},[10,15414,279,15415,283],{},[63,15416,282],{},[14,15418,286],{"id":286},[10,15420,289],{},[291,15422,15423,15425],{},[10,15424,295],{},[291,15426,15427,15433,15435,15439,15441],{},[10,15428,300,15429,304,15431,308],{},[63,15430,303],{},[63,15432,307],{},[10,15434,311],{},[10,15436,314,15437,319],{},[316,15438,318],{},[10,15440,322],{},[10,15442,15443],{},[26,15444],{"alt":327,"src":328},[291,15446,15447,15449],{},[10,15448,333],{},[291,15450,15451,15453],{},[10,15452,338],{},[10,15454,15455],{},[26,15456],{"alt":343,"src":344},[14,15458,348],{"id":347},[185,15460,352],{"id":351},[10,15462,355,15463,363],{},[357,15464,362],{"href":359,"rel":15465},[361],[291,15467,15468],{},[10,15469,368],{},[10,15471,15472],{},[26,15473],{"alt":373,"src":374},[37,15475,15476,15480,15484],{},[40,15477,379,15478,383],{},[316,15479,382],{},[40,15481,386,15482,383],{},[316,15483,389],{},[40,15485,392],{},[10,15487,15488],{},[26,15489],{"alt":397,"src":398},[291,15491,15492],{},[10,15493,403],{},[10,15495,15496],{},[26,15497],{"alt":408,"src":409},[185,15499,413],{"id":412},[291,15501,15502,15506,15510,15530],{},[291,15503,15504],{},[10,15505,420],{},[10,15507,423,15508,427],{},[316,15509,426],{},[56,15511,15512],{"className":58,"code":430,"language":60,"meta":61,"style":61},[63,15513,15514,15518,15522,15526],{"__ignoreMap":61},[66,15515,15516],{"class":68,"line":69},[66,15517,437],{},[66,15519,15520],{"class":68,"line":75},[66,15521,442],{},[66,15523,15524],{"class":68,"line":81},[66,15525,447],{},[66,15527,15528],{"class":68,"line":88},[66,15529,452],{},[10,15531,455,15532,459],{},[316,15533,458],{},[10,15535,462],{},[10,15537,465,15538,468],{},[63,15539,60],{},[10,15541,15542],{},[26,15543],{"alt":473,"src":474},[10,15545,477],{},[291,15547,15548,15550,15554],{},[10,15549,482],{},[10,15551,15552],{},[316,15553,487],{},[291,15555,15556,15560,15564],{},[10,15557,492,15558,495],{},[63,15559,60],{},[10,15561,498,15562,501],{},[63,15563,60],{},[10,15565,504,15566,508],{},[316,15567,507],{},[291,15569,15570,15572,15576],{},[10,15571,513],{},[10,15573,15574],{},[316,15575,518],{},[291,15577,15578,15584,15592,15594],{},[10,15579,15580,526,15582,530],{},[63,15581,525],{},[63,15583,529],{},[10,15585,533,15586,536,15588,540,15590,544],{},[63,15587,525],{},[316,15589,539],{},[316,15591,543],{},[10,15593,547],{},[10,15595,15596,553],{},[316,15597,552],{},[291,15599,15600,15602],{},[10,15601,558],{},[291,15603,15604,15608],{},[10,15605,563,15606,567],{},[316,15607,566],{},[10,15609,570],{},[291,15611,15612,15616],{},[10,15613,575,15614],{},[316,15615,578],{},[10,15617,15618],{},[26,15619],{"alt":583,"src":584},[291,15621,15622,15624],{},[10,15623,589],{},[10,15625,15626],{},[26,15627],{"alt":583,"src":594},[185,15629,598],{"id":597},[10,15631,601,15632,605,15634,609],{},[63,15633,604],{},[63,15635,608],{},[56,15637,15638],{"className":612,"code":613,"language":614,"meta":61,"style":61},[63,15639,15640],{"__ignoreMap":61},[66,15641,15642,15644],{"class":68,"line":69},[66,15643,60],{"class":621},[66,15645,625],{"class":624},[10,15647,628],{},[56,15649,15651],{"className":15650,"code":632,"language":163,"meta":61},[161],[63,15652,632],{"__ignoreMap":61},[10,15654,15655],{},[26,15656],{"alt":583,"src":639},[10,15658,642],{},[56,15660,15661],{"className":612,"code":645,"language":614,"meta":61,"style":61},[63,15662,15663],{"__ignoreMap":61},[66,15664,15665,15667,15669,15671],{"class":68,"line":69},[66,15666,60],{"class":621},[66,15668,654],{"class":624},[66,15670,658],{"class":657},[66,15672,625],{"class":624},[10,15674,663,15675,666,15677,670],{},[63,15676,60],{},[63,15678,669],{},[56,15680,15681],{"className":612,"code":673,"language":614,"meta":61,"style":61},[63,15682,15683,15689],{"__ignoreMap":61},[66,15684,15685,15687],{"class":68,"line":69},[66,15686,529],{"class":621},[66,15688,625],{"class":624},[66,15690,15691,15693,15695,15697],{"class":68,"line":75},[66,15692,529],{"class":621},[66,15694,654],{"class":624},[66,15696,658],{"class":657},[66,15698,625],{"class":624},[14,15700,695],{"id":694},[185,15702,699],{"id":698},[10,15704,702],{},[56,15706,15707],{"className":612,"code":705,"language":614,"meta":61,"style":61},[63,15708,15709],{"__ignoreMap":61},[66,15710,15711,15713],{"class":68,"line":69},[66,15712,712],{"class":621},[66,15714,625],{"class":624},[10,15716,717,15717,721],{},[63,15718,720],{},[185,15720,725],{"id":724},[10,15722,355,15723,733,15726,383,15728,740],{},[357,15724,732],{"href":730,"rel":15725},[361],[316,15727,736],{},[63,15729,739],{},[10,15731,743,15732,747],{},[63,15733,746],{},[185,15735,751],{"id":750},[10,15737,754],{},[56,15739,15740],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,15741,15742,15748],{"__ignoreMap":61},[66,15743,15744,15746],{"class":68,"line":69},[66,15745,712],{"class":621},[66,15747,625],{"class":624},[66,15749,15750,15752,15754,15756],{"class":68,"line":75},[66,15751,712],{"class":621},[66,15753,654],{"class":624},[66,15755,658],{"class":657},[66,15757,625],{"class":624},[10,15759,778,15760,781],{},[63,15761,712],{},[14,15763,785],{"id":784},[10,15765,788],{},[185,15767,792],{"id":791},[10,15769,795],{},[56,15771,15772],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,15773,15774,15780],{"__ignoreMap":61},[66,15775,15776,15778],{"class":68,"line":69},[66,15777,712],{"class":621},[66,15779,625],{"class":624},[66,15781,15782,15784,15786,15788],{"class":68,"line":75},[66,15783,712],{"class":621},[66,15785,654],{"class":624},[66,15787,658],{"class":657},[66,15789,625],{"class":624},[10,15791,818],{},[185,15793,822],{"id":821},[10,15795,825],{},[56,15797,15798],{"className":612,"code":828,"language":614,"meta":61,"style":61},[63,15799,15800,15808],{"__ignoreMap":61},[66,15801,15802,15804,15806],{"class":68,"line":69},[66,15803,835],{"class":621},[66,15805,838],{"class":657},[66,15807,841],{"class":657},[66,15809,15810,15812,15814,15816,15818,15820],{"class":68,"line":75},[66,15811,835],{"class":621},[66,15813,838],{"class":657},[66,15815,850],{"class":657},[66,15817,853],{"class":657},[66,15819,856],{"class":657},[66,15821,859],{"class":657},[10,15823,862],{},[56,15825,15826],{"className":612,"code":865,"language":614,"meta":61,"style":61},[63,15827,15828],{"__ignoreMap":61},[66,15829,15830,15832,15834,15836,15838],{"class":68,"line":69},[66,15831,835],{"class":621},[66,15833,874],{"class":657},[66,15835,850],{"class":657},[66,15837,853],{"class":657},[66,15839,881],{"class":657},[10,15841,884],{},[56,15843,15844],{"className":612,"code":887,"language":614,"meta":61,"style":61},[63,15845,15846],{"__ignoreMap":61},[66,15847,15848,15850,15852,15854,15856],{"class":68,"line":69},[66,15849,835],{"class":621},[66,15851,896],{"class":657},[66,15853,899],{"class":624},[66,15855,902],{"class":657},[66,15857,905],{"class":657},[10,15859,15860,910],{},[63,15861,835],{},[185,15863,914],{"id":913},[10,15865,917],{},[56,15867,15868],{"className":612,"code":757,"language":614,"meta":61,"style":61},[63,15869,15870,15876],{"__ignoreMap":61},[66,15871,15872,15874],{"class":68,"line":69},[66,15873,712],{"class":621},[66,15875,625],{"class":624},[66,15877,15878,15880,15882,15884],{"class":68,"line":75},[66,15879,712],{"class":621},[66,15881,654],{"class":624},[66,15883,658],{"class":657},[66,15885,625],{"class":624},[10,15887,940],{},[14,15889,943],{"id":943},[185,15891,947],{"id":946},[10,15893,950,15894,954],{},[63,15895,953],{},[173,15897,15898,15902,15904],{},[40,15899,959,15900,962],{},[63,15901,669],{},[40,15903,965],{},[40,15905,968],{},[10,15907,971],{},[185,15909,975],{"id":974},[10,15911,978],{},[56,15913,15914],{"className":612,"code":705,"language":614,"meta":61,"style":61},[63,15915,15916],{"__ignoreMap":61},[66,15917,15918,15920],{"class":68,"line":69},[66,15919,712],{"class":621},[66,15921,625],{"class":624},[10,15923,991,15924,994,15926,997,15928,383],{},[63,15925,712],{},[63,15927,60],{},[63,15929,712],{},[185,15931,1003],{"id":1002},[10,15933,1006],{},[56,15935,15936],{"className":612,"code":1009,"language":614,"meta":61,"style":61},[63,15937,15938],{"__ignoreMap":61},[66,15939,15940,15942,15944,15946],{"class":68,"line":69},[66,15941,712],{"class":621},[66,15943,654],{"class":624},[66,15945,658],{"class":657},[66,15947,625],{"class":624},[10,15949,1024,15950,1027,15952,1030,15954,1033,15956,1037],{},[63,15951,712],{},[63,15953,60],{},[63,15955,529],{},[63,15957,1036],{},[232,15959,1040],{},{"title":61,"searchDepth":75,"depth":75,"links":15961},[15962,15963,15964,15969,15974,15979],{"id":270,"depth":75,"text":270},{"id":286,"depth":75,"text":286},{"id":347,"depth":75,"text":348,"children":15965},[15966,15967,15968],{"id":351,"depth":81,"text":352},{"id":412,"depth":81,"text":413},{"id":597,"depth":81,"text":598},{"id":694,"depth":75,"text":695,"children":15970},[15971,15972,15973],{"id":698,"depth":81,"text":699},{"id":724,"depth":81,"text":725},{"id":750,"depth":81,"text":751},{"id":784,"depth":75,"text":785,"children":15975},[15976,15977,15978],{"id":791,"depth":81,"text":792},{"id":821,"depth":81,"text":822},{"id":913,"depth":81,"text":914},{"id":943,"depth":75,"text":943,"children":15980},[15981,15982,15983],{"id":946,"depth":81,"text":947},{"id":974,"depth":81,"text":975},{"id":1002,"depth":81,"text":1003},{},{"title":265,"description":61},[247,1073,1074],1786973366438]