[{"data":1,"prerenderedAt":15967},["ShallowReactive",2],{"post-python-package-venv-pip":3,"sidebar-posts":238,"post-related-source":9158},{"id":4,"title":5,"body":6,"category":222,"cover":223,"description":12,"extension":224,"meta":225,"navigation":226,"path":227,"pinned":228,"publishedAt":229,"seo":230,"slug":231,"stem":232,"summary":233,"tags":234,"updatedAt":229,"visible":226,"__hash__":237},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":8,"toc":212},"minimark",[9,13,17,20,23,30,33,36,53,56,59,124,127,135,138,141,170,173,184,187,199,202,205,208],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,15,16],"h2",{"id":16},"本篇要解决的问题",[10,18,19],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 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\u002F28-venv-boundary.svg",[10,31,32],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,34,35],{"id":35},"核心概念",[37,38,39,47,50],"ul",{},[40,41,42,46],"li",{},[43,44,45],"code",{},".venv"," 是常见目录名，不应提交到 Git。",[40,48,49],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[40,51,52],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,54,55],{"id":55},"跟着示例运行",[10,57,58],{},"在 macOS 终端执行：",[60,61,66],"pre",{"className":62,"code":63,"language":64,"meta":65,"style":65},"language-bash shiki shiki-themes github-dark","python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n","bash","",[43,67,68,88,97,106,118],{"__ignoreMap":65},[69,70,73,77,81,85],"span",{"class":71,"line":72},"line",1,[69,74,76],{"class":75},"svObZ","python3",[69,78,80],{"class":79},"sDLfK"," -m",[69,82,84],{"class":83},"sU2Wk"," venv",[69,86,87],{"class":83}," .venv\n",[69,89,91,94],{"class":71,"line":90},2,[69,92,93],{"class":79},"source",[69,95,96],{"class":83}," .venv\u002Fbin\u002Factivate\n",[69,98,100,103],{"class":71,"line":99},3,[69,101,102],{"class":75},"python",[69,104,105],{"class":79}," --version\n",[69,107,109,111,113,116],{"class":71,"line":108},4,[69,110,102],{"class":75},[69,112,80],{"class":79},[69,114,115],{"class":83}," pip",[69,117,105],{"class":79},[69,119,121],{"class":71,"line":120},5,[69,122,123],{"class":75},"deactivate\n",[10,125,126],{},"预期结果：",[60,128,133],{"className":129,"code":131,"language":132,"meta":65},[130],"language-text","Python 和 pip 的路径应指向当前项目的 .venv\n","text",[43,134,131],{"__ignoreMap":65},[10,136,137],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,139,140],{"id":140},"按执行顺序拆开看",[142,143,144,153],"ol",{},[40,145,146,149,150,152],{},[43,147,148],{},"venv"," 根据当前 ",[43,151,76],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[40,154,155,156,158,159,162,163,165,166,169],{},"激活后 ",[43,157,102],{}," 与 ",[43,160,161],{},"python -m pip"," 优先指向 ",[43,164,45],{},"；",[43,167,168],{},"deactivate"," 只恢复当前终端的命令查找。",[14,171,172],{"id":172},"初学者容易混淆的地方",[37,174,175,178],{},[40,176,177],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[40,179,180,181,183],{},"把 ",[43,182,45],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,185,186],{"id":186},"练习",[142,188,189,196],{},[40,190,191,192,195],{},"创建虚拟环境并记录激活前后的 ",[43,193,194],{},"which python","。",[40,197,198],{},"退出后重新激活，确认项目环境可以重复使用。",[10,200,201],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,203,204],{"id":204},"本篇边界",[10,206,207],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,210,211],"style",{},"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":65,"searchDepth":90,"depth":90,"links":213},[214,215,216,217,218,219,220,221],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},"Python",null,"md",{},true,"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",false,"2026-08-17",{"title":5,"description":12},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[222,235,236],"虚拟环境","pip","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",[239,1043,1382,1518,1668,1847,2035,2199,2383,2566,2759,2990,3174,3351,3507,3678,3842,4057,4286,4468,4632,4821,5009,5164,5324,5521,5718,5932,6099,6343,6486,6691,6886,7070,7271,7561,7753,7982,8177,8397,8637,8841],{"id":240,"title":241,"body":242,"category":222,"cover":223,"description":65,"extension":224,"meta":1032,"navigation":226,"path":1033,"pinned":228,"publishedAt":1034,"seo":1035,"slug":1036,"stem":1037,"summary":1038,"tags":1039,"updatedAt":1034,"visible":226,"__hash__":1042},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":243,"toc":1008},[244,247,250,253,259,262,265,304,320,324,329,340,345,351,368,374,379,385,389,436,439,445,451,454,485,530,547,561,571,575,586,597,600,606,611,614,629,639,660,664,668,671,682,689,693,708,715,719,722,743,749,753,756,760,763,783,786,790,793,827,830,849,852,873,878,882,885,905,908,911,915,922,936,939,943,946,956,967,971,974,989,1005],[14,245,246],{"id":246},"引言",[10,248,249],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,251,252],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,254,255,256,258],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[43,257,236],{}," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,260,261],{"id":261},"扫盲",[10,263,264],{},"那么这里有几个概念：",[266,267,268,271],"blockquote",{},[10,269,270],{},"为什么需要安装python解释器？",[266,272,273,284,287,295,298],{},[10,274,275,276,279,280,283],{},"我们写的代码，电脑其实看不懂，电脑只认识",[43,277,278],{},"0","和",[43,281,282],{},"1","组成的机器指令。",[10,285,286],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,288,289,290,294],{},"这样，我们就能用",[291,292,293],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,296,297],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,299,300],{},[26,301],{"alt":302,"src":303},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[266,305,306,309],{},[10,307,308],{},"pip又是什么？",[266,310,311,314],{},[10,312,313],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,315,316],{},[26,317],{"alt":318,"src":319},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,321,323],{"id":322},"windows-安装","Windows 安装",[325,326,328],"h3",{"id":327},"_1-下载官方安装程序","1. 下载官方安装程序",[10,330,331,332,339],{},"打开 ",[333,334,338],"a",{"href":335,"rel":336},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[337],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[266,341,342],{},[10,343,344],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,346,347],{},[26,348],{"alt":349,"src":350},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[37,352,353,359,365],{},[40,354,355,356,195],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[291,357,358],{},"Windows installer (64-bit)",[40,360,361,362,195],{},"搭载 ARM 处理器的 Windows 设备选择 ",[291,363,364],{},"Windows installer (ARM64)",[40,366,367],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,369,370],{},[26,371],{"alt":372,"src":373},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[266,375,376],{},[10,377,378],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,380,381],{},[26,382],{"alt":383,"src":384},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[325,386,388],{"id":387},"_2-安装并加入-path","2. 安装并加入 PATH",[266,390,391,396,403,429],{},[266,392,393],{},[10,394,395],{},"PATH 环境变量",[10,397,398,399,402],{},"Windows 有一个特殊的变量叫 ",[291,400,401],{},"PATH","，它里面存了一串文件夹路径，比如：",[60,404,407],{"className":405,"code":406,"language":102,"meta":65,"style":65},"language-python shiki shiki-themes github-dark","D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[43,408,409,414,419,424],{"__ignoreMap":65},[69,410,411],{"class":71,"line":72},[69,412,413],{},"D:\\Python313\\\n",[69,415,416],{"class":71,"line":90},[69,417,418],{},"D:\\Python313\\Scripts\\\n",[69,420,421],{"class":71,"line":99},[69,422,423],{},"C:\\Windows\\System32\\\n",[69,425,426],{"class":71,"line":108},[69,427,428],{},"...\n",[10,430,431,432,435],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[291,433,434],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,437,438],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,440,441,442,444],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[43,443,102],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,446,447],{},[26,448],{"alt":449,"src":450},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,452,453],{},"对安装界面最底部的两个勾选项分别解释 :",[266,455,456,459,464],{},[10,457,458],{},"Add python.exe to PATH",[10,460,461],{},[291,462,463],{},"把 Python 添加到系统环境变量",[266,465,466,472,478],{},[10,467,468,469,471],{},"勾选后，你可以在命令行任意位置直接输入 ",[43,470,102],{}," 就能运行",[10,473,474,475,477],{},"不勾选的话，命令行输入 ",[43,476,102],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,479,480,481,484],{},"必须",[291,482,483],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[266,486,487,490,495],{},[10,488,489],{},"Use admin privileges when installing py.exe",[10,491,492],{},[291,493,494],{},"使用管理员权限安装 py.exe（Python 启动器）",[266,496,497,507,521,524],{},[10,498,499,502,503,506],{},[43,500,501],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[43,504,505],{},"py"," 来启动 Python。",[10,508,509,510,512,513,516,517,520],{},"勾选后，",[43,511,501],{}," 会安装到",[291,514,515],{},"系统级目录","，电脑上",[291,518,519],{},"所有用户账户","都能用",[10,522,523],{},"不勾选，只有当前用户能用",[10,525,526,529],{},[291,527,528],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[266,531,532,535],{},[10,533,534],{},"操作建议",[266,536,537,544],{},[10,538,539,540,543],{},"两个都勾上之后，再点 ",[291,541,542],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,545,546],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[266,548,549,555],{},[10,550,551,552],{},"Python 安装的",[291,553,554],{},"可选功能页",[10,556,557],{},[26,558],{"alt":559,"src":560},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[266,562,563,566],{},[10,564,565],{},"高级选项页",[10,567,568],{},[26,569],{"alt":559,"src":570},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[325,572,574],{"id":573},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,576,577,578,581,582,585],{},"按 ",[43,579,580],{},"Win + R","，输入 ",[43,583,584],{},"cmd"," 并回车，然后执行：",[60,587,589],{"className":62,"code":588,"language":64,"meta":65,"style":65},"python --version\n",[43,590,591],{"__ignoreMap":65},[69,592,593,595],{"class":71,"line":72},[69,594,102],{"class":75},[69,596,105],{"class":79},[10,598,599],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[60,601,604],{"className":602,"code":603,"language":132,"meta":65},[130],"Python 3.x.x\n",[43,605,603],{"__ignoreMap":65},[10,607,608],{},[26,609],{"alt":559,"src":610},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,612,613],{},"继续检查 pip：",[60,615,617],{"className":62,"code":616,"language":64,"meta":65,"style":65},"python -m pip --version\n",[43,618,619],{"__ignoreMap":65},[69,620,621,623,625,627],{"class":71,"line":72},[69,622,102],{"class":75},[69,624,80],{"class":79},[69,626,115],{"class":83},[69,628,105],{"class":79},[10,630,631,632,634,635,638],{},"如果 ",[43,633,102],{}," 无法识别，但 ",[43,636,637],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[60,640,642],{"className":62,"code":641,"language":64,"meta":65,"style":65},"py --version\npy -m pip --version\n",[43,643,644,650],{"__ignoreMap":65},[69,645,646,648],{"class":71,"line":72},[69,647,505],{"class":75},[69,649,105],{"class":79},[69,651,652,654,656,658],{"class":71,"line":90},[69,653,505],{"class":75},[69,655,80],{"class":79},[69,657,115],{"class":83},[69,659,105],{"class":79},[14,661,663],{"id":662},"macos-安装","macOS 安装",[325,665,667],{"id":666},"_1-先检查现有环境","1. 先检查现有环境",[10,669,670],{},"打开“终端”应用，执行：",[60,672,674],{"className":62,"code":673,"language":64,"meta":65,"style":65},"python3 --version\n",[43,675,676],{"__ignoreMap":65},[69,677,678,680],{"class":71,"line":72},[69,679,76],{"class":75},[69,681,105],{"class":79},[10,683,684,685,688],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[43,686,687],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[325,690,692],{"id":691},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,694,331,695,700,701,195,704,707],{},[333,696,699],{"href":697,"rel":698},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[337],"Python macOS 下载页","，下载当前稳定版的 ",[291,702,703],{},"macOS 64-bit universal2 installer",[43,705,706],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,709,710,711,714],{},"下载完成后打开 ",[43,712,713],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[325,716,718],{"id":717},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,720,721],{},"安装完成后重新打开终端，执行：",[60,723,725],{"className":62,"code":724,"language":64,"meta":65,"style":65},"python3 --version\npython3 -m pip --version\n",[43,726,727,733],{"__ignoreMap":65},[69,728,729,731],{"class":71,"line":72},[69,730,76],{"class":75},[69,732,105],{"class":79},[69,734,735,737,739,741],{"class":71,"line":90},[69,736,76],{"class":75},[69,738,80],{"class":79},[69,740,115],{"class":83},[69,742,105],{"class":79},[10,744,745,746,748],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[43,747,76],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,750,752],{"id":751},"linux-安装","Linux 安装",[10,754,755],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[325,757,759],{"id":758},"_1-检查是否已经安装","1. 检查是否已经安装",[10,761,762],{},"打开终端，执行：",[60,764,765],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,766,767,773],{"__ignoreMap":65},[69,768,769,771],{"class":71,"line":72},[69,770,76],{"class":75},[69,772,105],{"class":79},[69,774,775,777,779,781],{"class":71,"line":90},[69,776,76],{"class":75},[69,778,80],{"class":79},[69,780,115],{"class":83},[69,782,105],{"class":79},[10,784,785],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[325,787,789],{"id":788},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,791,792],{},"Ubuntu 或 Debian：",[60,794,796],{"className":62,"code":795,"language":64,"meta":65,"style":65},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[43,797,798,809],{"__ignoreMap":65},[69,799,800,803,806],{"class":71,"line":72},[69,801,802],{"class":75},"sudo",[69,804,805],{"class":83}," apt",[69,807,808],{"class":83}," update\n",[69,810,811,813,815,818,821,824],{"class":71,"line":90},[69,812,802],{"class":75},[69,814,805],{"class":83},[69,816,817],{"class":83}," install",[69,819,820],{"class":83}," python3",[69,822,823],{"class":83}," python3-pip",[69,825,826],{"class":83}," python3-venv\n",[10,828,829],{},"Fedora：",[60,831,833],{"className":62,"code":832,"language":64,"meta":65,"style":65},"sudo dnf install python3 python3-pip\n",[43,834,835],{"__ignoreMap":65},[69,836,837,839,842,844,846],{"class":71,"line":72},[69,838,802],{"class":75},[69,840,841],{"class":83}," dnf",[69,843,817],{"class":83},[69,845,820],{"class":83},[69,847,848],{"class":83}," python3-pip\n",[10,850,851],{},"Arch Linux：",[60,853,855],{"className":62,"code":854,"language":64,"meta":65,"style":65},"sudo pacman -S python python-pip\n",[43,856,857],{"__ignoreMap":65},[69,858,859,861,864,867,870],{"class":71,"line":72},[69,860,802],{"class":75},[69,862,863],{"class":83}," pacman",[69,865,866],{"class":79}," -S",[69,868,869],{"class":83}," python",[69,871,872],{"class":83}," python-pip\n",[10,874,875,877],{},[43,876,802],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[325,879,881],{"id":880},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,883,884],{},"安装结束后执行：",[60,886,887],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,888,889,895],{"__ignoreMap":65},[69,890,891,893],{"class":71,"line":72},[69,892,76],{"class":75},[69,894,105],{"class":79},[69,896,897,899,901,903],{"class":71,"line":90},[69,898,76],{"class":75},[69,900,80],{"class":79},[69,902,115],{"class":83},[69,904,105],{"class":79},[10,906,907],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,909,910],{"id":910},"常见问题",[325,912,914],{"id":913},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,916,917,918,921],{},"先关闭当前命令提示符并重新打开，再执行 ",[43,919,920],{},"python --version","。如果仍然失败，按下面的顺序检查：",[142,923,924,930,933],{},[40,925,926,927,929],{},"执行 ",[43,928,637],{},"，确认 Python Launcher 是否可用。",[40,931,932],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[40,934,935],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,937,938],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[325,940,942],{"id":941},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,944,945],{},"先尝试：",[60,947,948],{"className":62,"code":673,"language":64,"meta":65,"style":65},[43,949,950],{"__ignoreMap":65},[69,951,952,954],{"class":71,"line":72},[69,953,76],{"class":75},[69,955,105],{"class":79},[10,957,958,959,961,962,964,965,195],{},"在这两个系统中，只有 ",[43,960,76],{}," 命令而没有 ",[43,963,102],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[43,966,76],{},[325,968,970],{"id":969},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,972,973],{},"先使用模块方式检查：",[60,975,977],{"className":62,"code":976,"language":64,"meta":65,"style":65},"python3 -m pip --version\n",[43,978,979],{"__ignoreMap":65},[69,980,981,983,985,987],{"class":71,"line":72},[69,982,76],{"class":75},[69,984,80],{"class":79},[69,986,115],{"class":83},[69,988,105],{"class":79},[10,990,991,992,994,995,997,998,1000,1001,1004],{},"Windows 用户将命令中的 ",[43,993,76],{}," 换成 ",[43,996,102],{}," 或 ",[43,999,505],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[43,1002,1003],{},"python3-pip","；不要直接使用其他系统的安装命令。",[209,1006,1007],{},"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":65,"searchDepth":90,"depth":90,"links":1009},[1010,1011,1012,1017,1022,1027],{"id":246,"depth":90,"text":246},{"id":261,"depth":90,"text":261},{"id":322,"depth":90,"text":323,"children":1013},[1014,1015,1016],{"id":327,"depth":99,"text":328},{"id":387,"depth":99,"text":388},{"id":573,"depth":99,"text":574},{"id":662,"depth":90,"text":663,"children":1018},[1019,1020,1021],{"id":666,"depth":99,"text":667},{"id":691,"depth":99,"text":692},{"id":717,"depth":99,"text":718},{"id":751,"depth":90,"text":752,"children":1023},[1024,1025,1026],{"id":758,"depth":99,"text":759},{"id":788,"depth":99,"text":789},{"id":880,"depth":99,"text":881},{"id":910,"depth":90,"text":910,"children":1028},[1029,1030,1031],{"id":913,"depth":99,"text":914},{"id":941,"depth":99,"text":942},{"id":969,"depth":99,"text":970},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":241,"description":65},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[222,1040,1041],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1044,"title":1045,"body":1046,"category":222,"cover":1053,"description":65,"extension":224,"meta":1371,"navigation":226,"path":1372,"pinned":228,"publishedAt":1373,"seo":1374,"slug":1375,"stem":1376,"summary":1377,"tags":1378,"updatedAt":1373,"visible":226,"__hash__":1381},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1047,"toc":1356},[1048,1054,1057,1060,1064,1067,1092,1095,1101,1104,1107,1142,1152,1156,1163,1166,1191,1194,1206,1209,1213,1216,1219,1222,1225,1228,1231,1234,1258,1261,1264,1270,1273,1276,1279,1283,1289,1292,1318,1321,1325,1328,1331,1335,1338,1341,1344,1347,1350,1353],[10,1049,1050],{},[26,1051],{"alt":1052,"src":1053},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1055,1056],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1058,1059],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1061,1063],{"id":1062},"python-代码是什么样的","Python 代码是什么样的",[10,1065,1066],{},"下面是一段简单的 Python 代码：",[60,1068,1070],{"className":405,"code":1069,"language":102,"meta":65,"style":65},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[43,1071,1072,1077,1082,1087],{"__ignoreMap":65},[69,1073,1074],{"class":71,"line":72},[69,1075,1076],{},"name = \"Python\"\n",[69,1078,1079],{"class":71,"line":90},[69,1080,1081],{},"year = 2026\n",[69,1083,1084],{"class":71,"line":99},[69,1085,1086],{"emptyLinePlaceholder":226},"\n",[69,1088,1089],{"class":71,"line":108},[69,1090,1091],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1093,1094],{},"运行结果：",[60,1096,1099],{"className":1097,"code":1098,"language":132,"meta":65},[130],"正在学习 Python，当前年份是 2026\n",[43,1100,1098],{"__ignoreMap":65},[10,1102,1103],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1105,1106],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[60,1108,1110],{"className":405,"code":1109,"language":102,"meta":65,"style":65},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[43,1111,1112,1117,1121,1126,1131,1136],{"__ignoreMap":65},[69,1113,1114],{"class":71,"line":72},[69,1115,1116],{},"score = 85\n",[69,1118,1119],{"class":71,"line":90},[69,1120,1086],{"emptyLinePlaceholder":226},[69,1122,1123],{"class":71,"line":99},[69,1124,1125],{},"if score >= 60:\n",[69,1127,1128],{"class":71,"line":108},[69,1129,1130],{},"    print(\"成绩合格\")\n",[69,1132,1133],{"class":71,"line":120},[69,1134,1135],{},"else:\n",[69,1137,1139],{"class":71,"line":1138},6,[69,1140,1141],{},"    print(\"需要继续学习\")\n",[10,1143,1144,1147,1148,1151],{},[43,1145,1146],{},"if"," 和 ",[43,1149,1150],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1153,1155],{"id":1154},"python-如何运行代码","Python 如何运行代码",[10,1157,1158,1159,1162],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[43,1160,1161],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1164,1165],{},"交互式环境适合快速验证一个表达式：",[60,1167,1169],{"className":405,"code":1168,"language":102,"meta":65,"style":65},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[43,1170,1171,1176,1181,1186],{"__ignoreMap":65},[69,1172,1173],{"class":71,"line":72},[69,1174,1175],{},">>> 10 + 20\n",[69,1177,1178],{"class":71,"line":90},[69,1179,1180],{},"30\n",[69,1182,1183],{"class":71,"line":99},[69,1184,1185],{},">>> \"Python\".lower()\n",[69,1187,1188],{"class":71,"line":108},[69,1189,1190],{},"'python'\n",[10,1192,1193],{},"需要保存和重复运行的程序，则可以写入文件：",[60,1195,1197],{"className":62,"code":1196,"language":64,"meta":65,"style":65},"python3 hello.py\n",[43,1198,1199],{"__ignoreMap":65},[69,1200,1201,1203],{"class":71,"line":72},[69,1202,76],{"class":75},[69,1204,1205],{"class":83}," hello.py\n",[10,1207,1208],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1210,1212],{"id":1211},"python-的特点","Python 的特点",[325,1214,1215],{"id":1215},"语法相对简洁",[10,1217,1218],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[325,1220,1221],{"id":1221},"支持多种编程方式",[10,1223,1224],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[325,1226,1227],{"id":1227},"标准库比较完整",[10,1229,1230],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1232,1233],{},"例如，获取当前时间：",[60,1235,1237],{"className":405,"code":1236,"language":102,"meta":65,"style":65},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[43,1238,1239,1244,1248,1253],{"__ignoreMap":65},[69,1240,1241],{"class":71,"line":72},[69,1242,1243],{},"from datetime import datetime\n",[69,1245,1246],{"class":71,"line":90},[69,1247,1086],{"emptyLinePlaceholder":226},[69,1249,1250],{"class":71,"line":99},[69,1251,1252],{},"now = datetime.now()\n",[69,1254,1255],{"class":71,"line":108},[69,1256,1257],{},"print(now)\n",[10,1259,1260],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[325,1262,1263],{"id":1263},"第三方工具丰富",[10,1265,1266,1267,1269],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[43,1268,236],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1271,1272],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[325,1274,1275],{"id":1275},"支持多个操作系统",[10,1277,1278],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1280,1282],{"id":1281},"python-可以做什么","Python 可以做什么",[10,1284,1285],{},[26,1286],{"alt":1287,"src":1288},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1290,1291],{},"Python 的应用范围比较广，常见方向包括：",[37,1293,1294,1297,1300,1303,1306,1309,1312,1315],{},[40,1295,1296],{},"编写自动化脚本，批量处理文件和重复任务；",[40,1298,1299],{},"开发网站后端和 API 服务；",[40,1301,1302],{},"进行数据清洗、统计分析和图表展示；",[40,1304,1305],{},"编写网络爬虫和信息采集工具；",[40,1307,1308],{},"开发自动化测试程序；",[40,1310,1311],{},"进行机器学习和人工智能开发；",[40,1313,1314],{},"编写运维、监控和辅助开发工具；",[40,1316,1317],{},"开发部分桌面应用和插件。",[10,1319,1320],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1322,1324],{"id":1323},"python-的发展","Python 的发展",[10,1326,1327],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1329,1330],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1332,1334],{"id":1333},"python-也有局限","Python 也有局限",[10,1336,1337],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1339,1340],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1342,1343],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1345,1346],{"id":1346},"写在最后",[10,1348,1349],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1351,1352],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[209,1354,1355],{},"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":65,"searchDepth":90,"depth":90,"links":1357},[1358,1359,1360,1367,1368,1369,1370],{"id":1062,"depth":90,"text":1063},{"id":1154,"depth":90,"text":1155},{"id":1211,"depth":90,"text":1212,"children":1361},[1362,1363,1364,1365,1366],{"id":1215,"depth":99,"text":1215},{"id":1221,"depth":99,"text":1221},{"id":1227,"depth":99,"text":1227},{"id":1263,"depth":99,"text":1263},{"id":1275,"depth":99,"text":1275},{"id":1281,"depth":90,"text":1282},{"id":1323,"depth":90,"text":1324},{"id":1333,"depth":90,"text":1334},{"id":1346,"depth":90,"text":1346},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1045,"description":65},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[222,1379,1380],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1383,"title":1384,"body":1385,"category":222,"cover":223,"description":1389,"extension":224,"meta":1509,"navigation":226,"path":1510,"pinned":228,"publishedAt":229,"seo":1511,"slug":1512,"stem":1513,"summary":1514,"tags":1515,"updatedAt":229,"visible":226,"__hash__":1517},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1386,"toc":1499},[1387,1390,1392,1395,1397,1403,1408,1410,1424,1426,1429,1438,1440,1446,1448,1450,1466,1468,1479,1481,1489,1491,1493,1496],[10,1388,1389],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1391,16],{"id":16},[10,1393,1394],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1396,22],{"id":22},[10,1398,1399],{},[26,1400],{"alt":1401,"src":1402},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1404,1405,1407],{},[43,1406,1161],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1409,35],{"id":35},[37,1411,1412,1418,1421],{},[40,1413,1414,1415,1417],{},"源代码是人编写的文本，通常保存在 ",[43,1416,1161],{}," 文件中。",[40,1419,1420],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[40,1422,1423],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1425,55],{"id":55},[10,1427,1428],{},"把下面代码保存到本课脚本并运行：",[60,1430,1432],{"className":405,"code":1431,"language":102,"meta":65,"style":65},"print(\"你好，Python\")\n",[43,1433,1434],{"__ignoreMap":65},[69,1435,1436],{"class":71,"line":72},[69,1437,1431],{},[10,1439,126],{},[60,1441,1444],{"className":1442,"code":1443,"language":132,"meta":65},[130],"你好，Python\n",[43,1445,1443],{"__ignoreMap":65},[10,1447,137],{},[14,1449,140],{"id":140},[142,1451,1452,1459],{},[40,1453,1454,1455,1458],{},"终端启动解释器后，解释器读取 ",[43,1456,1457],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[40,1460,1461,1462,1465],{},"字符串对象先准备好，再交给 ",[43,1463,1464],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1467,172],{"id":172},[37,1469,1470,1473],{},[40,1471,1472],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[40,1474,1475,1476,1478],{},"认为 ",[43,1477,1161],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1480,186],{"id":186},[142,1482,1483,1486],{},[40,1484,1485],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[40,1487,1488],{},"把示例文字改成自己的学习目标并重新运行。",[10,1490,201],{},[14,1492,204],{"id":204},[10,1494,1495],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,1497,1498],{},"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":65,"searchDepth":90,"depth":90,"links":1500},[1501,1502,1503,1504,1505,1506,1507,1508],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1384,"description":1389},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[222,1379,1516],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1519,"title":1520,"body":1521,"category":222,"cover":223,"description":1525,"extension":224,"meta":1659,"navigation":226,"path":1660,"pinned":228,"publishedAt":229,"seo":1661,"slug":1662,"stem":1663,"summary":1664,"tags":1665,"updatedAt":229,"visible":226,"__hash__":1667},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1522,"toc":1649},[1523,1526,1528,1531,1533,1539,1545,1547,1562,1564,1566,1586,1588,1594,1596,1598,1611,1613,1627,1629,1640,1642,1644,1647],[10,1524,1525],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1527,16],{"id":16},[10,1529,1530],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1532,22],{"id":22},[10,1534,1535],{},[26,1536],{"alt":1537,"src":1538},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1540,1541,1542,1544],{},"终端收到 ",[43,1543,76],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1546,35],{"id":35},[37,1548,1549,1552,1555],{},[40,1550,1551],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[40,1553,1554],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[40,1556,1557,1558,1561],{},"检查 pip 时使用 ",[43,1559,1560],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1563,55],{"id":55},[10,1565,58],{},[60,1567,1568],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,1569,1570,1576],{"__ignoreMap":65},[69,1571,1572,1574],{"class":71,"line":72},[69,1573,76],{"class":75},[69,1575,105],{"class":79},[69,1577,1578,1580,1582,1584],{"class":71,"line":90},[69,1579,76],{"class":75},[69,1581,80],{"class":79},[69,1583,115],{"class":83},[69,1585,105],{"class":79},[10,1587,126],{},[60,1589,1592],{"className":1590,"code":1591,"language":132,"meta":65},[130],"Python 3.14.x\npip 版本信息与安装路径\n",[43,1593,1591],{"__ignoreMap":65},[10,1595,137],{},[14,1597,140],{"id":140},[142,1599,1600,1606],{},[40,1601,1602,1605],{},[43,1603,1604],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[40,1607,1608,1610],{},[43,1609,687],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1612,172],{"id":172},[37,1614,1615,1621],{},[40,1616,1617,1618,1620],{},"看到系统已有 ",[43,1619,76],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[40,1622,1623,1624,1626],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[43,1625,76],{},"，不修改系统自带工具。",[14,1628,186],{"id":186},[142,1630,1631,1637],{},[40,1632,926,1633,1636],{},[43,1634,1635],{},"which python3","，记录当前解释器路径。",[40,1638,1639],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1641,201],{},[14,1643,204],{"id":204},[10,1645,1646],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,1648,211],{},{"title":65,"searchDepth":90,"depth":90,"links":1650},[1651,1652,1653,1654,1655,1656,1657,1658],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1520,"description":1525},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[222,1666,1040],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1669,"title":1670,"body":1671,"category":222,"cover":223,"description":1836,"extension":224,"meta":1837,"navigation":226,"path":1838,"pinned":228,"publishedAt":229,"seo":1839,"slug":1840,"stem":1841,"summary":1842,"tags":1843,"updatedAt":229,"visible":226,"__hash__":1846},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1672,"toc":1826},[1673,1679,1681,1684,1686,1692,1695,1697,1721,1723,1725,1752,1754,1760,1762,1764,1782,1784,1798,1800,1814,1816,1818,1824],[10,1674,1675,1676,1678],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[43,1677,1161],{}," 脚本。",[14,1680,16],{"id":16},[10,1682,1683],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1685,22],{"id":22},[10,1687,1688],{},[26,1689],{"alt":1690,"src":1691},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1693,1694],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1696,35],{"id":35},[37,1698,1699,1708,1715],{},[40,1700,1701,1702,1704,1705,195],{},"在终端输入 ",[43,1703,76],{}," 进入 REPL，提示符通常是 ",[43,1706,1707],{},">>>",[40,1709,1710,1711,1714],{},"输入 ",[43,1712,1713],{},"exit()"," 或按 Control-D 退出 REPL。",[40,1716,1717,1718,1720],{},"需要保存、复查或多次运行的代码应写入 ",[43,1719,1161],{}," 文件。",[14,1722,55],{"id":55},[10,1724,1428],{},[60,1726,1730],{"className":1727,"code":1728,"language":1729,"meta":65,"style":65},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[43,1731,1732,1737,1742,1747],{"__ignoreMap":65},[69,1733,1734],{"class":71,"line":72},[69,1735,1736],{},">>> 2 + 3\n",[69,1738,1739],{"class":71,"line":90},[69,1740,1741],{},"5\n",[69,1743,1744],{"class":71,"line":99},[69,1745,1746],{},">>> \"python\".upper()\n",[69,1748,1749],{"class":71,"line":108},[69,1750,1751],{},"'PYTHON'\n",[10,1753,126],{},[60,1755,1758],{"className":1756,"code":1757,"language":132,"meta":65},[130],"REPL 会直接显示表达式结果\n",[43,1759,1757],{"__ignoreMap":65},[10,1761,137],{},[14,1763,140],{"id":140},[142,1765,1766,1776],{},[40,1767,1768,1769,1772,1773,195],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[43,1770,1771],{},"2 + 3"," 能直接看到 ",[43,1774,1775],{},"5",[40,1777,1778,1779,1781],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[43,1780,1464],{}," 才会写到标准输出。",[14,1783,172],{"id":172},[37,1785,1786,1795],{},[40,1787,1788,1789,1791,1792,1794],{},"把提示符 ",[43,1790,1707],{}," 复制进 ",[43,1793,1161],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[40,1796,1797],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1799,186],{"id":186},[142,1801,1802,1808],{},[40,1803,1804,1805,195],{},"在 REPL 计算 ",[43,1806,1807],{},"12 * 8",[40,1809,1810,1811,1813],{},"把同一表达式写入脚本；观察脚本中不调用 ",[43,1812,1464],{}," 时是否显示结果。",[10,1815,201],{},[14,1817,204],{"id":204},[10,1819,1820,1821,1823],{},"本篇目标是根据任务选择 REPL 或 ",[43,1822,1161],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,1825,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":1827},[1828,1829,1830,1831,1832,1833,1834,1835],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1670,"description":1836},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[222,1844,1845],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1848,"title":1849,"body":1850,"category":222,"cover":223,"description":1854,"extension":224,"meta":2025,"navigation":226,"path":2026,"pinned":228,"publishedAt":229,"seo":2027,"slug":2028,"stem":2029,"summary":2030,"tags":2031,"updatedAt":229,"visible":226,"__hash__":2034},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1851,"toc":2015},[1852,1855,1857,1860,1862,1868,1874,1876,1894,1896,1898,1943,1945,1951,1953,1955,1977,1979,1991,1993,2005,2007,2009,2012],[10,1853,1854],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1856,16],{"id":16},[10,1858,1859],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1861,22],{"id":22},[10,1863,1864],{},[26,1865],{"alt":1866,"src":1867},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1869,1870,1873],{},[43,1871,1872],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1875,35],{"id":35},[37,1877,1878,1881,1891],{},[40,1879,1880],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[40,1882,1883,1886,1887,1890],{},[43,1884,1885],{},"pwd"," 显示当前目录，",[43,1888,1889],{},"ls"," 显示目录里的文件。",[40,1892,1893],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1895,55],{"id":55},[10,1897,58],{},[60,1899,1901],{"className":62,"code":1900,"language":64,"meta":65,"style":65},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[43,1902,1903,1911,1918,1923,1937],{"__ignoreMap":65},[69,1904,1905,1908],{"class":71,"line":72},[69,1906,1907],{"class":75},"mkdir",[69,1909,1910],{"class":83}," python-study\n",[69,1912,1913,1916],{"class":71,"line":90},[69,1914,1915],{"class":79},"cd",[69,1917,1910],{"class":83},[69,1919,1920],{"class":71,"line":99},[69,1921,1922],{"class":79},"pwd\n",[69,1924,1925,1928,1931,1935],{"class":71,"line":108},[69,1926,1927],{"class":79},"printf",[69,1929,1930],{"class":83}," 'print(\"项目已经运行\")\\n'",[69,1932,1934],{"class":1933},"snl16"," >",[69,1936,1205],{"class":83},[69,1938,1939,1941],{"class":71,"line":120},[69,1940,76],{"class":75},[69,1942,1205],{"class":83},[10,1944,126],{},[60,1946,1949],{"className":1947,"code":1948,"language":132,"meta":65},[130],"项目已经运行\n",[43,1950,1948],{"__ignoreMap":65},[10,1952,137],{},[14,1954,140],{"id":140},[142,1956,1957,1968],{},[40,1958,1959,1961,1962,1964,1965,1967],{},[43,1960,1907],{}," 创建目录，",[43,1963,1915],{}," 改变终端当前目录，",[43,1966,1885],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[40,1969,1970,1972,1973,1976],{},[43,1971,1872],{}," 会在当前目录寻找 ",[43,1974,1975],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,1978,172],{"id":172},[37,1980,1981,1988],{},[40,1982,1983,1984,1147,1986,195],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[43,1985,1885],{},[43,1987,1889],{},[40,1989,1990],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,1992,186],{"id":186},[142,1994,1995,2002],{},[40,1996,1997,1998,2001],{},"新建 ",[43,1999,2000],{},"lesson01.py"," 并输出课程编号。",[40,2003,2004],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2006,201],{},[14,2008,204],{"id":204},[10,2010,2011],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,2013,2014],{},"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":65,"searchDepth":90,"depth":90,"links":2016},[2017,2018,2019,2020,2021,2022,2023,2024],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1849,"description":1854},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[222,2032,2033],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2036,"title":2037,"body":2038,"category":222,"cover":223,"description":2042,"extension":224,"meta":2189,"navigation":226,"path":2190,"pinned":228,"publishedAt":229,"seo":2191,"slug":2192,"stem":2193,"summary":2194,"tags":2195,"updatedAt":229,"visible":226,"__hash__":2198},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2039,"toc":2179},[2040,2043,2045,2048,2050,2056,2067,2069,2089,2091,2093,2113,2115,2121,2123,2125,2144,2146,2154,2156,2170,2172,2174,2177],[10,2041,2042],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2044,16],{"id":16},[10,2046,2047],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2049,22],{"id":22},[10,2051,2052],{},[26,2053],{"alt":2054,"src":2055},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2057,2058,2059,195,2061,2064,2065,195],{},"Python 先计算表达式，再把得到的对象交给 ",[43,2060,1464],{},[43,2062,2063],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[43,2066,1771],{},[14,2068,35],{"id":35},[37,2070,2071,2077,2086],{},[40,2072,2073,2076],{},[43,2074,2075],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[40,2078,2079,2082,2083,195],{},[43,2080,2081],{},"7 + 5"," 是表达式，运行时先求值得到 ",[43,2084,2085],{},"12",[40,2087,2088],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2090,55],{"id":55},[10,2092,1428],{},[60,2094,2096],{"className":405,"code":2095,"language":102,"meta":65,"style":65},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[43,2097,2098,2103,2108],{"__ignoreMap":65},[69,2099,2100],{"class":71,"line":72},[69,2101,2102],{},"print(42)\n",[69,2104,2105],{"class":71,"line":90},[69,2106,2107],{},"print(7 + 5)\n",[69,2109,2110],{"class":71,"line":99},[69,2111,2112],{},"print(\"Python 基础课\")\n",[10,2114,126],{},[60,2116,2119],{"className":2117,"code":2118,"language":132,"meta":65},[130],"42\n12\nPython 基础课\n",[43,2120,2118],{"__ignoreMap":65},[10,2122,137],{},[14,2124,140],{"id":140},[142,2126,2127,2135],{},[40,2128,2129,2132,2133,195],{},[43,2130,2131],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[43,2134,2085],{},[40,2136,2137,2139,2140,2143],{},[43,2138,1464],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[43,2141,2142],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2145,172],{"id":172},[37,2147,2148,2151],{},[40,2149,2150],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[40,2152,2153],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2155,186],{"id":186},[142,2157,2158,2161],{},[40,2159,2160],{},"分别输出一个整数、一个小数和一段文本。",[40,2162,2163,2164,158,2166,2169],{},"比较 ",[43,2165,2063],{},[43,2167,2168],{},"print(\"2 + 3\")"," 的结果。",[10,2171,201],{},[14,2173,204],{"id":204},[10,2175,2176],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,2178,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":2180},[2181,2182,2183,2184,2185,2186,2187,2188],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2037,"description":2042},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[222,2196,2197],"表达式","print","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2200,"title":2201,"body":2202,"category":222,"cover":223,"description":2206,"extension":224,"meta":2373,"navigation":226,"path":2374,"pinned":228,"publishedAt":229,"seo":2375,"slug":2376,"stem":2377,"summary":2378,"tags":2379,"updatedAt":229,"visible":226,"__hash__":2382},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2203,"toc":2363},[2204,2207,2209,2212,2214,2220,2223,2225,2251,2253,2255,2283,2285,2291,2293,2295,2319,2321,2337,2339,2354,2356,2358,2361],[10,2205,2206],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2208,16],{"id":16},[10,2210,2211],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2213,22],{"id":22},[10,2215,2216],{},[26,2217],{"alt":2218,"src":2219},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2221,2222],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2224,35],{"id":35},[37,2226,2227,2230,2240],{},[40,2228,2229],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[40,2231,2232,2233,158,2236,2239],{},"变量名区分大小写，",[43,2234,2235],{},"score",[43,2237,2238],{},"Score"," 是两个名字。",[40,2241,2242,2243,2246,2247,2250],{},"使用能表达含义的名称；不要用 ",[43,2244,2245],{},"list","、",[43,2248,2249],{},"str"," 等内置名称作为普通变量名。",[14,2252,55],{"id":55},[10,2254,1428],{},[60,2256,2258],{"className":405,"code":2257,"language":102,"meta":65,"style":65},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[43,2259,2260,2265,2270,2274,2279],{"__ignoreMap":65},[69,2261,2262],{"class":71,"line":72},[69,2263,2264],{},"score = 90\n",[69,2266,2267],{"class":71,"line":90},[69,2268,2269],{},"print(score)\n",[69,2271,2272],{"class":71,"line":99},[69,2273,1086],{"emptyLinePlaceholder":226},[69,2275,2276],{"class":71,"line":108},[69,2277,2278],{},"score = 95\n",[69,2280,2281],{"class":71,"line":120},[69,2282,2269],{},[10,2284,126],{},[60,2286,2289],{"className":2287,"code":2288,"language":132,"meta":65},[130],"90\n95\n",[43,2290,2288],{"__ignoreMap":65},[10,2292,137],{},[14,2294,140],{"id":140},[142,2296,2297,2306],{},[40,2298,926,2299,2302,2303,2305],{},[43,2300,2301],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[43,2304,2235],{}," 再绑定到它。",[40,2307,926,2308,2311,2312,2315,2316,195],{},[43,2309,2310],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[43,2313,2314],{},"90"," 没有被改造成 ",[43,2317,2318],{},"95",[14,2320,172],{"id":172},[37,2322,2323,2326],{},[40,2324,2325],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[40,2327,2328,2329,2246,2331,2246,2333,2336],{},"使用 ",[43,2330,2245],{},[43,2332,2249],{},[43,2334,2335],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2338,186],{"id":186},[142,2340,2341,2351],{},[40,2342,2343,2344,1147,2347,2350],{},"创建 ",[43,2345,2346],{},"course_name",[43,2348,2349],{},"lesson_count"," 两个变量并输出。",[40,2352,2353],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2355,201],{},[14,2357,204],{"id":204},[10,2359,2360],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,2362,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":2364},[2365,2366,2367,2368,2369,2370,2371,2372],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2201,"description":2206},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[222,2380,2381],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2384,"title":2385,"body":2386,"category":222,"cover":223,"description":2390,"extension":224,"meta":2556,"navigation":226,"path":2557,"pinned":228,"publishedAt":229,"seo":2558,"slug":2559,"stem":2560,"summary":2561,"tags":2562,"updatedAt":229,"visible":226,"__hash__":2565},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2387,"toc":2546},[2388,2391,2393,2396,2398,2404,2407,2409,2438,2440,2442,2488,2490,2496,2498,2500,2514,2516,2527,2529,2537,2539,2541,2544],[10,2389,2390],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2392,16],{"id":16},[10,2394,2395],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2397,22],{"id":22},[10,2399,2400],{},[26,2401],{"alt":2402,"src":2403},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2405,2406],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2408,35],{"id":35},[37,2410,2411,2421,2435],{},[40,2412,2413,2416,2417,2420],{},[43,2414,2415],{},"int"," 表示整数，",[43,2418,2419],{},"float"," 表示浮点数。",[40,2422,2423,2426,2427,2430,2431,2434],{},[43,2424,2425],{},"\u002F"," 总是进行真除法；",[43,2428,2429],{},"\u002F\u002F"," 是向下取整除法，",[43,2432,2433],{},"%"," 得到余数。",[40,2436,2437],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2439,55],{"id":55},[10,2441,1428],{},[60,2443,2445],{"className":405,"code":2444,"language":102,"meta":65,"style":65},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[43,2446,2447,2452,2457,2462,2466,2471,2476,2482],{"__ignoreMap":65},[69,2448,2449],{"class":71,"line":72},[69,2450,2451],{},"price = 25\n",[69,2453,2454],{"class":71,"line":90},[69,2455,2456],{},"count = 4\n",[69,2458,2459],{"class":71,"line":99},[69,2460,2461],{},"discount = 0.9\n",[69,2463,2464],{"class":71,"line":108},[69,2465,1086],{"emptyLinePlaceholder":226},[69,2467,2468],{"class":71,"line":120},[69,2469,2470],{},"total = price * count * discount\n",[69,2472,2473],{"class":71,"line":1138},[69,2474,2475],{},"average = total \u002F count\n",[69,2477,2479],{"class":71,"line":2478},7,[69,2480,2481],{},"print(total)\n",[69,2483,2485],{"class":71,"line":2484},8,[69,2486,2487],{},"print(average)\n",[10,2489,126],{},[60,2491,2494],{"className":2492,"code":2493,"language":132,"meta":65},[130],"90.0\n22.5\n",[43,2495,2493],{"__ignoreMap":65},[10,2497,137],{},[14,2499,140],{"id":140},[142,2501,2502,2508],{},[40,2503,2504,2507],{},[43,2505,2506],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[40,2509,2510,2513],{},[43,2511,2512],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2515,172],{"id":172},[37,2517,2518,2524],{},[40,2519,2520,2521,195],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[43,2522,2523],{},"decimal.Decimal",[40,2525,2526],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2528,186],{"id":186},[142,2530,2531,2534],{},[40,2532,2533],{},"计算 137 除以 10 的商和余数。",[40,2535,2536],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2538,201],{},[14,2540,204],{"id":204},[10,2542,2543],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,2545,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":2547},[2548,2549,2550,2551,2552,2553,2554,2555],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2385,"description":2390},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[222,2563,2564],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2567,"title":2568,"body":2569,"category":222,"cover":223,"description":2573,"extension":224,"meta":2749,"navigation":226,"path":2750,"pinned":228,"publishedAt":229,"seo":2751,"slug":2752,"stem":2753,"summary":2754,"tags":2755,"updatedAt":229,"visible":226,"__hash__":2758},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2570,"toc":2737},[2571,2574,2576,2579,2581,2587,2597,2599,2610,2612,2614,2644,2646,2652,2654,2656,2686,2689,2692,2698,2701,2703,2711,2713,2728,2730,2732,2735],[10,2572,2573],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2575,16],{"id":16},[10,2577,2578],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2580,22],{"id":22},[10,2582,2583],{},[26,2584],{"alt":2585,"src":2586},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2588,2589,2590,2593,2594,195],{},"切片 ",[43,2591,2592],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[43,2595,2596],{},"stop - start",[14,2598,35],{"id":35},[37,2600,2601,2604,2607],{},[40,2602,2603],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[40,2605,2606],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[40,2608,2609],{},"切片会创建新的字符串，不会修改原字符串。",[14,2611,55],{"id":55},[10,2613,1428],{},[60,2615,2617],{"className":405,"code":2616,"language":102,"meta":65,"style":65},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[43,2618,2619,2624,2629,2634,2639],{"__ignoreMap":65},[69,2620,2621],{"class":71,"line":72},[69,2622,2623],{},"language = \"Python\"\n",[69,2625,2626],{"class":71,"line":90},[69,2627,2628],{},"print(language[0])\n",[69,2630,2631],{"class":71,"line":99},[69,2632,2633],{},"print(language[-1])\n",[69,2635,2636],{"class":71,"line":108},[69,2637,2638],{},"print(language[0:3])\n",[69,2640,2641],{"class":71,"line":120},[69,2642,2643],{},"print(language + \" 3.14\")\n",[10,2645,126],{},[60,2647,2650],{"className":2648,"code":2649,"language":132,"meta":65},[130],"P\nn\nPyt\nPython 3.14\n",[43,2651,2649],{"__ignoreMap":65},[10,2653,137],{},[14,2655,140],{"id":140},[142,2657,2658,2672],{},[40,2659,2660,2661,2663,2664,2667,2668,2671],{},"字符串 ",[43,2662,222],{}," 的正索引从 ",[43,2665,2666],{},"P"," 的 0 开始，负索引从末尾 ",[43,2669,2670],{},"n"," 的 -1 开始。",[40,2673,2674,2677,2678,2681,2682,2685],{},[43,2675,2676],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[43,2679,2680],{},"Pyt","；索引 3 的 ",[43,2683,2684],{},"h"," 不在结果中。",[325,2687,2688],{"id":2688},"再看一个具体细节",[10,2690,2691],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2693,2694],{},[26,2695],{"alt":2696,"src":2697},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2699,2700],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2702,172],{"id":172},[37,2704,2705,2708],{},[40,2706,2707],{},"把第一个字符写成索引 1，造成整体偏移一位。",[40,2709,2710],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2712,186],{"id":186},[142,2714,2715,2725],{},[40,2716,2717,2718,2721,2722,195],{},"从 ",[43,2719,2720],{},"\"programming\""," 中切出 ",[43,2723,2724],{},"\"gram\"",[40,2726,2727],{},"使用负索引取得字符串倒数第二个字符。",[10,2729,201],{},[14,2731,204],{"id":204},[10,2733,2734],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,2736,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":2738},[2739,2740,2741,2742,2743,2746,2747,2748],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":2744},[2745],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2568,"description":2573},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[222,2756,2757],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2760,"title":2761,"body":2762,"category":222,"cover":223,"description":2766,"extension":224,"meta":2980,"navigation":226,"path":2981,"pinned":228,"publishedAt":229,"seo":2982,"slug":2983,"stem":2984,"summary":2985,"tags":2986,"updatedAt":229,"visible":226,"__hash__":2989},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2763,"toc":2968},[2764,2767,2769,2772,2774,2780,2790,2792,2825,2827,2829,2873,2875,2881,2883,2885,2906,2908,2911,2917,2925,2927,2941,2943,2959,2961,2963,2966],[10,2765,2766],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2768,16],{"id":16},[10,2770,2771],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2773,22],{"id":22},[10,2775,2776],{},[26,2777],{"alt":2778,"src":2779},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2781,2782,2783,997,2786,2789],{},"比较表达式先产生 ",[43,2784,2785],{},"True",[43,2787,2788],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2791,35],{"id":35},[37,2793,2794,2808,2822],{},[40,2795,2796,2799,2800,2803,2804,2807],{},[43,2797,2798],{},"=="," 判断是否相等，",[43,2801,2802],{},"!="," 判断是否不等；单个 ",[43,2805,2806],{},"="," 是赋值。",[40,2809,2810,2813,2814,2817,2818,2821],{},[43,2811,2812],{},"and"," 要求两侧都为真，",[43,2815,2816],{},"or"," 只需一侧为真，",[43,2819,2820],{},"not"," 取反。",[40,2823,2824],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2826,55],{"id":55},[10,2828,1428],{},[60,2830,2832],{"className":405,"code":2831,"language":102,"meta":65,"style":65},"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",[43,2833,2834,2839,2844,2848,2853,2858,2863,2868],{"__ignoreMap":65},[69,2835,2836],{"class":71,"line":72},[69,2837,2838],{},"age = 20\n",[69,2840,2841],{"class":71,"line":90},[69,2842,2843],{},"has_ticket = True\n",[69,2845,2846],{"class":71,"line":99},[69,2847,1086],{"emptyLinePlaceholder":226},[69,2849,2850],{"class":71,"line":108},[69,2851,2852],{},"is_adult = age >= 18\n",[69,2854,2855],{"class":71,"line":120},[69,2856,2857],{},"can_enter = is_adult and has_ticket\n",[69,2859,2860],{"class":71,"line":1138},[69,2861,2862],{},"print(is_adult)\n",[69,2864,2865],{"class":71,"line":2478},[69,2866,2867],{},"print(can_enter)\n",[69,2869,2870],{"class":71,"line":2484},[69,2871,2872],{},"print(not has_ticket)\n",[10,2874,126],{},[60,2876,2879],{"className":2877,"code":2878,"language":132,"meta":65},[130],"True\nTrue\nFalse\n",[43,2880,2878],{"__ignoreMap":65},[10,2882,137],{},[14,2884,140],{"id":140},[142,2886,2887,2897],{},[40,2888,2889,2892,2893,2896],{},[43,2890,2891],{},"age >= 18"," 先产生布尔值并绑定给 ",[43,2894,2895],{},"is_adult","，这一步没有任何分支跳转。",[40,2898,2899,2902,2903,2905],{},[43,2900,2901],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[43,2904,2820],{}," 只对紧随其后的值取反。",[325,2907,2688],{"id":2688},[10,2909,2910],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2912,2913],{},[26,2914],{"alt":2915,"src":2916},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2918,2919,2921,2922,2924],{},[43,2920,2812],{}," 只有“真、真”得到真；",[43,2923,2816],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2926,172],{"id":172},[37,2928,2929,2938],{},[40,2930,2931,2932,2934,2935,2937],{},"用单个等号判断相等。",[43,2933,2806],{}," 是赋值，",[43,2936,2798],{}," 才是相等比较。",[40,2939,2940],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,2942,186],{"id":186},[142,2944,2945,2952],{},[40,2946,2947,2948,2951],{},"判断数字 ",[43,2949,2950],{},"15"," 是否同时大于 10 且小于 20。",[40,2953,2954,2955,2958],{},"分别修改年龄和票据状态，记录 ",[43,2956,2957],{},"can_enter"," 的四种组合结果。",[10,2960,201],{},[14,2962,204],{"id":204},[10,2964,2965],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,2967,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":2969},[2970,2971,2972,2973,2974,2977,2978,2979],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":2975},[2976],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2761,"description":2766},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[222,2987,2988],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":2991,"title":2992,"body":2993,"category":222,"cover":223,"description":2997,"extension":224,"meta":3165,"navigation":226,"path":3166,"pinned":228,"publishedAt":229,"seo":3167,"slug":3168,"stem":3169,"summary":3170,"tags":3171,"updatedAt":229,"visible":226,"__hash__":3173},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":2994,"toc":3155},[2995,2998,3000,3003,3005,3011,3029,3031,3044,3046,3048,3082,3084,3090,3092,3094,3116,3118,3130,3132,3146,3148,3150,3153],[10,2996,2997],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,2999,16],{"id":16},[10,3001,3002],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3004,22],{"id":22},[10,3006,3007],{},[26,3008],{"alt":3009,"src":3010},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3012,3013,3016,3017,3020,3021,3024,3025,3028],{},[43,3014,3015],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[43,3018,3019],{},"18","，程序首先得到的也是 ",[43,3022,3023],{},"\"18\"","，需要 ",[43,3026,3027],{},"int()"," 后才能按整数参与计算。",[14,3030,35],{"id":35},[37,3032,3033,3036,3041],{},[40,3034,3035],{},"提示文字应告诉用户需要输入什么。",[40,3037,3038,3040],{},[43,3039,3027],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[40,3042,3043],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3045,55],{"id":55},[10,3047,1428],{},[60,3049,3051],{"className":405,"code":3050,"language":102,"meta":65,"style":65},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[43,3052,3053,3058,3063,3068,3072,3077],{"__ignoreMap":65},[69,3054,3055],{"class":71,"line":72},[69,3056,3057],{},"name = input(\"请输入姓名：\")\n",[69,3059,3060],{"class":71,"line":90},[69,3061,3062],{},"age_text = input(\"请输入年龄：\")\n",[69,3064,3065],{"class":71,"line":99},[69,3066,3067],{},"age = int(age_text)\n",[69,3069,3070],{"class":71,"line":108},[69,3071,1086],{"emptyLinePlaceholder":226},[69,3073,3074],{"class":71,"line":120},[69,3075,3076],{},"print(\"你好，\" + name)\n",[69,3078,3079],{"class":71,"line":1138},[69,3080,3081],{},"print(age + 1)\n",[10,3083,126],{},[60,3085,3088],{"className":3086,"code":3087,"language":132,"meta":65},[130],"根据输入显示姓名，并输出下一年的年龄\n",[43,3089,3087],{"__ignoreMap":65},[10,3091,137],{},[14,3093,140],{"id":140},[142,3095,3096,3106],{},[40,3097,3098,3099,3101,3102,3105],{},"两次 ",[43,3100,3015],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[43,3103,3104],{},"age_text"," 用来提醒这仍是文本。",[40,3107,3108,3111,3112,3115],{},[43,3109,3110],{},"int(age_text)"," 创建整数对象，后面的 ",[43,3113,3114],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3117,172],{"id":172},[37,3119,3120,3127],{},[40,3121,3122,3123,3126],{},"直接计算 ",[43,3124,3125],{},"input(...) + 1","，忽略输入结果是字符串。",[40,3128,3129],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3131,186],{"id":186},[142,3133,3134,3137],{},[40,3135,3136],{},"接收两个整数并输出它们的和。",[40,3138,1710,3139,3142,3143,3145],{},[43,3140,3141],{},"18.5"," 给 ",[43,3144,3027],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3147,201],{},[14,3149,204],{"id":204},[10,3151,3152],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,3154,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":3156},[3157,3158,3159,3160,3161,3162,3163,3164],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":2992,"description":2997},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[222,2335,3172],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3175,"title":3176,"body":3177,"category":222,"cover":223,"description":3181,"extension":224,"meta":3341,"navigation":226,"path":3342,"pinned":228,"publishedAt":229,"seo":3343,"slug":3344,"stem":3345,"summary":3346,"tags":3347,"updatedAt":229,"visible":226,"__hash__":3350},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3178,"toc":3331},[3179,3182,3184,3187,3189,3195,3202,3204,3218,3220,3222,3261,3263,3269,3271,3273,3292,3294,3309,3311,3322,3324,3326,3329],[10,3180,3181],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3183,16],{"id":16},[10,3185,3186],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3188,22],{"id":22},[10,3190,3191],{},[26,3192],{"alt":3193,"src":3194},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3196,3197,3198,3201],{},"列表为元素维护从 0 开始的位置索引。修改 ",[43,3199,3200],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3203,35],{"id":35},[37,3205,3206,3209,3212],{},[40,3207,3208],{},"列表使用方括号，元素之间用逗号分隔。",[40,3210,3211],{},"列表可变，可以替换、追加和删除元素。",[40,3213,3214,3215,195],{},"访问不存在的索引会产生 ",[43,3216,3217],{},"IndexError",[14,3219,55],{"id":55},[10,3221,1428],{},[60,3223,3225],{"className":405,"code":3224,"language":102,"meta":65,"style":65},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[43,3226,3227,3232,3237,3241,3246,3251,3256],{"__ignoreMap":65},[69,3228,3229],{"class":71,"line":72},[69,3230,3231],{},"scores = [82, 90, 76]\n",[69,3233,3234],{"class":71,"line":90},[69,3235,3236],{},"print(scores[0])\n",[69,3238,3239],{"class":71,"line":99},[69,3240,1086],{"emptyLinePlaceholder":226},[69,3242,3243],{"class":71,"line":108},[69,3244,3245],{},"scores[1] = 95\n",[69,3247,3248],{"class":71,"line":120},[69,3249,3250],{},"scores.append(88)\n",[69,3252,3253],{"class":71,"line":1138},[69,3254,3255],{},"print(scores)\n",[69,3257,3258],{"class":71,"line":2478},[69,3259,3260],{},"print(len(scores))\n",[10,3262,126],{},[60,3264,3267],{"className":3265,"code":3266,"language":132,"meta":65},[130],"82\n[82, 95, 76, 88]\n4\n",[43,3268,3266],{"__ignoreMap":65},[10,3270,137],{},[14,3272,140],{"id":140},[142,3274,3275,3278],{},[40,3276,3277],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[40,3279,3280,3283,3284,3287,3288,3291],{},[43,3281,3282],{},"scores[1] = 95"," 替换第二个位置，",[43,3285,3286],{},"append(88)"," 在末尾增加新位置，",[43,3289,3290],{},"len()"," 因而从 3 变为 4。",[14,3293,172],{"id":172},[37,3295,3296,3306],{},[40,3297,3298,3299,3302,3303,195],{},"访问 ",[43,3300,3301],{},"scores[len(scores)]","。最后一个合法正索引是 ",[43,3304,3305],{},"len(scores) - 1",[40,3307,3308],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3310,186],{"id":186},[142,3312,3313,3316],{},[40,3314,3315],{},"建立三项学习任务列表，再追加第四项。",[40,3317,3318,3319,3321],{},"修改第二项，并用 ",[43,3320,3290],{}," 检查元素数量。",[10,3323,201],{},[14,3325,204],{"id":204},[10,3327,3328],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,3330,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":3332},[3333,3334,3335,3336,3337,3338,3339,3340],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3176,"description":3181},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[222,3348,3349],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3352,"title":3353,"body":3354,"category":222,"cover":223,"description":3358,"extension":224,"meta":3498,"navigation":226,"path":3499,"pinned":228,"publishedAt":229,"seo":3500,"slug":3501,"stem":3502,"summary":3503,"tags":3504,"updatedAt":229,"visible":226,"__hash__":3506},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3355,"toc":3488},[3356,3359,3361,3364,3366,3372,3375,3377,3388,3390,3392,3426,3428,3434,3436,3438,3452,3454,3465,3467,3479,3481,3483,3486],[10,3357,3358],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3360,16],{"id":16},[10,3362,3363],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3365,22],{"id":22},[10,3367,3368],{},[26,3369],{"alt":3370,"src":3371},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3373,3374],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3376,35],{"id":35},[37,3378,3379,3382,3385],{},[40,3380,3381],{},"元组常用来表达固定数量、固定含义的一组值。",[40,3383,3384],{},"只有一个元素的元组必须保留尾随逗号。",[40,3386,3387],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3389,55],{"id":55},[10,3391,1428],{},[60,3393,3395],{"className":405,"code":3394,"language":102,"meta":65,"style":65},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[43,3396,3397,3402,3407,3412,3416,3421],{"__ignoreMap":65},[69,3398,3399],{"class":71,"line":72},[69,3400,3401],{},"point = (120, 80)\n",[69,3403,3404],{"class":71,"line":90},[69,3405,3406],{},"print(point[0])\n",[69,3408,3409],{"class":71,"line":99},[69,3410,3411],{},"print(point[1])\n",[69,3413,3414],{"class":71,"line":108},[69,3415,1086],{"emptyLinePlaceholder":226},[69,3417,3418],{"class":71,"line":120},[69,3419,3420],{},"single = (5,)\n",[69,3422,3423],{"class":71,"line":1138},[69,3424,3425],{},"print(single)\n",[10,3427,126],{},[60,3429,3432],{"className":3430,"code":3431,"language":132,"meta":65},[130],"120\n80\n(5,)\n",[43,3433,3431],{"__ignoreMap":65},[10,3435,137],{},[14,3437,140],{"id":140},[142,3439,3440,3446],{},[40,3441,3442,3445],{},[43,3443,3444],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[40,3447,3448,3451],{},[43,3449,3450],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3453,172],{"id":172},[37,3455,3456,3462],{},[40,3457,180,3458,3461],{},[43,3459,3460],{},"(5)"," 当作元组，实际它仍是整数。",[40,3463,3464],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3466,186],{"id":186},[142,3468,3469,3472],{},[40,3470,3471],{},"用元组表示宽度和高度。",[40,3473,2163,3474,158,3476,3478],{},[43,3475,3460],{},[43,3477,3450],{}," 的类型。",[10,3480,201],{},[14,3482,204],{"id":204},[10,3484,3485],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,3487,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":3489},[3490,3491,3492,3493,3494,3495,3496,3497],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3353,"description":3358},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[222,3505,3349],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3508,"title":3509,"body":3510,"category":222,"cover":223,"description":3514,"extension":224,"meta":3669,"navigation":226,"path":3670,"pinned":228,"publishedAt":229,"seo":3671,"slug":3672,"stem":3673,"summary":3674,"tags":3675,"updatedAt":229,"visible":226,"__hash__":3677},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3511,"toc":3659},[3512,3515,3517,3520,3522,3528,3538,3540,3554,3556,3558,3592,3594,3600,3602,3604,3619,3621,3640,3642,3650,3652,3654,3657],[10,3513,3514],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3516,16],{"id":16},[10,3518,3519],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3521,22],{"id":22},[10,3523,3524],{},[26,3525],{"alt":3526,"src":3527},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3529,3530,3531,3534,3535,3537],{},"字典通过键定位值，不使用连续位置表达含义。",[43,3532,3533],{},"student[\"score\"]"," 读取的是键 ",[43,3536,2235],{}," 对应的值，而不是“第几个元素”。",[14,3539,35],{"id":35},[37,3541,3542,3545,3551],{},[40,3543,3544],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[40,3546,2328,3547,3550],{},[43,3548,3549],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[40,3552,3553],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3555,55],{"id":55},[10,3557,1428],{},[60,3559,3561],{"className":405,"code":3560,"language":102,"meta":65,"style":65},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[43,3562,3563,3568,3573,3577,3582,3587],{"__ignoreMap":65},[69,3564,3565],{"class":71,"line":72},[69,3566,3567],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[69,3569,3570],{"class":71,"line":90},[69,3571,3572],{},"print(student[\"name\"])\n",[69,3574,3575],{"class":71,"line":99},[69,3576,1086],{"emptyLinePlaceholder":226},[69,3578,3579],{"class":71,"line":108},[69,3580,3581],{},"student[\"score\"] = 95\n",[69,3583,3584],{"class":71,"line":120},[69,3585,3586],{},"student[\"city\"] = \"郑州\"\n",[69,3588,3589],{"class":71,"line":1138},[69,3590,3591],{},"print(student)\n",[10,3593,126],{},[60,3595,3598],{"className":3596,"code":3597,"language":132,"meta":65},[130],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[43,3599,3597],{"__ignoreMap":65},[10,3601,137],{},[14,3603,140],{"id":140},[142,3605,3606,3609],{},[40,3607,3608],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[40,3610,3611,3612,3614,3615,3618],{},"给已有键 ",[43,3613,2235],{}," 赋值会更新映射，给新键 ",[43,3616,3617],{},"city"," 赋值会增加映射。",[14,3620,172],{"id":172},[37,3622,3623,3630],{},[40,3624,3625,3626,3629],{},"按位置理解字典并尝试 ",[43,3627,3628],{},"student[0]","，而实际键是字符串。",[40,3631,3632,3633,3636,3637,195],{},"直接读取不确定存在的键并忽略 ",[43,3634,3635],{},"KeyError","；后续可根据场景使用成员检查或 ",[43,3638,3639],{},"get()",[14,3641,186],{"id":186},[142,3643,3644,3647],{},[40,3645,3646],{},"建立一本书的标题、作者和页数字典。",[40,3648,3649],{},"添加分类键，再修改页数。",[10,3651,201],{},[14,3653,204],{"id":204},[10,3655,3656],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,3658,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":3660},[3661,3662,3663,3664,3665,3666,3667,3668],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3509,"description":3514},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[222,3676,3349],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3679,"title":3680,"body":3681,"category":222,"cover":223,"description":3685,"extension":224,"meta":3833,"navigation":226,"path":3834,"pinned":228,"publishedAt":229,"seo":3835,"slug":3836,"stem":3837,"summary":3838,"tags":3839,"updatedAt":229,"visible":226,"__hash__":3841},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3682,"toc":3823},[3683,3686,3688,3691,3693,3699,3702,3704,3722,3724,3726,3760,3762,3768,3770,3772,3787,3789,3801,3803,3814,3816,3818,3821],[10,3684,3685],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3687,16],{"id":16},[10,3689,3690],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3692,22],{"id":22},[10,3694,3695],{},[26,3696],{"alt":3697,"src":3698},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3700,3701],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3703,35],{"id":35},[37,3705,3706,3709,3712],{},[40,3707,3708],{},"集合中的元素不重复。",[40,3710,3711],{},"集合是无序容器，不要依赖打印顺序或索引。",[40,3713,3714,3715,165,3718,3721],{},"创建空集合必须写 ",[43,3716,3717],{},"set()",[43,3719,3720],{},"{}"," 创建的是空字典。",[14,3723,55],{"id":55},[10,3725,1428],{},[60,3727,3729],{"className":405,"code":3728,"language":102,"meta":65,"style":65},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[43,3730,3731,3736,3741,3745,3750,3755],{"__ignoreMap":65},[69,3732,3733],{"class":71,"line":72},[69,3734,3735],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[69,3737,3738],{"class":71,"line":90},[69,3739,3740],{},"right = {\"Python\", \"Docker\"}\n",[69,3742,3743],{"class":71,"line":99},[69,3744,1086],{"emptyLinePlaceholder":226},[69,3746,3747],{"class":71,"line":108},[69,3748,3749],{},"print(left & right)\n",[69,3751,3752],{"class":71,"line":120},[69,3753,3754],{},"print(left | right)\n",[69,3756,3757],{"class":71,"line":1138},[69,3758,3759],{},"print(\"Git\" in left)\n",[10,3761,126],{},[60,3763,3766],{"className":3764,"code":3765,"language":132,"meta":65},[130],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[43,3767,3765],{"__ignoreMap":65},[10,3769,137],{},[14,3771,140],{"id":140},[142,3773,3774,3777],{},[40,3775,3776],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[40,3778,3779,3782,3783,3786],{},[43,3780,3781],{},"&"," 计算交集，",[43,3784,3785],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3788,172],{"id":172},[37,3790,3791,3798],{},[40,3792,2328,3793,3795,3796,195],{},[43,3794,3720],{}," 创建空集合，实际得到空字典；空集合应写 ",[43,3797,3717],{},[40,3799,3800],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3802,186],{"id":186},[142,3804,3805,3811],{},[40,3806,3807,3808,3810],{},"把包含重复标签的列表交给 ",[43,3809,3717],{}," 去重。",[40,3812,3813],{},"计算两组课程标签的交集和差集。",[10,3815,201],{},[14,3817,204],{"id":204},[10,3819,3820],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,3822,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":3824},[3825,3826,3827,3828,3829,3830,3831,3832],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3680,"description":3685},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[222,3840,3349],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3843,"title":3844,"body":3845,"category":222,"cover":223,"description":3849,"extension":224,"meta":4047,"navigation":226,"path":4048,"pinned":228,"publishedAt":229,"seo":4049,"slug":4050,"stem":4051,"summary":4052,"tags":4053,"updatedAt":229,"visible":226,"__hash__":4056},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3846,"toc":4035},[3847,3850,3852,3855,3857,3863,3873,3875,3892,3894,3896,3946,3948,3954,3956,3958,3980,3982,3985,3991,3994,3996,4009,4011,4026,4028,4030,4033],[10,3848,3849],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3851,16],{"id":16},[10,3853,3854],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3856,22],{"id":22},[10,3858,3859],{},[26,3860],{"alt":3861,"src":3862},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3864,3865,3868,3869,3872],{},[43,3866,3867],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[43,3870,3871],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3874,35],{"id":35},[37,3876,3877,3886,3889],{},[40,3878,3879,3881,3882,3885],{},[43,3880,2798],{}," 比较内容是否相等，",[43,3883,3884],{},"is"," 比较是否为同一个对象。",[40,3887,3888],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[40,3890,3891],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3893,55],{"id":55},[10,3895,1428],{},[60,3897,3899],{"className":405,"code":3898,"language":102,"meta":65,"style":65},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[43,3900,3901,3906,3911,3916,3920,3925,3930,3935,3940],{"__ignoreMap":65},[69,3902,3903],{"class":71,"line":72},[69,3904,3905],{},"tasks = [\"变量\", \"字符串\"]\n",[69,3907,3908],{"class":71,"line":90},[69,3909,3910],{},"shared = tasks\n",[69,3912,3913],{"class":71,"line":99},[69,3914,3915],{},"backup = tasks.copy()\n",[69,3917,3918],{"class":71,"line":108},[69,3919,1086],{"emptyLinePlaceholder":226},[69,3921,3922],{"class":71,"line":120},[69,3923,3924],{},"tasks.append(\"列表\")\n",[69,3926,3927],{"class":71,"line":1138},[69,3928,3929],{},"print(shared)\n",[69,3931,3932],{"class":71,"line":2478},[69,3933,3934],{},"print(backup)\n",[69,3936,3937],{"class":71,"line":2484},[69,3938,3939],{},"print(tasks is shared)\n",[69,3941,3943],{"class":71,"line":3942},9,[69,3944,3945],{},"print(tasks is backup)\n",[10,3947,126],{},[60,3949,3952],{"className":3950,"code":3951,"language":132,"meta":65},[130],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[43,3953,3951],{"__ignoreMap":65},[10,3955,137],{},[14,3957,140],{"id":140},[142,3959,3960,3966],{},[40,3961,3962,3965],{},[43,3963,3964],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[40,3967,3968,3971,3972,3975,3976,3979],{},[43,3969,3970],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[43,3973,3974],{},"shared"," 能观察到变化，",[43,3977,3978],{},"backup"," 不会。",[325,3981,2688],{"id":2688},[10,3983,3984],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,3986,3987],{},[26,3988],{"alt":3989,"src":3990},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,3992,3993],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,3995,172],{"id":172},[37,3997,3998,4006],{},[40,3999,4000,4001,4003,4004,195],{},"用 ",[43,4002,2798],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[43,4005,3884],{},[40,4007,4008],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4010,186],{"id":186},[142,4012,4013,4016],{},[40,4014,4015],{},"让两个变量引用同一个字典并修改其中一个。",[40,4017,2328,4018,4021,4022,1147,4024,195],{},[43,4019,4020],{},"copy()"," 创建外层副本，再比较 ",[43,4023,3884],{},[43,4025,2798],{},[10,4027,201],{},[14,4029,204],{"id":204},[10,4031,4032],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,4034,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":4036},[4037,4038,4039,4040,4041,4044,4045,4046],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":4042},[4043],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3844,"description":3849},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[222,4054,4055],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4058,"title":4059,"body":4060,"category":222,"cover":223,"description":4064,"extension":224,"meta":4277,"navigation":226,"path":4278,"pinned":228,"publishedAt":229,"seo":4279,"slug":4280,"stem":4281,"summary":4282,"tags":4283,"updatedAt":229,"visible":226,"__hash__":4285},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4061,"toc":4264},[4062,4065,4067,4070,4072,4078,4088,4090,4101,4103,4105,4158,4160,4166,4168,4170,4188,4190,4193,4199,4207,4210,4213,4219,4225,4227,4245,4247,4255,4257,4259,4262],[10,4063,4064],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4066,16],{"id":16},[10,4068,4069],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4071,22],{"id":22},[10,4073,4074],{},[26,4075],{"alt":4076,"src":4077},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4079,4080,2246,4082,2246,4085,4087],{},[43,4081,1146],{},[43,4083,4084],{},"elif",[43,4086,1150],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4089,35],{"id":35},[37,4091,4092,4095,4098],{},[40,4093,4094],{},"冒号表示接下来开始一个代码块。",[40,4096,4097],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[40,4099,4100],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4102,55],{"id":55},[10,4104,1428],{},[60,4106,4108],{"className":405,"code":4107,"language":102,"meta":65,"style":65},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[43,4109,4110,4115,4119,4124,4129,4134,4139,4143,4148,4152],{"__ignoreMap":65},[69,4111,4112],{"class":71,"line":72},[69,4113,4114],{},"score = int(input(\"请输入分数：\"))\n",[69,4116,4117],{"class":71,"line":90},[69,4118,1086],{"emptyLinePlaceholder":226},[69,4120,4121],{"class":71,"line":99},[69,4122,4123],{},"if score >= 90:\n",[69,4125,4126],{"class":71,"line":108},[69,4127,4128],{},"    level = \"优秀\"\n",[69,4130,4131],{"class":71,"line":120},[69,4132,4133],{},"elif score >= 60:\n",[69,4135,4136],{"class":71,"line":1138},[69,4137,4138],{},"    level = \"合格\"\n",[69,4140,4141],{"class":71,"line":2478},[69,4142,1135],{},[69,4144,4145],{"class":71,"line":2484},[69,4146,4147],{},"    level = \"需要继续学习\"\n",[69,4149,4150],{"class":71,"line":3942},[69,4151,1086],{"emptyLinePlaceholder":226},[69,4153,4155],{"class":71,"line":4154},10,[69,4156,4157],{},"print(level)\n",[10,4159,126],{},[60,4161,4164],{"className":4162,"code":4163,"language":132,"meta":65},[130],"输入 85 时输出：合格\n",[43,4165,4163],{"__ignoreMap":65},[10,4167,137],{},[14,4169,140],{"id":140},[142,4171,4172,4179],{},[40,4173,4174,4175,4178],{},"输入先转换为整数，程序从 ",[43,4176,4177],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[40,4180,4181,4184,4185,4187],{},[43,4182,4183],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[43,4186,1150],{}," 被跳过；最终三个分支只会选择一个。",[325,4189,2688],{"id":2688},[10,4191,4192],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4194,4195],{},[26,4196],{"alt":4197,"src":4198},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4200,4201,4203,4204,4206],{},[43,4202,4177],{}," 必须放在 ",[43,4205,4183],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[325,4208,2688],{"id":4209},"再看一个具体细节-1",[10,4211,4212],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4214,4215],{},[26,4216],{"alt":4217,"src":4218},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4220,4221,4222,4224],{},"同一缩进层级属于同一个代码块；回到 ",[43,4223,1146],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4226,172],{"id":172},[37,4228,4229,4235],{},[40,4230,4231,4232,4234],{},"先写 ",[43,4233,4183],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[40,4236,4237,4238,4240,4241,4244],{},"混用多个独立 ",[43,4239,1146],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[43,4242,4243],{},"if\u002Felif\u002Felse"," 链。",[14,4246,186],{"id":186},[142,4248,4249,4252],{},[40,4250,4251],{},"根据温度输出“冷、适中、热”三个等级。",[40,4253,4254],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4256,201],{},[14,4258,204],{"id":204},[10,4260,4261],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,4263,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":4265},[4266,4267,4268,4269,4270,4274,4275,4276],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":4271},[4272,4273],{"id":2688,"depth":99,"text":2688},{"id":4209,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4059,"description":4064},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[222,1146,4284],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4287,"title":4288,"body":4289,"category":222,"cover":223,"description":4293,"extension":224,"meta":4459,"navigation":226,"path":4460,"pinned":228,"publishedAt":229,"seo":4461,"slug":4462,"stem":4463,"summary":4464,"tags":4465,"updatedAt":229,"visible":226,"__hash__":4467},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4290,"toc":4447},[4291,4294,4296,4299,4301,4307,4313,4315,4330,4332,4334,4372,4374,4380,4382,4384,4399,4401,4404,4410,4416,4418,4426,4428,4438,4440,4442,4445],[10,4292,4293],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4295,16],{"id":16},[10,4297,4298],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4300,22],{"id":22},[10,4302,4303],{},[26,4304],{"alt":4305,"src":4306},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4308,4309,4312],{},[43,4310,4311],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4314,35],{"id":35},[37,4316,4317,4320,4323],{},[40,4318,4319],{},"进入循环前先准备参与条件判断的状态。",[40,4321,4322],{},"循环体中必须有机会让条件变为假。",[40,4324,4325,4326,4329],{},"能够预先确定遍历对象时，后续介绍的 ",[43,4327,4328],{},"for"," 通常更直接。",[14,4331,55],{"id":55},[10,4333,1428],{},[60,4335,4337],{"className":405,"code":4336,"language":102,"meta":65,"style":65},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[43,4338,4339,4344,4348,4353,4358,4363,4367],{"__ignoreMap":65},[69,4340,4341],{"class":71,"line":72},[69,4342,4343],{},"count = 1\n",[69,4345,4346],{"class":71,"line":90},[69,4347,1086],{"emptyLinePlaceholder":226},[69,4349,4350],{"class":71,"line":99},[69,4351,4352],{},"while count \u003C= 3:\n",[69,4354,4355],{"class":71,"line":108},[69,4356,4357],{},"    print(\"第\", count, \"次练习\")\n",[69,4359,4360],{"class":71,"line":120},[69,4361,4362],{},"    count = count + 1\n",[69,4364,4365],{"class":71,"line":1138},[69,4366,1086],{"emptyLinePlaceholder":226},[69,4368,4369],{"class":71,"line":2478},[69,4370,4371],{},"print(\"练习结束\")\n",[10,4373,126],{},[60,4375,4378],{"className":4376,"code":4377,"language":132,"meta":65},[130],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[43,4379,4377],{"__ignoreMap":65},[10,4381,137],{},[14,4383,140],{"id":140},[142,4385,4386,4393],{},[40,4387,4388,4389,4392],{},"进入循环前 ",[43,4390,4391],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[40,4394,4395,4396,4398],{},"循环体末尾把 ",[43,4397,4391],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[325,4400,2688],{"id":2688},[10,4402,4403],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4405,4406],{},[26,4407],{"alt":4408,"src":4409},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4411,4412,4413,4415],{},"第4次检查时 ",[43,4414,4391],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4417,172],{"id":172},[37,4419,4420,4423],{},[40,4421,4422],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[40,4424,4425],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4427,186],{"id":186},[142,4429,4430,4435],{},[40,4431,2328,4432,4434],{},[43,4433,4311],{}," 输出 1 到 5。",[40,4436,4437],{},"计算 1 到 10 的累加和。",[10,4439,201],{},[14,4441,204],{"id":204},[10,4443,4444],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,4446,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":4448},[4449,4450,4451,4452,4453,4456,4457,4458],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":4454},[4455],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4288,"description":4293},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[222,4311,4466],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4469,"title":4470,"body":4471,"category":222,"cover":223,"description":4475,"extension":224,"meta":4623,"navigation":226,"path":4624,"pinned":228,"publishedAt":229,"seo":4625,"slug":4626,"stem":4627,"summary":4628,"tags":4629,"updatedAt":229,"visible":226,"__hash__":4631},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4472,"toc":4613},[4473,4476,4478,4481,4483,4489,4494,4496,4510,4512,4514,4552,4554,4560,4562,4564,4581,4583,4591,4593,4604,4606,4608,4611],[10,4474,4475],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4477,16],{"id":16},[10,4479,4480],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4482,22],{"id":22},[10,4484,4485],{},[26,4486],{"alt":4487,"src":4488},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4490,4491,4493],{},[43,4492,4328],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4495,35],{"id":35},[37,4497,4498,4504,4507],{},[40,4499,4500,4503],{},[43,4501,4502],{},"range(1, 4)"," 包含 1，不包含 4。",[40,4505,4506],{},"只需要元素时直接遍历元素，不必手工维护索引。",[40,4508,4509],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4511,55],{"id":55},[10,4513,1428],{},[60,4515,4517],{"className":405,"code":4516,"language":102,"meta":65,"style":65},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[43,4518,4519,4524,4528,4533,4538,4542,4547],{"__ignoreMap":65},[69,4520,4521],{"class":71,"line":72},[69,4522,4523],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[69,4525,4526],{"class":71,"line":90},[69,4527,1086],{"emptyLinePlaceholder":226},[69,4529,4530],{"class":71,"line":99},[69,4531,4532],{},"for course in courses:\n",[69,4534,4535],{"class":71,"line":108},[69,4536,4537],{},"    print(course)\n",[69,4539,4540],{"class":71,"line":120},[69,4541,1086],{"emptyLinePlaceholder":226},[69,4543,4544],{"class":71,"line":1138},[69,4545,4546],{},"for number in range(1, 4):\n",[69,4548,4549],{"class":71,"line":2478},[69,4550,4551],{},"    print(number)\n",[10,4553,126],{},[60,4555,4558],{"className":4556,"code":4557,"language":132,"meta":65},[130],"变量\n字符串\n列表\n1\n2\n3\n",[43,4559,4557],{"__ignoreMap":65},[10,4561,137],{},[14,4563,140],{"id":140},[142,4565,4566,4576],{},[40,4567,4568,4569,4571,4572,4575],{},"第一个 ",[43,4570,4328],{}," 依次从列表取得字符串，循环变量 ",[43,4573,4574],{},"course"," 每轮重新绑定。",[40,4577,4578,4580],{},[43,4579,4502],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4582,172],{"id":172},[37,4584,4585,4588],{},[40,4586,4587],{},"只需要元素却手工维护索引，增加越界风险。",[40,4589,4590],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4592,186],{"id":186},[142,4594,4595,4598],{},[40,4596,4597],{},"逐项输出一个字符串中的字符。",[40,4599,2328,4600,4603],{},[43,4601,4602],{},"range()"," 输出 2、4、6、8。",[10,4605,201],{},[14,4607,204],{"id":204},[10,4609,4610],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,4612,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":4614},[4615,4616,4617,4618,4619,4620,4621,4622],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4470,"description":4475},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[222,4328,4630],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4633,"title":4634,"body":4635,"category":222,"cover":223,"description":4639,"extension":224,"meta":4813,"navigation":226,"path":4814,"pinned":228,"publishedAt":229,"seo":4815,"slug":4816,"stem":4817,"summary":4818,"tags":4819,"updatedAt":229,"visible":226,"__hash__":4820},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4636,"toc":4803},[4637,4640,4642,4645,4647,4653,4663,4665,4684,4686,4688,4740,4742,4748,4750,4752,4766,4768,4784,4786,4794,4796,4798,4801],[10,4638,4639],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4641,16],{"id":16},[10,4643,4644],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4646,22],{"id":22},[10,4648,4649],{},[26,4650],{"alt":4651,"src":4652},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4654,4655,4658,4659,4662],{},[43,4656,4657],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[43,4660,4661],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4664,35],{"id":35},[37,4666,4667,4670,4678],{},[40,4668,4669],{},"先写普通循环，再在确有需要时加入流程控制语句。",[40,4671,4672,4674,4675,4677],{},[43,4673,4657],{}," 前要确认不会跳过 ",[43,4676,4311],{}," 循环中的状态更新。",[40,4679,4680,4681,4683],{},"多层嵌套中 ",[43,4682,4661],{}," 只结束它所在的最内层循环。",[14,4685,55],{"id":55},[10,4687,1428],{},[60,4689,4691],{"className":405,"code":4690,"language":102,"meta":65,"style":65},"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",[43,4692,4693,4698,4702,4707,4712,4717,4722,4727,4731,4735],{"__ignoreMap":65},[69,4694,4695],{"class":71,"line":72},[69,4696,4697],{},"numbers = [3, -1, 0, 8, 12]\n",[69,4699,4700],{"class":71,"line":90},[69,4701,1086],{"emptyLinePlaceholder":226},[69,4703,4704],{"class":71,"line":99},[69,4705,4706],{},"for number in numbers:\n",[69,4708,4709],{"class":71,"line":108},[69,4710,4711],{},"    if number \u003C 0:\n",[69,4713,4714],{"class":71,"line":120},[69,4715,4716],{},"        continue\n",[69,4718,4719],{"class":71,"line":1138},[69,4720,4721],{},"    if number == 0:\n",[69,4723,4724],{"class":71,"line":2478},[69,4725,4726],{},"        break\n",[69,4728,4729],{"class":71,"line":2484},[69,4730,4551],{},[69,4732,4733],{"class":71,"line":3942},[69,4734,1086],{"emptyLinePlaceholder":226},[69,4736,4737],{"class":71,"line":4154},[69,4738,4739],{},"print(\"循环结束\")\n",[10,4741,126],{},[60,4743,4746],{"className":4744,"code":4745,"language":132,"meta":65},[130],"3\n循环结束\n",[43,4747,4745],{"__ignoreMap":65},[10,4749,137],{},[14,4751,140],{"id":140},[142,4753,4754,4760],{},[40,4755,4756,4757,4759],{},"遇到 -1 时 ",[43,4758,4657],{}," 立即结束本轮，后面的判断和输出都不执行。",[40,4761,4762,4763,4765],{},"遇到 0 时 ",[43,4764,4661],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4767,172],{"id":172},[37,4769,4770,4775],{},[40,4771,180,4772,4774],{},[43,4773,4657],{}," 当作结束循环，实际它只跳到下一轮。",[40,4776,4777,4778,4780,4781,4783],{},"在 ",[43,4779,4311],{}," 中把状态更新放在可能被 ",[43,4782,4657],{}," 跳过的位置，造成无限循环。",[14,4785,186],{"id":186},[142,4787,4788,4791],{},[40,4789,4790],{},"跳过列表中的空字符串并输出其他内容。",[40,4792,4793],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4795,201],{},[14,4797,204],{"id":204},[10,4799,4800],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,4802,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":4804},[4805,4806,4807,4808,4809,4810,4811,4812],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4634,"description":4639},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[222,4661,4657],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4822,"title":4823,"body":4824,"category":222,"cover":223,"description":4828,"extension":224,"meta":4999,"navigation":226,"path":5000,"pinned":228,"publishedAt":229,"seo":5001,"slug":5002,"stem":5003,"summary":5004,"tags":5005,"updatedAt":229,"visible":226,"__hash__":5008},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4825,"toc":4987},[4826,4829,4831,4834,4836,4842,4845,4847,4871,4873,4875,4909,4911,4917,4919,4921,4938,4940,4943,4949,4952,4954,4968,4970,4978,4980,4982,4985],[10,4827,4828],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4830,16],{"id":16},[10,4832,4833],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4835,22],{"id":22},[10,4837,4838],{},[26,4839],{"alt":4840,"src":4841},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4843,4844],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4846,35],{"id":35},[37,4848,4849,4852,4855],{},[40,4850,4851],{},"每增加一层嵌套，阅读成本都会上升。",[40,4853,4854],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[40,4856,4857,4858,2246,4861,4864,4865,2246,4868,195],{},"变量名使用 ",[43,4859,4860],{},"row",[43,4862,4863],{},"cell"," 等层级含义，避免全部写成 ",[43,4866,4867],{},"i",[43,4869,4870],{},"j",[14,4872,55],{"id":55},[10,4874,1428],{},[60,4876,4878],{"className":405,"code":4877,"language":102,"meta":65,"style":65},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[43,4879,4880,4885,4889,4894,4899,4904],{"__ignoreMap":65},[69,4881,4882],{"class":71,"line":72},[69,4883,4884],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[69,4886,4887],{"class":71,"line":90},[69,4888,1086],{"emptyLinePlaceholder":226},[69,4890,4891],{"class":71,"line":99},[69,4892,4893],{},"for row in table:\n",[69,4895,4896],{"class":71,"line":108},[69,4897,4898],{},"    for cell in row:\n",[69,4900,4901],{"class":71,"line":120},[69,4902,4903],{},"        print(cell)\n",[69,4905,4906],{"class":71,"line":1138},[69,4907,4908],{},"    print(\"一行结束\")\n",[10,4910,126],{},[60,4912,4915],{"className":4913,"code":4914,"language":132,"meta":65},[130],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[43,4916,4914],{"__ignoreMap":65},[10,4918,137],{},[14,4920,140],{"id":140},[142,4922,4923,4935],{},[40,4924,4925,4926,4928,4929,1147,4932,195],{},"外层变量 ",[43,4927,4860],{}," 先引用第一行列表，内层才依次处理 ",[43,4930,4931],{},"A1",[43,4933,4934],{},"A2",[40,4936,4937],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[325,4939,2688],{"id":2688},[10,4941,4942],{},"二维列表的输出顺序可以展开成一条时间线。",[10,4944,4945],{},[26,4946],{"alt":4947,"src":4948},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,4950,4951],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,4953,172],{"id":172},[37,4955,4956,4965],{},[40,4957,4958,4959,997,4962,4964],{},"把两层循环变量都叫 ",[43,4960,4961],{},"item",[43,4963,4867],{},"，难以确认当前层级。",[40,4966,4967],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,4969,186],{"id":186},[142,4971,4972,4975],{},[40,4973,4974],{},"打印一个 2×3 数字表。",[40,4976,4977],{},"在内层增加条件，只输出大于 3 的元素。",[10,4979,201],{},[14,4981,204],{"id":204},[10,4983,4984],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,4986,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":4988},[4989,4990,4991,4992,4993,4996,4997,4998],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":4994},[4995],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4823,"description":4828},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[222,5006,5007],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5010,"title":5011,"body":5012,"category":222,"cover":223,"description":5016,"extension":224,"meta":5154,"navigation":226,"path":5155,"pinned":228,"publishedAt":229,"seo":5156,"slug":5157,"stem":5158,"summary":5159,"tags":5160,"updatedAt":229,"visible":226,"__hash__":5163},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5013,"toc":5144},[5014,5017,5019,5022,5024,5030,5033,5035,5046,5048,5050,5088,5090,5096,5098,5100,5112,5114,5125,5127,5135,5137,5139,5142],[10,5015,5016],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5018,16],{"id":16},[10,5020,5021],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5023,22],{"id":22},[10,5025,5026],{},[26,5027],{"alt":5028,"src":5029},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5031,5032],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5034,35],{"id":35},[37,5036,5037,5040,5043],{},[40,5038,5039],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[40,5041,5042],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[40,5044,5045],{},"推导式创建新列表，不修改输入列表。",[14,5047,55],{"id":55},[10,5049,1428],{},[60,5051,5053],{"className":405,"code":5052,"language":102,"meta":65,"style":65},"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",[43,5054,5055,5060,5064,5069,5074,5078,5083],{"__ignoreMap":65},[69,5056,5057],{"class":71,"line":72},[69,5058,5059],{},"numbers = [1, 2, 3, 4, 5]\n",[69,5061,5062],{"class":71,"line":90},[69,5063,1086],{"emptyLinePlaceholder":226},[69,5065,5066],{"class":71,"line":99},[69,5067,5068],{},"squares = [number * number for number in numbers]\n",[69,5070,5071],{"class":71,"line":108},[69,5072,5073],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[69,5075,5076],{"class":71,"line":120},[69,5077,1086],{"emptyLinePlaceholder":226},[69,5079,5080],{"class":71,"line":1138},[69,5081,5082],{},"print(squares)\n",[69,5084,5085],{"class":71,"line":2478},[69,5086,5087],{},"print(even_squares)\n",[10,5089,126],{},[60,5091,5094],{"className":5092,"code":5093,"language":132,"meta":65},[130],"[1, 4, 9, 16, 25]\n[4, 16]\n",[43,5095,5093],{"__ignoreMap":65},[10,5097,137],{},[14,5099,140],{"id":140},[142,5101,5102,5105],{},[40,5103,5104],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[40,5106,5107,5108,5111],{},"第二条先用 ",[43,5109,5110],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5113,172],{"id":172},[37,5115,5116,5122],{},[40,5117,5118,5119,5121],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[43,5120,4328],{}," 开始找输入。",[40,5123,5124],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5126,186],{"id":186},[142,5128,5129,5132],{},[40,5130,5131],{},"把字符串列表转换为长度列表。",[40,5133,5134],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5136,201],{},[14,5138,204],{"id":204},[10,5140,5141],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,5143,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":5145},[5146,5147,5148,5149,5150,5151,5152,5153],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5011,"description":5016},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[222,5161,5162],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5165,"title":5166,"body":5167,"category":222,"cover":223,"description":5171,"extension":224,"meta":5314,"navigation":226,"path":5315,"pinned":228,"publishedAt":229,"seo":5316,"slug":5317,"stem":5318,"summary":5319,"tags":5320,"updatedAt":229,"visible":226,"__hash__":5323},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5168,"toc":5304},[5169,5172,5174,5177,5179,5185,5188,5190,5201,5203,5205,5244,5246,5252,5254,5256,5271,5273,5281,5283,5295,5297,5299,5302],[10,5170,5171],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5173,16],{"id":16},[10,5175,5176],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5178,22],{"id":22},[10,5180,5181],{},[26,5182],{"alt":5183,"src":5184},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5186,5187],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5189,35],{"id":35},[37,5191,5192,5195,5198],{},[40,5193,5194],{},"函数名描述动作，使用小写字母和下划线。",[40,5196,5197],{},"函数定义要先执行，之后才能调用。",[40,5199,5200],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5202,55],{"id":55},[10,5204,1428],{},[60,5206,5208],{"className":405,"code":5207,"language":102,"meta":65,"style":65},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[43,5209,5210,5215,5220,5225,5229,5234,5239],{"__ignoreMap":65},[69,5211,5212],{"class":71,"line":72},[69,5213,5214],{},"def show_progress():\n",[69,5216,5217],{"class":71,"line":90},[69,5218,5219],{},"    print(\"正在学习函数\")\n",[69,5221,5222],{"class":71,"line":99},[69,5223,5224],{},"    print(\"本节完成 50%\")\n",[69,5226,5227],{"class":71,"line":108},[69,5228,1086],{"emptyLinePlaceholder":226},[69,5230,5231],{"class":71,"line":120},[69,5232,5233],{},"print(\"调用前\")\n",[69,5235,5236],{"class":71,"line":1138},[69,5237,5238],{},"show_progress()\n",[69,5240,5241],{"class":71,"line":2478},[69,5242,5243],{},"print(\"调用后\")\n",[10,5245,126],{},[60,5247,5250],{"className":5248,"code":5249,"language":132,"meta":65},[130],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[43,5251,5249],{"__ignoreMap":65},[10,5253,137],{},[14,5255,140],{"id":140},[142,5257,5258,5264],{},[40,5259,926,5260,5263],{},[43,5261,5262],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[40,5265,5266,5267,5270],{},"运行到 ",[43,5268,5269],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5272,172],{"id":172},[37,5274,5275,5278],{},[40,5276,5277],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[40,5279,5280],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5282,186],{"id":186},[142,5284,5285,5292],{},[40,5286,5287,5288,5291],{},"定义 ",[43,5289,5290],{},"show_plan()"," 输出两行学习计划。",[40,5293,5294],{},"连续调用同一个函数两次，观察执行顺序。",[10,5296,201],{},[14,5298,204],{"id":204},[10,5300,5301],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,5303,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":5305},[5306,5307,5308,5309,5310,5311,5312,5313],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5166,"description":5171},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[222,5321,5322],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5325,"title":5326,"body":5327,"category":222,"cover":223,"description":5331,"extension":224,"meta":5511,"navigation":226,"path":5512,"pinned":228,"publishedAt":229,"seo":5513,"slug":5514,"stem":5515,"summary":5516,"tags":5517,"updatedAt":229,"visible":226,"__hash__":5520},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5328,"toc":5499},[5329,5332,5334,5337,5339,5345,5352,5354,5371,5373,5375,5409,5411,5417,5419,5421,5442,5444,5447,5453,5463,5465,5480,5482,5490,5492,5494,5497],[10,5330,5331],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5333,16],{"id":16},[10,5335,5336],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5338,22],{"id":22},[10,5340,5341],{},[26,5342],{"alt":5343,"src":5344},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5346,5347,5348,5351],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[43,5349,5350],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5353,35],{"id":35},[37,5355,5356,5359,5362],{},[40,5357,5358],{},"形参出现在函数定义中，实参出现在函数调用中。",[40,5360,5361],{},"局部变量默认只在函数内部可见。",[40,5363,5364,5365,5367,5368,195],{},"没有显式 ",[43,5366,5350],{}," 的函数会返回 ",[43,5369,5370],{},"None",[14,5372,55],{"id":55},[10,5374,1428],{},[60,5376,5378],{"className":405,"code":5377,"language":102,"meta":65,"style":65},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[43,5379,5380,5385,5390,5395,5399,5404],{"__ignoreMap":65},[69,5381,5382],{"class":71,"line":72},[69,5383,5384],{},"def calculate_total(price, count):\n",[69,5386,5387],{"class":71,"line":90},[69,5388,5389],{},"    total = price * count\n",[69,5391,5392],{"class":71,"line":99},[69,5393,5394],{},"    return total\n",[69,5396,5397],{"class":71,"line":108},[69,5398,1086],{"emptyLinePlaceholder":226},[69,5400,5401],{"class":71,"line":120},[69,5402,5403],{},"result = calculate_total(25, 4)\n",[69,5405,5406],{"class":71,"line":1138},[69,5407,5408],{},"print(result)\n",[10,5410,126],{},[60,5412,5415],{"className":5413,"code":5414,"language":132,"meta":65},[130],"100\n",[43,5416,5414],{"__ignoreMap":65},[10,5418,137],{},[14,5420,140],{"id":140},[142,5422,5423,5432],{},[40,5424,5425,5426,2246,5429,5431],{},"调用时 25 和 4 分别绑定到 ",[43,5427,5428],{},"price",[43,5430,4391],{},"，它们只在本次函数调用的局部范围中使用。",[40,5433,5434,5437,5438,5441],{},[43,5435,5436],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[43,5439,5440],{},"result"," 并输出。",[325,5443,2688],{"id":2688},[10,5445,5446],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5448,5449],{},[26,5450],{"alt":5451,"src":5452},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5454,5455,2246,5457,1147,5459,5462],{},[43,5456,5428],{},[43,5458,4391],{},[43,5460,5461],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5464,172],{"id":172},[37,5466,5467,5474],{},[40,5468,5469,5470,5473],{},"在函数内部只 ",[43,5471,5472],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[40,5475,5476,5477,5479],{},"试图在函数外直接访问局部变量 ",[43,5478,5461],{},"，它的名字只在调用期间的局部作用域存在。",[14,5481,186],{"id":186},[142,5483,5484,5487],{},[40,5485,5486],{},"编写计算长方形面积的函数。",[40,5488,5489],{},"让函数返回结果后在调用方加上单位再输出。",[10,5491,201],{},[14,5493,204],{"id":204},[10,5495,5496],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,5498,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":5500},[5501,5502,5503,5504,5505,5508,5509,5510],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":5506},[5507],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5326,"description":5331},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[222,5518,5519],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5522,"title":5523,"body":5524,"category":222,"cover":223,"description":5528,"extension":224,"meta":5708,"navigation":226,"path":5709,"pinned":228,"publishedAt":229,"seo":5710,"slug":5711,"stem":5712,"summary":5713,"tags":5714,"updatedAt":229,"visible":226,"__hash__":5717},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5525,"toc":5696},[5526,5529,5531,5534,5536,5542,5545,5547,5564,5566,5568,5620,5622,5628,5630,5632,5650,5652,5655,5661,5664,5666,5677,5679,5687,5689,5691,5694],[10,5527,5528],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5530,16],{"id":16},[10,5532,5533],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5535,22],{"id":22},[10,5537,5538],{},[26,5539],{"alt":5540,"src":5541},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5543,5544],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5546,35],{"id":35},[37,5548,5549,5552,5558],{},[40,5550,5551],{},"必需参数应放在有默认值的参数之前。",[40,5553,5554,5557],{},[43,5555,5556],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[40,5559,5560,5563],{},[43,5561,5562],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5565,55],{"id":55},[10,5567,1428],{},[60,5569,5571],{"className":405,"code":5570,"language":102,"meta":65,"style":65},"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",[43,5572,5573,5578,5583,5587,5592,5597,5601,5606,5611,5615],{"__ignoreMap":65},[69,5574,5575],{"class":71,"line":72},[69,5576,5577],{},"def build_title(name, level=\"基础\"):\n",[69,5579,5580],{"class":71,"line":90},[69,5581,5582],{},"    return name + \"｜\" + level\n",[69,5584,5585],{"class":71,"line":99},[69,5586,1086],{"emptyLinePlaceholder":226},[69,5588,5589],{"class":71,"line":108},[69,5590,5591],{},"print(build_title(\"Python\"))\n",[69,5593,5594],{"class":71,"line":120},[69,5595,5596],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[69,5598,5599],{"class":71,"line":1138},[69,5600,1086],{"emptyLinePlaceholder":226},[69,5602,5603],{"class":71,"line":2478},[69,5604,5605],{},"def total(*numbers):\n",[69,5607,5608],{"class":71,"line":2484},[69,5609,5610],{},"    return sum(numbers)\n",[69,5612,5613],{"class":71,"line":3942},[69,5614,1086],{"emptyLinePlaceholder":226},[69,5616,5617],{"class":71,"line":4154},[69,5618,5619],{},"print(total(10, 20, 30))\n",[10,5621,126],{},[60,5623,5626],{"className":5624,"code":5625,"language":132,"meta":65},[130],"Python｜基础\n异常处理｜进阶\n60\n",[43,5627,5625],{"__ignoreMap":65},[10,5629,137],{},[14,5631,140],{"id":140},[142,5633,5634,5641],{},[40,5635,5636,5637,5640],{},"第一次调用只提供必需参数，",[43,5638,5639],{},"level"," 使用默认值；第二次按参数名绑定两个实参。",[40,5642,5643,5646,5647,195],{},[43,5644,5645],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[43,5648,5649],{},"sum()",[325,5651,2688],{"id":2688},[10,5653,5654],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5656,5657],{},[26,5658],{"alt":5659,"src":5660},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5662,5663],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5665,172],{"id":172},[37,5667,5668,5674],{},[40,5669,5670,5671,5673],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[43,5672,5370],{}," 再在函数内创建。",[40,5675,5676],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5678,186],{"id":186},[142,5680,5681,5684],{},[40,5682,5683],{},"给问候函数增加默认称呼。",[40,5685,5686],{},"编写接收任意数量分数并返回总分的函数。",[10,5688,201],{},[14,5690,204],{"id":204},[10,5692,5693],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,5695,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":5697},[5698,5699,5700,5701,5702,5705,5706,5707],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":5703},[5704],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5523,"description":5528},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[222,5715,5716],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":5719,"title":5720,"body":5721,"category":222,"cover":223,"description":5725,"extension":224,"meta":5922,"navigation":226,"path":5923,"pinned":228,"publishedAt":229,"seo":5924,"slug":5925,"stem":5926,"summary":5927,"tags":5928,"updatedAt":229,"visible":226,"__hash__":5931},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":5722,"toc":5910},[5723,5726,5728,5731,5733,5739,5742,5744,5761,5763,5765,5828,5830,5836,5838,5840,5867,5869,5872,5878,5881,5883,5891,5893,5901,5903,5905,5908],[10,5724,5725],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,5727,16],{"id":16},[10,5729,5730],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5732,22],{"id":22},[10,5734,5735],{},[26,5736],{"alt":5737,"src":5738},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,5740,5741],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,5743,35],{"id":35},[37,5745,5746,5749,5752],{},[40,5747,5748],{},"函数内部赋值默认创建局部变量。",[40,5750,5751],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[40,5753,5754,158,5757,5760],{},[43,5755,5756],{},"global",[43,5758,5759],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,5762,55],{"id":55},[10,5764,1428],{},[60,5766,5768],{"className":405,"code":5767,"language":102,"meta":65,"style":65},"course = \"Python\"\n\ndef outer():\n    level = \"基础\"\n\n    def show():\n        lesson = \"作用域\"\n        print(course, level, lesson)\n\n    show()\n\nouter()\n",[43,5769,5770,5775,5779,5784,5789,5793,5798,5803,5808,5812,5817,5822],{"__ignoreMap":65},[69,5771,5772],{"class":71,"line":72},[69,5773,5774],{},"course = \"Python\"\n",[69,5776,5777],{"class":71,"line":90},[69,5778,1086],{"emptyLinePlaceholder":226},[69,5780,5781],{"class":71,"line":99},[69,5782,5783],{},"def outer():\n",[69,5785,5786],{"class":71,"line":108},[69,5787,5788],{},"    level = \"基础\"\n",[69,5790,5791],{"class":71,"line":120},[69,5792,1086],{"emptyLinePlaceholder":226},[69,5794,5795],{"class":71,"line":1138},[69,5796,5797],{},"    def show():\n",[69,5799,5800],{"class":71,"line":2478},[69,5801,5802],{},"        lesson = \"作用域\"\n",[69,5804,5805],{"class":71,"line":2484},[69,5806,5807],{},"        print(course, level, lesson)\n",[69,5809,5810],{"class":71,"line":3942},[69,5811,1086],{"emptyLinePlaceholder":226},[69,5813,5814],{"class":71,"line":4154},[69,5815,5816],{},"    show()\n",[69,5818,5820],{"class":71,"line":5819},11,[69,5821,1086],{"emptyLinePlaceholder":226},[69,5823,5825],{"class":71,"line":5824},12,[69,5826,5827],{},"outer()\n",[10,5829,126],{},[60,5831,5834],{"className":5832,"code":5833,"language":132,"meta":65},[130],"Python 基础 作用域\n",[43,5835,5833],{"__ignoreMap":65},[10,5837,137],{},[14,5839,140],{"id":140},[142,5841,5842,5859],{},[40,5843,5844,5847,5848,5851,5852,5854,5855,5858],{},[43,5845,5846],{},"show()"," 中查找 ",[43,5849,5850],{},"lesson"," 时先在局部找到，查找 ",[43,5853,5639],{}," 时到外层 ",[43,5856,5857],{},"outer()"," 找到。",[40,5860,5861,5863,5864,5866],{},[43,5862,4574],{}," 在局部和外层都不存在，继续到模块全局找到；",[43,5865,2197],{}," 最后在内置作用域找到。",[325,5868,2688],{"id":2688},[10,5870,5871],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,5873,5874],{},[26,5875],{"alt":5876,"src":5877},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,5879,5880],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,5882,172],{"id":172},[37,5884,5885,5888],{},[40,5886,5887],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[40,5889,5890],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,5892,186],{"id":186},[142,5894,5895,5898],{},[40,5896,5897],{},"在内外层定义同名变量，观察最近作用域优先。",[40,5899,5900],{},"尝试在函数外访问局部变量，记录异常类型。",[10,5902,201],{},[14,5904,204],{"id":204},[10,5906,5907],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,5909,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":5911},[5912,5913,5914,5915,5916,5919,5920,5921],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":5917},[5918],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",{"title":5720,"description":5725},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[222,5929,5930],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",{"id":5933,"title":5934,"body":5935,"category":222,"cover":223,"description":5939,"extension":224,"meta":6089,"navigation":226,"path":6090,"pinned":228,"publishedAt":229,"seo":6091,"slug":6092,"stem":6093,"summary":6094,"tags":6095,"updatedAt":229,"visible":226,"__hash__":6098},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5936,"toc":6079},[5937,5940,5942,5945,5947,5953,5956,5958,5977,5979,5981,6015,6017,6023,6025,6027,6042,6044,6056,6058,6070,6072,6074,6077],[10,5938,5939],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,5941,16],{"id":16},[10,5943,5944],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5946,22],{"id":22},[10,5948,5949],{},[26,5950],{"alt":5951,"src":5952},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,5954,5955],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,5957,35],{"id":35},[37,5959,5960,5963,5966],{},[40,5961,5962],{},"文档字符串紧跟在函数定义后的第一条语句。",[40,5964,5965],{},"注解表达接口意图，不代替输入校验和测试。",[40,5967,5968,5969,2246,5971,2246,5973,5976],{},"基础注解优先使用 ",[43,5970,2249],{},[43,5972,2415],{},[43,5974,5975],{},"list[str]"," 等直接写法。",[14,5978,55],{"id":55},[10,5980,1428],{},[60,5982,5984],{"className":405,"code":5983,"language":102,"meta":65,"style":65},"def format_score(name: str, score: int) -> str:\n    \"\"\"返回带姓名的分数文本。\"\"\"\n    return name + \"：\" + str(score)\n\nprint(format_score(\"小郑\", 95))\nprint(format_score.__doc__)\n",[43,5985,5986,5991,5996,6001,6005,6010],{"__ignoreMap":65},[69,5987,5988],{"class":71,"line":72},[69,5989,5990],{},"def format_score(name: str, score: int) -> str:\n",[69,5992,5993],{"class":71,"line":90},[69,5994,5995],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[69,5997,5998],{"class":71,"line":99},[69,5999,6000],{},"    return name + \"：\" + str(score)\n",[69,6002,6003],{"class":71,"line":108},[69,6004,1086],{"emptyLinePlaceholder":226},[69,6006,6007],{"class":71,"line":120},[69,6008,6009],{},"print(format_score(\"小郑\", 95))\n",[69,6011,6012],{"class":71,"line":1138},[69,6013,6014],{},"print(format_score.__doc__)\n",[10,6016,126],{},[60,6018,6021],{"className":6019,"code":6020,"language":132,"meta":65},[130],"小郑：95\n返回带姓名的分数文本。\n",[43,6022,6020],{"__ignoreMap":65},[10,6024,137],{},[14,6026,140],{"id":140},[142,6028,6029,6039],{},[40,6030,6031,6032,6035,6036,6038],{},"函数签名说明 ",[43,6033,6034],{},"name"," 预期为字符串、",[43,6037,2235],{}," 预期为整数，返回值预期为字符串。",[40,6040,6041],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6043,172],{"id":172},[37,6045,6046,6053],{},[40,6047,6048,6049,6052],{},"认为加了 ",[43,6050,6051],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[40,6054,6055],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6057,186],{"id":186},[142,6059,6060,6063],{},[40,6061,6062],{},"为面积函数补充参数和返回值注解。",[40,6064,6065,6066,6069],{},"通过 ",[43,6067,6068],{},"函数名.__doc__"," 查看文档字符串。",[10,6071,201],{},[14,6073,204],{"id":204},[10,6075,6076],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,6078,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":6080},[6081,6082,6083,6084,6085,6086,6087,6088],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5934,"description":5939},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[222,6096,6097],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6100,"title":6101,"body":6102,"category":222,"cover":223,"description":6106,"extension":224,"meta":6333,"navigation":226,"path":6334,"pinned":228,"publishedAt":229,"seo":6335,"slug":6336,"stem":6337,"summary":6338,"tags":6339,"updatedAt":229,"visible":226,"__hash__":6342},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6103,"toc":6321},[6104,6107,6109,6115,6117,6123,6134,6136,6154,6156,6163,6192,6199,6218,6227,6229,6235,6237,6239,6262,6264,6267,6273,6279,6281,6297,6299,6312,6314,6316,6319],[10,6105,6106],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6108,16],{"id":16},[10,6110,6111,6112,6114],{},"本篇只处理“模块、import 与 ",[291,6113,6034],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6116,22],{"id":22},[10,6118,6119],{},[26,6120],{"alt":6121,"src":6122},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6124,6125,6126,6129,6130,6133],{},"同一个文件直接运行时 ",[43,6127,6128],{},"__name__"," 等于 ",[43,6131,6132],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6135,35],{"id":35},[37,6137,6138,6144,6147],{},[40,6139,6140,6141,6143],{},"一个 ",[43,6142,1161],{}," 文件就是一个模块。",[40,6145,6146],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[40,6148,6149,6150,6153],{},"避免使用 ",[43,6151,6152],{},"from module import *","，它会让名字来源不清楚。",[14,6155,55],{"id":55},[10,6157,6158,6159,6162],{},"先在同一个目录中创建两个文件。把函数放进 ",[43,6160,6161],{},"calculator.py","：",[60,6164,6166],{"className":405,"code":6165,"language":102,"meta":65,"style":65},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[43,6167,6168,6173,6178,6182,6187],{"__ignoreMap":65},[69,6169,6170],{"class":71,"line":72},[69,6171,6172],{},"def add(left, right):\n",[69,6174,6175],{"class":71,"line":90},[69,6176,6177],{},"    return left + right\n",[69,6179,6180],{"class":71,"line":99},[69,6181,1086],{"emptyLinePlaceholder":226},[69,6183,6184],{"class":71,"line":108},[69,6185,6186],{},"if __name__ == \"__main__\":\n",[69,6188,6189],{"class":71,"line":120},[69,6190,6191],{},"    print(add(2, 3))\n",[10,6193,6194,6195,6198],{},"再创建 ",[43,6196,6197],{},"app.py","，从模块中导入函数：",[60,6200,6202],{"className":405,"code":6201,"language":102,"meta":65,"style":65},"from calculator import add\n\nprint(add(10, 20))\n",[43,6203,6204,6209,6213],{"__ignoreMap":65},[69,6205,6206],{"class":71,"line":72},[69,6207,6208],{},"from calculator import add\n",[69,6210,6211],{"class":71,"line":90},[69,6212,1086],{"emptyLinePlaceholder":226},[69,6214,6215],{"class":71,"line":99},[69,6216,6217],{},"print(add(10, 20))\n",[10,6219,6220,6221,1147,6224,195],{},"分别执行 ",[43,6222,6223],{},"python3 calculator.py",[43,6225,6226],{},"python3 app.py",[10,6228,126],{},[60,6230,6233],{"className":6231,"code":6232,"language":132,"meta":65},[130],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[43,6234,6232],{"__ignoreMap":65},[10,6236,137],{},[14,6238,140],{"id":140},[142,6240,6241,6251],{},[40,6242,6243,6244,6246,6247,6250],{},"直接运行 ",[43,6245,6161],{}," 时，模块名是 ",[43,6248,6249],{},"__main__","，入口代码输出 5。",[40,6252,6253,6255,6256,6258,6259,6261],{},[43,6254,6197],{}," 导入模块时，",[43,6257,6161],{}," 的函数定义会执行，但入口判断为假；随后 ",[43,6260,6197],{}," 调用函数输出 30。",[325,6263,2688],{"id":2688},[10,6265,6266],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6268,6269],{},[26,6270],{"alt":6271,"src":6272},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6274,6275,6276,6278],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[43,6277,6249],{}," 保护下的演示代码。",[14,6280,172],{"id":172},[37,6282,6283,6290],{},[40,6284,6285,6286,1147,6288,195],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[43,6287,6161],{},[43,6289,6197],{},[40,6291,6292,6293,6296],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[43,6294,6295],{},"json.py","，导致导入目标被遮蔽。",[14,6298,186],{"id":186},[142,6300,6301,6307],{},[40,6302,2343,6303,6306],{},[43,6304,6305],{},"text_tools.py"," 并导出一个格式化函数。",[40,6308,6309,6310,195],{},"分别直接运行模块和从另一个脚本导入，输出 ",[43,6311,6128],{},[10,6313,201],{},[14,6315,204],{"id":204},[10,6317,6318],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,6320,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":6322},[6323,6324,6325,6326,6327,6330,6331,6332],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":6328},[6329],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6101,"description":6106},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[222,6340,6341],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":4,"title":5,"body":6344,"category":222,"cover":223,"description":12,"extension":224,"meta":6483,"navigation":226,"path":227,"pinned":228,"publishedAt":229,"seo":6484,"slug":231,"stem":232,"summary":233,"tags":6485,"updatedAt":229,"visible":226,"__hash__":237},{"type":7,"value":6345,"toc":6473},[6346,6348,6350,6352,6354,6358,6360,6362,6372,6374,6376,6416,6418,6423,6425,6427,6445,6447,6455,6457,6465,6467,6469,6471],[10,6347,12],{},[14,6349,16],{"id":16},[10,6351,19],{},[14,6353,22],{"id":22},[10,6355,6356],{},[26,6357],{"alt":28,"src":29},[10,6359,32],{},[14,6361,35],{"id":35},[37,6363,6364,6368,6370],{},[40,6365,6366,46],{},[43,6367,45],{},[40,6369,49],{},[40,6371,52],{},[14,6373,55],{"id":55},[10,6375,58],{},[60,6377,6378],{"className":62,"code":63,"language":64,"meta":65,"style":65},[43,6379,6380,6390,6396,6402,6412],{"__ignoreMap":65},[69,6381,6382,6384,6386,6388],{"class":71,"line":72},[69,6383,76],{"class":75},[69,6385,80],{"class":79},[69,6387,84],{"class":83},[69,6389,87],{"class":83},[69,6391,6392,6394],{"class":71,"line":90},[69,6393,93],{"class":79},[69,6395,96],{"class":83},[69,6397,6398,6400],{"class":71,"line":99},[69,6399,102],{"class":75},[69,6401,105],{"class":79},[69,6403,6404,6406,6408,6410],{"class":71,"line":108},[69,6405,102],{"class":75},[69,6407,80],{"class":79},[69,6409,115],{"class":83},[69,6411,105],{"class":79},[69,6413,6414],{"class":71,"line":120},[69,6415,123],{"class":75},[10,6417,126],{},[60,6419,6421],{"className":6420,"code":131,"language":132,"meta":65},[130],[43,6422,131],{"__ignoreMap":65},[10,6424,137],{},[14,6426,140],{"id":140},[142,6428,6429,6435],{},[40,6430,6431,149,6433,152],{},[43,6432,148],{},[43,6434,76],{},[40,6436,155,6437,158,6439,162,6441,165,6443,169],{},[43,6438,102],{},[43,6440,161],{},[43,6442,45],{},[43,6444,168],{},[14,6446,172],{"id":172},[37,6448,6449,6451],{},[40,6450,177],{},[40,6452,180,6453,183],{},[43,6454,45],{},[14,6456,186],{"id":186},[142,6458,6459,6463],{},[40,6460,191,6461,195],{},[43,6462,194],{},[40,6464,198],{},[10,6466,201],{},[14,6468,204],{"id":204},[10,6470,207],{},[209,6472,211],{},{"title":65,"searchDepth":90,"depth":90,"links":6474},[6475,6476,6477,6478,6479,6480,6481,6482],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5,"description":12},[222,235,236],{"id":6487,"title":6488,"body":6489,"category":222,"cover":223,"description":6493,"extension":224,"meta":6681,"navigation":226,"path":6682,"pinned":228,"publishedAt":229,"seo":6683,"slug":6684,"stem":6685,"summary":6686,"tags":6687,"updatedAt":229,"visible":226,"__hash__":6690},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6490,"toc":6671},[6491,6494,6496,6499,6501,6507,6516,6518,6542,6544,6546,6599,6601,6607,6609,6611,6627,6629,6648,6650,6662,6664,6666,6669],[10,6492,6493],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6495,16],{"id":16},[10,6497,6498],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6500,22],{"id":22},[10,6502,6503],{},[26,6504],{"alt":6505,"src":6506},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6508,6509,6512,6513,6515],{},[43,6510,6511],{},"Path"," 使用 ",[43,6514,2425],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6517,35],{"id":35},[37,6519,6520,6523,6535],{},[40,6521,6522],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[40,6524,6525,2246,6528,2246,6531,6534],{},[43,6526,6527],{},"exists()",[43,6529,6530],{},"is_file()",[43,6532,6533],{},"is_dir()"," 检查真实文件系统状态。",[40,6536,6537,6538,6541],{},"创建目录前明确目标；",[43,6539,6540],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6543,55],{"id":55},[10,6545,1428],{},[60,6547,6549],{"className":405,"code":6548,"language":102,"meta":65,"style":65},"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",[43,6550,6551,6556,6560,6565,6570,6575,6579,6584,6589,6594],{"__ignoreMap":65},[69,6552,6553],{"class":71,"line":72},[69,6554,6555],{},"from pathlib import Path\n",[69,6557,6558],{"class":71,"line":90},[69,6559,1086],{"emptyLinePlaceholder":226},[69,6561,6562],{"class":71,"line":99},[69,6563,6564],{},"project = Path.cwd()\n",[69,6566,6567],{"class":71,"line":108},[69,6568,6569],{},"data_dir = project \u002F \"data\"\n",[69,6571,6572],{"class":71,"line":120},[69,6573,6574],{},"file_path = data_dir \u002F \"records.json\"\n",[69,6576,6577],{"class":71,"line":1138},[69,6578,1086],{"emptyLinePlaceholder":226},[69,6580,6581],{"class":71,"line":2478},[69,6582,6583],{},"print(project)\n",[69,6585,6586],{"class":71,"line":2484},[69,6587,6588],{},"print(file_path.name)\n",[69,6590,6591],{"class":71,"line":3942},[69,6592,6593],{},"print(file_path.suffix)\n",[69,6595,6596],{"class":71,"line":4154},[69,6597,6598],{},"print(file_path.exists())\n",[10,6600,126],{},[60,6602,6605],{"className":6603,"code":6604,"language":132,"meta":65},[130],"显示当前项目路径、records.json、.json 和存在状态\n",[43,6606,6604],{"__ignoreMap":65},[10,6608,137],{},[14,6610,140],{"id":140},[142,6612,6613,6619],{},[40,6614,6615,6618],{},[43,6616,6617],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[40,6620,2328,6621,6623,6624,6626],{},[43,6622,2425],{}," 组合路径片段只创建新的 ",[43,6625,6511],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6628,172],{"id":172},[37,6630,6631,6639],{},[40,6632,180,6633,6635,6636,6638],{},[43,6634,6511],{}," 对象存在当成真实文件存在，仍需调用 ",[43,6637,6527],{}," 等方法确认。",[40,6640,6641,6642,997,6644,6647],{},"手工拼接 ",[43,6643,2425],{},[43,6645,6646],{},"\\"," 分隔符，降低跨平台可读性。",[14,6649,186],{"id":186},[142,6651,6652,6659],{},[40,6653,6654,6655,6658],{},"组合 ",[43,6656,6657],{},"output\u002Freport.txt"," 路径但先不创建文件。",[40,6660,6661],{},"输出路径的父目录、文件名和扩展名。",[10,6663,201],{},[14,6665,204],{"id":204},[10,6667,6668],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,6670,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":6672},[6673,6674,6675,6676,6677,6678,6679,6680],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6488,"description":6493},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[222,6688,6689],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6692,"title":6693,"body":6694,"category":222,"cover":223,"description":6698,"extension":224,"meta":6876,"navigation":226,"path":6877,"pinned":228,"publishedAt":229,"seo":6878,"slug":6879,"stem":6880,"summary":6881,"tags":6882,"updatedAt":229,"visible":226,"__hash__":6885},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6695,"toc":6866},[6696,6699,6701,6704,6706,6712,6715,6717,6745,6747,6749,6806,6808,6814,6816,6818,6829,6831,6844,6846,6857,6859,6861,6864],[10,6697,6698],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6700,16],{"id":16},[10,6702,6703],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6705,22],{"id":22},[10,6707,6708],{},[26,6709],{"alt":6710,"src":6711},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6713,6714],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6716,35],{"id":35},[37,6718,6719,6725,6734],{},[40,6720,6721,6724],{},[43,6722,6723],{},"w"," 模式会截断原文件，写入前必须确认目标。",[40,6726,6727,6730,6731,195],{},[43,6728,6729],{},"r"," 模式读取不存在文件会产生 ",[43,6732,6733],{},"FileNotFoundError",[40,6735,6736,6737,6740,6741,6744],{},"本篇显式调用 ",[43,6738,6739],{},"close()","；第 34 篇会用 ",[43,6742,6743],{},"with"," 更可靠地管理关闭动作。",[14,6746,55],{"id":55},[10,6748,1428],{},[60,6750,6752],{"className":405,"code":6751,"language":102,"meta":65,"style":65},"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",[43,6753,6754,6758,6762,6767,6772,6777,6782,6786,6791,6796,6801],{"__ignoreMap":65},[69,6755,6756],{"class":71,"line":72},[69,6757,6555],{},[69,6759,6760],{"class":71,"line":90},[69,6761,1086],{"emptyLinePlaceholder":226},[69,6763,6764],{"class":71,"line":99},[69,6765,6766],{},"file_path = Path(\"notes.txt\")\n",[69,6768,6769],{"class":71,"line":108},[69,6770,6771],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[69,6773,6774],{"class":71,"line":120},[69,6775,6776],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[69,6778,6779],{"class":71,"line":1138},[69,6780,6781],{},"writer.close()\n",[69,6783,6784],{"class":71,"line":2478},[69,6785,1086],{"emptyLinePlaceholder":226},[69,6787,6788],{"class":71,"line":2484},[69,6789,6790],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[69,6792,6793],{"class":71,"line":3942},[69,6794,6795],{},"content = reader.read()\n",[69,6797,6798],{"class":71,"line":4154},[69,6799,6800],{},"reader.close()\n",[69,6802,6803],{"class":71,"line":5819},[69,6804,6805],{},"print(content)\n",[10,6807,126],{},[60,6809,6812],{"className":6810,"code":6811,"language":132,"meta":65},[130],"变量\n循环\n函数\n",[43,6813,6811],{"__ignoreMap":65},[10,6815,137],{},[14,6817,140],{"id":140},[142,6819,6820,6826],{},[40,6821,6822,6823,6825],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[43,6824,6739],{}," 确保缓冲内容交给文件系统。",[40,6827,6828],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6830,172],{"id":172},[37,6832,6833,6838],{},[40,6834,2328,6835,6837],{},[43,6836,6723],{}," 模式打开重要文件却未确认覆盖风险。",[40,6839,6840,6841,195],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[43,6842,6843],{},"encoding=\"utf-8\"",[14,6845,186],{"id":186},[142,6847,6848,6851],{},[40,6849,6850],{},"写入三行学习记录并读取。",[40,6852,6853,6854,6856],{},"改用 ",[43,6855,333],{}," 模式追加一行，确认原内容仍保留。",[10,6858,201],{},[14,6860,204],{"id":204},[10,6862,6863],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,6865,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":6867},[6868,6869,6870,6871,6872,6873,6874,6875],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6693,"description":6698},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[222,6883,6884],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6887,"title":6888,"body":6889,"category":222,"cover":223,"description":6893,"extension":224,"meta":7060,"navigation":226,"path":7061,"pinned":228,"publishedAt":229,"seo":7062,"slug":7063,"stem":7064,"summary":7065,"tags":7066,"updatedAt":229,"visible":226,"__hash__":7069},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6890,"toc":7050},[6891,6894,6896,6899,6901,6907,6917,6919,6933,6935,6937,6997,6999,7005,7007,7009,7021,7023,7031,7033,7041,7043,7045,7048],[10,6892,6893],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6895,16],{"id":16},[10,6897,6898],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6900,22],{"id":22},[10,6902,6903],{},[26,6904],{"alt":6905,"src":6906},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,6908,6909,6912,6913,6916],{},[43,6910,6911],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[43,6914,6915],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,6918,35],{"id":35},[37,6920,6921,6924,6930],{},[40,6922,6923],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[40,6925,6926,6929],{},[43,6927,6928],{},"ensure_ascii=False"," 让中文以可读字符写入。",[40,6931,6932],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,6934,55],{"id":55},[10,6936,1428],{},[60,6938,6940],{"className":405,"code":6939,"language":102,"meta":65,"style":65},"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",[43,6941,6942,6947,6951,6956,6960,6965,6970,6974,6978,6983,6988,6992],{"__ignoreMap":65},[69,6943,6944],{"class":71,"line":72},[69,6945,6946],{},"import json\n",[69,6948,6949],{"class":71,"line":90},[69,6950,1086],{"emptyLinePlaceholder":226},[69,6952,6953],{"class":71,"line":99},[69,6954,6955],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[69,6957,6958],{"class":71,"line":108},[69,6959,1086],{"emptyLinePlaceholder":226},[69,6961,6962],{"class":71,"line":120},[69,6963,6964],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[69,6966,6967],{"class":71,"line":1138},[69,6968,6969],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[69,6971,6972],{"class":71,"line":2478},[69,6973,6781],{},[69,6975,6976],{"class":71,"line":2484},[69,6977,1086],{"emptyLinePlaceholder":226},[69,6979,6980],{"class":71,"line":3942},[69,6981,6982],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[69,6984,6985],{"class":71,"line":4154},[69,6986,6987],{},"loaded = json.load(reader)\n",[69,6989,6990],{"class":71,"line":5819},[69,6991,6800],{},[69,6993,6994],{"class":71,"line":5824},[69,6995,6996],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,6998,126],{},[60,7000,7003],{"className":7001,"code":7002,"language":132,"meta":65},[130],"Python 60\n",[43,7004,7002],{"__ignoreMap":65},[10,7006,137],{},[14,7008,140],{"id":140},[142,7010,7011,7016],{},[40,7012,7013,7015],{},[43,7014,6911],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[40,7017,7018,7020],{},[43,7019,6915],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7022,172],{"id":172},[37,7024,7025,7028],{},[40,7026,7027],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[40,7029,7030],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7032,186],{"id":186},[142,7034,7035,7038],{},[40,7036,7037],{},"保存包含两条学习记录的列表。",[40,7039,7040],{},"读取后修改进度，再重新写回文件。",[10,7042,201],{},[14,7044,204],{"id":204},[10,7046,7047],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,7049,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":7051},[7052,7053,7054,7055,7056,7057,7058,7059],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6888,"description":6893},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[222,7067,7068],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7071,"title":7072,"body":7073,"category":222,"cover":223,"description":7077,"extension":224,"meta":7261,"navigation":226,"path":7262,"pinned":228,"publishedAt":229,"seo":7263,"slug":7264,"stem":7265,"summary":7266,"tags":7267,"updatedAt":229,"visible":226,"__hash__":7270},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7074,"toc":7251},[7075,7078,7080,7083,7085,7091,7097,7099,7121,7123,7125,7188,7190,7196,7198,7200,7216,7218,7232,7234,7242,7244,7246,7249],[10,7076,7077],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7079,16],{"id":16},[10,7081,7082],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7084,22],{"id":22},[10,7086,7087],{},[26,7088],{"alt":7089,"src":7090},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7092,7093,7096],{},[43,7094,7095],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7098,35],{"id":35},[37,7100,7101,7111,7118],{},[40,7102,2328,7103,7106,7107,7110],{},[43,7104,7105],{},"newline=\"\""," 让 ",[43,7108,7109],{},"csv"," 模块正确处理换行。",[40,7112,7113,7114,7117],{},"字段顺序由 ",[43,7115,7116],{},"fieldnames"," 决定，字典键需要与字段名一致。",[40,7119,7120],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7122,55],{"id":55},[10,7124,1428],{},[60,7126,7128],{"className":405,"code":7127,"language":102,"meta":65,"style":65},"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",[43,7129,7130,7135,7139,7144,7149,7154,7159,7164,7168,7173,7178,7183],{"__ignoreMap":65},[69,7131,7132],{"class":71,"line":72},[69,7133,7134],{},"import csv\n",[69,7136,7137],{"class":71,"line":90},[69,7138,1086],{"emptyLinePlaceholder":226},[69,7140,7141],{"class":71,"line":99},[69,7142,7143],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[69,7145,7146],{"class":71,"line":108},[69,7147,7148],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[69,7150,7151],{"class":71,"line":120},[69,7152,7153],{},"writer.writeheader()\n",[69,7155,7156],{"class":71,"line":1138},[69,7157,7158],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[69,7160,7161],{"class":71,"line":2478},[69,7162,7163],{},"writer_file.close()\n",[69,7165,7166],{"class":71,"line":2484},[69,7167,1086],{"emptyLinePlaceholder":226},[69,7169,7170],{"class":71,"line":3942},[69,7171,7172],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[69,7174,7175],{"class":71,"line":4154},[69,7176,7177],{},"for row in csv.DictReader(reader_file):\n",[69,7179,7180],{"class":71,"line":5819},[69,7181,7182],{},"    print(row[\"name\"], row[\"score\"])\n",[69,7184,7185],{"class":71,"line":5824},[69,7186,7187],{},"reader_file.close()\n",[10,7189,126],{},[60,7191,7194],{"className":7192,"code":7193,"language":132,"meta":65},[130],"小郑 95\n",[43,7195,7193],{"__ignoreMap":65},[10,7197,137],{},[14,7199,140],{"id":140},[142,7201,7202,7211],{},[40,7203,7204,7207,7208,7210],{},[43,7205,7206],{},"DictWriter"," 按 ",[43,7209,7116],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[40,7212,7213,7215],{},[43,7214,7095],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7217,172],{"id":172},[37,7219,7220,7223],{},[40,7221,7222],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[40,7224,7225,7226,7228,7229,7231],{},"在 macOS 以外环境忽略 ",[43,7227,7105],{}," 可能出现额外空行；统一交给 ",[43,7230,7109],{}," 模块管理换行。",[14,7233,186],{"id":186},[142,7235,7236,7239],{},[40,7237,7238],{},"写入三名学习者的课程和分数。",[40,7240,7241],{},"读取 CSV 后把分数字符串转换为整数。",[10,7243,201],{},[14,7245,204],{"id":204},[10,7247,7248],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,7250,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":7252},[7253,7254,7255,7256,7257,7258,7259,7260],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7072,"description":7077},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[222,7268,7269],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7272,"title":7273,"body":7274,"category":222,"cover":223,"description":7278,"extension":224,"meta":7551,"navigation":226,"path":7552,"pinned":228,"publishedAt":229,"seo":7553,"slug":7554,"stem":7555,"summary":7556,"tags":7557,"updatedAt":229,"visible":226,"__hash__":7560},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7275,"toc":7538},[7276,7279,7281,7284,7286,7292,7303,7305,7322,7324,7326,7401,7403,7409,7411,7413,7438,7440,7449,7455,7466,7468,7474,7480,7489,7491,7506,7508,7529,7531,7533,7536],[10,7277,7278],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7280,16],{"id":16},[10,7282,7283],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7285,22],{"id":22},[10,7287,7288],{},[26,7289],{"alt":7290,"src":7291},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7293,7294,7295,7298,7299,7302],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[43,7296,7297],{},"except","；无论是否异常，",[43,7300,7301],{},"finally"," 都会在离开结构前执行。",[14,7304,35],{"id":35},[37,7306,7307,7313,7319],{},[40,7308,7309,7310,7312],{},"只捕获能够处理的具体异常，不使用空的 ",[43,7311,7297],{}," 吞掉全部错误。",[40,7314,7315,7318],{},[43,7316,7317],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[40,7320,7321],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7323,55],{"id":55},[10,7325,1428],{},[60,7327,7329],{"className":405,"code":7328,"language":102,"meta":65,"style":65},"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",[43,7330,7331,7336,7341,7346,7351,7356,7360,7365,7370,7375,7380,7384,7389,7395],{"__ignoreMap":65},[69,7332,7333],{"class":71,"line":72},[69,7334,7335],{},"def parse_age(text):\n",[69,7337,7338],{"class":71,"line":90},[69,7339,7340],{},"    age = int(text)\n",[69,7342,7343],{"class":71,"line":99},[69,7344,7345],{},"    if age \u003C 0:\n",[69,7347,7348],{"class":71,"line":108},[69,7349,7350],{},"        raise ValueError(\"年龄不能为负数\")\n",[69,7352,7353],{"class":71,"line":120},[69,7354,7355],{},"    return age\n",[69,7357,7358],{"class":71,"line":1138},[69,7359,1086],{"emptyLinePlaceholder":226},[69,7361,7362],{"class":71,"line":2478},[69,7363,7364],{},"try:\n",[69,7366,7367],{"class":71,"line":2484},[69,7368,7369],{},"    age = parse_age(\"18\")\n",[69,7371,7372],{"class":71,"line":3942},[69,7373,7374],{},"except ValueError as error:\n",[69,7376,7377],{"class":71,"line":4154},[69,7378,7379],{},"    print(\"输入错误：\", error)\n",[69,7381,7382],{"class":71,"line":5819},[69,7383,1135],{},[69,7385,7386],{"class":71,"line":5824},[69,7387,7388],{},"    print(\"年龄：\", age)\n",[69,7390,7392],{"class":71,"line":7391},13,[69,7393,7394],{},"finally:\n",[69,7396,7398],{"class":71,"line":7397},14,[69,7399,7400],{},"    print(\"处理结束\")\n",[10,7402,126],{},[60,7404,7407],{"className":7405,"code":7406,"language":132,"meta":65},[130],"年龄： 18\n处理结束\n",[43,7408,7406],{"__ignoreMap":65},[10,7410,137],{},[14,7412,140],{"id":140},[142,7414,7415,7427],{},[40,7416,7417,7419,7420,7422,7423,7426],{},[43,7418,3027],{}," 或主动 ",[43,7421,7317],{}," 都可能产生 ",[43,7424,7425],{},"ValueError","，控制流立即离开当前正常路径。",[40,7428,7429,7430,7432,7433,7435,7436,195],{},"有异常时进入匹配的 ",[43,7431,7297],{},"；没有异常时执行 ",[43,7434,1150],{},"；两种情况最后都会执行 ",[43,7437,7301],{},[325,7439,2688],{"id":2688},[10,7441,7442,2246,7444,1147,7446,7448],{},[43,7443,7297],{},[43,7445,1150],{},[43,7447,7301],{}," 的职责不同，不能只看它们出现的顺序。",[10,7450,7451],{},[26,7452],{"alt":7453,"src":7454},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7456,7457,7459,7460,7462,7463,7465],{},[43,7458,7297],{}," 处理匹配异常，",[43,7461,1150],{}," 只在无异常时运行，",[43,7464,7301],{}," 负责两条路径都需要的清理动作。",[325,7467,2688],{"id":4209},[10,7469,7470,7473],{},[43,7471,7472],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7475,7476],{},[26,7477],{"alt":7478,"src":7479},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7481,7482,7483,7485,7486,7488],{},"只把可能产生预期异常的操作放进 ",[43,7484,7472],{},"，后续正常业务放进 ",[43,7487,1150],{},"，错误边界会更清楚。",[14,7490,172],{"id":172},[37,7492,7493,7500],{},[40,7494,7495,7496,7499],{},"使用裸 ",[43,7497,7498],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[40,7501,7502,7503,7505],{},"把整个程序包在一个巨大 ",[43,7504,7472],{}," 中，无法判断究竟哪一步允许失败。",[14,7507,186],{"id":186},[142,7509,7510,7523],{},[40,7511,7512,7513,7516,7517,1147,7520,195],{},"让 ",[43,7514,7515],{},"parse_age"," 分别处理 ",[43,7518,7519],{},"\"abc\"",[43,7521,7522],{},"\"-1\"",[40,7524,7525,7526,7528],{},"为文件读取捕获 ",[43,7527,6733],{}," 并给出清晰提示。",[10,7530,201],{},[14,7532,204],{"id":204},[10,7534,7535],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,7537,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":7539},[7540,7541,7542,7543,7544,7548,7549,7550],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":7545},[7546,7547],{"id":2688,"depth":99,"text":2688},{"id":4209,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7273,"description":7278},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[222,7558,7559],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7562,"title":7563,"body":7564,"category":222,"cover":223,"description":7568,"extension":224,"meta":7744,"navigation":226,"path":7745,"pinned":228,"publishedAt":229,"seo":7746,"slug":7747,"stem":7748,"summary":7749,"tags":7750,"updatedAt":229,"visible":226,"__hash__":7752},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7565,"toc":7734},[7566,7569,7571,7574,7576,7582,7588,7590,7606,7608,7610,7664,7666,7672,7674,7676,7689,7691,7704,7706,7725,7727,7729,7732],[10,7567,7568],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7570,16],{"id":16},[10,7572,7573],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7575,22],{"id":22},[10,7577,7578],{},[26,7579],{"alt":7580,"src":7581},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7583,7584,7585,7587],{},"进入 ",[43,7586,6743],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7589,35],{"id":35},[37,7591,7592,7597,7603],{},[40,7593,7594,7596],{},[43,7595,6743],{}," 把资源获取和释放配成一个清晰边界。",[40,7598,7599,7602],{},[43,7600,7601],{},"as file"," 得到的是上下文返回的资源对象。",[40,7604,7605],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7607,55],{"id":55},[10,7609,1428],{},[60,7611,7613],{"className":405,"code":7612,"language":102,"meta":65,"style":65},"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",[43,7614,7615,7619,7623,7627,7631,7636,7641,7645,7650,7655,7659],{"__ignoreMap":65},[69,7616,7617],{"class":71,"line":72},[69,7618,6555],{},[69,7620,7621],{"class":71,"line":90},[69,7622,1086],{"emptyLinePlaceholder":226},[69,7624,7625],{"class":71,"line":99},[69,7626,6766],{},[69,7628,7629],{"class":71,"line":108},[69,7630,1086],{"emptyLinePlaceholder":226},[69,7632,7633],{"class":71,"line":120},[69,7634,7635],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[69,7637,7638],{"class":71,"line":1138},[69,7639,7640],{},"    file.write(\"上下文管理器\\n\")\n",[69,7642,7643],{"class":71,"line":2478},[69,7644,1086],{"emptyLinePlaceholder":226},[69,7646,7647],{"class":71,"line":2484},[69,7648,7649],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[69,7651,7652],{"class":71,"line":3942},[69,7653,7654],{},"    print(file.read())\n",[69,7656,7657],{"class":71,"line":4154},[69,7658,1086],{"emptyLinePlaceholder":226},[69,7660,7661],{"class":71,"line":5819},[69,7662,7663],{},"print(file.closed)\n",[10,7665,126],{},[60,7667,7670],{"className":7668,"code":7669,"language":132,"meta":65},[130],"上下文管理器\n\nTrue\n",[43,7671,7669],{"__ignoreMap":65},[10,7673,137],{},[14,7675,140],{"id":140},[142,7677,7678,7686],{},[40,7679,7584,7680,7682,7683,195],{},[43,7681,6743],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[43,7684,7685],{},"file",[40,7687,7688],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7690,172],{"id":172},[37,7692,7693,7698],{},[40,7694,4777,7695,7697],{},[43,7696,6743],{}," 代码块外继续读写已经关闭的文件对象。",[40,7699,7700,7701,7703],{},"误以为 ",[43,7702,6743],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7705,186],{"id":186},[142,7707,7708,7717],{},[40,7709,7710,7711,7714,7715,195],{},"把第 30 篇的手动 ",[43,7712,7713],{},"open\u002Fclose"," 改写为 ",[43,7716,6743],{},[40,7718,4777,7719,7721,7722,195],{},[43,7720,6743],{}," 块后检查 ",[43,7723,7724],{},"file.closed",[10,7726,201],{},[14,7728,204],{"id":204},[10,7730,7731],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,7733,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":7735},[7736,7737,7738,7739,7740,7741,7742,7743],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7563,"description":7568},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[222,6743,7751],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7754,"title":7755,"body":7756,"category":222,"cover":223,"description":7760,"extension":224,"meta":7972,"navigation":226,"path":7973,"pinned":228,"publishedAt":229,"seo":7974,"slug":7975,"stem":7976,"summary":7977,"tags":7978,"updatedAt":229,"visible":226,"__hash__":7981},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7757,"toc":7960},[7758,7761,7763,7766,7768,7774,7777,7779,7796,7798,7800,7868,7870,7876,7878,7880,7905,7907,7910,7916,7925,7927,7938,7940,7951,7953,7955,7958],[10,7759,7760],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7762,16],{"id":16},[10,7764,7765],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7767,22],{"id":22},[10,7769,7770],{},[26,7771],{"alt":7772,"src":7773},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7775,7776],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7778,35],{"id":35},[37,7780,7781,7787,7793],{},[40,7782,7783,7786],{},[43,7784,7785],{},"self"," 表示当前实例，由方法调用自动传入。",[40,7788,7789,7792],{},[43,7790,7791],{},"__init__"," 在实例创建过程中初始化属性。",[40,7794,7795],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7797,55],{"id":55},[10,7799,1428],{},[60,7801,7803],{"className":405,"code":7802,"language":102,"meta":65,"style":65},"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",[43,7804,7805,7810,7815,7820,7825,7829,7834,7839,7844,7849,7853,7858,7863],{"__ignoreMap":65},[69,7806,7807],{"class":71,"line":72},[69,7808,7809],{},"class LearningRecord:\n",[69,7811,7812],{"class":71,"line":90},[69,7813,7814],{},"    def __init__(self, course, progress=0):\n",[69,7816,7817],{"class":71,"line":99},[69,7818,7819],{},"        self.course = course\n",[69,7821,7822],{"class":71,"line":108},[69,7823,7824],{},"        self.progress = progress\n",[69,7826,7827],{"class":71,"line":120},[69,7828,1086],{"emptyLinePlaceholder":226},[69,7830,7831],{"class":71,"line":1138},[69,7832,7833],{},"    def advance(self, amount):\n",[69,7835,7836],{"class":71,"line":2478},[69,7837,7838],{},"        self.progress = self.progress + amount\n",[69,7840,7841],{"class":71,"line":2484},[69,7842,7843],{},"        if self.progress > 100:\n",[69,7845,7846],{"class":71,"line":3942},[69,7847,7848],{},"            self.progress = 100\n",[69,7850,7851],{"class":71,"line":4154},[69,7852,1086],{"emptyLinePlaceholder":226},[69,7854,7855],{"class":71,"line":5819},[69,7856,7857],{},"record = LearningRecord(\"Python\", 40)\n",[69,7859,7860],{"class":71,"line":5824},[69,7861,7862],{},"record.advance(15)\n",[69,7864,7865],{"class":71,"line":7391},[69,7866,7867],{},"print(record.course, record.progress)\n",[10,7869,126],{},[60,7871,7874],{"className":7872,"code":7873,"language":132,"meta":65},[130],"Python 55\n",[43,7875,7873],{"__ignoreMap":65},[10,7877,137],{},[14,7879,140],{"id":140},[142,7881,7882,7892],{},[40,7883,7884,7885,7888,7889,7891],{},"调用 ",[43,7886,7887],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[43,7890,7791],{}," 把课程和进度保存在该实例属性中。",[40,7893,7894,7897,7898,7901,7902,7904],{},[43,7895,7896],{},"record.advance(15)"," 自动把 ",[43,7899,7900],{},"record"," 作为 ",[43,7903,7785],{},"，方法更新同一实例的进度并限制上限。",[325,7906,2688],{"id":2688},[10,7908,7909],{},"类是共同定义，实例则各自保存状态。",[10,7911,7912],{},[26,7913],{"alt":7914,"src":7915},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7917,7918,7919,1147,7921,7924],{},"两个实例共享同一套方法定义，但 ",[43,7920,4574],{},[43,7922,7923],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,7926,172],{"id":172},[37,7928,7929,7935],{},[40,7930,7931,7932,7934],{},"调用实例方法时手工再传一次 ",[43,7933,7785],{},"。通过实例调用时 Python 会自动绑定。",[40,7936,7937],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,7939,186],{"id":186},[142,7941,7942,7948],{},[40,7943,5287,7944,7947],{},[43,7945,7946],{},"Book"," 类，保存标题和阅读页数。",[40,7949,7950],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,7952,201],{},[14,7954,204],{"id":204},[10,7956,7957],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,7959,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":7961},[7962,7963,7964,7965,7966,7969,7970,7971],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":7967},[7968],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7755,"description":7760},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[222,7979,7980],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":7983,"title":7984,"body":7985,"category":222,"cover":223,"description":7989,"extension":224,"meta":8167,"navigation":226,"path":8168,"pinned":228,"publishedAt":229,"seo":8169,"slug":8170,"stem":8171,"summary":8172,"tags":8173,"updatedAt":229,"visible":226,"__hash__":8176},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":7986,"toc":8157},[7987,7990,7992,7995,7997,8003,8006,8008,8019,8021,8023,8090,8092,8098,8100,8102,8121,8123,8131,8133,8148,8150,8152,8155],[10,7988,7989],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,7991,16],{"id":16},[10,7993,7994],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7996,22],{"id":22},[10,7998,7999],{},[26,8000],{"alt":8001,"src":8002},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8004,8005],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8007,35],{"id":35},[37,8009,8010,8013,8016],{},[40,8011,8012],{},"封装让对象通过方法维护自己的有效状态。",[40,8014,8015],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[40,8017,8018],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8020,55],{"id":55},[10,8022,1428],{},[60,8024,8026],{"className":405,"code":8025,"language":102,"meta":65,"style":65},"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",[43,8027,8028,8033,8038,8043,8047,8052,8057,8062,8066,8071,8076,8080,8085],{"__ignoreMap":65},[69,8029,8030],{"class":71,"line":72},[69,8031,8032],{},"class Storage:\n",[69,8034,8035],{"class":71,"line":90},[69,8036,8037],{},"    def save(self, text):\n",[69,8039,8040],{"class":71,"line":99},[69,8041,8042],{},"        print(\"保存：\", text)\n",[69,8044,8045],{"class":71,"line":108},[69,8046,1086],{"emptyLinePlaceholder":226},[69,8048,8049],{"class":71,"line":120},[69,8050,8051],{},"class LearningService:\n",[69,8053,8054],{"class":71,"line":1138},[69,8055,8056],{},"    def __init__(self, storage):\n",[69,8058,8059],{"class":71,"line":2478},[69,8060,8061],{},"        self.storage = storage\n",[69,8063,8064],{"class":71,"line":2484},[69,8065,1086],{"emptyLinePlaceholder":226},[69,8067,8068],{"class":71,"line":3942},[69,8069,8070],{},"    def finish_lesson(self, title):\n",[69,8072,8073],{"class":71,"line":4154},[69,8074,8075],{},"        self.storage.save(title)\n",[69,8077,8078],{"class":71,"line":5819},[69,8079,1086],{"emptyLinePlaceholder":226},[69,8081,8082],{"class":71,"line":5824},[69,8083,8084],{},"service = LearningService(Storage())\n",[69,8086,8087],{"class":71,"line":7391},[69,8088,8089],{},"service.finish_lesson(\"异常处理\")\n",[10,8091,126],{},[60,8093,8096],{"className":8094,"code":8095,"language":132,"meta":65},[130],"保存： 异常处理\n",[43,8097,8095],{"__ignoreMap":65},[10,8099,137],{},[14,8101,140],{"id":140},[142,8103,8104,8114],{},[40,8105,8106,8109,8110,8113],{},[43,8107,8108],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[43,8111,8112],{},"save()"," 的协作对象。",[40,8115,8116,8117,8120],{},"调用业务方法时，服务把保存动作委托给 ",[43,8118,8119],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8122,172],{"id":172},[37,8124,8125,8128],{},[40,8126,8127],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[40,8129,8130],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8132,186],{"id":186},[142,8134,8135,8145],{},[40,8136,8137,8138,8141,8142,195],{},"用组合让 ",[43,8139,8140],{},"OrderService"," 使用一个 ",[43,8143,8144],{},"Notifier",[40,8146,8147],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8149,201],{},[14,8151,204],{"id":204},[10,8153,8154],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,8156,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":8158},[8159,8160,8161,8162,8163,8164,8165,8166],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":7984,"description":7989},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[222,8174,8175],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8178,"title":8179,"body":8180,"category":222,"cover":223,"description":8184,"extension":224,"meta":8387,"navigation":226,"path":8388,"pinned":228,"publishedAt":229,"seo":8389,"slug":8390,"stem":8391,"summary":8392,"tags":8393,"updatedAt":229,"visible":226,"__hash__":8396},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8181,"toc":8375},[8182,8185,8187,8190,8192,8198,8205,8207,8232,8234,8236,8288,8290,8296,8298,8300,8321,8323,8329,8335,8341,8343,8351,8353,8366,8368,8370,8373],[10,8183,8184],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8186,16],{"id":16},[10,8188,8189],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8191,22],{"id":22},[10,8193,8194],{},[26,8195],{"alt":8196,"src":8197},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8199,8200,8201,8204],{},"生成器运行到 ",[43,8202,8203],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8206,35],{"id":35},[37,8208,8209,8219,8229],{},[40,8210,8211,8214,8215,8218],{},[43,8212,8213],{},"iter()"," 从可迭代对象取得迭代器，",[43,8216,8217],{},"next()"," 请求下一个值。",[40,8220,8221,8222,8225,8226,8228],{},"没有更多值时迭代器抛出 ",[43,8223,8224],{},"StopIteration","，",[43,8227,4328],{}," 会自动处理。",[40,8230,8231],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8233,55],{"id":55},[10,8235,1428],{},[60,8237,8239],{"className":405,"code":8238,"language":102,"meta":65,"style":65},"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",[43,8240,8241,8246,8251,8256,8261,8266,8270,8275,8280,8284],{"__ignoreMap":65},[69,8242,8243],{"class":71,"line":72},[69,8244,8245],{},"def countdown(start):\n",[69,8247,8248],{"class":71,"line":90},[69,8249,8250],{},"    current = start\n",[69,8252,8253],{"class":71,"line":99},[69,8254,8255],{},"    while current > 0:\n",[69,8257,8258],{"class":71,"line":108},[69,8259,8260],{},"        yield current\n",[69,8262,8263],{"class":71,"line":120},[69,8264,8265],{},"        current = current - 1\n",[69,8267,8268],{"class":71,"line":1138},[69,8269,1086],{"emptyLinePlaceholder":226},[69,8271,8272],{"class":71,"line":2478},[69,8273,8274],{},"iterator = countdown(3)\n",[69,8276,8277],{"class":71,"line":2484},[69,8278,8279],{},"print(next(iterator))\n",[69,8281,8282],{"class":71,"line":3942},[69,8283,8279],{},[69,8285,8286],{"class":71,"line":4154},[69,8287,8279],{},[10,8289,126],{},[60,8291,8294],{"className":8292,"code":8293,"language":132,"meta":65},[130],"3\n2\n1\n",[43,8295,8293],{"__ignoreMap":65},[10,8297,137],{},[14,8299,140],{"id":140},[142,8301,8302,8308],{},[40,8303,7884,8304,8307],{},[43,8305,8306],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[40,8309,8310,8311,8313,8314,8316,8317,8320],{},"每次 ",[43,8312,8217],{}," 运行到下一个 ",[43,8315,8203],{}," 并暂停，局部变量 ",[43,8318,8319],{},"current"," 和执行位置被保留。",[325,8322,2688],{"id":2688},[10,8324,8325,8326,8328],{},"生成器的暂停位置可以展开成多次 ",[43,8327,8217],{}," 的时间线。",[10,8330,8331],{},[26,8332],{"alt":8333,"src":8334},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8336,8337,8338,8340],{},"每次请求只推进到下一个 ",[43,8339,8203],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8342,172],{"id":172},[37,8344,8345,8348],{},[40,8346,8347],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[40,8349,8350],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8352,186],{"id":186},[142,8354,8355,8358],{},[40,8356,8357],{},"编写产生 1 到指定上限偶数的生成器。",[40,8359,4000,8360,8362,8363,8365],{},[43,8361,4328],{}," 遍历生成器，比较手动 ",[43,8364,8217],{}," 的差异。",[10,8367,201],{},[14,8369,204],{"id":204},[10,8371,8372],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,8374,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":8376},[8377,8378,8379,8380,8381,8384,8385,8386],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":8382},[8383],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8179,"description":8184},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[222,8394,8395],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8398,"title":8399,"body":8400,"category":222,"cover":223,"description":8404,"extension":224,"meta":8628,"navigation":226,"path":8629,"pinned":228,"publishedAt":229,"seo":8630,"slug":8631,"stem":8632,"summary":8633,"tags":8634,"updatedAt":229,"visible":226,"__hash__":8636},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8401,"toc":8616},[8402,8405,8407,8410,8412,8418,8421,8423,8443,8445,8447,8529,8531,8537,8539,8541,8563,8565,8568,8574,8581,8583,8593,8595,8607,8609,8611,8614],[10,8403,8404],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8406,16],{"id":16},[10,8408,8409],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8411,22],{"id":22},[10,8413,8414],{},[26,8415],{"alt":8416,"src":8417},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8419,8420],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8422,35],{"id":35},[37,8424,8425,8434,8437],{},[40,8426,8427,8430,8431,195],{},[43,8428,8429],{},"@trace"," 等价于 ",[43,8432,8433],{},"add = trace(add)",[40,8435,8436],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[40,8438,8439,8442],{},[43,8440,8441],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8444,55],{"id":55},[10,8446,1428],{},[60,8448,8450],{"className":405,"code":8449,"language":102,"meta":65,"style":65},"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",[43,8451,8452,8457,8461,8466,8471,8476,8481,8486,8491,8496,8501,8505,8510,8514,8518,8523],{"__ignoreMap":65},[69,8453,8454],{"class":71,"line":72},[69,8455,8456],{},"from functools import wraps\n",[69,8458,8459],{"class":71,"line":90},[69,8460,1086],{"emptyLinePlaceholder":226},[69,8462,8463],{"class":71,"line":99},[69,8464,8465],{},"def trace(function):\n",[69,8467,8468],{"class":71,"line":108},[69,8469,8470],{},"    @wraps(function)\n",[69,8472,8473],{"class":71,"line":120},[69,8474,8475],{},"    def wrapper(*args, **kwargs):\n",[69,8477,8478],{"class":71,"line":1138},[69,8479,8480],{},"        print(\"开始：\", function.__name__)\n",[69,8482,8483],{"class":71,"line":2478},[69,8484,8485],{},"        result = function(*args, **kwargs)\n",[69,8487,8488],{"class":71,"line":2484},[69,8489,8490],{},"        print(\"结束：\", function.__name__)\n",[69,8492,8493],{"class":71,"line":3942},[69,8494,8495],{},"        return result\n",[69,8497,8498],{"class":71,"line":4154},[69,8499,8500],{},"    return wrapper\n",[69,8502,8503],{"class":71,"line":5819},[69,8504,1086],{"emptyLinePlaceholder":226},[69,8506,8507],{"class":71,"line":5824},[69,8508,8509],{},"@trace\n",[69,8511,8512],{"class":71,"line":7391},[69,8513,6172],{},[69,8515,8516],{"class":71,"line":7397},[69,8517,6177],{},[69,8519,8521],{"class":71,"line":8520},15,[69,8522,1086],{"emptyLinePlaceholder":226},[69,8524,8526],{"class":71,"line":8525},16,[69,8527,8528],{},"print(add(2, 3))\n",[10,8530,126],{},[60,8532,8535],{"className":8533,"code":8534,"language":132,"meta":65},[130],"开始： add\n结束： add\n5\n",[43,8536,8534],{"__ignoreMap":65},[10,8538,137],{},[14,8540,140],{"id":140},[142,8542,8543,8560],{},[40,8544,8545,8546,8549,8550,8553,8554,8557,8558,195],{},"解释器执行定义时，把原 ",[43,8547,8548],{},"add"," 函数交给 ",[43,8551,8552],{},"trace","，返回的 ",[43,8555,8556],{},"wrapper"," 重新绑定到名字 ",[43,8559,8548],{},[40,8561,8562],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[325,8564,2688],{"id":2688},[10,8566,8567],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8569,8570],{},[26,8571],{"alt":8572,"src":8573},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8575,8576,8578,8579,195],{},[43,8577,8429],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[43,8580,8433],{},[14,8582,172],{"id":172},[37,8584,8585,8590],{},[40,8586,8587,8588,195],{},"包装函数忘记返回原函数结果，调用方得到 ",[43,8589,5370],{},[40,8591,8592],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8594,186],{"id":186},[142,8596,8597,8600],{},[40,8598,8599],{},"编写只记录调用次数的简单装饰器。",[40,8601,8602,8603,8606],{},"删除包装函数的 ",[43,8604,8605],{},"return result","，观察调用方得到什么。",[10,8608,201],{},[14,8610,204],{"id":204},[10,8612,8613],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,8615,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":8617},[8618,8619,8620,8621,8622,8625,8626,8627],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":8623},[8624],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8399,"description":8404},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[222,8635,5321],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8638,"title":8639,"body":8640,"category":222,"cover":223,"description":8644,"extension":224,"meta":8831,"navigation":226,"path":8832,"pinned":228,"publishedAt":229,"seo":8833,"slug":8834,"stem":8835,"summary":8836,"tags":8837,"updatedAt":229,"visible":226,"__hash__":8840},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8641,"toc":8819},[8642,8645,8647,8650,8652,8658,8661,8663,8674,8676,8678,8753,8755,8761,8763,8765,8776,8778,8781,8787,8790,8792,8800,8802,8810,8812,8814,8817],[10,8643,8644],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8646,16],{"id":16},[10,8648,8649],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8651,22],{"id":22},[10,8653,8654],{},[26,8655],{"alt":8656,"src":8657},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8659,8660],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8662,35],{"id":35},[37,8664,8665,8668,8671],{},[40,8666,8667],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[40,8669,8670],{},"日志记录运行状态，测试判断结果是否符合约定。",[40,8672,8673],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8675,55],{"id":55},[10,8677,1428],{},[60,8679,8681],{"className":405,"code":8680,"language":102,"meta":65,"style":65},"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",[43,8682,8683,8688,8693,8697,8702,8706,8711,8716,8721,8725,8730,8735,8740,8744,8748],{"__ignoreMap":65},[69,8684,8685],{"class":71,"line":72},[69,8686,8687],{},"import logging\n",[69,8689,8690],{"class":71,"line":90},[69,8691,8692],{},"import unittest\n",[69,8694,8695],{"class":71,"line":99},[69,8696,1086],{"emptyLinePlaceholder":226},[69,8698,8699],{"class":71,"line":108},[69,8700,8701],{},"logging.basicConfig(level=logging.INFO)\n",[69,8703,8704],{"class":71,"line":120},[69,8705,1086],{"emptyLinePlaceholder":226},[69,8707,8708],{"class":71,"line":1138},[69,8709,8710],{},"def clamp_progress(value):\n",[69,8712,8713],{"class":71,"line":2478},[69,8714,8715],{},"    logging.info(\"检查进度：%s\", value)\n",[69,8717,8718],{"class":71,"line":2484},[69,8719,8720],{},"    return max(0, min(100, value))\n",[69,8722,8723],{"class":71,"line":3942},[69,8724,1086],{"emptyLinePlaceholder":226},[69,8726,8727],{"class":71,"line":4154},[69,8728,8729],{},"class ProgressTest(unittest.TestCase):\n",[69,8731,8732],{"class":71,"line":5819},[69,8733,8734],{},"    def test_upper_limit(self):\n",[69,8736,8737],{"class":71,"line":5824},[69,8738,8739],{},"        self.assertEqual(clamp_progress(120), 100)\n",[69,8741,8742],{"class":71,"line":7391},[69,8743,1086],{"emptyLinePlaceholder":226},[69,8745,8746],{"class":71,"line":7397},[69,8747,6186],{},[69,8749,8750],{"class":71,"line":8520},[69,8751,8752],{},"    unittest.main()\n",[10,8754,126],{},[60,8756,8759],{"className":8757,"code":8758,"language":132,"meta":65},[130],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[43,8760,8758],{"__ignoreMap":65},[10,8762,137],{},[14,8764,140],{"id":140},[142,8766,8767,8773],{},[40,8768,8769,8772],{},[43,8770,8771],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[40,8774,8775],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[325,8777,2688],{"id":2688},[10,8779,8780],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8782,8783],{},[26,8784],{"alt":8785,"src":8786},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8788,8789],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8791,172],{"id":172},[37,8793,8794,8797],{},[40,8795,8796],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[40,8798,8799],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8801,186],{"id":186},[142,8803,8804,8807],{},[40,8805,8806],{},"为负数进度增加测试。",[40,8808,8809],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8811,201],{},[14,8813,204],{"id":204},[10,8815,8816],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,8818,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":8820},[8821,8822,8823,8824,8825,8828,8829,8830],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":8826},[8827],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8639,"description":8644},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[222,8838,8839],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8842,"title":8843,"body":8844,"category":222,"cover":223,"description":8848,"extension":224,"meta":9148,"navigation":226,"path":9149,"pinned":228,"publishedAt":229,"seo":9150,"slug":9151,"stem":9152,"summary":9153,"tags":9154,"updatedAt":229,"visible":226,"__hash__":9157},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8845,"toc":9135},[8846,8849,8851,8854,8856,8862,8865,8867,8882,8884,8886,9033,9035,9041,9043,9045,9058,9060,9063,9069,9072,9074,9077,9083,9090,9092,9103,9105,9126,9128,9130,9133],[10,8847,8848],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8850,16],{"id":16},[10,8852,8853],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8855,22],{"id":22},[10,8857,8858],{},[26,8859],{"alt":8860,"src":8861},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8863,8864],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8866,35],{"id":35},[37,8868,8869,8872,8875],{},[40,8870,8871],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[40,8873,8874],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[40,8876,8877,8878,8881],{},"实际扩展前先为 ",[43,8879,8880],{},"add()"," 和存储边界补充测试。",[14,8883,55],{"id":55},[10,8885,1428],{},[60,8887,8889],{"className":405,"code":8888,"language":102,"meta":65,"style":65},"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",[43,8890,8891,8895,8899,8903,8908,8913,8918,8923,8927,8932,8937,8942,8947,8952,8956,8961,8966,8972,8977,8983,8988,8993,8999,9005,9011,9016,9022,9027],{"__ignoreMap":65},[69,8892,8893],{"class":71,"line":72},[69,8894,6946],{},[69,8896,8897],{"class":71,"line":90},[69,8898,6555],{},[69,8900,8901],{"class":71,"line":99},[69,8902,1086],{"emptyLinePlaceholder":226},[69,8904,8905],{"class":71,"line":108},[69,8906,8907],{},"class LearningRecords:\n",[69,8909,8910],{"class":71,"line":120},[69,8911,8912],{},"    def __init__(self, file_path):\n",[69,8914,8915],{"class":71,"line":1138},[69,8916,8917],{},"        self.file_path = Path(file_path)\n",[69,8919,8920],{"class":71,"line":2478},[69,8921,8922],{},"        self.items = []\n",[69,8924,8925],{"class":71,"line":2484},[69,8926,1086],{"emptyLinePlaceholder":226},[69,8928,8929],{"class":71,"line":3942},[69,8930,8931],{},"    def add(self, title):\n",[69,8933,8934],{"class":71,"line":4154},[69,8935,8936],{},"        title = title.strip()\n",[69,8938,8939],{"class":71,"line":5819},[69,8940,8941],{},"        if not title:\n",[69,8943,8944],{"class":71,"line":5824},[69,8945,8946],{},"            raise ValueError(\"课程名称不能为空\")\n",[69,8948,8949],{"class":71,"line":7391},[69,8950,8951],{},"        self.items.append({\"title\": title, \"done\": False})\n",[69,8953,8954],{"class":71,"line":7397},[69,8955,1086],{"emptyLinePlaceholder":226},[69,8957,8958],{"class":71,"line":8520},[69,8959,8960],{},"    def save(self):\n",[69,8962,8963],{"class":71,"line":8525},[69,8964,8965],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[69,8967,8969],{"class":71,"line":8968},17,[69,8970,8971],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[69,8973,8975],{"class":71,"line":8974},18,[69,8976,1086],{"emptyLinePlaceholder":226},[69,8978,8980],{"class":71,"line":8979},19,[69,8981,8982],{},"records = LearningRecords(\"learning-records.json\")\n",[69,8984,8986],{"class":71,"line":8985},20,[69,8987,1086],{"emptyLinePlaceholder":226},[69,8989,8991],{"class":71,"line":8990},21,[69,8992,7364],{},[69,8994,8996],{"class":71,"line":8995},22,[69,8997,8998],{},"    title = input(\"输入已学习课程：\")\n",[69,9000,9002],{"class":71,"line":9001},23,[69,9003,9004],{},"    records.add(title)\n",[69,9006,9008],{"class":71,"line":9007},24,[69,9009,9010],{},"    records.save()\n",[69,9012,9014],{"class":71,"line":9013},25,[69,9015,7374],{},[69,9017,9019],{"class":71,"line":9018},26,[69,9020,9021],{},"    print(\"无法保存：\", error)\n",[69,9023,9025],{"class":71,"line":9024},27,[69,9026,1135],{},[69,9028,9030],{"class":71,"line":9029},28,[69,9031,9032],{},"    print(\"已保存 1 条学习记录\")\n",[10,9034,126],{},[60,9036,9039],{"className":9037,"code":9038,"language":132,"meta":65},[130],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[43,9040,9038],{"__ignoreMap":65},[10,9042,137],{},[14,9044,140],{"id":140},[142,9046,9047,9053],{},[40,9048,9049,9050,9052],{},"输入层取得课程名后，",[43,9051,8880],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[40,9054,9055,9057],{},[43,9056,8112],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[325,9059,2688],{"id":2688},[10,9061,9062],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9064,9065],{},[26,9066],{"alt":9067,"src":9068},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9070,9071],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[325,9073,2688],{"id":4209},[10,9075,9076],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9078,9079],{},[26,9080],{"alt":9081,"src":9082},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9084,9085,9086,9089],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[43,9087,9088],{},"load()"," 把文件状态恢复到内存。",[14,9091,172],{"id":172},[37,9093,9094,9097],{},[40,9095,9096],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[40,9098,9099,9100,9102],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[43,9101,9088],{}," 是下一项必要扩展。",[14,9104,186],{"id":186},[142,9106,9107,9113,9116],{},[40,9108,9109,9110,9112],{},"增加 ",[43,9111,9088],{},"，文件不存在时从空列表开始。",[40,9114,9115],{},"增加按序号标记完成的功能，并校验序号范围。",[40,9117,9118,9119,9122,9123,9125],{},"把输入循环放进 ",[43,9120,9121],{},"main()","，通过 ",[43,9124,6128],{}," 控制程序入口。",[10,9127,201],{},[14,9129,204],{"id":204},[10,9131,9132],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[209,9134,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":9136},[9137,9138,9139,9140,9141,9145,9146,9147],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":9142},[9143,9144],{"id":2688,"depth":99,"text":2688},{"id":4209,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8843,"description":8848},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[222,9155,9156],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9159,9262,9381,9512,9655,9780,9917,10054,10195,10364,10501,10634,10757,10886,11013,11176,11352,11493,11622,11771,11914,12035,12158,12307,12460,12625,12752,12933,13076,13233,13384,13531,13686,13904,14059,14234,14385,14552,14739,14902,15144,15384],{"id":1383,"title":1384,"body":9160,"category":222,"cover":223,"description":1389,"extension":224,"meta":9259,"navigation":226,"path":1510,"pinned":228,"publishedAt":229,"seo":9260,"slug":1512,"stem":1513,"summary":1514,"tags":9261,"updatedAt":229,"visible":226,"__hash__":1517},{"type":7,"value":9161,"toc":9249},[9162,9164,9166,9168,9170,9174,9178,9180,9190,9192,9194,9202,9204,9209,9211,9213,9223,9225,9233,9235,9241,9243,9245,9247],[10,9163,1389],{},[14,9165,16],{"id":16},[10,9167,1394],{},[14,9169,22],{"id":22},[10,9171,9172],{},[26,9173],{"alt":1401,"src":1402},[10,9175,9176,1407],{},[43,9177,1161],{},[14,9179,35],{"id":35},[37,9181,9182,9186,9188],{},[40,9183,1414,9184,1417],{},[43,9185,1161],{},[40,9187,1420],{},[40,9189,1423],{},[14,9191,55],{"id":55},[10,9193,1428],{},[60,9195,9196],{"className":405,"code":1431,"language":102,"meta":65,"style":65},[43,9197,9198],{"__ignoreMap":65},[69,9199,9200],{"class":71,"line":72},[69,9201,1431],{},[10,9203,126],{},[60,9205,9207],{"className":9206,"code":1443,"language":132,"meta":65},[130],[43,9208,1443],{"__ignoreMap":65},[10,9210,137],{},[14,9212,140],{"id":140},[142,9214,9215,9219],{},[40,9216,1454,9217,1458],{},[43,9218,1457],{},[40,9220,1461,9221,1465],{},[43,9222,1464],{},[14,9224,172],{"id":172},[37,9226,9227,9229],{},[40,9228,1472],{},[40,9230,1475,9231,1478],{},[43,9232,1161],{},[14,9234,186],{"id":186},[142,9236,9237,9239],{},[40,9238,1485],{},[40,9240,1488],{},[10,9242,201],{},[14,9244,204],{"id":204},[10,9246,1495],{},[209,9248,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":9250},[9251,9252,9253,9254,9255,9256,9257,9258],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":1384,"description":1389},[222,1379,1516],{"id":1519,"title":1520,"body":9263,"category":222,"cover":223,"description":1525,"extension":224,"meta":9378,"navigation":226,"path":1660,"pinned":228,"publishedAt":229,"seo":9379,"slug":1662,"stem":1663,"summary":1664,"tags":9380,"updatedAt":229,"visible":226,"__hash__":1667},{"type":7,"value":9264,"toc":9368},[9265,9267,9269,9271,9273,9277,9281,9283,9293,9295,9297,9317,9319,9324,9326,9328,9338,9340,9350,9352,9360,9362,9364,9366],[10,9266,1525],{},[14,9268,16],{"id":16},[10,9270,1530],{},[14,9272,22],{"id":22},[10,9274,9275],{},[26,9276],{"alt":1537,"src":1538},[10,9278,1541,9279,1544],{},[43,9280,76],{},[14,9282,35],{"id":35},[37,9284,9285,9287,9289],{},[40,9286,1551],{},[40,9288,1554],{},[40,9290,1557,9291,1561],{},[43,9292,1560],{},[14,9294,55],{"id":55},[10,9296,58],{},[60,9298,9299],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,9300,9301,9307],{"__ignoreMap":65},[69,9302,9303,9305],{"class":71,"line":72},[69,9304,76],{"class":75},[69,9306,105],{"class":79},[69,9308,9309,9311,9313,9315],{"class":71,"line":90},[69,9310,76],{"class":75},[69,9312,80],{"class":79},[69,9314,115],{"class":83},[69,9316,105],{"class":79},[10,9318,126],{},[60,9320,9322],{"className":9321,"code":1591,"language":132,"meta":65},[130],[43,9323,1591],{"__ignoreMap":65},[10,9325,137],{},[14,9327,140],{"id":140},[142,9329,9330,9334],{},[40,9331,9332,1605],{},[43,9333,1604],{},[40,9335,9336,1610],{},[43,9337,687],{},[14,9339,172],{"id":172},[37,9341,9342,9346],{},[40,9343,1617,9344,1620],{},[43,9345,76],{},[40,9347,1623,9348,1626],{},[43,9349,76],{},[14,9351,186],{"id":186},[142,9353,9354,9358],{},[40,9355,926,9356,1636],{},[43,9357,1635],{},[40,9359,1639],{},[10,9361,201],{},[14,9363,204],{"id":204},[10,9365,1646],{},[209,9367,211],{},{"title":65,"searchDepth":90,"depth":90,"links":9369},[9370,9371,9372,9373,9374,9375,9376,9377],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":1520,"description":1525},[222,1666,1040],{"id":1669,"title":1670,"body":9382,"category":222,"cover":223,"description":1836,"extension":224,"meta":9509,"navigation":226,"path":1838,"pinned":228,"publishedAt":229,"seo":9510,"slug":1840,"stem":1841,"summary":1842,"tags":9511,"updatedAt":229,"visible":226,"__hash__":1846},{"type":7,"value":9383,"toc":9499},[9384,9388,9390,9392,9394,9398,9400,9402,9418,9420,9422,9442,9444,9449,9451,9453,9465,9467,9477,9479,9489,9491,9493,9497],[10,9385,1675,9386,1678],{},[43,9387,1161],{},[14,9389,16],{"id":16},[10,9391,1683],{},[14,9393,22],{"id":22},[10,9395,9396],{},[26,9397],{"alt":1690,"src":1691},[10,9399,1694],{},[14,9401,35],{"id":35},[37,9403,9404,9410,9414],{},[40,9405,1701,9406,1704,9408,195],{},[43,9407,76],{},[43,9409,1707],{},[40,9411,1710,9412,1714],{},[43,9413,1713],{},[40,9415,1717,9416,1720],{},[43,9417,1161],{},[14,9419,55],{"id":55},[10,9421,1428],{},[60,9423,9424],{"className":1727,"code":1728,"language":1729,"meta":65,"style":65},[43,9425,9426,9430,9434,9438],{"__ignoreMap":65},[69,9427,9428],{"class":71,"line":72},[69,9429,1736],{},[69,9431,9432],{"class":71,"line":90},[69,9433,1741],{},[69,9435,9436],{"class":71,"line":99},[69,9437,1746],{},[69,9439,9440],{"class":71,"line":108},[69,9441,1751],{},[10,9443,126],{},[60,9445,9447],{"className":9446,"code":1757,"language":132,"meta":65},[130],[43,9448,1757],{"__ignoreMap":65},[10,9450,137],{},[14,9452,140],{"id":140},[142,9454,9455,9461],{},[40,9456,1768,9457,1772,9459,195],{},[43,9458,1771],{},[43,9460,1775],{},[40,9462,1778,9463,1781],{},[43,9464,1464],{},[14,9466,172],{"id":172},[37,9468,9469,9475],{},[40,9470,1788,9471,1791,9473,1794],{},[43,9472,1707],{},[43,9474,1161],{},[40,9476,1797],{},[14,9478,186],{"id":186},[142,9480,9481,9485],{},[40,9482,1804,9483,195],{},[43,9484,1807],{},[40,9486,1810,9487,1813],{},[43,9488,1464],{},[10,9490,201],{},[14,9492,204],{"id":204},[10,9494,1820,9495,1823],{},[43,9496,1161],{},[209,9498,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":9500},[9501,9502,9503,9504,9505,9506,9507,9508],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":1670,"description":1836},[222,1844,1845],{"id":1848,"title":1849,"body":9513,"category":222,"cover":223,"description":1854,"extension":224,"meta":9652,"navigation":226,"path":2026,"pinned":228,"publishedAt":229,"seo":9653,"slug":2028,"stem":2029,"summary":2030,"tags":9654,"updatedAt":229,"visible":226,"__hash__":2034},{"type":7,"value":9514,"toc":9642},[9515,9517,9519,9521,9523,9527,9531,9533,9545,9547,9549,9585,9587,9592,9594,9596,9612,9614,9624,9626,9634,9636,9638,9640],[10,9516,1854],{},[14,9518,16],{"id":16},[10,9520,1859],{},[14,9522,22],{"id":22},[10,9524,9525],{},[26,9526],{"alt":1866,"src":1867},[10,9528,9529,1873],{},[43,9530,1872],{},[14,9532,35],{"id":35},[37,9534,9535,9537,9543],{},[40,9536,1880],{},[40,9538,9539,1886,9541,1890],{},[43,9540,1885],{},[43,9542,1889],{},[40,9544,1893],{},[14,9546,55],{"id":55},[10,9548,58],{},[60,9550,9551],{"className":62,"code":1900,"language":64,"meta":65,"style":65},[43,9552,9553,9559,9565,9569,9579],{"__ignoreMap":65},[69,9554,9555,9557],{"class":71,"line":72},[69,9556,1907],{"class":75},[69,9558,1910],{"class":83},[69,9560,9561,9563],{"class":71,"line":90},[69,9562,1915],{"class":79},[69,9564,1910],{"class":83},[69,9566,9567],{"class":71,"line":99},[69,9568,1922],{"class":79},[69,9570,9571,9573,9575,9577],{"class":71,"line":108},[69,9572,1927],{"class":79},[69,9574,1930],{"class":83},[69,9576,1934],{"class":1933},[69,9578,1205],{"class":83},[69,9580,9581,9583],{"class":71,"line":120},[69,9582,76],{"class":75},[69,9584,1205],{"class":83},[10,9586,126],{},[60,9588,9590],{"className":9589,"code":1948,"language":132,"meta":65},[130],[43,9591,1948],{"__ignoreMap":65},[10,9593,137],{},[14,9595,140],{"id":140},[142,9597,9598,9606],{},[40,9599,9600,1961,9602,1964,9604,1967],{},[43,9601,1907],{},[43,9603,1915],{},[43,9605,1885],{},[40,9607,9608,1972,9610,1976],{},[43,9609,1872],{},[43,9611,1975],{},[14,9613,172],{"id":172},[37,9615,9616,9622],{},[40,9617,1983,9618,1147,9620,195],{},[43,9619,1885],{},[43,9621,1889],{},[40,9623,1990],{},[14,9625,186],{"id":186},[142,9627,9628,9632],{},[40,9629,1997,9630,2001],{},[43,9631,2000],{},[40,9633,2004],{},[10,9635,201],{},[14,9637,204],{"id":204},[10,9639,2011],{},[209,9641,2014],{},{"title":65,"searchDepth":90,"depth":90,"links":9643},[9644,9645,9646,9647,9648,9649,9650,9651],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":1849,"description":1854},[222,2032,2033],{"id":2036,"title":2037,"body":9656,"category":222,"cover":223,"description":2042,"extension":224,"meta":9777,"navigation":226,"path":2190,"pinned":228,"publishedAt":229,"seo":9778,"slug":2192,"stem":2193,"summary":2194,"tags":9779,"updatedAt":229,"visible":226,"__hash__":2198},{"type":7,"value":9657,"toc":9767},[9658,9660,9662,9664,9666,9670,9678,9680,9694,9696,9698,9714,9716,9721,9723,9725,9739,9741,9747,9749,9759,9761,9763,9765],[10,9659,2042],{},[14,9661,16],{"id":16},[10,9663,2047],{},[14,9665,22],{"id":22},[10,9667,9668],{},[26,9669],{"alt":2054,"src":2055},[10,9671,2058,9672,195,9674,2064,9676,195],{},[43,9673,1464],{},[43,9675,2063],{},[43,9677,1771],{},[14,9679,35],{"id":35},[37,9681,9682,9686,9692],{},[40,9683,9684,2076],{},[43,9685,2075],{},[40,9687,9688,2082,9690,195],{},[43,9689,2081],{},[43,9691,2085],{},[40,9693,2088],{},[14,9695,55],{"id":55},[10,9697,1428],{},[60,9699,9700],{"className":405,"code":2095,"language":102,"meta":65,"style":65},[43,9701,9702,9706,9710],{"__ignoreMap":65},[69,9703,9704],{"class":71,"line":72},[69,9705,2102],{},[69,9707,9708],{"class":71,"line":90},[69,9709,2107],{},[69,9711,9712],{"class":71,"line":99},[69,9713,2112],{},[10,9715,126],{},[60,9717,9719],{"className":9718,"code":2118,"language":132,"meta":65},[130],[43,9720,2118],{"__ignoreMap":65},[10,9722,137],{},[14,9724,140],{"id":140},[142,9726,9727,9733],{},[40,9728,9729,2132,9731,195],{},[43,9730,2131],{},[43,9732,2085],{},[40,9734,9735,2139,9737,2143],{},[43,9736,1464],{},[43,9738,2142],{},[14,9740,172],{"id":172},[37,9742,9743,9745],{},[40,9744,2150],{},[40,9746,2153],{},[14,9748,186],{"id":186},[142,9750,9751,9753],{},[40,9752,2160],{},[40,9754,2163,9755,158,9757,2169],{},[43,9756,2063],{},[43,9758,2168],{},[10,9760,201],{},[14,9762,204],{"id":204},[10,9764,2176],{},[209,9766,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":9768},[9769,9770,9771,9772,9773,9774,9775,9776],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":2037,"description":2042},[222,2196,2197],{"id":2200,"title":2201,"body":9781,"category":222,"cover":223,"description":2206,"extension":224,"meta":9914,"navigation":226,"path":2374,"pinned":228,"publishedAt":229,"seo":9915,"slug":2376,"stem":2377,"summary":2378,"tags":9916,"updatedAt":229,"visible":226,"__hash__":2382},{"type":7,"value":9782,"toc":9904},[9783,9785,9787,9789,9791,9795,9797,9799,9815,9817,9819,9843,9845,9850,9852,9854,9870,9872,9884,9886,9896,9898,9900,9902],[10,9784,2206],{},[14,9786,16],{"id":16},[10,9788,2211],{},[14,9790,22],{"id":22},[10,9792,9793],{},[26,9794],{"alt":2218,"src":2219},[10,9796,2222],{},[14,9798,35],{"id":35},[37,9800,9801,9803,9809],{},[40,9802,2229],{},[40,9804,2232,9805,158,9807,2239],{},[43,9806,2235],{},[43,9808,2238],{},[40,9810,2242,9811,2246,9813,2250],{},[43,9812,2245],{},[43,9814,2249],{},[14,9816,55],{"id":55},[10,9818,1428],{},[60,9820,9821],{"className":405,"code":2257,"language":102,"meta":65,"style":65},[43,9822,9823,9827,9831,9835,9839],{"__ignoreMap":65},[69,9824,9825],{"class":71,"line":72},[69,9826,2264],{},[69,9828,9829],{"class":71,"line":90},[69,9830,2269],{},[69,9832,9833],{"class":71,"line":99},[69,9834,1086],{"emptyLinePlaceholder":226},[69,9836,9837],{"class":71,"line":108},[69,9838,2278],{},[69,9840,9841],{"class":71,"line":120},[69,9842,2269],{},[10,9844,126],{},[60,9846,9848],{"className":9847,"code":2288,"language":132,"meta":65},[130],[43,9849,2288],{"__ignoreMap":65},[10,9851,137],{},[14,9853,140],{"id":140},[142,9855,9856,9862],{},[40,9857,926,9858,2302,9860,2305],{},[43,9859,2301],{},[43,9861,2235],{},[40,9863,926,9864,2311,9866,2315,9868,195],{},[43,9865,2310],{},[43,9867,2314],{},[43,9869,2318],{},[14,9871,172],{"id":172},[37,9873,9874,9876],{},[40,9875,2325],{},[40,9877,2328,9878,2246,9880,2246,9882,2336],{},[43,9879,2245],{},[43,9881,2249],{},[43,9883,2335],{},[14,9885,186],{"id":186},[142,9887,9888,9894],{},[40,9889,2343,9890,1147,9892,2350],{},[43,9891,2346],{},[43,9893,2349],{},[40,9895,2353],{},[10,9897,201],{},[14,9899,204],{"id":204},[10,9901,2360],{},[209,9903,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":9905},[9906,9907,9908,9909,9910,9911,9912,9913],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":2201,"description":2206},[222,2380,2381],{"id":2384,"title":2385,"body":9918,"category":222,"cover":223,"description":2390,"extension":224,"meta":10051,"navigation":226,"path":2557,"pinned":228,"publishedAt":229,"seo":10052,"slug":2559,"stem":2560,"summary":2561,"tags":10053,"updatedAt":229,"visible":226,"__hash__":2565},{"type":7,"value":9919,"toc":10041},[9920,9922,9924,9926,9928,9932,9934,9936,9954,9956,9958,9994,9996,10001,10003,10005,10015,10017,10025,10027,10033,10035,10037,10039],[10,9921,2390],{},[14,9923,16],{"id":16},[10,9925,2395],{},[14,9927,22],{"id":22},[10,9929,9930],{},[26,9931],{"alt":2402,"src":2403},[10,9933,2406],{},[14,9935,35],{"id":35},[37,9937,9938,9944,9952],{},[40,9939,9940,2416,9942,2420],{},[43,9941,2415],{},[43,9943,2419],{},[40,9945,9946,2426,9948,2430,9950,2434],{},[43,9947,2425],{},[43,9949,2429],{},[43,9951,2433],{},[40,9953,2437],{},[14,9955,55],{"id":55},[10,9957,1428],{},[60,9959,9960],{"className":405,"code":2444,"language":102,"meta":65,"style":65},[43,9961,9962,9966,9970,9974,9978,9982,9986,9990],{"__ignoreMap":65},[69,9963,9964],{"class":71,"line":72},[69,9965,2451],{},[69,9967,9968],{"class":71,"line":90},[69,9969,2456],{},[69,9971,9972],{"class":71,"line":99},[69,9973,2461],{},[69,9975,9976],{"class":71,"line":108},[69,9977,1086],{"emptyLinePlaceholder":226},[69,9979,9980],{"class":71,"line":120},[69,9981,2470],{},[69,9983,9984],{"class":71,"line":1138},[69,9985,2475],{},[69,9987,9988],{"class":71,"line":2478},[69,9989,2481],{},[69,9991,9992],{"class":71,"line":2484},[69,9993,2487],{},[10,9995,126],{},[60,9997,9999],{"className":9998,"code":2493,"language":132,"meta":65},[130],[43,10000,2493],{"__ignoreMap":65},[10,10002,137],{},[14,10004,140],{"id":140},[142,10006,10007,10011],{},[40,10008,10009,2507],{},[43,10010,2506],{},[40,10012,10013,2513],{},[43,10014,2512],{},[14,10016,172],{"id":172},[37,10018,10019,10023],{},[40,10020,2520,10021,195],{},[43,10022,2523],{},[40,10024,2526],{},[14,10026,186],{"id":186},[142,10028,10029,10031],{},[40,10030,2533],{},[40,10032,2536],{},[10,10034,201],{},[14,10036,204],{"id":204},[10,10038,2543],{},[209,10040,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10042},[10043,10044,10045,10046,10047,10048,10049,10050],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":2385,"description":2390},[222,2563,2564],{"id":2567,"title":2568,"body":10055,"category":222,"cover":223,"description":2573,"extension":224,"meta":10192,"navigation":226,"path":2750,"pinned":228,"publishedAt":229,"seo":10193,"slug":2752,"stem":2753,"summary":2754,"tags":10194,"updatedAt":229,"visible":226,"__hash__":2758},{"type":7,"value":10056,"toc":10180},[10057,10059,10061,10063,10065,10069,10075,10077,10085,10087,10089,10113,10115,10120,10122,10124,10142,10144,10146,10150,10152,10154,10160,10162,10172,10174,10176,10178],[10,10058,2573],{},[14,10060,16],{"id":16},[10,10062,2578],{},[14,10064,22],{"id":22},[10,10066,10067],{},[26,10068],{"alt":2585,"src":2586},[10,10070,2589,10071,2593,10073,195],{},[43,10072,2592],{},[43,10074,2596],{},[14,10076,35],{"id":35},[37,10078,10079,10081,10083],{},[40,10080,2603],{},[40,10082,2606],{},[40,10084,2609],{},[14,10086,55],{"id":55},[10,10088,1428],{},[60,10090,10091],{"className":405,"code":2616,"language":102,"meta":65,"style":65},[43,10092,10093,10097,10101,10105,10109],{"__ignoreMap":65},[69,10094,10095],{"class":71,"line":72},[69,10096,2623],{},[69,10098,10099],{"class":71,"line":90},[69,10100,2628],{},[69,10102,10103],{"class":71,"line":99},[69,10104,2633],{},[69,10106,10107],{"class":71,"line":108},[69,10108,2638],{},[69,10110,10111],{"class":71,"line":120},[69,10112,2643],{},[10,10114,126],{},[60,10116,10118],{"className":10117,"code":2649,"language":132,"meta":65},[130],[43,10119,2649],{"__ignoreMap":65},[10,10121,137],{},[14,10123,140],{"id":140},[142,10125,10126,10134],{},[40,10127,2660,10128,2663,10130,2667,10132,2671],{},[43,10129,222],{},[43,10131,2666],{},[43,10133,2670],{},[40,10135,10136,2677,10138,2681,10140,2685],{},[43,10137,2676],{},[43,10139,2680],{},[43,10141,2684],{},[325,10143,2688],{"id":2688},[10,10145,2691],{},[10,10147,10148],{},[26,10149],{"alt":2696,"src":2697},[10,10151,2700],{},[14,10153,172],{"id":172},[37,10155,10156,10158],{},[40,10157,2707],{},[40,10159,2710],{},[14,10161,186],{"id":186},[142,10163,10164,10170],{},[40,10165,2717,10166,2721,10168,195],{},[43,10167,2720],{},[43,10169,2724],{},[40,10171,2727],{},[10,10173,201],{},[14,10175,204],{"id":204},[10,10177,2734],{},[209,10179,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10181},[10182,10183,10184,10185,10186,10189,10190,10191],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":10187},[10188],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":2568,"description":2573},[222,2756,2757],{"id":2760,"title":2761,"body":10196,"category":222,"cover":223,"description":2766,"extension":224,"meta":10361,"navigation":226,"path":2981,"pinned":228,"publishedAt":229,"seo":10362,"slug":2983,"stem":2984,"summary":2985,"tags":10363,"updatedAt":229,"visible":226,"__hash__":2989},{"type":7,"value":10197,"toc":10349},[10198,10200,10202,10204,10206,10210,10216,10218,10238,10240,10242,10278,10280,10285,10287,10289,10303,10305,10307,10311,10317,10319,10329,10331,10341,10343,10345,10347],[10,10199,2766],{},[14,10201,16],{"id":16},[10,10203,2771],{},[14,10205,22],{"id":22},[10,10207,10208],{},[26,10209],{"alt":2778,"src":2779},[10,10211,2782,10212,997,10214,2789],{},[43,10213,2785],{},[43,10215,2788],{},[14,10217,35],{"id":35},[37,10219,10220,10228,10236],{},[40,10221,10222,2799,10224,2803,10226,2807],{},[43,10223,2798],{},[43,10225,2802],{},[43,10227,2806],{},[40,10229,10230,2813,10232,2817,10234,2821],{},[43,10231,2812],{},[43,10233,2816],{},[43,10235,2820],{},[40,10237,2824],{},[14,10239,55],{"id":55},[10,10241,1428],{},[60,10243,10244],{"className":405,"code":2831,"language":102,"meta":65,"style":65},[43,10245,10246,10250,10254,10258,10262,10266,10270,10274],{"__ignoreMap":65},[69,10247,10248],{"class":71,"line":72},[69,10249,2838],{},[69,10251,10252],{"class":71,"line":90},[69,10253,2843],{},[69,10255,10256],{"class":71,"line":99},[69,10257,1086],{"emptyLinePlaceholder":226},[69,10259,10260],{"class":71,"line":108},[69,10261,2852],{},[69,10263,10264],{"class":71,"line":120},[69,10265,2857],{},[69,10267,10268],{"class":71,"line":1138},[69,10269,2862],{},[69,10271,10272],{"class":71,"line":2478},[69,10273,2867],{},[69,10275,10276],{"class":71,"line":2484},[69,10277,2872],{},[10,10279,126],{},[60,10281,10283],{"className":10282,"code":2878,"language":132,"meta":65},[130],[43,10284,2878],{"__ignoreMap":65},[10,10286,137],{},[14,10288,140],{"id":140},[142,10290,10291,10297],{},[40,10292,10293,2892,10295,2896],{},[43,10294,2891],{},[43,10296,2895],{},[40,10298,10299,2902,10301,2905],{},[43,10300,2901],{},[43,10302,2820],{},[325,10304,2688],{"id":2688},[10,10306,2910],{},[10,10308,10309],{},[26,10310],{"alt":2915,"src":2916},[10,10312,10313,2921,10315,2924],{},[43,10314,2812],{},[43,10316,2816],{},[14,10318,172],{"id":172},[37,10320,10321,10327],{},[40,10322,2931,10323,2934,10325,2937],{},[43,10324,2806],{},[43,10326,2798],{},[40,10328,2940],{},[14,10330,186],{"id":186},[142,10332,10333,10337],{},[40,10334,2947,10335,2951],{},[43,10336,2950],{},[40,10338,2954,10339,2958],{},[43,10340,2957],{},[10,10342,201],{},[14,10344,204],{"id":204},[10,10346,2965],{},[209,10348,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10350},[10351,10352,10353,10354,10355,10358,10359,10360],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":10356},[10357],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":2761,"description":2766},[222,2987,2988],{"id":2991,"title":2992,"body":10365,"category":222,"cover":223,"description":2997,"extension":224,"meta":10498,"navigation":226,"path":3166,"pinned":228,"publishedAt":229,"seo":10499,"slug":3168,"stem":3169,"summary":3170,"tags":10500,"updatedAt":229,"visible":226,"__hash__":3173},{"type":7,"value":10366,"toc":10488},[10367,10369,10371,10373,10375,10379,10389,10391,10401,10403,10405,10433,10435,10440,10442,10444,10458,10460,10468,10470,10480,10482,10484,10486],[10,10368,2997],{},[14,10370,16],{"id":16},[10,10372,3002],{},[14,10374,22],{"id":22},[10,10376,10377],{},[26,10378],{"alt":3009,"src":3010},[10,10380,10381,3016,10383,3020,10385,3024,10387,3028],{},[43,10382,3015],{},[43,10384,3019],{},[43,10386,3023],{},[43,10388,3027],{},[14,10390,35],{"id":35},[37,10392,10393,10395,10399],{},[40,10394,3035],{},[40,10396,10397,3040],{},[43,10398,3027],{},[40,10400,3043],{},[14,10402,55],{"id":55},[10,10404,1428],{},[60,10406,10407],{"className":405,"code":3050,"language":102,"meta":65,"style":65},[43,10408,10409,10413,10417,10421,10425,10429],{"__ignoreMap":65},[69,10410,10411],{"class":71,"line":72},[69,10412,3057],{},[69,10414,10415],{"class":71,"line":90},[69,10416,3062],{},[69,10418,10419],{"class":71,"line":99},[69,10420,3067],{},[69,10422,10423],{"class":71,"line":108},[69,10424,1086],{"emptyLinePlaceholder":226},[69,10426,10427],{"class":71,"line":120},[69,10428,3076],{},[69,10430,10431],{"class":71,"line":1138},[69,10432,3081],{},[10,10434,126],{},[60,10436,10438],{"className":10437,"code":3087,"language":132,"meta":65},[130],[43,10439,3087],{"__ignoreMap":65},[10,10441,137],{},[14,10443,140],{"id":140},[142,10445,10446,10452],{},[40,10447,3098,10448,3101,10450,3105],{},[43,10449,3015],{},[43,10451,3104],{},[40,10453,10454,3111,10456,3115],{},[43,10455,3110],{},[43,10457,3114],{},[14,10459,172],{"id":172},[37,10461,10462,10466],{},[40,10463,3122,10464,3126],{},[43,10465,3125],{},[40,10467,3129],{},[14,10469,186],{"id":186},[142,10471,10472,10474],{},[40,10473,3136],{},[40,10475,1710,10476,3142,10478,3145],{},[43,10477,3141],{},[43,10479,3027],{},[10,10481,201],{},[14,10483,204],{"id":204},[10,10485,3152],{},[209,10487,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10489},[10490,10491,10492,10493,10494,10495,10496,10497],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":2992,"description":2997},[222,2335,3172],{"id":3175,"title":3176,"body":10502,"category":222,"cover":223,"description":3181,"extension":224,"meta":10631,"navigation":226,"path":3342,"pinned":228,"publishedAt":229,"seo":10632,"slug":3344,"stem":3345,"summary":3346,"tags":10633,"updatedAt":229,"visible":226,"__hash__":3350},{"type":7,"value":10503,"toc":10621},[10504,10506,10508,10510,10512,10516,10520,10522,10532,10534,10536,10568,10570,10575,10577,10579,10591,10593,10603,10605,10613,10615,10617,10619],[10,10505,3181],{},[14,10507,16],{"id":16},[10,10509,3186],{},[14,10511,22],{"id":22},[10,10513,10514],{},[26,10515],{"alt":3193,"src":3194},[10,10517,3197,10518,3201],{},[43,10519,3200],{},[14,10521,35],{"id":35},[37,10523,10524,10526,10528],{},[40,10525,3208],{},[40,10527,3211],{},[40,10529,3214,10530,195],{},[43,10531,3217],{},[14,10533,55],{"id":55},[10,10535,1428],{},[60,10537,10538],{"className":405,"code":3224,"language":102,"meta":65,"style":65},[43,10539,10540,10544,10548,10552,10556,10560,10564],{"__ignoreMap":65},[69,10541,10542],{"class":71,"line":72},[69,10543,3231],{},[69,10545,10546],{"class":71,"line":90},[69,10547,3236],{},[69,10549,10550],{"class":71,"line":99},[69,10551,1086],{"emptyLinePlaceholder":226},[69,10553,10554],{"class":71,"line":108},[69,10555,3245],{},[69,10557,10558],{"class":71,"line":120},[69,10559,3250],{},[69,10561,10562],{"class":71,"line":1138},[69,10563,3255],{},[69,10565,10566],{"class":71,"line":2478},[69,10567,3260],{},[10,10569,126],{},[60,10571,10573],{"className":10572,"code":3266,"language":132,"meta":65},[130],[43,10574,3266],{"__ignoreMap":65},[10,10576,137],{},[14,10578,140],{"id":140},[142,10580,10581,10583],{},[40,10582,3277],{},[40,10584,10585,3283,10587,3287,10589,3291],{},[43,10586,3282],{},[43,10588,3286],{},[43,10590,3290],{},[14,10592,172],{"id":172},[37,10594,10595,10601],{},[40,10596,3298,10597,3302,10599,195],{},[43,10598,3301],{},[43,10600,3305],{},[40,10602,3308],{},[14,10604,186],{"id":186},[142,10606,10607,10609],{},[40,10608,3315],{},[40,10610,3318,10611,3321],{},[43,10612,3290],{},[10,10614,201],{},[14,10616,204],{"id":204},[10,10618,3328],{},[209,10620,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10622},[10623,10624,10625,10626,10627,10628,10629,10630],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":3176,"description":3181},[222,3348,3349],{"id":3352,"title":3353,"body":10635,"category":222,"cover":223,"description":3358,"extension":224,"meta":10754,"navigation":226,"path":3499,"pinned":228,"publishedAt":229,"seo":10755,"slug":3501,"stem":3502,"summary":3503,"tags":10756,"updatedAt":229,"visible":226,"__hash__":3506},{"type":7,"value":10636,"toc":10744},[10637,10639,10641,10643,10645,10649,10651,10653,10661,10663,10665,10693,10695,10700,10702,10704,10714,10716,10724,10726,10736,10738,10740,10742],[10,10638,3358],{},[14,10640,16],{"id":16},[10,10642,3363],{},[14,10644,22],{"id":22},[10,10646,10647],{},[26,10648],{"alt":3370,"src":3371},[10,10650,3374],{},[14,10652,35],{"id":35},[37,10654,10655,10657,10659],{},[40,10656,3381],{},[40,10658,3384],{},[40,10660,3387],{},[14,10662,55],{"id":55},[10,10664,1428],{},[60,10666,10667],{"className":405,"code":3394,"language":102,"meta":65,"style":65},[43,10668,10669,10673,10677,10681,10685,10689],{"__ignoreMap":65},[69,10670,10671],{"class":71,"line":72},[69,10672,3401],{},[69,10674,10675],{"class":71,"line":90},[69,10676,3406],{},[69,10678,10679],{"class":71,"line":99},[69,10680,3411],{},[69,10682,10683],{"class":71,"line":108},[69,10684,1086],{"emptyLinePlaceholder":226},[69,10686,10687],{"class":71,"line":120},[69,10688,3420],{},[69,10690,10691],{"class":71,"line":1138},[69,10692,3425],{},[10,10694,126],{},[60,10696,10698],{"className":10697,"code":3431,"language":132,"meta":65},[130],[43,10699,3431],{"__ignoreMap":65},[10,10701,137],{},[14,10703,140],{"id":140},[142,10705,10706,10710],{},[40,10707,10708,3445],{},[43,10709,3444],{},[40,10711,10712,3451],{},[43,10713,3450],{},[14,10715,172],{"id":172},[37,10717,10718,10722],{},[40,10719,180,10720,3461],{},[43,10721,3460],{},[40,10723,3464],{},[14,10725,186],{"id":186},[142,10727,10728,10730],{},[40,10729,3471],{},[40,10731,2163,10732,158,10734,3478],{},[43,10733,3460],{},[43,10735,3450],{},[10,10737,201],{},[14,10739,204],{"id":204},[10,10741,3485],{},[209,10743,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10745},[10746,10747,10748,10749,10750,10751,10752,10753],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":3353,"description":3358},[222,3505,3349],{"id":3508,"title":3509,"body":10758,"category":222,"cover":223,"description":3514,"extension":224,"meta":10883,"navigation":226,"path":3670,"pinned":228,"publishedAt":229,"seo":10884,"slug":3672,"stem":3673,"summary":3674,"tags":10885,"updatedAt":229,"visible":226,"__hash__":3677},{"type":7,"value":10759,"toc":10873},[10760,10762,10764,10766,10768,10772,10778,10780,10790,10792,10794,10822,10824,10829,10831,10833,10843,10845,10857,10859,10865,10867,10869,10871],[10,10761,3514],{},[14,10763,16],{"id":16},[10,10765,3519],{},[14,10767,22],{"id":22},[10,10769,10770],{},[26,10771],{"alt":3526,"src":3527},[10,10773,3530,10774,3534,10776,3537],{},[43,10775,3533],{},[43,10777,2235],{},[14,10779,35],{"id":35},[37,10781,10782,10784,10788],{},[40,10783,3544],{},[40,10785,2328,10786,3550],{},[43,10787,3549],{},[40,10789,3553],{},[14,10791,55],{"id":55},[10,10793,1428],{},[60,10795,10796],{"className":405,"code":3560,"language":102,"meta":65,"style":65},[43,10797,10798,10802,10806,10810,10814,10818],{"__ignoreMap":65},[69,10799,10800],{"class":71,"line":72},[69,10801,3567],{},[69,10803,10804],{"class":71,"line":90},[69,10805,3572],{},[69,10807,10808],{"class":71,"line":99},[69,10809,1086],{"emptyLinePlaceholder":226},[69,10811,10812],{"class":71,"line":108},[69,10813,3581],{},[69,10815,10816],{"class":71,"line":120},[69,10817,3586],{},[69,10819,10820],{"class":71,"line":1138},[69,10821,3591],{},[10,10823,126],{},[60,10825,10827],{"className":10826,"code":3597,"language":132,"meta":65},[130],[43,10828,3597],{"__ignoreMap":65},[10,10830,137],{},[14,10832,140],{"id":140},[142,10834,10835,10837],{},[40,10836,3608],{},[40,10838,3611,10839,3614,10841,3618],{},[43,10840,2235],{},[43,10842,3617],{},[14,10844,172],{"id":172},[37,10846,10847,10851],{},[40,10848,3625,10849,3629],{},[43,10850,3628],{},[40,10852,3632,10853,3636,10855,195],{},[43,10854,3635],{},[43,10856,3639],{},[14,10858,186],{"id":186},[142,10860,10861,10863],{},[40,10862,3646],{},[40,10864,3649],{},[10,10866,201],{},[14,10868,204],{"id":204},[10,10870,3656],{},[209,10872,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":10874},[10875,10876,10877,10878,10879,10880,10881,10882],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":3509,"description":3514},[222,3676,3349],{"id":3679,"title":3680,"body":10887,"category":222,"cover":223,"description":3685,"extension":224,"meta":11010,"navigation":226,"path":3834,"pinned":228,"publishedAt":229,"seo":11011,"slug":3836,"stem":3837,"summary":3838,"tags":11012,"updatedAt":229,"visible":226,"__hash__":3841},{"type":7,"value":10888,"toc":11000},[10889,10891,10893,10895,10897,10901,10903,10905,10917,10919,10921,10949,10951,10956,10958,10960,10970,10972,10982,10984,10992,10994,10996,10998],[10,10890,3685],{},[14,10892,16],{"id":16},[10,10894,3690],{},[14,10896,22],{"id":22},[10,10898,10899],{},[26,10900],{"alt":3697,"src":3698},[10,10902,3701],{},[14,10904,35],{"id":35},[37,10906,10907,10909,10911],{},[40,10908,3708],{},[40,10910,3711],{},[40,10912,3714,10913,165,10915,3721],{},[43,10914,3717],{},[43,10916,3720],{},[14,10918,55],{"id":55},[10,10920,1428],{},[60,10922,10923],{"className":405,"code":3728,"language":102,"meta":65,"style":65},[43,10924,10925,10929,10933,10937,10941,10945],{"__ignoreMap":65},[69,10926,10927],{"class":71,"line":72},[69,10928,3735],{},[69,10930,10931],{"class":71,"line":90},[69,10932,3740],{},[69,10934,10935],{"class":71,"line":99},[69,10936,1086],{"emptyLinePlaceholder":226},[69,10938,10939],{"class":71,"line":108},[69,10940,3749],{},[69,10942,10943],{"class":71,"line":120},[69,10944,3754],{},[69,10946,10947],{"class":71,"line":1138},[69,10948,3759],{},[10,10950,126],{},[60,10952,10954],{"className":10953,"code":3765,"language":132,"meta":65},[130],[43,10955,3765],{"__ignoreMap":65},[10,10957,137],{},[14,10959,140],{"id":140},[142,10961,10962,10964],{},[40,10963,3776],{},[40,10965,10966,3782,10968,3786],{},[43,10967,3781],{},[43,10969,3785],{},[14,10971,172],{"id":172},[37,10973,10974,10980],{},[40,10975,2328,10976,3795,10978,195],{},[43,10977,3720],{},[43,10979,3717],{},[40,10981,3800],{},[14,10983,186],{"id":186},[142,10985,10986,10990],{},[40,10987,3807,10988,3810],{},[43,10989,3717],{},[40,10991,3813],{},[10,10993,201],{},[14,10995,204],{"id":204},[10,10997,3820],{},[209,10999,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11001},[11002,11003,11004,11005,11006,11007,11008,11009],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":3680,"description":3685},[222,3840,3349],{"id":3843,"title":3844,"body":11014,"category":222,"cover":223,"description":3849,"extension":224,"meta":11173,"navigation":226,"path":4048,"pinned":228,"publishedAt":229,"seo":11174,"slug":4050,"stem":4051,"summary":4052,"tags":11175,"updatedAt":229,"visible":226,"__hash__":4056},{"type":7,"value":11015,"toc":11161},[11016,11018,11020,11022,11024,11028,11034,11036,11048,11050,11052,11092,11094,11099,11101,11103,11117,11119,11121,11125,11127,11129,11139,11141,11153,11155,11157,11159],[10,11017,3849],{},[14,11019,16],{"id":16},[10,11021,3854],{},[14,11023,22],{"id":22},[10,11025,11026],{},[26,11027],{"alt":3861,"src":3862},[10,11029,11030,3868,11032,3872],{},[43,11031,3867],{},[43,11033,3871],{},[14,11035,35],{"id":35},[37,11037,11038,11044,11046],{},[40,11039,11040,3881,11042,3885],{},[43,11041,2798],{},[43,11043,3884],{},[40,11045,3888],{},[40,11047,3891],{},[14,11049,55],{"id":55},[10,11051,1428],{},[60,11053,11054],{"className":405,"code":3898,"language":102,"meta":65,"style":65},[43,11055,11056,11060,11064,11068,11072,11076,11080,11084,11088],{"__ignoreMap":65},[69,11057,11058],{"class":71,"line":72},[69,11059,3905],{},[69,11061,11062],{"class":71,"line":90},[69,11063,3910],{},[69,11065,11066],{"class":71,"line":99},[69,11067,3915],{},[69,11069,11070],{"class":71,"line":108},[69,11071,1086],{"emptyLinePlaceholder":226},[69,11073,11074],{"class":71,"line":120},[69,11075,3924],{},[69,11077,11078],{"class":71,"line":1138},[69,11079,3929],{},[69,11081,11082],{"class":71,"line":2478},[69,11083,3934],{},[69,11085,11086],{"class":71,"line":2484},[69,11087,3939],{},[69,11089,11090],{"class":71,"line":3942},[69,11091,3945],{},[10,11093,126],{},[60,11095,11097],{"className":11096,"code":3951,"language":132,"meta":65},[130],[43,11098,3951],{"__ignoreMap":65},[10,11100,137],{},[14,11102,140],{"id":140},[142,11104,11105,11109],{},[40,11106,11107,3965],{},[43,11108,3964],{},[40,11110,11111,3971,11113,3975,11115,3979],{},[43,11112,3970],{},[43,11114,3974],{},[43,11116,3978],{},[325,11118,2688],{"id":2688},[10,11120,3984],{},[10,11122,11123],{},[26,11124],{"alt":3989,"src":3990},[10,11126,3993],{},[14,11128,172],{"id":172},[37,11130,11131,11137],{},[40,11132,4000,11133,4003,11135,195],{},[43,11134,2798],{},[43,11136,3884],{},[40,11138,4008],{},[14,11140,186],{"id":186},[142,11142,11143,11145],{},[40,11144,4015],{},[40,11146,2328,11147,4021,11149,1147,11151,195],{},[43,11148,4020],{},[43,11150,3884],{},[43,11152,2798],{},[10,11154,201],{},[14,11156,204],{"id":204},[10,11158,4032],{},[209,11160,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11162},[11163,11164,11165,11166,11167,11170,11171,11172],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":11168},[11169],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":3844,"description":3849},[222,4054,4055],{"id":4058,"title":4059,"body":11177,"category":222,"cover":223,"description":4064,"extension":224,"meta":11349,"navigation":226,"path":4278,"pinned":228,"publishedAt":229,"seo":11350,"slug":4280,"stem":4281,"summary":4282,"tags":11351,"updatedAt":229,"visible":226,"__hash__":4285},{"type":7,"value":11178,"toc":11336},[11179,11181,11183,11185,11187,11191,11199,11201,11209,11211,11213,11257,11259,11264,11266,11268,11280,11282,11284,11288,11294,11296,11298,11302,11306,11308,11320,11322,11328,11330,11332,11334],[10,11180,4064],{},[14,11182,16],{"id":16},[10,11184,4069],{},[14,11186,22],{"id":22},[10,11188,11189],{},[26,11190],{"alt":4076,"src":4077},[10,11192,11193,2246,11195,2246,11197,4087],{},[43,11194,1146],{},[43,11196,4084],{},[43,11198,1150],{},[14,11200,35],{"id":35},[37,11202,11203,11205,11207],{},[40,11204,4094],{},[40,11206,4097],{},[40,11208,4100],{},[14,11210,55],{"id":55},[10,11212,1428],{},[60,11214,11215],{"className":405,"code":4107,"language":102,"meta":65,"style":65},[43,11216,11217,11221,11225,11229,11233,11237,11241,11245,11249,11253],{"__ignoreMap":65},[69,11218,11219],{"class":71,"line":72},[69,11220,4114],{},[69,11222,11223],{"class":71,"line":90},[69,11224,1086],{"emptyLinePlaceholder":226},[69,11226,11227],{"class":71,"line":99},[69,11228,4123],{},[69,11230,11231],{"class":71,"line":108},[69,11232,4128],{},[69,11234,11235],{"class":71,"line":120},[69,11236,4133],{},[69,11238,11239],{"class":71,"line":1138},[69,11240,4138],{},[69,11242,11243],{"class":71,"line":2478},[69,11244,1135],{},[69,11246,11247],{"class":71,"line":2484},[69,11248,4147],{},[69,11250,11251],{"class":71,"line":3942},[69,11252,1086],{"emptyLinePlaceholder":226},[69,11254,11255],{"class":71,"line":4154},[69,11256,4157],{},[10,11258,126],{},[60,11260,11262],{"className":11261,"code":4163,"language":132,"meta":65},[130],[43,11263,4163],{"__ignoreMap":65},[10,11265,137],{},[14,11267,140],{"id":140},[142,11269,11270,11274],{},[40,11271,4174,11272,4178],{},[43,11273,4177],{},[40,11275,11276,4184,11278,4187],{},[43,11277,4183],{},[43,11279,1150],{},[325,11281,2688],{"id":2688},[10,11283,4192],{},[10,11285,11286],{},[26,11287],{"alt":4197,"src":4198},[10,11289,11290,4203,11292,4206],{},[43,11291,4177],{},[43,11293,4183],{},[325,11295,2688],{"id":4209},[10,11297,4212],{},[10,11299,11300],{},[26,11301],{"alt":4217,"src":4218},[10,11303,4221,11304,4224],{},[43,11305,1146],{},[14,11307,172],{"id":172},[37,11309,11310,11314],{},[40,11311,4231,11312,4234],{},[43,11313,4183],{},[40,11315,4237,11316,4240,11318,4244],{},[43,11317,1146],{},[43,11319,4243],{},[14,11321,186],{"id":186},[142,11323,11324,11326],{},[40,11325,4251],{},[40,11327,4254],{},[10,11329,201],{},[14,11331,204],{"id":204},[10,11333,4261],{},[209,11335,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11337},[11338,11339,11340,11341,11342,11346,11347,11348],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":11343},[11344,11345],{"id":2688,"depth":99,"text":2688},{"id":4209,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":4059,"description":4064},[222,1146,4284],{"id":4287,"title":4288,"body":11353,"category":222,"cover":223,"description":4293,"extension":224,"meta":11490,"navigation":226,"path":4460,"pinned":228,"publishedAt":229,"seo":11491,"slug":4462,"stem":4463,"summary":4464,"tags":11492,"updatedAt":229,"visible":226,"__hash__":4467},{"type":7,"value":11354,"toc":11478},[11355,11357,11359,11361,11363,11367,11371,11373,11383,11385,11387,11419,11421,11426,11428,11430,11440,11442,11444,11448,11452,11454,11460,11462,11470,11472,11474,11476],[10,11356,4293],{},[14,11358,16],{"id":16},[10,11360,4298],{},[14,11362,22],{"id":22},[10,11364,11365],{},[26,11366],{"alt":4305,"src":4306},[10,11368,11369,4312],{},[43,11370,4311],{},[14,11372,35],{"id":35},[37,11374,11375,11377,11379],{},[40,11376,4319],{},[40,11378,4322],{},[40,11380,4325,11381,4329],{},[43,11382,4328],{},[14,11384,55],{"id":55},[10,11386,1428],{},[60,11388,11389],{"className":405,"code":4336,"language":102,"meta":65,"style":65},[43,11390,11391,11395,11399,11403,11407,11411,11415],{"__ignoreMap":65},[69,11392,11393],{"class":71,"line":72},[69,11394,4343],{},[69,11396,11397],{"class":71,"line":90},[69,11398,1086],{"emptyLinePlaceholder":226},[69,11400,11401],{"class":71,"line":99},[69,11402,4352],{},[69,11404,11405],{"class":71,"line":108},[69,11406,4357],{},[69,11408,11409],{"class":71,"line":120},[69,11410,4362],{},[69,11412,11413],{"class":71,"line":1138},[69,11414,1086],{"emptyLinePlaceholder":226},[69,11416,11417],{"class":71,"line":2478},[69,11418,4371],{},[10,11420,126],{},[60,11422,11424],{"className":11423,"code":4377,"language":132,"meta":65},[130],[43,11425,4377],{"__ignoreMap":65},[10,11427,137],{},[14,11429,140],{"id":140},[142,11431,11432,11436],{},[40,11433,4388,11434,4392],{},[43,11435,4391],{},[40,11437,4395,11438,4398],{},[43,11439,4391],{},[325,11441,2688],{"id":2688},[10,11443,4403],{},[10,11445,11446],{},[26,11447],{"alt":4408,"src":4409},[10,11449,4412,11450,4415],{},[43,11451,4391],{},[14,11453,172],{"id":172},[37,11455,11456,11458],{},[40,11457,4422],{},[40,11459,4425],{},[14,11461,186],{"id":186},[142,11463,11464,11468],{},[40,11465,2328,11466,4434],{},[43,11467,4311],{},[40,11469,4437],{},[10,11471,201],{},[14,11473,204],{"id":204},[10,11475,4444],{},[209,11477,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11479},[11480,11481,11482,11483,11484,11487,11488,11489],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":11485},[11486],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":4288,"description":4293},[222,4311,4466],{"id":4469,"title":4470,"body":11494,"category":222,"cover":223,"description":4475,"extension":224,"meta":11619,"navigation":226,"path":4624,"pinned":228,"publishedAt":229,"seo":11620,"slug":4626,"stem":4627,"summary":4628,"tags":11621,"updatedAt":229,"visible":226,"__hash__":4631},{"type":7,"value":11495,"toc":11609},[11496,11498,11500,11502,11504,11508,11512,11514,11524,11526,11528,11560,11562,11567,11569,11571,11583,11585,11591,11593,11601,11603,11605,11607],[10,11497,4475],{},[14,11499,16],{"id":16},[10,11501,4480],{},[14,11503,22],{"id":22},[10,11505,11506],{},[26,11507],{"alt":4487,"src":4488},[10,11509,11510,4493],{},[43,11511,4328],{},[14,11513,35],{"id":35},[37,11515,11516,11520,11522],{},[40,11517,11518,4503],{},[43,11519,4502],{},[40,11521,4506],{},[40,11523,4509],{},[14,11525,55],{"id":55},[10,11527,1428],{},[60,11529,11530],{"className":405,"code":4516,"language":102,"meta":65,"style":65},[43,11531,11532,11536,11540,11544,11548,11552,11556],{"__ignoreMap":65},[69,11533,11534],{"class":71,"line":72},[69,11535,4523],{},[69,11537,11538],{"class":71,"line":90},[69,11539,1086],{"emptyLinePlaceholder":226},[69,11541,11542],{"class":71,"line":99},[69,11543,4532],{},[69,11545,11546],{"class":71,"line":108},[69,11547,4537],{},[69,11549,11550],{"class":71,"line":120},[69,11551,1086],{"emptyLinePlaceholder":226},[69,11553,11554],{"class":71,"line":1138},[69,11555,4546],{},[69,11557,11558],{"class":71,"line":2478},[69,11559,4551],{},[10,11561,126],{},[60,11563,11565],{"className":11564,"code":4557,"language":132,"meta":65},[130],[43,11566,4557],{"__ignoreMap":65},[10,11568,137],{},[14,11570,140],{"id":140},[142,11572,11573,11579],{},[40,11574,4568,11575,4571,11577,4575],{},[43,11576,4328],{},[43,11578,4574],{},[40,11580,11581,4580],{},[43,11582,4502],{},[14,11584,172],{"id":172},[37,11586,11587,11589],{},[40,11588,4587],{},[40,11590,4590],{},[14,11592,186],{"id":186},[142,11594,11595,11597],{},[40,11596,4597],{},[40,11598,2328,11599,4603],{},[43,11600,4602],{},[10,11602,201],{},[14,11604,204],{"id":204},[10,11606,4610],{},[209,11608,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11610},[11611,11612,11613,11614,11615,11616,11617,11618],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":4470,"description":4475},[222,4328,4630],{"id":4633,"title":4634,"body":11623,"category":222,"cover":223,"description":4639,"extension":224,"meta":11768,"navigation":226,"path":4814,"pinned":228,"publishedAt":229,"seo":11769,"slug":4816,"stem":4817,"summary":4818,"tags":11770,"updatedAt":229,"visible":226,"__hash__":4820},{"type":7,"value":11624,"toc":11758},[11625,11627,11629,11631,11633,11637,11643,11645,11659,11661,11663,11707,11709,11714,11716,11718,11728,11730,11742,11744,11750,11752,11754,11756],[10,11626,4639],{},[14,11628,16],{"id":16},[10,11630,4644],{},[14,11632,22],{"id":22},[10,11634,11635],{},[26,11636],{"alt":4651,"src":4652},[10,11638,11639,4658,11641,4662],{},[43,11640,4657],{},[43,11642,4661],{},[14,11644,35],{"id":35},[37,11646,11647,11649,11655],{},[40,11648,4669],{},[40,11650,11651,4674,11653,4677],{},[43,11652,4657],{},[43,11654,4311],{},[40,11656,4680,11657,4683],{},[43,11658,4661],{},[14,11660,55],{"id":55},[10,11662,1428],{},[60,11664,11665],{"className":405,"code":4690,"language":102,"meta":65,"style":65},[43,11666,11667,11671,11675,11679,11683,11687,11691,11695,11699,11703],{"__ignoreMap":65},[69,11668,11669],{"class":71,"line":72},[69,11670,4697],{},[69,11672,11673],{"class":71,"line":90},[69,11674,1086],{"emptyLinePlaceholder":226},[69,11676,11677],{"class":71,"line":99},[69,11678,4706],{},[69,11680,11681],{"class":71,"line":108},[69,11682,4711],{},[69,11684,11685],{"class":71,"line":120},[69,11686,4716],{},[69,11688,11689],{"class":71,"line":1138},[69,11690,4721],{},[69,11692,11693],{"class":71,"line":2478},[69,11694,4726],{},[69,11696,11697],{"class":71,"line":2484},[69,11698,4551],{},[69,11700,11701],{"class":71,"line":3942},[69,11702,1086],{"emptyLinePlaceholder":226},[69,11704,11705],{"class":71,"line":4154},[69,11706,4739],{},[10,11708,126],{},[60,11710,11712],{"className":11711,"code":4745,"language":132,"meta":65},[130],[43,11713,4745],{"__ignoreMap":65},[10,11715,137],{},[14,11717,140],{"id":140},[142,11719,11720,11724],{},[40,11721,4756,11722,4759],{},[43,11723,4657],{},[40,11725,4762,11726,4765],{},[43,11727,4661],{},[14,11729,172],{"id":172},[37,11731,11732,11736],{},[40,11733,180,11734,4774],{},[43,11735,4657],{},[40,11737,4777,11738,4780,11740,4783],{},[43,11739,4311],{},[43,11741,4657],{},[14,11743,186],{"id":186},[142,11745,11746,11748],{},[40,11747,4790],{},[40,11749,4793],{},[10,11751,201],{},[14,11753,204],{"id":204},[10,11755,4800],{},[209,11757,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11759},[11760,11761,11762,11763,11764,11765,11766,11767],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":4634,"description":4639},[222,4661,4657],{"id":4822,"title":4823,"body":11772,"category":222,"cover":223,"description":4828,"extension":224,"meta":11911,"navigation":226,"path":5000,"pinned":228,"publishedAt":229,"seo":11912,"slug":5002,"stem":5003,"summary":5004,"tags":11913,"updatedAt":229,"visible":226,"__hash__":5008},{"type":7,"value":11773,"toc":11899},[11774,11776,11778,11780,11782,11786,11788,11790,11806,11808,11810,11838,11840,11845,11847,11849,11861,11863,11865,11869,11871,11873,11883,11885,11891,11893,11895,11897],[10,11775,4828],{},[14,11777,16],{"id":16},[10,11779,4833],{},[14,11781,22],{"id":22},[10,11783,11784],{},[26,11785],{"alt":4840,"src":4841},[10,11787,4844],{},[14,11789,35],{"id":35},[37,11791,11792,11794,11796],{},[40,11793,4851],{},[40,11795,4854],{},[40,11797,4857,11798,2246,11800,4864,11802,2246,11804,195],{},[43,11799,4860],{},[43,11801,4863],{},[43,11803,4867],{},[43,11805,4870],{},[14,11807,55],{"id":55},[10,11809,1428],{},[60,11811,11812],{"className":405,"code":4877,"language":102,"meta":65,"style":65},[43,11813,11814,11818,11822,11826,11830,11834],{"__ignoreMap":65},[69,11815,11816],{"class":71,"line":72},[69,11817,4884],{},[69,11819,11820],{"class":71,"line":90},[69,11821,1086],{"emptyLinePlaceholder":226},[69,11823,11824],{"class":71,"line":99},[69,11825,4893],{},[69,11827,11828],{"class":71,"line":108},[69,11829,4898],{},[69,11831,11832],{"class":71,"line":120},[69,11833,4903],{},[69,11835,11836],{"class":71,"line":1138},[69,11837,4908],{},[10,11839,126],{},[60,11841,11843],{"className":11842,"code":4914,"language":132,"meta":65},[130],[43,11844,4914],{"__ignoreMap":65},[10,11846,137],{},[14,11848,140],{"id":140},[142,11850,11851,11859],{},[40,11852,4925,11853,4928,11855,1147,11857,195],{},[43,11854,4860],{},[43,11856,4931],{},[43,11858,4934],{},[40,11860,4937],{},[325,11862,2688],{"id":2688},[10,11864,4942],{},[10,11866,11867],{},[26,11868],{"alt":4947,"src":4948},[10,11870,4951],{},[14,11872,172],{"id":172},[37,11874,11875,11881],{},[40,11876,4958,11877,997,11879,4964],{},[43,11878,4961],{},[43,11880,4867],{},[40,11882,4967],{},[14,11884,186],{"id":186},[142,11886,11887,11889],{},[40,11888,4974],{},[40,11890,4977],{},[10,11892,201],{},[14,11894,204],{"id":204},[10,11896,4984],{},[209,11898,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":11900},[11901,11902,11903,11904,11905,11908,11909,11910],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":11906},[11907],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":4823,"description":4828},[222,5006,5007],{"id":5010,"title":5011,"body":11915,"category":222,"cover":223,"description":5016,"extension":224,"meta":12032,"navigation":226,"path":5155,"pinned":228,"publishedAt":229,"seo":12033,"slug":5157,"stem":5158,"summary":5159,"tags":12034,"updatedAt":229,"visible":226,"__hash__":5163},{"type":7,"value":11916,"toc":12022},[11917,11919,11921,11923,11925,11929,11931,11933,11941,11943,11945,11977,11979,11984,11986,11988,11996,11998,12006,12008,12014,12016,12018,12020],[10,11918,5016],{},[14,11920,16],{"id":16},[10,11922,5021],{},[14,11924,22],{"id":22},[10,11926,11927],{},[26,11928],{"alt":5028,"src":5029},[10,11930,5032],{},[14,11932,35],{"id":35},[37,11934,11935,11937,11939],{},[40,11936,5039],{},[40,11938,5042],{},[40,11940,5045],{},[14,11942,55],{"id":55},[10,11944,1428],{},[60,11946,11947],{"className":405,"code":5052,"language":102,"meta":65,"style":65},[43,11948,11949,11953,11957,11961,11965,11969,11973],{"__ignoreMap":65},[69,11950,11951],{"class":71,"line":72},[69,11952,5059],{},[69,11954,11955],{"class":71,"line":90},[69,11956,1086],{"emptyLinePlaceholder":226},[69,11958,11959],{"class":71,"line":99},[69,11960,5068],{},[69,11962,11963],{"class":71,"line":108},[69,11964,5073],{},[69,11966,11967],{"class":71,"line":120},[69,11968,1086],{"emptyLinePlaceholder":226},[69,11970,11971],{"class":71,"line":1138},[69,11972,5082],{},[69,11974,11975],{"class":71,"line":2478},[69,11976,5087],{},[10,11978,126],{},[60,11980,11982],{"className":11981,"code":5093,"language":132,"meta":65},[130],[43,11983,5093],{"__ignoreMap":65},[10,11985,137],{},[14,11987,140],{"id":140},[142,11989,11990,11992],{},[40,11991,5104],{},[40,11993,5107,11994,5111],{},[43,11995,5110],{},[14,11997,172],{"id":172},[37,11999,12000,12004],{},[40,12001,5118,12002,5121],{},[43,12003,4328],{},[40,12005,5124],{},[14,12007,186],{"id":186},[142,12009,12010,12012],{},[40,12011,5131],{},[40,12013,5134],{},[10,12015,201],{},[14,12017,204],{"id":204},[10,12019,5141],{},[209,12021,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12023},[12024,12025,12026,12027,12028,12029,12030,12031],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5011,"description":5016},[222,5161,5162],{"id":5165,"title":5166,"body":12036,"category":222,"cover":223,"description":5171,"extension":224,"meta":12155,"navigation":226,"path":5315,"pinned":228,"publishedAt":229,"seo":12156,"slug":5317,"stem":5318,"summary":5319,"tags":12157,"updatedAt":229,"visible":226,"__hash__":5323},{"type":7,"value":12037,"toc":12145},[12038,12040,12042,12044,12046,12050,12052,12054,12062,12064,12066,12098,12100,12105,12107,12109,12119,12121,12127,12129,12137,12139,12141,12143],[10,12039,5171],{},[14,12041,16],{"id":16},[10,12043,5176],{},[14,12045,22],{"id":22},[10,12047,12048],{},[26,12049],{"alt":5183,"src":5184},[10,12051,5187],{},[14,12053,35],{"id":35},[37,12055,12056,12058,12060],{},[40,12057,5194],{},[40,12059,5197],{},[40,12061,5200],{},[14,12063,55],{"id":55},[10,12065,1428],{},[60,12067,12068],{"className":405,"code":5207,"language":102,"meta":65,"style":65},[43,12069,12070,12074,12078,12082,12086,12090,12094],{"__ignoreMap":65},[69,12071,12072],{"class":71,"line":72},[69,12073,5214],{},[69,12075,12076],{"class":71,"line":90},[69,12077,5219],{},[69,12079,12080],{"class":71,"line":99},[69,12081,5224],{},[69,12083,12084],{"class":71,"line":108},[69,12085,1086],{"emptyLinePlaceholder":226},[69,12087,12088],{"class":71,"line":120},[69,12089,5233],{},[69,12091,12092],{"class":71,"line":1138},[69,12093,5238],{},[69,12095,12096],{"class":71,"line":2478},[69,12097,5243],{},[10,12099,126],{},[60,12101,12103],{"className":12102,"code":5249,"language":132,"meta":65},[130],[43,12104,5249],{"__ignoreMap":65},[10,12106,137],{},[14,12108,140],{"id":140},[142,12110,12111,12115],{},[40,12112,926,12113,5263],{},[43,12114,5262],{},[40,12116,5266,12117,5270],{},[43,12118,5269],{},[14,12120,172],{"id":172},[37,12122,12123,12125],{},[40,12124,5277],{},[40,12126,5280],{},[14,12128,186],{"id":186},[142,12130,12131,12135],{},[40,12132,5287,12133,5291],{},[43,12134,5290],{},[40,12136,5294],{},[10,12138,201],{},[14,12140,204],{"id":204},[10,12142,5301],{},[209,12144,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12146},[12147,12148,12149,12150,12151,12152,12153,12154],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5166,"description":5171},[222,5321,5322],{"id":5325,"title":5326,"body":12159,"category":222,"cover":223,"description":5331,"extension":224,"meta":12304,"navigation":226,"path":5512,"pinned":228,"publishedAt":229,"seo":12305,"slug":5514,"stem":5515,"summary":5516,"tags":12306,"updatedAt":229,"visible":226,"__hash__":5520},{"type":7,"value":12160,"toc":12292},[12161,12163,12165,12167,12169,12173,12177,12179,12191,12193,12195,12223,12225,12230,12232,12234,12248,12250,12252,12256,12264,12266,12276,12278,12284,12286,12288,12290],[10,12162,5331],{},[14,12164,16],{"id":16},[10,12166,5336],{},[14,12168,22],{"id":22},[10,12170,12171],{},[26,12172],{"alt":5343,"src":5344},[10,12174,5347,12175,5351],{},[43,12176,5350],{},[14,12178,35],{"id":35},[37,12180,12181,12183,12185],{},[40,12182,5358],{},[40,12184,5361],{},[40,12186,5364,12187,5367,12189,195],{},[43,12188,5350],{},[43,12190,5370],{},[14,12192,55],{"id":55},[10,12194,1428],{},[60,12196,12197],{"className":405,"code":5377,"language":102,"meta":65,"style":65},[43,12198,12199,12203,12207,12211,12215,12219],{"__ignoreMap":65},[69,12200,12201],{"class":71,"line":72},[69,12202,5384],{},[69,12204,12205],{"class":71,"line":90},[69,12206,5389],{},[69,12208,12209],{"class":71,"line":99},[69,12210,5394],{},[69,12212,12213],{"class":71,"line":108},[69,12214,1086],{"emptyLinePlaceholder":226},[69,12216,12217],{"class":71,"line":120},[69,12218,5403],{},[69,12220,12221],{"class":71,"line":1138},[69,12222,5408],{},[10,12224,126],{},[60,12226,12228],{"className":12227,"code":5414,"language":132,"meta":65},[130],[43,12229,5414],{"__ignoreMap":65},[10,12231,137],{},[14,12233,140],{"id":140},[142,12235,12236,12242],{},[40,12237,5425,12238,2246,12240,5431],{},[43,12239,5428],{},[43,12241,4391],{},[40,12243,12244,5437,12246,5441],{},[43,12245,5436],{},[43,12247,5440],{},[325,12249,2688],{"id":2688},[10,12251,5446],{},[10,12253,12254],{},[26,12255],{"alt":5451,"src":5452},[10,12257,12258,2246,12260,1147,12262,5462],{},[43,12259,5428],{},[43,12261,4391],{},[43,12263,5461],{},[14,12265,172],{"id":172},[37,12267,12268,12272],{},[40,12269,5469,12270,5473],{},[43,12271,5472],{},[40,12273,5476,12274,5479],{},[43,12275,5461],{},[14,12277,186],{"id":186},[142,12279,12280,12282],{},[40,12281,5486],{},[40,12283,5489],{},[10,12285,201],{},[14,12287,204],{"id":204},[10,12289,5496],{},[209,12291,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12293},[12294,12295,12296,12297,12298,12301,12302,12303],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":12299},[12300],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5326,"description":5331},[222,5518,5519],{"id":5522,"title":5523,"body":12308,"category":222,"cover":223,"description":5528,"extension":224,"meta":12457,"navigation":226,"path":5709,"pinned":228,"publishedAt":229,"seo":12458,"slug":5711,"stem":5712,"summary":5713,"tags":12459,"updatedAt":229,"visible":226,"__hash__":5717},{"type":7,"value":12309,"toc":12445},[12310,12312,12314,12316,12318,12322,12324,12326,12338,12340,12342,12386,12388,12393,12395,12397,12409,12411,12413,12417,12419,12421,12429,12431,12437,12439,12441,12443],[10,12311,5528],{},[14,12313,16],{"id":16},[10,12315,5533],{},[14,12317,22],{"id":22},[10,12319,12320],{},[26,12321],{"alt":5540,"src":5541},[10,12323,5544],{},[14,12325,35],{"id":35},[37,12327,12328,12330,12334],{},[40,12329,5551],{},[40,12331,12332,5557],{},[43,12333,5556],{},[40,12335,12336,5563],{},[43,12337,5562],{},[14,12339,55],{"id":55},[10,12341,1428],{},[60,12343,12344],{"className":405,"code":5570,"language":102,"meta":65,"style":65},[43,12345,12346,12350,12354,12358,12362,12366,12370,12374,12378,12382],{"__ignoreMap":65},[69,12347,12348],{"class":71,"line":72},[69,12349,5577],{},[69,12351,12352],{"class":71,"line":90},[69,12353,5582],{},[69,12355,12356],{"class":71,"line":99},[69,12357,1086],{"emptyLinePlaceholder":226},[69,12359,12360],{"class":71,"line":108},[69,12361,5591],{},[69,12363,12364],{"class":71,"line":120},[69,12365,5596],{},[69,12367,12368],{"class":71,"line":1138},[69,12369,1086],{"emptyLinePlaceholder":226},[69,12371,12372],{"class":71,"line":2478},[69,12373,5605],{},[69,12375,12376],{"class":71,"line":2484},[69,12377,5610],{},[69,12379,12380],{"class":71,"line":3942},[69,12381,1086],{"emptyLinePlaceholder":226},[69,12383,12384],{"class":71,"line":4154},[69,12385,5619],{},[10,12387,126],{},[60,12389,12391],{"className":12390,"code":5625,"language":132,"meta":65},[130],[43,12392,5625],{"__ignoreMap":65},[10,12394,137],{},[14,12396,140],{"id":140},[142,12398,12399,12403],{},[40,12400,5636,12401,5640],{},[43,12402,5639],{},[40,12404,12405,5646,12407,195],{},[43,12406,5645],{},[43,12408,5649],{},[325,12410,2688],{"id":2688},[10,12412,5654],{},[10,12414,12415],{},[26,12416],{"alt":5659,"src":5660},[10,12418,5663],{},[14,12420,172],{"id":172},[37,12422,12423,12427],{},[40,12424,5670,12425,5673],{},[43,12426,5370],{},[40,12428,5676],{},[14,12430,186],{"id":186},[142,12432,12433,12435],{},[40,12434,5683],{},[40,12436,5686],{},[10,12438,201],{},[14,12440,204],{"id":204},[10,12442,5693],{},[209,12444,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12446},[12447,12448,12449,12450,12451,12454,12455,12456],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":12452},[12453],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5523,"description":5528},[222,5715,5716],{"id":5719,"title":5720,"body":12461,"category":222,"cover":223,"description":5725,"extension":224,"meta":12622,"navigation":226,"path":5923,"pinned":228,"publishedAt":229,"seo":12623,"slug":5925,"stem":5926,"summary":5927,"tags":12624,"updatedAt":229,"visible":226,"__hash__":5931},{"type":7,"value":12462,"toc":12610},[12463,12465,12467,12469,12471,12475,12477,12479,12491,12493,12495,12547,12549,12554,12556,12558,12576,12578,12580,12584,12586,12588,12594,12596,12602,12604,12606,12608],[10,12464,5725],{},[14,12466,16],{"id":16},[10,12468,5730],{},[14,12470,22],{"id":22},[10,12472,12473],{},[26,12474],{"alt":5737,"src":5738},[10,12476,5741],{},[14,12478,35],{"id":35},[37,12480,12481,12483,12485],{},[40,12482,5748],{},[40,12484,5751],{},[40,12486,12487,158,12489,5760],{},[43,12488,5756],{},[43,12490,5759],{},[14,12492,55],{"id":55},[10,12494,1428],{},[60,12496,12497],{"className":405,"code":5767,"language":102,"meta":65,"style":65},[43,12498,12499,12503,12507,12511,12515,12519,12523,12527,12531,12535,12539,12543],{"__ignoreMap":65},[69,12500,12501],{"class":71,"line":72},[69,12502,5774],{},[69,12504,12505],{"class":71,"line":90},[69,12506,1086],{"emptyLinePlaceholder":226},[69,12508,12509],{"class":71,"line":99},[69,12510,5783],{},[69,12512,12513],{"class":71,"line":108},[69,12514,5788],{},[69,12516,12517],{"class":71,"line":120},[69,12518,1086],{"emptyLinePlaceholder":226},[69,12520,12521],{"class":71,"line":1138},[69,12522,5797],{},[69,12524,12525],{"class":71,"line":2478},[69,12526,5802],{},[69,12528,12529],{"class":71,"line":2484},[69,12530,5807],{},[69,12532,12533],{"class":71,"line":3942},[69,12534,1086],{"emptyLinePlaceholder":226},[69,12536,12537],{"class":71,"line":4154},[69,12538,5816],{},[69,12540,12541],{"class":71,"line":5819},[69,12542,1086],{"emptyLinePlaceholder":226},[69,12544,12545],{"class":71,"line":5824},[69,12546,5827],{},[10,12548,126],{},[60,12550,12552],{"className":12551,"code":5833,"language":132,"meta":65},[130],[43,12553,5833],{"__ignoreMap":65},[10,12555,137],{},[14,12557,140],{"id":140},[142,12559,12560,12570],{},[40,12561,12562,5847,12564,5851,12566,5854,12568,5858],{},[43,12563,5846],{},[43,12565,5850],{},[43,12567,5639],{},[43,12569,5857],{},[40,12571,12572,5863,12574,5866],{},[43,12573,4574],{},[43,12575,2197],{},[325,12577,2688],{"id":2688},[10,12579,5871],{},[10,12581,12582],{},[26,12583],{"alt":5876,"src":5877},[10,12585,5880],{},[14,12587,172],{"id":172},[37,12589,12590,12592],{},[40,12591,5887],{},[40,12593,5890],{},[14,12595,186],{"id":186},[142,12597,12598,12600],{},[40,12599,5897],{},[40,12601,5900],{},[10,12603,201],{},[14,12605,204],{"id":204},[10,12607,5907],{},[209,12609,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12611},[12612,12613,12614,12615,12616,12619,12620,12621],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":12617},[12618],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5720,"description":5725},[222,5929,5930],{"id":5933,"title":5934,"body":12626,"category":222,"cover":223,"description":5939,"extension":224,"meta":12749,"navigation":226,"path":6090,"pinned":228,"publishedAt":229,"seo":12750,"slug":6092,"stem":6093,"summary":6094,"tags":12751,"updatedAt":229,"visible":226,"__hash__":6098},{"type":7,"value":12627,"toc":12739},[12628,12630,12632,12634,12636,12640,12642,12644,12658,12660,12662,12690,12692,12697,12699,12701,12711,12713,12721,12723,12731,12733,12735,12737],[10,12629,5939],{},[14,12631,16],{"id":16},[10,12633,5944],{},[14,12635,22],{"id":22},[10,12637,12638],{},[26,12639],{"alt":5951,"src":5952},[10,12641,5955],{},[14,12643,35],{"id":35},[37,12645,12646,12648,12650],{},[40,12647,5962],{},[40,12649,5965],{},[40,12651,5968,12652,2246,12654,2246,12656,5976],{},[43,12653,2249],{},[43,12655,2415],{},[43,12657,5975],{},[14,12659,55],{"id":55},[10,12661,1428],{},[60,12663,12664],{"className":405,"code":5983,"language":102,"meta":65,"style":65},[43,12665,12666,12670,12674,12678,12682,12686],{"__ignoreMap":65},[69,12667,12668],{"class":71,"line":72},[69,12669,5990],{},[69,12671,12672],{"class":71,"line":90},[69,12673,5995],{},[69,12675,12676],{"class":71,"line":99},[69,12677,6000],{},[69,12679,12680],{"class":71,"line":108},[69,12681,1086],{"emptyLinePlaceholder":226},[69,12683,12684],{"class":71,"line":120},[69,12685,6009],{},[69,12687,12688],{"class":71,"line":1138},[69,12689,6014],{},[10,12691,126],{},[60,12693,12695],{"className":12694,"code":6020,"language":132,"meta":65},[130],[43,12696,6020],{"__ignoreMap":65},[10,12698,137],{},[14,12700,140],{"id":140},[142,12702,12703,12709],{},[40,12704,6031,12705,6035,12707,6038],{},[43,12706,6034],{},[43,12708,2235],{},[40,12710,6041],{},[14,12712,172],{"id":172},[37,12714,12715,12719],{},[40,12716,6048,12717,6052],{},[43,12718,6051],{},[40,12720,6055],{},[14,12722,186],{"id":186},[142,12724,12725,12727],{},[40,12726,6062],{},[40,12728,6065,12729,6069],{},[43,12730,6068],{},[10,12732,201],{},[14,12734,204],{"id":204},[10,12736,6076],{},[209,12738,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12740},[12741,12742,12743,12744,12745,12746,12747,12748],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5934,"description":5939},[222,6096,6097],{"id":6100,"title":6101,"body":12753,"category":222,"cover":223,"description":6106,"extension":224,"meta":12930,"navigation":226,"path":6334,"pinned":228,"publishedAt":229,"seo":12931,"slug":6336,"stem":6337,"summary":6338,"tags":12932,"updatedAt":229,"visible":226,"__hash__":6342},{"type":7,"value":12754,"toc":12918},[12755,12757,12759,12763,12765,12769,12775,12777,12789,12791,12795,12819,12823,12839,12845,12847,12852,12854,12856,12872,12874,12876,12880,12884,12886,12898,12900,12910,12912,12914,12916],[10,12756,6106],{},[14,12758,16],{"id":16},[10,12760,6111,12761,6114],{},[291,12762,6034],{},[14,12764,22],{"id":22},[10,12766,12767],{},[26,12768],{"alt":6121,"src":6122},[10,12770,6125,12771,6129,12773,6133],{},[43,12772,6128],{},[43,12774,6132],{},[14,12776,35],{"id":35},[37,12778,12779,12783,12785],{},[40,12780,6140,12781,6143],{},[43,12782,1161],{},[40,12784,6146],{},[40,12786,6149,12787,6153],{},[43,12788,6152],{},[14,12790,55],{"id":55},[10,12792,6158,12793,6162],{},[43,12794,6161],{},[60,12796,12797],{"className":405,"code":6165,"language":102,"meta":65,"style":65},[43,12798,12799,12803,12807,12811,12815],{"__ignoreMap":65},[69,12800,12801],{"class":71,"line":72},[69,12802,6172],{},[69,12804,12805],{"class":71,"line":90},[69,12806,6177],{},[69,12808,12809],{"class":71,"line":99},[69,12810,1086],{"emptyLinePlaceholder":226},[69,12812,12813],{"class":71,"line":108},[69,12814,6186],{},[69,12816,12817],{"class":71,"line":120},[69,12818,6191],{},[10,12820,6194,12821,6198],{},[43,12822,6197],{},[60,12824,12825],{"className":405,"code":6201,"language":102,"meta":65,"style":65},[43,12826,12827,12831,12835],{"__ignoreMap":65},[69,12828,12829],{"class":71,"line":72},[69,12830,6208],{},[69,12832,12833],{"class":71,"line":90},[69,12834,1086],{"emptyLinePlaceholder":226},[69,12836,12837],{"class":71,"line":99},[69,12838,6217],{},[10,12840,6220,12841,1147,12843,195],{},[43,12842,6223],{},[43,12844,6226],{},[10,12846,126],{},[60,12848,12850],{"className":12849,"code":6232,"language":132,"meta":65},[130],[43,12851,6232],{"__ignoreMap":65},[10,12853,137],{},[14,12855,140],{"id":140},[142,12857,12858,12864],{},[40,12859,6243,12860,6246,12862,6250],{},[43,12861,6161],{},[43,12863,6249],{},[40,12865,12866,6255,12868,6258,12870,6261],{},[43,12867,6197],{},[43,12869,6161],{},[43,12871,6197],{},[325,12873,2688],{"id":2688},[10,12875,6266],{},[10,12877,12878],{},[26,12879],{"alt":6271,"src":6272},[10,12881,6275,12882,6278],{},[43,12883,6249],{},[14,12885,172],{"id":172},[37,12887,12888,12894],{},[40,12889,6285,12890,1147,12892,195],{},[43,12891,6161],{},[43,12893,6197],{},[40,12895,6292,12896,6296],{},[43,12897,6295],{},[14,12899,186],{"id":186},[142,12901,12902,12906],{},[40,12903,2343,12904,6306],{},[43,12905,6305],{},[40,12907,6309,12908,195],{},[43,12909,6128],{},[10,12911,201],{},[14,12913,204],{"id":204},[10,12915,6318],{},[209,12917,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":12919},[12920,12921,12922,12923,12924,12927,12928,12929],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":12925},[12926],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":6101,"description":6106},[222,6340,6341],{"id":4,"title":5,"body":12934,"category":222,"cover":223,"description":12,"extension":224,"meta":13073,"navigation":226,"path":227,"pinned":228,"publishedAt":229,"seo":13074,"slug":231,"stem":232,"summary":233,"tags":13075,"updatedAt":229,"visible":226,"__hash__":237},{"type":7,"value":12935,"toc":13063},[12936,12938,12940,12942,12944,12948,12950,12952,12962,12964,12966,13006,13008,13013,13015,13017,13035,13037,13045,13047,13055,13057,13059,13061],[10,12937,12],{},[14,12939,16],{"id":16},[10,12941,19],{},[14,12943,22],{"id":22},[10,12945,12946],{},[26,12947],{"alt":28,"src":29},[10,12949,32],{},[14,12951,35],{"id":35},[37,12953,12954,12958,12960],{},[40,12955,12956,46],{},[43,12957,45],{},[40,12959,49],{},[40,12961,52],{},[14,12963,55],{"id":55},[10,12965,58],{},[60,12967,12968],{"className":62,"code":63,"language":64,"meta":65,"style":65},[43,12969,12970,12980,12986,12992,13002],{"__ignoreMap":65},[69,12971,12972,12974,12976,12978],{"class":71,"line":72},[69,12973,76],{"class":75},[69,12975,80],{"class":79},[69,12977,84],{"class":83},[69,12979,87],{"class":83},[69,12981,12982,12984],{"class":71,"line":90},[69,12983,93],{"class":79},[69,12985,96],{"class":83},[69,12987,12988,12990],{"class":71,"line":99},[69,12989,102],{"class":75},[69,12991,105],{"class":79},[69,12993,12994,12996,12998,13000],{"class":71,"line":108},[69,12995,102],{"class":75},[69,12997,80],{"class":79},[69,12999,115],{"class":83},[69,13001,105],{"class":79},[69,13003,13004],{"class":71,"line":120},[69,13005,123],{"class":75},[10,13007,126],{},[60,13009,13011],{"className":13010,"code":131,"language":132,"meta":65},[130],[43,13012,131],{"__ignoreMap":65},[10,13014,137],{},[14,13016,140],{"id":140},[142,13018,13019,13025],{},[40,13020,13021,149,13023,152],{},[43,13022,148],{},[43,13024,76],{},[40,13026,155,13027,158,13029,162,13031,165,13033,169],{},[43,13028,102],{},[43,13030,161],{},[43,13032,45],{},[43,13034,168],{},[14,13036,172],{"id":172},[37,13038,13039,13041],{},[40,13040,177],{},[40,13042,180,13043,183],{},[43,13044,45],{},[14,13046,186],{"id":186},[142,13048,13049,13053],{},[40,13050,191,13051,195],{},[43,13052,194],{},[40,13054,198],{},[10,13056,201],{},[14,13058,204],{"id":204},[10,13060,207],{},[209,13062,211],{},{"title":65,"searchDepth":90,"depth":90,"links":13064},[13065,13066,13067,13068,13069,13070,13071,13072],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":5,"description":12},[222,235,236],{"id":6487,"title":6488,"body":13077,"category":222,"cover":223,"description":6493,"extension":224,"meta":13230,"navigation":226,"path":6682,"pinned":228,"publishedAt":229,"seo":13231,"slug":6684,"stem":6685,"summary":6686,"tags":13232,"updatedAt":229,"visible":226,"__hash__":6690},{"type":7,"value":13078,"toc":13220},[13079,13081,13083,13085,13087,13091,13097,13099,13115,13117,13119,13163,13165,13170,13172,13174,13186,13188,13202,13204,13212,13214,13216,13218],[10,13080,6493],{},[14,13082,16],{"id":16},[10,13084,6498],{},[14,13086,22],{"id":22},[10,13088,13089],{},[26,13090],{"alt":6505,"src":6506},[10,13092,13093,6512,13095,6515],{},[43,13094,6511],{},[43,13096,2425],{},[14,13098,35],{"id":35},[37,13100,13101,13103,13111],{},[40,13102,6522],{},[40,13104,13105,2246,13107,2246,13109,6534],{},[43,13106,6527],{},[43,13108,6530],{},[43,13110,6533],{},[40,13112,6537,13113,6541],{},[43,13114,6540],{},[14,13116,55],{"id":55},[10,13118,1428],{},[60,13120,13121],{"className":405,"code":6548,"language":102,"meta":65,"style":65},[43,13122,13123,13127,13131,13135,13139,13143,13147,13151,13155,13159],{"__ignoreMap":65},[69,13124,13125],{"class":71,"line":72},[69,13126,6555],{},[69,13128,13129],{"class":71,"line":90},[69,13130,1086],{"emptyLinePlaceholder":226},[69,13132,13133],{"class":71,"line":99},[69,13134,6564],{},[69,13136,13137],{"class":71,"line":108},[69,13138,6569],{},[69,13140,13141],{"class":71,"line":120},[69,13142,6574],{},[69,13144,13145],{"class":71,"line":1138},[69,13146,1086],{"emptyLinePlaceholder":226},[69,13148,13149],{"class":71,"line":2478},[69,13150,6583],{},[69,13152,13153],{"class":71,"line":2484},[69,13154,6588],{},[69,13156,13157],{"class":71,"line":3942},[69,13158,6593],{},[69,13160,13161],{"class":71,"line":4154},[69,13162,6598],{},[10,13164,126],{},[60,13166,13168],{"className":13167,"code":6604,"language":132,"meta":65},[130],[43,13169,6604],{"__ignoreMap":65},[10,13171,137],{},[14,13173,140],{"id":140},[142,13175,13176,13180],{},[40,13177,13178,6618],{},[43,13179,6617],{},[40,13181,2328,13182,6623,13184,6626],{},[43,13183,2425],{},[43,13185,6511],{},[14,13187,172],{"id":172},[37,13189,13190,13196],{},[40,13191,180,13192,6635,13194,6638],{},[43,13193,6511],{},[43,13195,6527],{},[40,13197,6641,13198,997,13200,6647],{},[43,13199,2425],{},[43,13201,6646],{},[14,13203,186],{"id":186},[142,13205,13206,13210],{},[40,13207,6654,13208,6658],{},[43,13209,6657],{},[40,13211,6661],{},[10,13213,201],{},[14,13215,204],{"id":204},[10,13217,6668],{},[209,13219,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":13221},[13222,13223,13224,13225,13226,13227,13228,13229],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":6488,"description":6493},[222,6688,6689],{"id":6692,"title":6693,"body":13234,"category":222,"cover":223,"description":6698,"extension":224,"meta":13381,"navigation":226,"path":6877,"pinned":228,"publishedAt":229,"seo":13382,"slug":6879,"stem":6880,"summary":6881,"tags":13383,"updatedAt":229,"visible":226,"__hash__":6885},{"type":7,"value":13235,"toc":13371},[13236,13238,13240,13242,13244,13248,13250,13252,13270,13272,13274,13322,13324,13329,13331,13333,13341,13343,13353,13355,13363,13365,13367,13369],[10,13237,6698],{},[14,13239,16],{"id":16},[10,13241,6703],{},[14,13243,22],{"id":22},[10,13245,13246],{},[26,13247],{"alt":6710,"src":6711},[10,13249,6714],{},[14,13251,35],{"id":35},[37,13253,13254,13258,13264],{},[40,13255,13256,6724],{},[43,13257,6723],{},[40,13259,13260,6730,13262,195],{},[43,13261,6729],{},[43,13263,6733],{},[40,13265,6736,13266,6740,13268,6744],{},[43,13267,6739],{},[43,13269,6743],{},[14,13271,55],{"id":55},[10,13273,1428],{},[60,13275,13276],{"className":405,"code":6751,"language":102,"meta":65,"style":65},[43,13277,13278,13282,13286,13290,13294,13298,13302,13306,13310,13314,13318],{"__ignoreMap":65},[69,13279,13280],{"class":71,"line":72},[69,13281,6555],{},[69,13283,13284],{"class":71,"line":90},[69,13285,1086],{"emptyLinePlaceholder":226},[69,13287,13288],{"class":71,"line":99},[69,13289,6766],{},[69,13291,13292],{"class":71,"line":108},[69,13293,6771],{},[69,13295,13296],{"class":71,"line":120},[69,13297,6776],{},[69,13299,13300],{"class":71,"line":1138},[69,13301,6781],{},[69,13303,13304],{"class":71,"line":2478},[69,13305,1086],{"emptyLinePlaceholder":226},[69,13307,13308],{"class":71,"line":2484},[69,13309,6790],{},[69,13311,13312],{"class":71,"line":3942},[69,13313,6795],{},[69,13315,13316],{"class":71,"line":4154},[69,13317,6800],{},[69,13319,13320],{"class":71,"line":5819},[69,13321,6805],{},[10,13323,126],{},[60,13325,13327],{"className":13326,"code":6811,"language":132,"meta":65},[130],[43,13328,6811],{"__ignoreMap":65},[10,13330,137],{},[14,13332,140],{"id":140},[142,13334,13335,13339],{},[40,13336,6822,13337,6825],{},[43,13338,6739],{},[40,13340,6828],{},[14,13342,172],{"id":172},[37,13344,13345,13349],{},[40,13346,2328,13347,6837],{},[43,13348,6723],{},[40,13350,6840,13351,195],{},[43,13352,6843],{},[14,13354,186],{"id":186},[142,13356,13357,13359],{},[40,13358,6850],{},[40,13360,6853,13361,6856],{},[43,13362,333],{},[10,13364,201],{},[14,13366,204],{"id":204},[10,13368,6863],{},[209,13370,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":13372},[13373,13374,13375,13376,13377,13378,13379,13380],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":6693,"description":6698},[222,6883,6884],{"id":6887,"title":6888,"body":13385,"category":222,"cover":223,"description":6893,"extension":224,"meta":13528,"navigation":226,"path":7061,"pinned":228,"publishedAt":229,"seo":13529,"slug":7063,"stem":7064,"summary":7065,"tags":13530,"updatedAt":229,"visible":226,"__hash__":7069},{"type":7,"value":13386,"toc":13518},[13387,13389,13391,13393,13395,13399,13405,13407,13417,13419,13421,13473,13475,13480,13482,13484,13494,13496,13502,13504,13510,13512,13514,13516],[10,13388,6893],{},[14,13390,16],{"id":16},[10,13392,6898],{},[14,13394,22],{"id":22},[10,13396,13397],{},[26,13398],{"alt":6905,"src":6906},[10,13400,13401,6912,13403,6916],{},[43,13402,6911],{},[43,13404,6915],{},[14,13406,35],{"id":35},[37,13408,13409,13411,13415],{},[40,13410,6923],{},[40,13412,13413,6929],{},[43,13414,6928],{},[40,13416,6932],{},[14,13418,55],{"id":55},[10,13420,1428],{},[60,13422,13423],{"className":405,"code":6939,"language":102,"meta":65,"style":65},[43,13424,13425,13429,13433,13437,13441,13445,13449,13453,13457,13461,13465,13469],{"__ignoreMap":65},[69,13426,13427],{"class":71,"line":72},[69,13428,6946],{},[69,13430,13431],{"class":71,"line":90},[69,13432,1086],{"emptyLinePlaceholder":226},[69,13434,13435],{"class":71,"line":99},[69,13436,6955],{},[69,13438,13439],{"class":71,"line":108},[69,13440,1086],{"emptyLinePlaceholder":226},[69,13442,13443],{"class":71,"line":120},[69,13444,6964],{},[69,13446,13447],{"class":71,"line":1138},[69,13448,6969],{},[69,13450,13451],{"class":71,"line":2478},[69,13452,6781],{},[69,13454,13455],{"class":71,"line":2484},[69,13456,1086],{"emptyLinePlaceholder":226},[69,13458,13459],{"class":71,"line":3942},[69,13460,6982],{},[69,13462,13463],{"class":71,"line":4154},[69,13464,6987],{},[69,13466,13467],{"class":71,"line":5819},[69,13468,6800],{},[69,13470,13471],{"class":71,"line":5824},[69,13472,6996],{},[10,13474,126],{},[60,13476,13478],{"className":13477,"code":7002,"language":132,"meta":65},[130],[43,13479,7002],{"__ignoreMap":65},[10,13481,137],{},[14,13483,140],{"id":140},[142,13485,13486,13490],{},[40,13487,13488,7015],{},[43,13489,6911],{},[40,13491,13492,7020],{},[43,13493,6915],{},[14,13495,172],{"id":172},[37,13497,13498,13500],{},[40,13499,7027],{},[40,13501,7030],{},[14,13503,186],{"id":186},[142,13505,13506,13508],{},[40,13507,7037],{},[40,13509,7040],{},[10,13511,201],{},[14,13513,204],{"id":204},[10,13515,7047],{},[209,13517,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":13519},[13520,13521,13522,13523,13524,13525,13526,13527],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":6888,"description":6893},[222,7067,7068],{"id":7071,"title":7072,"body":13532,"category":222,"cover":223,"description":7077,"extension":224,"meta":13683,"navigation":226,"path":7262,"pinned":228,"publishedAt":229,"seo":13684,"slug":7264,"stem":7265,"summary":7266,"tags":13685,"updatedAt":229,"visible":226,"__hash__":7270},{"type":7,"value":13533,"toc":13673},[13534,13536,13538,13540,13542,13546,13550,13552,13566,13568,13570,13622,13624,13629,13631,13633,13645,13647,13657,13659,13665,13667,13669,13671],[10,13535,7077],{},[14,13537,16],{"id":16},[10,13539,7082],{},[14,13541,22],{"id":22},[10,13543,13544],{},[26,13545],{"alt":7089,"src":7090},[10,13547,13548,7096],{},[43,13549,7095],{},[14,13551,35],{"id":35},[37,13553,13554,13560,13564],{},[40,13555,2328,13556,7106,13558,7110],{},[43,13557,7105],{},[43,13559,7109],{},[40,13561,7113,13562,7117],{},[43,13563,7116],{},[40,13565,7120],{},[14,13567,55],{"id":55},[10,13569,1428],{},[60,13571,13572],{"className":405,"code":7127,"language":102,"meta":65,"style":65},[43,13573,13574,13578,13582,13586,13590,13594,13598,13602,13606,13610,13614,13618],{"__ignoreMap":65},[69,13575,13576],{"class":71,"line":72},[69,13577,7134],{},[69,13579,13580],{"class":71,"line":90},[69,13581,1086],{"emptyLinePlaceholder":226},[69,13583,13584],{"class":71,"line":99},[69,13585,7143],{},[69,13587,13588],{"class":71,"line":108},[69,13589,7148],{},[69,13591,13592],{"class":71,"line":120},[69,13593,7153],{},[69,13595,13596],{"class":71,"line":1138},[69,13597,7158],{},[69,13599,13600],{"class":71,"line":2478},[69,13601,7163],{},[69,13603,13604],{"class":71,"line":2484},[69,13605,1086],{"emptyLinePlaceholder":226},[69,13607,13608],{"class":71,"line":3942},[69,13609,7172],{},[69,13611,13612],{"class":71,"line":4154},[69,13613,7177],{},[69,13615,13616],{"class":71,"line":5819},[69,13617,7182],{},[69,13619,13620],{"class":71,"line":5824},[69,13621,7187],{},[10,13623,126],{},[60,13625,13627],{"className":13626,"code":7193,"language":132,"meta":65},[130],[43,13628,7193],{"__ignoreMap":65},[10,13630,137],{},[14,13632,140],{"id":140},[142,13634,13635,13641],{},[40,13636,13637,7207,13639,7210],{},[43,13638,7206],{},[43,13640,7116],{},[40,13642,13643,7215],{},[43,13644,7095],{},[14,13646,172],{"id":172},[37,13648,13649,13651],{},[40,13650,7222],{},[40,13652,7225,13653,7228,13655,7231],{},[43,13654,7105],{},[43,13656,7109],{},[14,13658,186],{"id":186},[142,13660,13661,13663],{},[40,13662,7238],{},[40,13664,7241],{},[10,13666,201],{},[14,13668,204],{"id":204},[10,13670,7248],{},[209,13672,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":13674},[13675,13676,13677,13678,13679,13680,13681,13682],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":7072,"description":7077},[222,7268,7269],{"id":7272,"title":7273,"body":13687,"category":222,"cover":223,"description":7278,"extension":224,"meta":13901,"navigation":226,"path":7552,"pinned":228,"publishedAt":229,"seo":13902,"slug":7554,"stem":7555,"summary":7556,"tags":13903,"updatedAt":229,"visible":226,"__hash__":7560},{"type":7,"value":13688,"toc":13888},[13689,13691,13693,13695,13697,13701,13707,13709,13721,13723,13725,13785,13787,13792,13794,13796,13814,13816,13824,13828,13836,13838,13842,13846,13852,13854,13864,13866,13880,13882,13884,13886],[10,13690,7278],{},[14,13692,16],{"id":16},[10,13694,7283],{},[14,13696,22],{"id":22},[10,13698,13699],{},[26,13700],{"alt":7290,"src":7291},[10,13702,7294,13703,7298,13705,7302],{},[43,13704,7297],{},[43,13706,7301],{},[14,13708,35],{"id":35},[37,13710,13711,13715,13719],{},[40,13712,7309,13713,7312],{},[43,13714,7297],{},[40,13716,13717,7318],{},[43,13718,7317],{},[40,13720,7321],{},[14,13722,55],{"id":55},[10,13724,1428],{},[60,13726,13727],{"className":405,"code":7328,"language":102,"meta":65,"style":65},[43,13728,13729,13733,13737,13741,13745,13749,13753,13757,13761,13765,13769,13773,13777,13781],{"__ignoreMap":65},[69,13730,13731],{"class":71,"line":72},[69,13732,7335],{},[69,13734,13735],{"class":71,"line":90},[69,13736,7340],{},[69,13738,13739],{"class":71,"line":99},[69,13740,7345],{},[69,13742,13743],{"class":71,"line":108},[69,13744,7350],{},[69,13746,13747],{"class":71,"line":120},[69,13748,7355],{},[69,13750,13751],{"class":71,"line":1138},[69,13752,1086],{"emptyLinePlaceholder":226},[69,13754,13755],{"class":71,"line":2478},[69,13756,7364],{},[69,13758,13759],{"class":71,"line":2484},[69,13760,7369],{},[69,13762,13763],{"class":71,"line":3942},[69,13764,7374],{},[69,13766,13767],{"class":71,"line":4154},[69,13768,7379],{},[69,13770,13771],{"class":71,"line":5819},[69,13772,1135],{},[69,13774,13775],{"class":71,"line":5824},[69,13776,7388],{},[69,13778,13779],{"class":71,"line":7391},[69,13780,7394],{},[69,13782,13783],{"class":71,"line":7397},[69,13784,7400],{},[10,13786,126],{},[60,13788,13790],{"className":13789,"code":7406,"language":132,"meta":65},[130],[43,13791,7406],{"__ignoreMap":65},[10,13793,137],{},[14,13795,140],{"id":140},[142,13797,13798,13806],{},[40,13799,13800,7419,13802,7422,13804,7426],{},[43,13801,3027],{},[43,13803,7317],{},[43,13805,7425],{},[40,13807,7429,13808,7432,13810,7435,13812,195],{},[43,13809,7297],{},[43,13811,1150],{},[43,13813,7301],{},[325,13815,2688],{"id":2688},[10,13817,13818,2246,13820,1147,13822,7448],{},[43,13819,7297],{},[43,13821,1150],{},[43,13823,7301],{},[10,13825,13826],{},[26,13827],{"alt":7453,"src":7454},[10,13829,13830,7459,13832,7462,13834,7465],{},[43,13831,7297],{},[43,13833,1150],{},[43,13835,7301],{},[325,13837,2688],{"id":4209},[10,13839,13840,7473],{},[43,13841,7472],{},[10,13843,13844],{},[26,13845],{"alt":7478,"src":7479},[10,13847,7482,13848,7485,13850,7488],{},[43,13849,7472],{},[43,13851,1150],{},[14,13853,172],{"id":172},[37,13855,13856,13860],{},[40,13857,7495,13858,7499],{},[43,13859,7498],{},[40,13861,7502,13862,7505],{},[43,13863,7472],{},[14,13865,186],{"id":186},[142,13867,13868,13876],{},[40,13869,7512,13870,7516,13872,1147,13874,195],{},[43,13871,7515],{},[43,13873,7519],{},[43,13875,7522],{},[40,13877,7525,13878,7528],{},[43,13879,6733],{},[10,13881,201],{},[14,13883,204],{"id":204},[10,13885,7535],{},[209,13887,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":13889},[13890,13891,13892,13893,13894,13898,13899,13900],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":13895},[13896,13897],{"id":2688,"depth":99,"text":2688},{"id":4209,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":7273,"description":7278},[222,7558,7559],{"id":7562,"title":7563,"body":13905,"category":222,"cover":223,"description":7568,"extension":224,"meta":14056,"navigation":226,"path":7745,"pinned":228,"publishedAt":229,"seo":14057,"slug":7747,"stem":7748,"summary":7749,"tags":14058,"updatedAt":229,"visible":226,"__hash__":7752},{"type":7,"value":13906,"toc":14046},[13907,13909,13911,13913,13915,13919,13923,13925,13937,13939,13941,13989,13991,13996,13998,14000,14010,14012,14022,14024,14038,14040,14042,14044],[10,13908,7568],{},[14,13910,16],{"id":16},[10,13912,7573],{},[14,13914,22],{"id":22},[10,13916,13917],{},[26,13918],{"alt":7580,"src":7581},[10,13920,7584,13921,7587],{},[43,13922,6743],{},[14,13924,35],{"id":35},[37,13926,13927,13931,13935],{},[40,13928,13929,7596],{},[43,13930,6743],{},[40,13932,13933,7602],{},[43,13934,7601],{},[40,13936,7605],{},[14,13938,55],{"id":55},[10,13940,1428],{},[60,13942,13943],{"className":405,"code":7612,"language":102,"meta":65,"style":65},[43,13944,13945,13949,13953,13957,13961,13965,13969,13973,13977,13981,13985],{"__ignoreMap":65},[69,13946,13947],{"class":71,"line":72},[69,13948,6555],{},[69,13950,13951],{"class":71,"line":90},[69,13952,1086],{"emptyLinePlaceholder":226},[69,13954,13955],{"class":71,"line":99},[69,13956,6766],{},[69,13958,13959],{"class":71,"line":108},[69,13960,1086],{"emptyLinePlaceholder":226},[69,13962,13963],{"class":71,"line":120},[69,13964,7635],{},[69,13966,13967],{"class":71,"line":1138},[69,13968,7640],{},[69,13970,13971],{"class":71,"line":2478},[69,13972,1086],{"emptyLinePlaceholder":226},[69,13974,13975],{"class":71,"line":2484},[69,13976,7649],{},[69,13978,13979],{"class":71,"line":3942},[69,13980,7654],{},[69,13982,13983],{"class":71,"line":4154},[69,13984,1086],{"emptyLinePlaceholder":226},[69,13986,13987],{"class":71,"line":5819},[69,13988,7663],{},[10,13990,126],{},[60,13992,13994],{"className":13993,"code":7669,"language":132,"meta":65},[130],[43,13995,7669],{"__ignoreMap":65},[10,13997,137],{},[14,13999,140],{"id":140},[142,14001,14002,14008],{},[40,14003,7584,14004,7682,14006,195],{},[43,14005,6743],{},[43,14007,7685],{},[40,14009,7688],{},[14,14011,172],{"id":172},[37,14013,14014,14018],{},[40,14015,4777,14016,7697],{},[43,14017,6743],{},[40,14019,7700,14020,7703],{},[43,14021,6743],{},[14,14023,186],{"id":186},[142,14025,14026,14032],{},[40,14027,7710,14028,7714,14030,195],{},[43,14029,7713],{},[43,14031,6743],{},[40,14033,4777,14034,7721,14036,195],{},[43,14035,6743],{},[43,14037,7724],{},[10,14039,201],{},[14,14041,204],{"id":204},[10,14043,7731],{},[209,14045,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":14047},[14048,14049,14050,14051,14052,14053,14054,14055],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":7563,"description":7568},[222,6743,7751],{"id":7754,"title":7755,"body":14060,"category":222,"cover":223,"description":7760,"extension":224,"meta":14231,"navigation":226,"path":7973,"pinned":228,"publishedAt":229,"seo":14232,"slug":7975,"stem":7976,"summary":7977,"tags":14233,"updatedAt":229,"visible":226,"__hash__":7981},{"type":7,"value":14061,"toc":14219},[14062,14064,14066,14068,14070,14074,14076,14078,14090,14092,14094,14150,14152,14157,14159,14161,14177,14179,14181,14185,14191,14193,14201,14203,14211,14213,14215,14217],[10,14063,7760],{},[14,14065,16],{"id":16},[10,14067,7765],{},[14,14069,22],{"id":22},[10,14071,14072],{},[26,14073],{"alt":7772,"src":7773},[10,14075,7776],{},[14,14077,35],{"id":35},[37,14079,14080,14084,14088],{},[40,14081,14082,7786],{},[43,14083,7785],{},[40,14085,14086,7792],{},[43,14087,7791],{},[40,14089,7795],{},[14,14091,55],{"id":55},[10,14093,1428],{},[60,14095,14096],{"className":405,"code":7802,"language":102,"meta":65,"style":65},[43,14097,14098,14102,14106,14110,14114,14118,14122,14126,14130,14134,14138,14142,14146],{"__ignoreMap":65},[69,14099,14100],{"class":71,"line":72},[69,14101,7809],{},[69,14103,14104],{"class":71,"line":90},[69,14105,7814],{},[69,14107,14108],{"class":71,"line":99},[69,14109,7819],{},[69,14111,14112],{"class":71,"line":108},[69,14113,7824],{},[69,14115,14116],{"class":71,"line":120},[69,14117,1086],{"emptyLinePlaceholder":226},[69,14119,14120],{"class":71,"line":1138},[69,14121,7833],{},[69,14123,14124],{"class":71,"line":2478},[69,14125,7838],{},[69,14127,14128],{"class":71,"line":2484},[69,14129,7843],{},[69,14131,14132],{"class":71,"line":3942},[69,14133,7848],{},[69,14135,14136],{"class":71,"line":4154},[69,14137,1086],{"emptyLinePlaceholder":226},[69,14139,14140],{"class":71,"line":5819},[69,14141,7857],{},[69,14143,14144],{"class":71,"line":5824},[69,14145,7862],{},[69,14147,14148],{"class":71,"line":7391},[69,14149,7867],{},[10,14151,126],{},[60,14153,14155],{"className":14154,"code":7873,"language":132,"meta":65},[130],[43,14156,7873],{"__ignoreMap":65},[10,14158,137],{},[14,14160,140],{"id":140},[142,14162,14163,14169],{},[40,14164,7884,14165,7888,14167,7891],{},[43,14166,7887],{},[43,14168,7791],{},[40,14170,14171,7897,14173,7901,14175,7904],{},[43,14172,7896],{},[43,14174,7900],{},[43,14176,7785],{},[325,14178,2688],{"id":2688},[10,14180,7909],{},[10,14182,14183],{},[26,14184],{"alt":7914,"src":7915},[10,14186,7918,14187,1147,14189,7924],{},[43,14188,4574],{},[43,14190,7923],{},[14,14192,172],{"id":172},[37,14194,14195,14199],{},[40,14196,7931,14197,7934],{},[43,14198,7785],{},[40,14200,7937],{},[14,14202,186],{"id":186},[142,14204,14205,14209],{},[40,14206,5287,14207,7947],{},[43,14208,7946],{},[40,14210,7950],{},[10,14212,201],{},[14,14214,204],{"id":204},[10,14216,7957],{},[209,14218,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":14220},[14221,14222,14223,14224,14225,14228,14229,14230],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":14226},[14227],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":7755,"description":7760},[222,7979,7980],{"id":7983,"title":7984,"body":14235,"category":222,"cover":223,"description":7989,"extension":224,"meta":14382,"navigation":226,"path":8168,"pinned":228,"publishedAt":229,"seo":14383,"slug":8170,"stem":8171,"summary":8172,"tags":14384,"updatedAt":229,"visible":226,"__hash__":8176},{"type":7,"value":14236,"toc":14372},[14237,14239,14241,14243,14245,14249,14251,14253,14261,14263,14265,14321,14323,14328,14330,14332,14344,14346,14352,14354,14364,14366,14368,14370],[10,14238,7989],{},[14,14240,16],{"id":16},[10,14242,7994],{},[14,14244,22],{"id":22},[10,14246,14247],{},[26,14248],{"alt":8001,"src":8002},[10,14250,8005],{},[14,14252,35],{"id":35},[37,14254,14255,14257,14259],{},[40,14256,8012],{},[40,14258,8015],{},[40,14260,8018],{},[14,14262,55],{"id":55},[10,14264,1428],{},[60,14266,14267],{"className":405,"code":8025,"language":102,"meta":65,"style":65},[43,14268,14269,14273,14277,14281,14285,14289,14293,14297,14301,14305,14309,14313,14317],{"__ignoreMap":65},[69,14270,14271],{"class":71,"line":72},[69,14272,8032],{},[69,14274,14275],{"class":71,"line":90},[69,14276,8037],{},[69,14278,14279],{"class":71,"line":99},[69,14280,8042],{},[69,14282,14283],{"class":71,"line":108},[69,14284,1086],{"emptyLinePlaceholder":226},[69,14286,14287],{"class":71,"line":120},[69,14288,8051],{},[69,14290,14291],{"class":71,"line":1138},[69,14292,8056],{},[69,14294,14295],{"class":71,"line":2478},[69,14296,8061],{},[69,14298,14299],{"class":71,"line":2484},[69,14300,1086],{"emptyLinePlaceholder":226},[69,14302,14303],{"class":71,"line":3942},[69,14304,8070],{},[69,14306,14307],{"class":71,"line":4154},[69,14308,8075],{},[69,14310,14311],{"class":71,"line":5819},[69,14312,1086],{"emptyLinePlaceholder":226},[69,14314,14315],{"class":71,"line":5824},[69,14316,8084],{},[69,14318,14319],{"class":71,"line":7391},[69,14320,8089],{},[10,14322,126],{},[60,14324,14326],{"className":14325,"code":8095,"language":132,"meta":65},[130],[43,14327,8095],{"__ignoreMap":65},[10,14329,137],{},[14,14331,140],{"id":140},[142,14333,14334,14340],{},[40,14335,14336,8109,14338,8113],{},[43,14337,8108],{},[43,14339,8112],{},[40,14341,8116,14342,8120],{},[43,14343,8119],{},[14,14345,172],{"id":172},[37,14347,14348,14350],{},[40,14349,8127],{},[40,14351,8130],{},[14,14353,186],{"id":186},[142,14355,14356,14362],{},[40,14357,8137,14358,8141,14360,195],{},[43,14359,8140],{},[43,14361,8144],{},[40,14363,8147],{},[10,14365,201],{},[14,14367,204],{"id":204},[10,14369,8154],{},[209,14371,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":14373},[14374,14375,14376,14377,14378,14379,14380,14381],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":7984,"description":7989},[222,8174,8175],{"id":8178,"title":8179,"body":14386,"category":222,"cover":223,"description":8184,"extension":224,"meta":14549,"navigation":226,"path":8388,"pinned":228,"publishedAt":229,"seo":14550,"slug":8390,"stem":8391,"summary":8392,"tags":14551,"updatedAt":229,"visible":226,"__hash__":8396},{"type":7,"value":14387,"toc":14537},[14388,14390,14392,14394,14396,14400,14404,14406,14422,14424,14426,14470,14472,14477,14479,14481,14495,14497,14501,14505,14509,14511,14517,14519,14529,14531,14533,14535],[10,14389,8184],{},[14,14391,16],{"id":16},[10,14393,8189],{},[14,14395,22],{"id":22},[10,14397,14398],{},[26,14399],{"alt":8196,"src":8197},[10,14401,8200,14402,8204],{},[43,14403,8203],{},[14,14405,35],{"id":35},[37,14407,14408,14414,14420],{},[40,14409,14410,8214,14412,8218],{},[43,14411,8213],{},[43,14413,8217],{},[40,14415,8221,14416,8225,14418,8228],{},[43,14417,8224],{},[43,14419,4328],{},[40,14421,8231],{},[14,14423,55],{"id":55},[10,14425,1428],{},[60,14427,14428],{"className":405,"code":8238,"language":102,"meta":65,"style":65},[43,14429,14430,14434,14438,14442,14446,14450,14454,14458,14462,14466],{"__ignoreMap":65},[69,14431,14432],{"class":71,"line":72},[69,14433,8245],{},[69,14435,14436],{"class":71,"line":90},[69,14437,8250],{},[69,14439,14440],{"class":71,"line":99},[69,14441,8255],{},[69,14443,14444],{"class":71,"line":108},[69,14445,8260],{},[69,14447,14448],{"class":71,"line":120},[69,14449,8265],{},[69,14451,14452],{"class":71,"line":1138},[69,14453,1086],{"emptyLinePlaceholder":226},[69,14455,14456],{"class":71,"line":2478},[69,14457,8274],{},[69,14459,14460],{"class":71,"line":2484},[69,14461,8279],{},[69,14463,14464],{"class":71,"line":3942},[69,14465,8279],{},[69,14467,14468],{"class":71,"line":4154},[69,14469,8279],{},[10,14471,126],{},[60,14473,14475],{"className":14474,"code":8293,"language":132,"meta":65},[130],[43,14476,8293],{"__ignoreMap":65},[10,14478,137],{},[14,14480,140],{"id":140},[142,14482,14483,14487],{},[40,14484,7884,14485,8307],{},[43,14486,8306],{},[40,14488,8310,14489,8313,14491,8316,14493,8320],{},[43,14490,8217],{},[43,14492,8203],{},[43,14494,8319],{},[325,14496,2688],{"id":2688},[10,14498,8325,14499,8328],{},[43,14500,8217],{},[10,14502,14503],{},[26,14504],{"alt":8333,"src":8334},[10,14506,8337,14507,8340],{},[43,14508,8203],{},[14,14510,172],{"id":172},[37,14512,14513,14515],{},[40,14514,8347],{},[40,14516,8350],{},[14,14518,186],{"id":186},[142,14520,14521,14523],{},[40,14522,8357],{},[40,14524,4000,14525,8362,14527,8365],{},[43,14526,4328],{},[43,14528,8217],{},[10,14530,201],{},[14,14532,204],{"id":204},[10,14534,8372],{},[209,14536,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":14538},[14539,14540,14541,14542,14543,14546,14547,14548],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":14544},[14545],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":8179,"description":8184},[222,8394,8395],{"id":8398,"title":8399,"body":14553,"category":222,"cover":223,"description":8404,"extension":224,"meta":14736,"navigation":226,"path":8629,"pinned":228,"publishedAt":229,"seo":14737,"slug":8631,"stem":8632,"summary":8633,"tags":14738,"updatedAt":229,"visible":226,"__hash__":8636},{"type":7,"value":14554,"toc":14724},[14555,14557,14559,14561,14563,14567,14569,14571,14585,14587,14589,14657,14659,14664,14666,14668,14682,14684,14686,14690,14696,14698,14706,14708,14716,14718,14720,14722],[10,14556,8404],{},[14,14558,16],{"id":16},[10,14560,8409],{},[14,14562,22],{"id":22},[10,14564,14565],{},[26,14566],{"alt":8416,"src":8417},[10,14568,8420],{},[14,14570,35],{"id":35},[37,14572,14573,14579,14581],{},[40,14574,14575,8430,14577,195],{},[43,14576,8429],{},[43,14578,8433],{},[40,14580,8436],{},[40,14582,14583,8442],{},[43,14584,8441],{},[14,14586,55],{"id":55},[10,14588,1428],{},[60,14590,14591],{"className":405,"code":8449,"language":102,"meta":65,"style":65},[43,14592,14593,14597,14601,14605,14609,14613,14617,14621,14625,14629,14633,14637,14641,14645,14649,14653],{"__ignoreMap":65},[69,14594,14595],{"class":71,"line":72},[69,14596,8456],{},[69,14598,14599],{"class":71,"line":90},[69,14600,1086],{"emptyLinePlaceholder":226},[69,14602,14603],{"class":71,"line":99},[69,14604,8465],{},[69,14606,14607],{"class":71,"line":108},[69,14608,8470],{},[69,14610,14611],{"class":71,"line":120},[69,14612,8475],{},[69,14614,14615],{"class":71,"line":1138},[69,14616,8480],{},[69,14618,14619],{"class":71,"line":2478},[69,14620,8485],{},[69,14622,14623],{"class":71,"line":2484},[69,14624,8490],{},[69,14626,14627],{"class":71,"line":3942},[69,14628,8495],{},[69,14630,14631],{"class":71,"line":4154},[69,14632,8500],{},[69,14634,14635],{"class":71,"line":5819},[69,14636,1086],{"emptyLinePlaceholder":226},[69,14638,14639],{"class":71,"line":5824},[69,14640,8509],{},[69,14642,14643],{"class":71,"line":7391},[69,14644,6172],{},[69,14646,14647],{"class":71,"line":7397},[69,14648,6177],{},[69,14650,14651],{"class":71,"line":8520},[69,14652,1086],{"emptyLinePlaceholder":226},[69,14654,14655],{"class":71,"line":8525},[69,14656,8528],{},[10,14658,126],{},[60,14660,14662],{"className":14661,"code":8534,"language":132,"meta":65},[130],[43,14663,8534],{"__ignoreMap":65},[10,14665,137],{},[14,14667,140],{"id":140},[142,14669,14670,14680],{},[40,14671,8545,14672,8549,14674,8553,14676,8557,14678,195],{},[43,14673,8548],{},[43,14675,8552],{},[43,14677,8556],{},[43,14679,8548],{},[40,14681,8562],{},[325,14683,2688],{"id":2688},[10,14685,8567],{},[10,14687,14688],{},[26,14689],{"alt":8572,"src":8573},[10,14691,14692,8578,14694,195],{},[43,14693,8429],{},[43,14695,8433],{},[14,14697,172],{"id":172},[37,14699,14700,14704],{},[40,14701,8587,14702,195],{},[43,14703,5370],{},[40,14705,8592],{},[14,14707,186],{"id":186},[142,14709,14710,14712],{},[40,14711,8599],{},[40,14713,8602,14714,8606],{},[43,14715,8605],{},[10,14717,201],{},[14,14719,204],{"id":204},[10,14721,8613],{},[209,14723,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":14725},[14726,14727,14728,14729,14730,14733,14734,14735],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":14731},[14732],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":8399,"description":8404},[222,8635,5321],{"id":8638,"title":8639,"body":14740,"category":222,"cover":223,"description":8644,"extension":224,"meta":14899,"navigation":226,"path":8832,"pinned":228,"publishedAt":229,"seo":14900,"slug":8834,"stem":8835,"summary":8836,"tags":14901,"updatedAt":229,"visible":226,"__hash__":8840},{"type":7,"value":14741,"toc":14887},[14742,14744,14746,14748,14750,14754,14756,14758,14766,14768,14770,14834,14836,14841,14843,14845,14853,14855,14857,14861,14863,14865,14871,14873,14879,14881,14883,14885],[10,14743,8644],{},[14,14745,16],{"id":16},[10,14747,8649],{},[14,14749,22],{"id":22},[10,14751,14752],{},[26,14753],{"alt":8656,"src":8657},[10,14755,8660],{},[14,14757,35],{"id":35},[37,14759,14760,14762,14764],{},[40,14761,8667],{},[40,14763,8670],{},[40,14765,8673],{},[14,14767,55],{"id":55},[10,14769,1428],{},[60,14771,14772],{"className":405,"code":8680,"language":102,"meta":65,"style":65},[43,14773,14774,14778,14782,14786,14790,14794,14798,14802,14806,14810,14814,14818,14822,14826,14830],{"__ignoreMap":65},[69,14775,14776],{"class":71,"line":72},[69,14777,8687],{},[69,14779,14780],{"class":71,"line":90},[69,14781,8692],{},[69,14783,14784],{"class":71,"line":99},[69,14785,1086],{"emptyLinePlaceholder":226},[69,14787,14788],{"class":71,"line":108},[69,14789,8701],{},[69,14791,14792],{"class":71,"line":120},[69,14793,1086],{"emptyLinePlaceholder":226},[69,14795,14796],{"class":71,"line":1138},[69,14797,8710],{},[69,14799,14800],{"class":71,"line":2478},[69,14801,8715],{},[69,14803,14804],{"class":71,"line":2484},[69,14805,8720],{},[69,14807,14808],{"class":71,"line":3942},[69,14809,1086],{"emptyLinePlaceholder":226},[69,14811,14812],{"class":71,"line":4154},[69,14813,8729],{},[69,14815,14816],{"class":71,"line":5819},[69,14817,8734],{},[69,14819,14820],{"class":71,"line":5824},[69,14821,8739],{},[69,14823,14824],{"class":71,"line":7391},[69,14825,1086],{"emptyLinePlaceholder":226},[69,14827,14828],{"class":71,"line":7397},[69,14829,6186],{},[69,14831,14832],{"class":71,"line":8520},[69,14833,8752],{},[10,14835,126],{},[60,14837,14839],{"className":14838,"code":8758,"language":132,"meta":65},[130],[43,14840,8758],{"__ignoreMap":65},[10,14842,137],{},[14,14844,140],{"id":140},[142,14846,14847,14851],{},[40,14848,14849,8772],{},[43,14850,8771],{},[40,14852,8775],{},[325,14854,2688],{"id":2688},[10,14856,8780],{},[10,14858,14859],{},[26,14860],{"alt":8785,"src":8786},[10,14862,8789],{},[14,14864,172],{"id":172},[37,14866,14867,14869],{},[40,14868,8796],{},[40,14870,8799],{},[14,14872,186],{"id":186},[142,14874,14875,14877],{},[40,14876,8806],{},[40,14878,8809],{},[10,14880,201],{},[14,14882,204],{"id":204},[10,14884,8816],{},[209,14886,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":14888},[14889,14890,14891,14892,14893,14896,14897,14898],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":14894},[14895],{"id":2688,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":8639,"description":8644},[222,8838,8839],{"id":8842,"title":8843,"body":14903,"category":222,"cover":223,"description":8848,"extension":224,"meta":15141,"navigation":226,"path":9149,"pinned":228,"publishedAt":229,"seo":15142,"slug":9151,"stem":9152,"summary":9153,"tags":15143,"updatedAt":229,"visible":226,"__hash__":9157},{"type":7,"value":14904,"toc":15128},[14905,14907,14909,14911,14913,14917,14919,14921,14931,14933,14935,15051,15053,15058,15060,15062,15072,15074,15076,15080,15082,15084,15086,15090,15094,15096,15104,15106,15120,15122,15124,15126],[10,14906,8848],{},[14,14908,16],{"id":16},[10,14910,8853],{},[14,14912,22],{"id":22},[10,14914,14915],{},[26,14916],{"alt":8860,"src":8861},[10,14918,8864],{},[14,14920,35],{"id":35},[37,14922,14923,14925,14927],{},[40,14924,8871],{},[40,14926,8874],{},[40,14928,8877,14929,8881],{},[43,14930,8880],{},[14,14932,55],{"id":55},[10,14934,1428],{},[60,14936,14937],{"className":405,"code":8888,"language":102,"meta":65,"style":65},[43,14938,14939,14943,14947,14951,14955,14959,14963,14967,14971,14975,14979,14983,14987,14991,14995,14999,15003,15007,15011,15015,15019,15023,15027,15031,15035,15039,15043,15047],{"__ignoreMap":65},[69,14940,14941],{"class":71,"line":72},[69,14942,6946],{},[69,14944,14945],{"class":71,"line":90},[69,14946,6555],{},[69,14948,14949],{"class":71,"line":99},[69,14950,1086],{"emptyLinePlaceholder":226},[69,14952,14953],{"class":71,"line":108},[69,14954,8907],{},[69,14956,14957],{"class":71,"line":120},[69,14958,8912],{},[69,14960,14961],{"class":71,"line":1138},[69,14962,8917],{},[69,14964,14965],{"class":71,"line":2478},[69,14966,8922],{},[69,14968,14969],{"class":71,"line":2484},[69,14970,1086],{"emptyLinePlaceholder":226},[69,14972,14973],{"class":71,"line":3942},[69,14974,8931],{},[69,14976,14977],{"class":71,"line":4154},[69,14978,8936],{},[69,14980,14981],{"class":71,"line":5819},[69,14982,8941],{},[69,14984,14985],{"class":71,"line":5824},[69,14986,8946],{},[69,14988,14989],{"class":71,"line":7391},[69,14990,8951],{},[69,14992,14993],{"class":71,"line":7397},[69,14994,1086],{"emptyLinePlaceholder":226},[69,14996,14997],{"class":71,"line":8520},[69,14998,8960],{},[69,15000,15001],{"class":71,"line":8525},[69,15002,8965],{},[69,15004,15005],{"class":71,"line":8968},[69,15006,8971],{},[69,15008,15009],{"class":71,"line":8974},[69,15010,1086],{"emptyLinePlaceholder":226},[69,15012,15013],{"class":71,"line":8979},[69,15014,8982],{},[69,15016,15017],{"class":71,"line":8985},[69,15018,1086],{"emptyLinePlaceholder":226},[69,15020,15021],{"class":71,"line":8990},[69,15022,7364],{},[69,15024,15025],{"class":71,"line":8995},[69,15026,8998],{},[69,15028,15029],{"class":71,"line":9001},[69,15030,9004],{},[69,15032,15033],{"class":71,"line":9007},[69,15034,9010],{},[69,15036,15037],{"class":71,"line":9013},[69,15038,7374],{},[69,15040,15041],{"class":71,"line":9018},[69,15042,9021],{},[69,15044,15045],{"class":71,"line":9024},[69,15046,1135],{},[69,15048,15049],{"class":71,"line":9029},[69,15050,9032],{},[10,15052,126],{},[60,15054,15056],{"className":15055,"code":9038,"language":132,"meta":65},[130],[43,15057,9038],{"__ignoreMap":65},[10,15059,137],{},[14,15061,140],{"id":140},[142,15063,15064,15068],{},[40,15065,9049,15066,9052],{},[43,15067,8880],{},[40,15069,15070,9057],{},[43,15071,8112],{},[325,15073,2688],{"id":2688},[10,15075,9062],{},[10,15077,15078],{},[26,15079],{"alt":9067,"src":9068},[10,15081,9071],{},[325,15083,2688],{"id":4209},[10,15085,9076],{},[10,15087,15088],{},[26,15089],{"alt":9081,"src":9082},[10,15091,9085,15092,9089],{},[43,15093,9088],{},[14,15095,172],{"id":172},[37,15097,15098,15100],{},[40,15099,9096],{},[40,15101,9099,15102,9102],{},[43,15103,9088],{},[14,15105,186],{"id":186},[142,15107,15108,15112,15114],{},[40,15109,9109,15110,9112],{},[43,15111,9088],{},[40,15113,9115],{},[40,15115,9118,15116,9122,15118,9125],{},[43,15117,9121],{},[43,15119,6128],{},[10,15121,201],{},[14,15123,204],{"id":204},[10,15125,9132],{},[209,15127,1498],{},{"title":65,"searchDepth":90,"depth":90,"links":15129},[15130,15131,15132,15133,15134,15138,15139,15140],{"id":16,"depth":90,"text":16},{"id":22,"depth":90,"text":22},{"id":35,"depth":90,"text":35},{"id":55,"depth":90,"text":55},{"id":140,"depth":90,"text":140,"children":15135},[15136,15137],{"id":2688,"depth":99,"text":2688},{"id":4209,"depth":99,"text":2688},{"id":172,"depth":90,"text":172},{"id":186,"depth":90,"text":186},{"id":204,"depth":90,"text":204},{},{"title":8843,"description":8848},[222,9155,9156],{"id":1044,"title":1045,"body":15145,"category":222,"cover":1053,"description":65,"extension":224,"meta":15381,"navigation":226,"path":1372,"pinned":228,"publishedAt":1373,"seo":15382,"slug":1375,"stem":1376,"summary":1377,"tags":15383,"updatedAt":1373,"visible":226,"__hash__":1381},{"type":7,"value":15146,"toc":15366},[15147,15151,15153,15155,15157,15159,15179,15181,15186,15188,15190,15218,15224,15226,15230,15232,15252,15254,15264,15266,15268,15270,15272,15274,15276,15278,15280,15282,15302,15304,15306,15310,15312,15314,15316,15318,15322,15324,15342,15344,15346,15348,15350,15352,15354,15356,15358,15360,15362,15364],[10,15148,15149],{},[26,15150],{"alt":1052,"src":1053},[10,15152,1056],{},[10,15154,1059],{},[14,15156,1063],{"id":1062},[10,15158,1066],{},[60,15160,15161],{"className":405,"code":1069,"language":102,"meta":65,"style":65},[43,15162,15163,15167,15171,15175],{"__ignoreMap":65},[69,15164,15165],{"class":71,"line":72},[69,15166,1076],{},[69,15168,15169],{"class":71,"line":90},[69,15170,1081],{},[69,15172,15173],{"class":71,"line":99},[69,15174,1086],{"emptyLinePlaceholder":226},[69,15176,15177],{"class":71,"line":108},[69,15178,1091],{},[10,15180,1094],{},[60,15182,15184],{"className":15183,"code":1098,"language":132,"meta":65},[130],[43,15185,1098],{"__ignoreMap":65},[10,15187,1103],{},[10,15189,1106],{},[60,15191,15192],{"className":405,"code":1109,"language":102,"meta":65,"style":65},[43,15193,15194,15198,15202,15206,15210,15214],{"__ignoreMap":65},[69,15195,15196],{"class":71,"line":72},[69,15197,1116],{},[69,15199,15200],{"class":71,"line":90},[69,15201,1086],{"emptyLinePlaceholder":226},[69,15203,15204],{"class":71,"line":99},[69,15205,1125],{},[69,15207,15208],{"class":71,"line":108},[69,15209,1130],{},[69,15211,15212],{"class":71,"line":120},[69,15213,1135],{},[69,15215,15216],{"class":71,"line":1138},[69,15217,1141],{},[10,15219,15220,1147,15222,1151],{},[43,15221,1146],{},[43,15223,1150],{},[14,15225,1155],{"id":1154},[10,15227,1158,15228,1162],{},[43,15229,1161],{},[10,15231,1165],{},[60,15233,15234],{"className":405,"code":1168,"language":102,"meta":65,"style":65},[43,15235,15236,15240,15244,15248],{"__ignoreMap":65},[69,15237,15238],{"class":71,"line":72},[69,15239,1175],{},[69,15241,15242],{"class":71,"line":90},[69,15243,1180],{},[69,15245,15246],{"class":71,"line":99},[69,15247,1185],{},[69,15249,15250],{"class":71,"line":108},[69,15251,1190],{},[10,15253,1193],{},[60,15255,15256],{"className":62,"code":1196,"language":64,"meta":65,"style":65},[43,15257,15258],{"__ignoreMap":65},[69,15259,15260,15262],{"class":71,"line":72},[69,15261,76],{"class":75},[69,15263,1205],{"class":83},[10,15265,1208],{},[14,15267,1212],{"id":1211},[325,15269,1215],{"id":1215},[10,15271,1218],{},[325,15273,1221],{"id":1221},[10,15275,1224],{},[325,15277,1227],{"id":1227},[10,15279,1230],{},[10,15281,1233],{},[60,15283,15284],{"className":405,"code":1236,"language":102,"meta":65,"style":65},[43,15285,15286,15290,15294,15298],{"__ignoreMap":65},[69,15287,15288],{"class":71,"line":72},[69,15289,1243],{},[69,15291,15292],{"class":71,"line":90},[69,15293,1086],{"emptyLinePlaceholder":226},[69,15295,15296],{"class":71,"line":99},[69,15297,1252],{},[69,15299,15300],{"class":71,"line":108},[69,15301,1257],{},[10,15303,1260],{},[325,15305,1263],{"id":1263},[10,15307,1266,15308,1269],{},[43,15309,236],{},[10,15311,1272],{},[325,15313,1275],{"id":1275},[10,15315,1278],{},[14,15317,1282],{"id":1281},[10,15319,15320],{},[26,15321],{"alt":1287,"src":1288},[10,15323,1291],{},[37,15325,15326,15328,15330,15332,15334,15336,15338,15340],{},[40,15327,1296],{},[40,15329,1299],{},[40,15331,1302],{},[40,15333,1305],{},[40,15335,1308],{},[40,15337,1311],{},[40,15339,1314],{},[40,15341,1317],{},[10,15343,1320],{},[14,15345,1324],{"id":1323},[10,15347,1327],{},[10,15349,1330],{},[14,15351,1334],{"id":1333},[10,15353,1337],{},[10,15355,1340],{},[10,15357,1343],{},[14,15359,1346],{"id":1346},[10,15361,1349],{},[10,15363,1352],{},[209,15365,1355],{},{"title":65,"searchDepth":90,"depth":90,"links":15367},[15368,15369,15370,15377,15378,15379,15380],{"id":1062,"depth":90,"text":1063},{"id":1154,"depth":90,"text":1155},{"id":1211,"depth":90,"text":1212,"children":15371},[15372,15373,15374,15375,15376],{"id":1215,"depth":99,"text":1215},{"id":1221,"depth":99,"text":1221},{"id":1227,"depth":99,"text":1227},{"id":1263,"depth":99,"text":1263},{"id":1275,"depth":99,"text":1275},{"id":1281,"depth":90,"text":1282},{"id":1323,"depth":90,"text":1324},{"id":1333,"depth":90,"text":1334},{"id":1346,"depth":90,"text":1346},{},{"title":1045,"description":65},[222,1379,1380],{"id":240,"title":241,"body":15385,"category":222,"cover":223,"description":65,"extension":224,"meta":15964,"navigation":226,"path":1033,"pinned":228,"publishedAt":1034,"seo":15965,"slug":1036,"stem":1037,"summary":1038,"tags":15966,"updatedAt":1034,"visible":226,"__hash__":1042},{"type":7,"value":15386,"toc":15940},[15387,15389,15391,15393,15397,15399,15401,15425,15437,15439,15441,15446,15450,15454,15466,15470,15474,15478,15480,15514,15516,15520,15524,15526,15548,15578,15590,15600,15608,15610,15616,15626,15628,15633,15637,15639,15653,15659,15679,15681,15683,15685,15695,15699,15701,15710,15714,15716,15718,15738,15742,15744,15746,15748,15750,15770,15772,15774,15776,15802,15804,15820,15822,15838,15842,15844,15846,15866,15868,15870,15872,15876,15886,15888,15890,15892,15902,15910,15912,15914,15928,15938],[14,15388,246],{"id":246},[10,15390,249],{},[10,15392,252],{},[10,15394,255,15395,258],{},[43,15396,236],{},[14,15398,261],{"id":261},[10,15400,264],{},[266,15402,15403,15405],{},[10,15404,270],{},[266,15406,15407,15413,15415,15419,15421],{},[10,15408,275,15409,279,15411,283],{},[43,15410,278],{},[43,15412,282],{},[10,15414,286],{},[10,15416,289,15417,294],{},[291,15418,293],{},[10,15420,297],{},[10,15422,15423],{},[26,15424],{"alt":302,"src":303},[266,15426,15427,15429],{},[10,15428,308],{},[266,15430,15431,15433],{},[10,15432,313],{},[10,15434,15435],{},[26,15436],{"alt":318,"src":319},[14,15438,323],{"id":322},[325,15440,328],{"id":327},[10,15442,331,15443,339],{},[333,15444,338],{"href":335,"rel":15445},[337],[266,15447,15448],{},[10,15449,344],{},[10,15451,15452],{},[26,15453],{"alt":349,"src":350},[37,15455,15456,15460,15464],{},[40,15457,355,15458,195],{},[291,15459,358],{},[40,15461,361,15462,195],{},[291,15463,364],{},[40,15465,367],{},[10,15467,15468],{},[26,15469],{"alt":372,"src":373},[266,15471,15472],{},[10,15473,378],{},[10,15475,15476],{},[26,15477],{"alt":383,"src":384},[325,15479,388],{"id":387},[266,15481,15482,15486,15490,15510],{},[266,15483,15484],{},[10,15485,395],{},[10,15487,398,15488,402],{},[291,15489,401],{},[60,15491,15492],{"className":405,"code":406,"language":102,"meta":65,"style":65},[43,15493,15494,15498,15502,15506],{"__ignoreMap":65},[69,15495,15496],{"class":71,"line":72},[69,15497,413],{},[69,15499,15500],{"class":71,"line":90},[69,15501,418],{},[69,15503,15504],{"class":71,"line":99},[69,15505,423],{},[69,15507,15508],{"class":71,"line":108},[69,15509,428],{},[10,15511,431,15512,435],{},[291,15513,434],{},[10,15515,438],{},[10,15517,441,15518,444],{},[43,15519,102],{},[10,15521,15522],{},[26,15523],{"alt":449,"src":450},[10,15525,453],{},[266,15527,15528,15530,15534],{},[10,15529,458],{},[10,15531,15532],{},[291,15533,463],{},[266,15535,15536,15540,15544],{},[10,15537,468,15538,471],{},[43,15539,102],{},[10,15541,474,15542,477],{},[43,15543,102],{},[10,15545,480,15546,484],{},[291,15547,483],{},[266,15549,15550,15552,15556],{},[10,15551,489],{},[10,15553,15554],{},[291,15555,494],{},[266,15557,15558,15564,15572,15574],{},[10,15559,15560,502,15562,506],{},[43,15561,501],{},[43,15563,505],{},[10,15565,509,15566,512,15568,516,15570,520],{},[43,15567,501],{},[291,15569,515],{},[291,15571,519],{},[10,15573,523],{},[10,15575,15576,529],{},[291,15577,528],{},[266,15579,15580,15582],{},[10,15581,534],{},[266,15583,15584,15588],{},[10,15585,539,15586,543],{},[291,15587,542],{},[10,15589,546],{},[266,15591,15592,15596],{},[10,15593,551,15594],{},[291,15595,554],{},[10,15597,15598],{},[26,15599],{"alt":559,"src":560},[266,15601,15602,15604],{},[10,15603,565],{},[10,15605,15606],{},[26,15607],{"alt":559,"src":570},[325,15609,574],{"id":573},[10,15611,577,15612,581,15614,585],{},[43,15613,580],{},[43,15615,584],{},[60,15617,15618],{"className":62,"code":588,"language":64,"meta":65,"style":65},[43,15619,15620],{"__ignoreMap":65},[69,15621,15622,15624],{"class":71,"line":72},[69,15623,102],{"class":75},[69,15625,105],{"class":79},[10,15627,599],{},[60,15629,15631],{"className":15630,"code":603,"language":132,"meta":65},[130],[43,15632,603],{"__ignoreMap":65},[10,15634,15635],{},[26,15636],{"alt":559,"src":610},[10,15638,613],{},[60,15640,15641],{"className":62,"code":616,"language":64,"meta":65,"style":65},[43,15642,15643],{"__ignoreMap":65},[69,15644,15645,15647,15649,15651],{"class":71,"line":72},[69,15646,102],{"class":75},[69,15648,80],{"class":79},[69,15650,115],{"class":83},[69,15652,105],{"class":79},[10,15654,631,15655,634,15657,638],{},[43,15656,102],{},[43,15658,637],{},[60,15660,15661],{"className":62,"code":641,"language":64,"meta":65,"style":65},[43,15662,15663,15669],{"__ignoreMap":65},[69,15664,15665,15667],{"class":71,"line":72},[69,15666,505],{"class":75},[69,15668,105],{"class":79},[69,15670,15671,15673,15675,15677],{"class":71,"line":90},[69,15672,505],{"class":75},[69,15674,80],{"class":79},[69,15676,115],{"class":83},[69,15678,105],{"class":79},[14,15680,663],{"id":662},[325,15682,667],{"id":666},[10,15684,670],{},[60,15686,15687],{"className":62,"code":673,"language":64,"meta":65,"style":65},[43,15688,15689],{"__ignoreMap":65},[69,15690,15691,15693],{"class":71,"line":72},[69,15692,76],{"class":75},[69,15694,105],{"class":79},[10,15696,684,15697,688],{},[43,15698,687],{},[325,15700,692],{"id":691},[10,15702,331,15703,700,15706,195,15708,707],{},[333,15704,699],{"href":697,"rel":15705},[337],[291,15707,703],{},[43,15709,706],{},[10,15711,710,15712,714],{},[43,15713,713],{},[325,15715,718],{"id":717},[10,15717,721],{},[60,15719,15720],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,15721,15722,15728],{"__ignoreMap":65},[69,15723,15724,15726],{"class":71,"line":72},[69,15725,76],{"class":75},[69,15727,105],{"class":79},[69,15729,15730,15732,15734,15736],{"class":71,"line":90},[69,15731,76],{"class":75},[69,15733,80],{"class":79},[69,15735,115],{"class":83},[69,15737,105],{"class":79},[10,15739,745,15740,748],{},[43,15741,76],{},[14,15743,752],{"id":751},[10,15745,755],{},[325,15747,759],{"id":758},[10,15749,762],{},[60,15751,15752],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,15753,15754,15760],{"__ignoreMap":65},[69,15755,15756,15758],{"class":71,"line":72},[69,15757,76],{"class":75},[69,15759,105],{"class":79},[69,15761,15762,15764,15766,15768],{"class":71,"line":90},[69,15763,76],{"class":75},[69,15765,80],{"class":79},[69,15767,115],{"class":83},[69,15769,105],{"class":79},[10,15771,785],{},[325,15773,789],{"id":788},[10,15775,792],{},[60,15777,15778],{"className":62,"code":795,"language":64,"meta":65,"style":65},[43,15779,15780,15788],{"__ignoreMap":65},[69,15781,15782,15784,15786],{"class":71,"line":72},[69,15783,802],{"class":75},[69,15785,805],{"class":83},[69,15787,808],{"class":83},[69,15789,15790,15792,15794,15796,15798,15800],{"class":71,"line":90},[69,15791,802],{"class":75},[69,15793,805],{"class":83},[69,15795,817],{"class":83},[69,15797,820],{"class":83},[69,15799,823],{"class":83},[69,15801,826],{"class":83},[10,15803,829],{},[60,15805,15806],{"className":62,"code":832,"language":64,"meta":65,"style":65},[43,15807,15808],{"__ignoreMap":65},[69,15809,15810,15812,15814,15816,15818],{"class":71,"line":72},[69,15811,802],{"class":75},[69,15813,841],{"class":83},[69,15815,817],{"class":83},[69,15817,820],{"class":83},[69,15819,848],{"class":83},[10,15821,851],{},[60,15823,15824],{"className":62,"code":854,"language":64,"meta":65,"style":65},[43,15825,15826],{"__ignoreMap":65},[69,15827,15828,15830,15832,15834,15836],{"class":71,"line":72},[69,15829,802],{"class":75},[69,15831,863],{"class":83},[69,15833,866],{"class":79},[69,15835,869],{"class":83},[69,15837,872],{"class":83},[10,15839,15840,877],{},[43,15841,802],{},[325,15843,881],{"id":880},[10,15845,884],{},[60,15847,15848],{"className":62,"code":724,"language":64,"meta":65,"style":65},[43,15849,15850,15856],{"__ignoreMap":65},[69,15851,15852,15854],{"class":71,"line":72},[69,15853,76],{"class":75},[69,15855,105],{"class":79},[69,15857,15858,15860,15862,15864],{"class":71,"line":90},[69,15859,76],{"class":75},[69,15861,80],{"class":79},[69,15863,115],{"class":83},[69,15865,105],{"class":79},[10,15867,907],{},[14,15869,910],{"id":910},[325,15871,914],{"id":913},[10,15873,917,15874,921],{},[43,15875,920],{},[142,15877,15878,15882,15884],{},[40,15879,926,15880,929],{},[43,15881,637],{},[40,15883,932],{},[40,15885,935],{},[10,15887,938],{},[325,15889,942],{"id":941},[10,15891,945],{},[60,15893,15894],{"className":62,"code":673,"language":64,"meta":65,"style":65},[43,15895,15896],{"__ignoreMap":65},[69,15897,15898,15900],{"class":71,"line":72},[69,15899,76],{"class":75},[69,15901,105],{"class":79},[10,15903,958,15904,961,15906,964,15908,195],{},[43,15905,76],{},[43,15907,102],{},[43,15909,76],{},[325,15911,970],{"id":969},[10,15913,973],{},[60,15915,15916],{"className":62,"code":976,"language":64,"meta":65,"style":65},[43,15917,15918],{"__ignoreMap":65},[69,15919,15920,15922,15924,15926],{"class":71,"line":72},[69,15921,76],{"class":75},[69,15923,80],{"class":79},[69,15925,115],{"class":83},[69,15927,105],{"class":79},[10,15929,991,15930,994,15932,997,15934,1000,15936,1004],{},[43,15931,76],{},[43,15933,102],{},[43,15935,505],{},[43,15937,1003],{},[209,15939,1007],{},{"title":65,"searchDepth":90,"depth":90,"links":15941},[15942,15943,15944,15949,15954,15959],{"id":246,"depth":90,"text":246},{"id":261,"depth":90,"text":261},{"id":322,"depth":90,"text":323,"children":15945},[15946,15947,15948],{"id":327,"depth":99,"text":328},{"id":387,"depth":99,"text":388},{"id":573,"depth":99,"text":574},{"id":662,"depth":90,"text":663,"children":15950},[15951,15952,15953],{"id":666,"depth":99,"text":667},{"id":691,"depth":99,"text":692},{"id":717,"depth":99,"text":718},{"id":751,"depth":90,"text":752,"children":15955},[15956,15957,15958],{"id":758,"depth":99,"text":759},{"id":788,"depth":99,"text":789},{"id":880,"depth":99,"text":881},{"id":910,"depth":90,"text":910,"children":15960},[15961,15962,15963],{"id":913,"depth":99,"text":914},{"id":941,"depth":99,"text":942},{"id":969,"depth":99,"text":970},{},{"title":241,"description":65},[222,1040,1041],1786973365452]