[{"data":1,"prerenderedAt":15989},["ShallowReactive",2],{"post-python-scope-lookup":3,"sidebar-posts":270,"post-related-source":9180},{"id":4,"title":5,"body":6,"category":255,"cover":256,"description":12,"extension":257,"meta":258,"navigation":85,"path":259,"pinned":260,"publishedAt":261,"seo":262,"slug":263,"stem":264,"summary":265,"tags":266,"updatedAt":261,"visible":85,"__hash__":269},"posts\u002Fposts\u002F20260817\u002F25-python-scope-lookup.md","25｜作用域与变量查找顺序",{"type":7,"value":8,"toc":243},"minimark",[9,13,17,20,23,30,33,36,57,60,63,144,147,155,158,161,192,196,199,205,208,211,219,222,230,233,236,239],[10,11,12],"p",{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够判断变量在函数内外的可见范围。",[14,15,16],"h2",{"id":16},"本篇要解决的问题",[10,18,19],{},"本篇只处理“作用域与变量查找顺序”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,21,22],{"id":22},"先看清一个容易误解的细节",[10,24,25],{},[26,27],"img",{"alt":28,"src":29},"变量按照作用域逐层查找","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-scope-lookup.svg",[10,31,32],{},"Python 查找名字时按局部、外层函数、全局、内置的顺序逐层寻找，找到后停止。这个顺序常简称 LEGB。",[14,34,35],{"id":35},"核心概念",[37,38,39,43,46],"ul",{},[40,41,42],"li",{},"函数内部赋值默认创建局部变量。",[40,44,45],{},"尽量通过参数和返回值传递数据，少依赖可修改的全局状态。",[40,47,48,52,53,56],{},[49,50,51],"code",{},"global"," 与 ",[49,54,55],{},"nonlocal"," 会改变赋值目标，基础代码中应谨慎使用。",[14,58,59],{"id":59},"跟着示例运行",[10,61,62],{},"把下面代码保存到本课脚本并运行：",[64,65,70],"pre",{"className":66,"code":67,"language":68,"meta":69,"style":69},"language-python shiki shiki-themes github-dark","course = \"Python\"\n\ndef outer():\n    level = \"基础\"\n\n    def show():\n        lesson = \"作用域\"\n        print(course, level, lesson)\n\n    show()\n\nouter()\n","python","",[49,71,72,80,87,93,99,104,110,116,122,127,133,138],{"__ignoreMap":69},[73,74,77],"span",{"class":75,"line":76},"line",1,[73,78,79],{},"course = \"Python\"\n",[73,81,83],{"class":75,"line":82},2,[73,84,86],{"emptyLinePlaceholder":85},true,"\n",[73,88,90],{"class":75,"line":89},3,[73,91,92],{},"def outer():\n",[73,94,96],{"class":75,"line":95},4,[73,97,98],{},"    level = \"基础\"\n",[73,100,102],{"class":75,"line":101},5,[73,103,86],{"emptyLinePlaceholder":85},[73,105,107],{"class":75,"line":106},6,[73,108,109],{},"    def show():\n",[73,111,113],{"class":75,"line":112},7,[73,114,115],{},"        lesson = \"作用域\"\n",[73,117,119],{"class":75,"line":118},8,[73,120,121],{},"        print(course, level, lesson)\n",[73,123,125],{"class":75,"line":124},9,[73,126,86],{"emptyLinePlaceholder":85},[73,128,130],{"class":75,"line":129},10,[73,131,132],{},"    show()\n",[73,134,136],{"class":75,"line":135},11,[73,137,86],{"emptyLinePlaceholder":85},[73,139,141],{"class":75,"line":140},12,[73,142,143],{},"outer()\n",[10,145,146],{},"预期结果：",[64,148,153],{"className":149,"code":151,"language":152,"meta":69},[150],"language-text","Python 基础 作用域\n","text",[49,154,151],{"__ignoreMap":69},[10,156,157],{},"输出中包含环境路径、集合元素或日志格式时，具体文字和顺序可能随本机环境变化；判断是否成功应以本篇说明的关键结果为准。",[14,159,160],{"id":160},"按执行顺序拆开看",[162,163,164,182],"ol",{},[40,165,166,169,170,173,174,177,178,181],{},[49,167,168],{},"show()"," 中查找 ",[49,171,172],{},"lesson"," 时先在局部找到，查找 ",[49,175,176],{},"level"," 时到外层 ",[49,179,180],{},"outer()"," 找到。",[40,183,184,187,188,191],{},[49,185,186],{},"course"," 在局部和外层都不存在，继续到模块全局找到；",[49,189,190],{},"print"," 最后在内置作用域找到。",[193,194,195],"h3",{"id":195},"再看一个具体细节",[10,197,198],{},"内层重新使用同一个变量名时，会遮蔽外层名字。",[10,200,201],{},[26,202],{"alt":203,"src":204},"内层同名变量遮蔽外层名字","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F25-shadowing-name.svg",[10,206,207],{},"查找在最近作用域已经找到结果后就停止；外层同名变量仍存在，只是当前表达式没有继续查找它。",[14,209,210],{"id":210},"初学者容易混淆的地方",[37,212,213,216],{},[40,214,215],{},"在函数内部赋值同名变量后仍期待修改全局变量；默认会创建局部绑定。",[40,217,218],{},"大量使用全局可变状态，让函数结果依赖隐含环境，难以测试和复用。",[14,220,221],{"id":221},"练习",[162,223,224,227],{},[40,225,226],{},"在内外层定义同名变量，观察最近作用域优先。",[40,228,229],{},"尝试在函数外访问局部变量，记录异常类型。",[10,231,232],{},"练习应先独立完成，再通过增加 print 输出或检查文件内容观察中间状态。当前课程尚未讲到的能力，不要求提前搜索复杂写法。",[14,234,235],{"id":235},"本篇边界",[10,237,238],{},"本篇目标是判断变量在函数内外的可见范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,241,242],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":69,"searchDepth":82,"depth":82,"links":244},[245,246,247,248,249,252,253,254],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":250},[251],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},"Python",null,"md",{},"\u002Fposts\u002F20260817\u002F25-python-scope-lookup",false,"2026-08-17",{"title":5,"description":12},"python-scope-lookup","posts\u002F20260817\u002F25-python-scope-lookup","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者判断变量在函数内外的可见范围。",[255,267,268],"作用域","LEGB","2KgHWcjvCENV4uVEdQA4-7UCJ9rIaz5CNRkEU3NeaxI",[271,1084,1421,1555,1707,1886,2074,2237,2421,2602,2794,3025,3209,3386,3543,3714,3879,4093,4321,4503,4666,4855,5043,5198,5358,5555,5751,5916,6083,6327,6508,6713,6908,7092,7293,7583,7775,8004,8199,8419,8659,8863],{"id":272,"title":273,"body":274,"category":255,"cover":256,"description":69,"extension":257,"meta":1073,"navigation":85,"path":1074,"pinned":260,"publishedAt":1075,"seo":1076,"slug":1077,"stem":1078,"summary":1079,"tags":1080,"updatedAt":1075,"visible":85,"__hash__":1083},"posts\u002Fposts\u002F20260717\u002Fpython-environment-installation.md","Python 环境安装",{"type":7,"value":275,"toc":1049},[276,279,282,285,292,295,298,337,353,357,361,372,377,383,401,407,412,418,422,468,471,477,483,486,517,562,579,593,603,607,618,634,637,643,648,651,669,679,700,704,708,711,723,730,734,749,756,760,763,784,790,794,797,801,804,824,827,831,834,868,871,890,893,914,919,923,926,946,949,952,956,963,977,980,984,987,997,1008,1012,1015,1030,1046],[14,277,278],{"id":278},"引言",[10,280,281],{},"这一节面向 Python 初学者，介绍在 Windows、macOS、Linux 三个平台上安装 Python 解释器的方法。",[10,283,284],{},"学习 Python 的第一步，就是先准备好一个能运行代码的环境。在这之前，你写的任何代码都没办法跑起来，所以这一步非常关键。",[10,286,287,288,291],{},"安装完成后，我们会打开终端，输入一条命令验证 Python 是否安装成功，同时确认 ",[49,289,290],{},"pip"," 这个包管理工具也能正常使用——后续安装各种库，都要靠它来完成。",[14,293,294],{"id":294},"扫盲",[10,296,297],{},"那么这里有几个概念：",[299,300,301,304],"blockquote",{},[10,302,303],{},"为什么需要安装python解释器？",[299,305,306,317,320,328,331],{},[10,307,308,309,312,313,316],{},"我们写的代码，电脑其实看不懂，电脑只认识",[49,310,311],{},"0","和",[49,314,315],{},"1","组成的机器指令。",[10,318,319],{},"那么python解释器的作用就是充当中间的翻译官，当我们在电脑上运行python代码，python解释器充当翻译官，当我们执行脚本，翻译官就会将python代码翻译成机器的0和1。",[10,321,322,323,327],{},"这样，我们就能用",[324,325,326],"strong",{},"人类能读懂的语言","来写代码，再由 Python 这个翻译官，把它翻译成机器能听懂的指令去执行——我们和计算机之间的\"语言障碍\"，就这么被解决了。",[10,329,330],{},"相当于我们的电脑要打开表格，需要安装excel。",[10,332,333],{},[26,334],{"alt":335,"src":336},"图1","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161622-%E5%9B%BE1.png",[299,338,339,342],{},[10,340,341],{},"pip又是什么？",[299,343,344,347],{},[10,345,346],{},"pip相当于插件市场，python除了我们自己写代码，还可以下载别人的代码库，来直接调用别人写好的优秀的方法。比如安装了requests库，未来我们就可以用程序模拟浏览器去访问网页。",[10,348,349],{},[26,350],{"alt":351,"src":352},"图2","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717172846-%E5%9B%BE2.png",[14,354,356],{"id":355},"windows-安装","Windows 安装",[193,358,360],{"id":359},"_1-下载官方安装程序","1. 下载官方安装程序",[10,362,363,364,371],{},"打开 ",[365,366,370],"a",{"href":367,"rel":368},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fwindows\u002F",[369],"nofollow","Python Windows 下载页","，选择当前稳定版对应的 Windows installer：",[299,373,374],{},[10,375,376],{},"本次以 Python 3 稳定版下载流程为准。Python 官网会持续更新补丁版本，安装时选择下载页当前提供的最新 Python 3 稳定版即可",[10,378,379],{},[26,380],{"alt":381,"src":382},"Python Windows 下载页面","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717123049-image.png",[37,384,385,392,398],{},[40,386,387,388,391],{},"大多数 Intel 或 AMD 处理器的电脑选择 ",[324,389,390],{},"Windows installer (64-bit)","。",[40,393,394,395,391],{},"搭载 ARM 处理器的 Windows 设备选择 ",[324,396,397],{},"Windows installer (ARM64)",[40,399,400],{},"只有明确使用 32 位 Windows 时才选择 32 位安装程序。",[10,402,403],{},[26,404],{"alt":405,"src":406},"Windows 安装程序类型","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120221-image.png",[299,408,409],{},[10,410,411],{},"我的电脑是 64 位，所以下载 Windows installer (64-bit)。",[10,413,414],{},[26,415],{"alt":416,"src":417},"Windows 64 位安装程序下载入口","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717120550-image.png",[193,419,421],{"id":420},"_2-安装并加入-path","2. 安装并加入 PATH",[299,423,424,429,436,461],{},[299,425,426],{},[10,427,428],{},"PATH 环境变量",[10,430,431,432,435],{},"Windows 有一个特殊的变量叫 ",[324,433,434],{},"PATH","，它里面存了一串文件夹路径，比如：",[64,437,439],{"className":66,"code":438,"language":68,"meta":69,"style":69},"D:\\Python313\\\nD:\\Python313\\Scripts\\\nC:\\Windows\\System32\\\n...\n",[49,440,441,446,451,456],{"__ignoreMap":69},[73,442,443],{"class":75,"line":76},[73,444,445],{},"D:\\Python313\\\n",[73,447,448],{"class":75,"line":82},[73,449,450],{},"D:\\Python313\\Scripts\\\n",[73,452,453],{"class":75,"line":89},[73,454,455],{},"C:\\Windows\\System32\\\n",[73,457,458],{"class":75,"line":95},[73,459,460],{},"...\n",[10,462,463,464,467],{},"我们每次在终端输一个命令，Windows 就拿着这个名字，",[324,465,466],{},"挨个去 PATH 里的文件夹翻","，找到了就执行，找不到就报错。",[10,469,470],{},"双击下载的安装程序。在安装界面中，勾选 底部两个选项，然后选择自定义安装。",[10,472,473,474,476],{},"PATH 是系统查找可执行程序时使用的一组目录。勾选后，Windows 才能在新的终端窗口中直接找到 ",[49,475,68],{}," 命令。不同 Python 安装器的界面文字可能略有差异，但目标都是让 Python 命令进入 PATH。",[10,478,479],{},[26,480],{"alt":481,"src":482},"未命名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717154915-%E6%9C%AA%E5%91%BD%E5%90%8D.png",[10,484,485],{},"对安装界面最底部的两个勾选项分别解释 :",[299,487,488,491,496],{},[10,489,490],{},"Add python.exe to PATH",[10,492,493],{},[324,494,495],{},"把 Python 添加到系统环境变量",[299,497,498,504,510],{},[10,499,500,501,503],{},"勾选后，你可以在命令行任意位置直接输入 ",[49,502,68],{}," 就能运行",[10,505,506,507,509],{},"不勾选的话，命令行输入 ",[49,508,68],{}," 会提示**\"找不到命令\"**，非常麻烦",[10,511,512,513,516],{},"必须",[324,514,515],{},"勾选","，这是最重要的一个选项，新手最容易忘记打勾",[299,518,519,522,527],{},[10,520,521],{},"Use admin privileges when installing py.exe",[10,523,524],{},[324,525,526],{},"使用管理员权限安装 py.exe（Python 启动器）",[299,528,529,539,553,556],{},[10,530,531,534,535,538],{},[49,532,533],{},"py.exe"," 是 Windows 专属的 Python 启动器，可以让你在命令行输入 ",[49,536,537],{},"py"," 来启动 Python。",[10,540,541,542,544,545,548,549,552],{},"勾选后，",[49,543,533],{}," 会安装到",[324,546,547],{},"系统级目录","，电脑上",[324,550,551],{},"所有用户账户","都能用",[10,554,555],{},"不勾选，只有当前用户能用",[10,557,558,561],{},[324,559,560],{},"建议勾选","，权限更完整，避免后续出现奇怪的权限问题",[299,563,564,567],{},[10,565,566],{},"操作建议",[299,568,569,576],{},[10,570,571,572,575],{},"两个都勾上之后，再点 ",[324,573,574],{},"\"Customize installation\""," 去修改安装路径到 D 盘，不要直接点 \"Install Now\"，否则会装到 C 盘。",[10,577,578],{},"系统文件归 C 盘，自己装的软件和项目归 D 盘，分类清晰，以后管理方便。",[299,580,581,587],{},[10,582,583,584],{},"Python 安装的",[324,585,586],{},"可选功能页",[10,588,589],{},[26,590],{"alt":591,"src":592},"image","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161424-image.png",[299,594,595,598],{},[10,596,597],{},"高级选项页",[10,599,600],{},[26,601],{"alt":591,"src":602},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717161340-image.png",[193,604,606],{"id":605},"_3-检查-windows-环境","3. 检查 Windows 环境",[10,608,609,610,613,614,617],{},"按 ",[49,611,612],{},"Win + R","，输入 ",[49,615,616],{},"cmd"," 并回车，然后执行：",[64,619,623],{"className":620,"code":621,"language":622,"meta":69,"style":69},"language-bash shiki shiki-themes github-dark","python --version\n","bash",[49,624,625],{"__ignoreMap":69},[73,626,627,630],{"class":75,"line":76},[73,628,68],{"class":629},"svObZ",[73,631,633],{"class":632},"sDLfK"," --version\n",[10,635,636],{},"正常情况下会看到类似下面的输出，具体补丁版本以实际安装结果为准：",[64,638,641],{"className":639,"code":640,"language":152,"meta":69},[150],"Python 3.x.x\n",[49,642,640],{"__ignoreMap":69},[10,644,645],{},[26,646],{"alt":591,"src":647},"https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260717\u002F20260717155647-image.png",[10,649,650],{},"继续检查 pip：",[64,652,654],{"className":620,"code":653,"language":622,"meta":69,"style":69},"python -m pip --version\n",[49,655,656],{"__ignoreMap":69},[73,657,658,660,663,667],{"class":75,"line":76},[73,659,68],{"class":629},[73,661,662],{"class":632}," -m",[73,664,666],{"class":665},"sU2Wk"," pip",[73,668,633],{"class":632},[10,670,671,672,674,675,678],{},"如果 ",[49,673,68],{}," 无法识别，但 ",[49,676,677],{},"py --version"," 可以输出版本号，后续也可以使用 Windows Python Launcher：",[64,680,682],{"className":620,"code":681,"language":622,"meta":69,"style":69},"py --version\npy -m pip --version\n",[49,683,684,690],{"__ignoreMap":69},[73,685,686,688],{"class":75,"line":76},[73,687,537],{"class":629},[73,689,633],{"class":632},[73,691,692,694,696,698],{"class":75,"line":82},[73,693,537],{"class":629},[73,695,662],{"class":632},[73,697,666],{"class":665},[73,699,633],{"class":632},[14,701,703],{"id":702},"macos-安装","macOS 安装",[193,705,707],{"id":706},"_1-先检查现有环境","1. 先检查现有环境",[10,709,710],{},"打开“终端”应用，执行：",[64,712,714],{"className":620,"code":713,"language":622,"meta":69,"style":69},"python3 --version\n",[49,715,716],{"__ignoreMap":69},[73,717,718,721],{"class":75,"line":76},[73,719,720],{"class":629},"python3",[73,722,633],{"class":632},[10,724,725,726,729],{},"如果已经输出符合学习要求的 Python 3 版本，可以继续执行 ",[49,727,728],{},"python3 -m pip --version","。两条命令都正常时，无需重复安装。",[193,731,733],{"id":732},"_2-下载-macos-官方安装包","2. 下载 macOS 官方安装包",[10,735,363,736,741,742,391,745,748],{},[365,737,740],{"href":738,"rel":739},"https:\u002F\u002Fwww.python.org\u002Fdownloads\u002Fmacos\u002F",[369],"Python macOS 下载页","，下载当前稳定版的 ",[324,743,744],{},"macOS 64-bit universal2 installer",[49,746,747],{},"universal2"," 安装包同时支持 Apple 芯片和 Intel 芯片 Mac。",[10,750,751,752,755],{},"下载完成后打开 ",[49,753,754],{},".pkg"," 文件，按照安装器提示完成安装。使用官网安装包时，系统可能要求输入当前 macOS 用户的登录密码，用于授权写入系统级安装目录。",[193,757,759],{"id":758},"_3-检查-macos-环境","3. 检查 macOS 环境",[10,761,762],{},"安装完成后重新打开终端，执行：",[64,764,766],{"className":620,"code":765,"language":622,"meta":69,"style":69},"python3 --version\npython3 -m pip --version\n",[49,767,768,774],{"__ignoreMap":69},[73,769,770,772],{"class":75,"line":76},[73,771,720],{"class":629},[73,773,633],{"class":632},[73,775,776,778,780,782],{"class":75,"line":82},[73,777,720],{"class":629},[73,779,662],{"class":632},[73,781,666],{"class":665},[73,783,633],{"class":632},[10,785,786,787,789],{},"正常情况下，两条命令都会显示版本信息。macOS 中建议始终使用 ",[49,788,720],{},"，不要为了缩短命令而修改或覆盖系统自带工具。",[14,791,793],{"id":792},"linux-安装","Linux 安装",[10,795,796],{},"Linux 发行版通常通过系统包管理器维护 Python。仓库中的版本可能落后于 Python 官网的最新补丁版，但会与当前系统的软件依赖和安全更新保持一致。对于本系列的入门代码，优先使用发行版仓库版本，安装和维护都更稳妥。",[193,798,800],{"id":799},"_1-检查是否已经安装","1. 检查是否已经安装",[10,802,803],{},"打开终端，执行：",[64,805,806],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,807,808,814],{"__ignoreMap":69},[73,809,810,812],{"class":75,"line":76},[73,811,720],{"class":629},[73,813,633],{"class":632},[73,815,816,818,820,822],{"class":75,"line":82},[73,817,720],{"class":629},[73,819,662],{"class":632},[73,821,666],{"class":665},[73,823,633],{"class":632},[10,825,826],{},"不少 Linux 系统已经包含 Python 3。如果第一条命令有输出、第二条命令提示没有 pip，只安装 pip 和虚拟环境支持即可。",[193,828,830],{"id":829},"_2-使用发行版包管理器安装","2. 使用发行版包管理器安装",[10,832,833],{},"Ubuntu 或 Debian：",[64,835,837],{"className":620,"code":836,"language":622,"meta":69,"style":69},"sudo apt update\nsudo apt install python3 python3-pip python3-venv\n",[49,838,839,850],{"__ignoreMap":69},[73,840,841,844,847],{"class":75,"line":76},[73,842,843],{"class":629},"sudo",[73,845,846],{"class":665}," apt",[73,848,849],{"class":665}," update\n",[73,851,852,854,856,859,862,865],{"class":75,"line":82},[73,853,843],{"class":629},[73,855,846],{"class":665},[73,857,858],{"class":665}," install",[73,860,861],{"class":665}," python3",[73,863,864],{"class":665}," python3-pip",[73,866,867],{"class":665}," python3-venv\n",[10,869,870],{},"Fedora：",[64,872,874],{"className":620,"code":873,"language":622,"meta":69,"style":69},"sudo dnf install python3 python3-pip\n",[49,875,876],{"__ignoreMap":69},[73,877,878,880,883,885,887],{"class":75,"line":76},[73,879,843],{"class":629},[73,881,882],{"class":665}," dnf",[73,884,858],{"class":665},[73,886,861],{"class":665},[73,888,889],{"class":665}," python3-pip\n",[10,891,892],{},"Arch Linux：",[64,894,896],{"className":620,"code":895,"language":622,"meta":69,"style":69},"sudo pacman -S python python-pip\n",[49,897,898],{"__ignoreMap":69},[73,899,900,902,905,908,911],{"class":75,"line":76},[73,901,843],{"class":629},[73,903,904],{"class":665}," pacman",[73,906,907],{"class":632}," -S",[73,909,910],{"class":665}," python",[73,912,913],{"class":665}," python-pip\n",[10,915,916,918],{},[49,917,843],{}," 会要求输入当前 Linux 用户的密码。执行前应确认该用户具备管理员权限，不要从来历不明的网页复制带有删除或覆盖操作的命令。",[193,920,922],{"id":921},"_3-检查-linux-环境","3. 检查 Linux 环境",[10,924,925],{},"安装结束后执行：",[64,927,928],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,929,930,936],{"__ignoreMap":69},[73,931,932,934],{"class":75,"line":76},[73,933,720],{"class":629},[73,935,633],{"class":632},[73,937,938,940,942,944],{"class":75,"line":82},[73,939,720],{"class":629},[73,941,662],{"class":632},[73,943,666],{"class":665},[73,945,633],{"class":632},[10,947,948],{},"看到 Python 3 和 pip 的版本信息，说明基础环境已经可用。",[14,950,951],{"id":951},"常见问题",[193,953,955],{"id":954},"windows-提示python-不是内部或外部命令","Windows 提示“python 不是内部或外部命令”",[10,957,958,959,962],{},"先关闭当前命令提示符并重新打开，再执行 ",[49,960,961],{},"python --version","。如果仍然失败，按下面的顺序检查：",[162,964,965,971,974],{},[40,966,967,968,970],{},"执行 ",[49,969,677],{},"，确认 Python Launcher 是否可用。",[40,972,973],{},"在 Windows 的“已安装的应用”中确认 Python 已经安装。",[40,975,976],{},"重新运行官方安装程序，选择修改安装，并启用将 Python 加入 PATH 的选项。",[10,978,979],{},"不要仅为解决命令问题而从非官方网站重新下载 Python。",[193,981,983],{"id":982},"macos-或-linux-提示python-command-not-found","macOS 或 Linux 提示“python: command not found”",[10,985,986],{},"先尝试：",[64,988,989],{"className":620,"code":713,"language":622,"meta":69,"style":69},[49,990,991],{"__ignoreMap":69},[73,992,993,995],{"class":75,"line":76},[73,994,720],{"class":629},[73,996,633],{"class":632},[10,998,999,1000,1002,1003,1005,1006,391],{},"在这两个系统中，只有 ",[49,1001,720],{}," 命令而没有 ",[49,1004,68],{}," 命令通常是正常情况。本系列在 macOS 和 Linux 上统一使用 ",[49,1007,720],{},[193,1009,1011],{"id":1010},"python-有版本输出但-pip-不可用","Python 有版本输出，但 pip 不可用",[10,1013,1014],{},"先使用模块方式检查：",[64,1016,1018],{"className":620,"code":1017,"language":622,"meta":69,"style":69},"python3 -m pip --version\n",[49,1019,1020],{"__ignoreMap":69},[73,1021,1022,1024,1026,1028],{"class":75,"line":76},[73,1023,720],{"class":629},[73,1025,662],{"class":632},[73,1027,666],{"class":665},[73,1029,633],{"class":632},[10,1031,1032,1033,1035,1036,1038,1039,1041,1042,1045],{},"Windows 用户将命令中的 ",[49,1034,720],{}," 换成 ",[49,1037,68],{}," 或 ",[49,1040,537],{},"。Linux 用户如果仍然提示缺少 pip，可以通过当前发行版的包管理器安装 ",[49,1043,1044],{},"python3-pip","；不要直接使用其他系统的安装命令。",[240,1047,1048],{},"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":69,"searchDepth":82,"depth":82,"links":1050},[1051,1052,1053,1058,1063,1068],{"id":278,"depth":82,"text":278},{"id":294,"depth":82,"text":294},{"id":355,"depth":82,"text":356,"children":1054},[1055,1056,1057],{"id":359,"depth":89,"text":360},{"id":420,"depth":89,"text":421},{"id":605,"depth":89,"text":606},{"id":702,"depth":82,"text":703,"children":1059},[1060,1061,1062],{"id":706,"depth":89,"text":707},{"id":732,"depth":89,"text":733},{"id":758,"depth":89,"text":759},{"id":792,"depth":82,"text":793,"children":1064},[1065,1066,1067],{"id":799,"depth":89,"text":800},{"id":829,"depth":89,"text":830},{"id":921,"depth":89,"text":922},{"id":951,"depth":82,"text":951,"children":1069},[1070,1071,1072],{"id":954,"depth":89,"text":955},{"id":982,"depth":89,"text":983},{"id":1010,"depth":89,"text":1011},{},"\u002Fposts\u002F20260717\u002Fpython-environment-installation","2026-07-17",{"title":273,"description":69},"python-environment-installation","posts\u002F20260717\u002Fpython-environment-installation","面向准备学习 Python 和爬虫的零基础读者，介绍 Windows、macOS 与常见 Linux 发行版的 Python 安装方法，并通过版本和 pip 命令检查环境是否可用。",[255,1081,1082],"环境搭建","爬虫入门","7N6OEzHY07pQJSD-Dpbm4vAePZra5Hx37AfZ4hvD_Uk",{"id":1085,"title":1086,"body":1087,"category":255,"cover":1094,"description":69,"extension":257,"meta":1410,"navigation":85,"path":1411,"pinned":260,"publishedAt":1412,"seo":1413,"slug":1414,"stem":1415,"summary":1416,"tags":1417,"updatedAt":1412,"visible":85,"__hash__":1420},"posts\u002Fposts\u002F20260815\u002Fpython-introduction.md","Python介绍",{"type":7,"value":1088,"toc":1395},[1089,1095,1098,1101,1105,1108,1132,1135,1141,1144,1147,1181,1191,1195,1202,1205,1230,1233,1245,1248,1252,1255,1258,1261,1264,1267,1270,1273,1297,1300,1303,1309,1312,1315,1318,1322,1328,1331,1357,1360,1364,1367,1370,1374,1377,1380,1383,1386,1389,1392],[10,1090,1091],{},[26,1092],{"alt":1093,"src":1094},"Python 编程语言介绍","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fcovers\u002Fpython-introduction.png",[10,1096,1097],{},"如果只用一句话介绍 Python，可以这样说：它是一门语法简洁、应用范围广，而且比较容易上手的编程语言。",[10,1099,1100],{},"Python 不要求开发者一开始就处理复杂的底层细节。编写代码时，我们通常更关注“程序需要完成什么”，例如整理文件、处理数据或者调用接口，而不必过早考虑内存分配和机器指令。这种设计降低了入门难度，也提高了开发效率。",[14,1102,1104],{"id":1103},"python-代码是什么样的","Python 代码是什么样的",[10,1106,1107],{},"下面是一段简单的 Python 代码：",[64,1109,1111],{"className":66,"code":1110,"language":68,"meta":69,"style":69},"name = \"Python\"\nyear = 2026\n\nprint(f\"正在学习 {name}，当前年份是 {year}\")\n",[49,1112,1113,1118,1123,1127],{"__ignoreMap":69},[73,1114,1115],{"class":75,"line":76},[73,1116,1117],{},"name = \"Python\"\n",[73,1119,1120],{"class":75,"line":82},[73,1121,1122],{},"year = 2026\n",[73,1124,1125],{"class":75,"line":89},[73,1126,86],{"emptyLinePlaceholder":85},[73,1128,1129],{"class":75,"line":95},[73,1130,1131],{},"print(f\"正在学习 {name}，当前年份是 {year}\")\n",[10,1133,1134],{},"运行结果：",[64,1136,1139],{"className":1137,"code":1138,"language":152,"meta":69},[150],"正在学习 Python，当前年份是 2026\n",[49,1140,1138],{"__ignoreMap":69},[10,1142,1143],{},"从这段代码可以看到，Python 不需要在每条语句结尾添加分号，也不需要提前声明变量类型。它使用换行和缩进组织代码，整体结构比较清楚。",[10,1145,1146],{},"缩进在 Python 中不仅用于排版，也是语法的一部分。例如：",[64,1148,1150],{"className":66,"code":1149,"language":68,"meta":69,"style":69},"score = 85\n\nif score >= 60:\n    print(\"成绩合格\")\nelse:\n    print(\"需要继续学习\")\n",[49,1151,1152,1157,1161,1166,1171,1176],{"__ignoreMap":69},[73,1153,1154],{"class":75,"line":76},[73,1155,1156],{},"score = 85\n",[73,1158,1159],{"class":75,"line":82},[73,1160,86],{"emptyLinePlaceholder":85},[73,1162,1163],{"class":75,"line":89},[73,1164,1165],{},"if score >= 60:\n",[73,1167,1168],{"class":75,"line":95},[73,1169,1170],{},"    print(\"成绩合格\")\n",[73,1172,1173],{"class":75,"line":101},[73,1174,1175],{},"else:\n",[73,1177,1178],{"class":75,"line":106},[73,1179,1180],{},"    print(\"需要继续学习\")\n",[10,1182,1183,1186,1187,1190],{},[49,1184,1185],{},"if"," 和 ",[49,1188,1189],{},"else"," 下面的代码必须保持正确缩进，否则程序可能无法运行。",[14,1192,1194],{"id":1193},"python-如何运行代码","Python 如何运行代码",[10,1196,1197,1198,1201],{},"Python 通常被称为解释型语言。安装 Python 解释器后，可以直接在终端中运行 ",[49,1199,1200],{},".py"," 文件，也可以进入交互式环境逐行执行代码。",[10,1203,1204],{},"交互式环境适合快速验证一个表达式：",[64,1206,1208],{"className":66,"code":1207,"language":68,"meta":69,"style":69},">>> 10 + 20\n30\n>>> \"Python\".lower()\n'python'\n",[49,1209,1210,1215,1220,1225],{"__ignoreMap":69},[73,1211,1212],{"class":75,"line":76},[73,1213,1214],{},">>> 10 + 20\n",[73,1216,1217],{"class":75,"line":82},[73,1218,1219],{},"30\n",[73,1221,1222],{"class":75,"line":89},[73,1223,1224],{},">>> \"Python\".lower()\n",[73,1226,1227],{"class":75,"line":95},[73,1228,1229],{},"'python'\n",[10,1231,1232],{},"需要保存和重复运行的程序，则可以写入文件：",[64,1234,1236],{"className":620,"code":1235,"language":622,"meta":69,"style":69},"python3 hello.py\n",[49,1237,1238],{"__ignoreMap":69},[73,1239,1240,1242],{"class":75,"line":76},[73,1241,720],{"class":629},[73,1243,1244],{"class":665}," hello.py\n",[10,1246,1247],{},"以常见的 CPython 解释器为例，源代码在运行过程中会先转换为字节码，再由 Python 虚拟机执行。这个过程通常由解释器自动完成，开发者不需要手动编译。",[14,1249,1251],{"id":1250},"python-的特点","Python 的特点",[193,1253,1254],{"id":1254},"语法相对简洁",[10,1256,1257],{},"Python 使用较少的代码就能完成许多常见任务。它的关键字和代码结构比较直观，阅读一段规范编写的 Python 程序时，通常能够较快判断程序正在做什么。",[193,1259,1260],{"id":1260},"支持多种编程方式",[10,1262,1263],{},"Python 支持面向过程、面向对象和函数式编程。小型脚本可以直接按照执行顺序编写，项目规模扩大后，也可以使用函数、类和模块拆分代码。",[193,1265,1266],{"id":1266},"标准库比较完整",[10,1268,1269],{},"Python 自带一批常用模块，可以处理文件、路径、日期时间、JSON 数据、日志、压缩文件和网络通信等任务。",[10,1271,1272],{},"例如，获取当前时间：",[64,1274,1276],{"className":66,"code":1275,"language":68,"meta":69,"style":69},"from datetime import datetime\n\nnow = datetime.now()\nprint(now)\n",[49,1277,1278,1283,1287,1292],{"__ignoreMap":69},[73,1279,1280],{"class":75,"line":76},[73,1281,1282],{},"from datetime import datetime\n",[73,1284,1285],{"class":75,"line":82},[73,1286,86],{"emptyLinePlaceholder":85},[73,1288,1289],{"class":75,"line":89},[73,1290,1291],{},"now = datetime.now()\n",[73,1293,1294],{"class":75,"line":95},[73,1295,1296],{},"print(now)\n",[10,1298,1299],{},"这段代码使用的是标准库，不需要另外安装第三方依赖。",[193,1301,1302],{"id":1302},"第三方工具丰富",[10,1304,1305,1306,1308],{},"除了标准库，Python 还拥有数量庞大的第三方软件包。开发者可以通过 ",[49,1307,290],{}," 安装所需工具，用于 Web 开发、数据分析、自动化测试、网络爬虫和人工智能等场景。",[10,1310,1311],{},"第三方包为开发带来了便利，但也需要管理好版本和项目环境。实际开发时，通常会为每个项目创建独立的虚拟环境，避免依赖互相影响。",[193,1313,1314],{"id":1314},"支持多个操作系统",[10,1316,1317],{},"Python 可以运行在 macOS、Linux、Windows 等主流操作系统上。大部分不依赖系统特性的代码可以跨平台使用，但涉及文件路径、系统命令和底层组件时，仍然需要根据运行环境进行调整。",[14,1319,1321],{"id":1320},"python-可以做什么","Python 可以做什么",[10,1323,1324],{},[26,1325],{"alt":1326,"src":1327},"Python 的常见应用方向","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260815\u002Fpython-application-fields.png",[10,1329,1330],{},"Python 的应用范围比较广，常见方向包括：",[37,1332,1333,1336,1339,1342,1345,1348,1351,1354],{},[40,1334,1335],{},"编写自动化脚本，批量处理文件和重复任务；",[40,1337,1338],{},"开发网站后端和 API 服务；",[40,1340,1341],{},"进行数据清洗、统计分析和图表展示；",[40,1343,1344],{},"编写网络爬虫和信息采集工具；",[40,1346,1347],{},"开发自动化测试程序；",[40,1349,1350],{},"进行机器学习和人工智能开发；",[40,1352,1353],{},"编写运维、监控和辅助开发工具；",[40,1355,1356],{},"开发部分桌面应用和插件。",[10,1358,1359],{},"Python 是这些开发方向的基础语言，具体项目通常还需要配合相应的框架或第三方库。例如，Web 开发可以使用 Django、Flask 或 FastAPI，数据处理可以使用 NumPy 和 pandas，机器学习领域则经常使用 PyTorch、TensorFlow 或 scikit-learn。",[14,1361,1363],{"id":1362},"python-的发展","Python 的发展",[10,1365,1366],{},"Python 由 Guido van Rossum 创建，最初的开发工作开始于 20 世纪 80 年代末。",[10,1368,1369],{},"Python 2.0 于 2000 年发布，Python 3.0 于 2008 年发布。Python 3 对语言进行了较大调整，并不完全兼容 Python 2。Python 2 已经结束官方支持，因此现在学习和开发新项目时，应当直接使用 Python 3。",[14,1371,1373],{"id":1372},"python-也有局限","Python 也有局限",[10,1375,1376],{},"Python 的优势主要是代码清晰、开发效率较高和工具生态丰富，但它并不适合所有任务。",[10,1378,1379],{},"在大量计算或对运行速度要求很高的场景中，纯 Python 代码的执行速度可能不如 C、C++ 等编译型语言。移动端原生应用、浏览器前端和部分底层系统开发，也不是 Python 最常见的使用方向。",[10,1381,1382],{},"实际项目中，经常会根据任务特点组合多种语言。Python 负责业务逻辑、数据处理或工具开发，对性能要求较高的部分则可以交给 C、C++ 或其他技术实现。",[14,1384,1385],{"id":1385},"写在最后",[10,1387,1388],{},"Python 容易让初学者快速写出能够运行的程序，同时又具备支撑实际项目的能力。它的价值不只是“语法简单”，还在于标准库完善、第三方生态成熟，并且能够覆盖自动化、Web、数据处理和人工智能等多个方向。",[10,1390,1391],{},"学习 Python 时，可以先掌握变量、数据类型、条件判断、循环和函数，再通过一个具体项目逐步熟悉模块、异常处理和第三方依赖。这样比只记语法更容易形成完整的编程思路。",[240,1393,1394],{},"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":69,"searchDepth":82,"depth":82,"links":1396},[1397,1398,1399,1406,1407,1408,1409],{"id":1103,"depth":82,"text":1104},{"id":1193,"depth":82,"text":1194},{"id":1250,"depth":82,"text":1251,"children":1400},[1401,1402,1403,1404,1405],{"id":1254,"depth":89,"text":1254},{"id":1260,"depth":89,"text":1260},{"id":1266,"depth":89,"text":1266},{"id":1302,"depth":89,"text":1302},{"id":1314,"depth":89,"text":1314},{"id":1320,"depth":82,"text":1321},{"id":1362,"depth":82,"text":1363},{"id":1372,"depth":82,"text":1373},{"id":1385,"depth":82,"text":1385},{},"\u002Fposts\u002F20260815\u002Fpython-introduction","2026-08-15",{"title":1086,"description":69},"python-introduction","posts\u002F20260815\u002Fpython-introduction","面向刚接触编程的读者，介绍 Python 的代码特点、运行方式、常见应用和适用边界，帮助读者建立对这门语言的整体认识。",[255,1418,1419],"编程入门","基础知识","Axa7hQfxA4rShWPXTEcuusziI3hLLaS4NlUR2zrOYls",{"id":1422,"title":1423,"body":1424,"category":255,"cover":256,"description":1428,"extension":257,"meta":1546,"navigation":85,"path":1547,"pinned":260,"publishedAt":261,"seo":1548,"slug":1549,"stem":1550,"summary":1551,"tags":1552,"updatedAt":261,"visible":85,"__hash__":1554},"posts\u002Fposts\u002F20260817\u002F01-python-source-to-output.md","01｜Python 程序从源码到输出经历了什么",{"type":7,"value":1425,"toc":1536},[1426,1429,1431,1434,1436,1442,1447,1449,1463,1465,1467,1476,1478,1484,1486,1488,1504,1506,1517,1519,1527,1529,1531,1534],[10,1427,1428],{},"这套课程按知识依赖排列。本篇的前置知识是：无。学完后，你应该能够理解源代码、解释器和输出之间的关系。",[14,1430,16],{"id":16},[10,1432,1433],{},"本篇只处理“Python 程序从源码到输出经历了什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1435,22],{"id":22},[10,1437,1438],{},[26,1439],{"alt":1440,"src":1441},"源码怎样变成输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F01-source-to-output.svg",[10,1443,1444,1446],{},[49,1445,1200],{}," 文件不会自己执行，它要交给 Python 解释器读取。图中的箭头只表示执行方向：源码进入解释器，解释器按语言规则执行语句，结果才显示在终端。",[14,1448,35],{"id":35},[37,1450,1451,1457,1460],{},[40,1452,1453,1454,1456],{},"源代码是人编写的文本，通常保存在 ",[49,1455,1200],{}," 文件中。",[40,1458,1459],{},"解释器是运行 Python 代码的程序；本课程以 CPython 3.14 为准。",[40,1461,1462],{},"终端只是输入命令和查看输出的界面，不等于 Python 本身。",[14,1464,59],{"id":59},[10,1466,62],{},[64,1468,1470],{"className":66,"code":1469,"language":68,"meta":69,"style":69},"print(\"你好，Python\")\n",[49,1471,1472],{"__ignoreMap":69},[73,1473,1474],{"class":75,"line":76},[73,1475,1469],{},[10,1477,146],{},[64,1479,1482],{"className":1480,"code":1481,"language":152,"meta":69},[150],"你好，Python\n",[49,1483,1481],{"__ignoreMap":69},[10,1485,157],{},[14,1487,160],{"id":160},[162,1489,1490,1497],{},[40,1491,1492,1493,1496],{},"终端启动解释器后，解释器读取 ",[49,1494,1495],{},"print(\"你好，Python\")","，识别函数调用、字符串字面量和右括号。",[40,1498,1499,1500,1503],{},"字符串对象先准备好，再交给 ",[49,1501,1502],{},"print()"," 写到标准输出；终端负责把这段输出显示出来。",[14,1505,210],{"id":210},[37,1507,1508,1511],{},[40,1509,1510],{},"把终端、编辑器和 Python 当成同一个程序。它们分别负责输入命令、编辑文本和执行代码。",[40,1512,1513,1514,1516],{},"认为 ",[49,1515,1200],{}," 文件双击后一定能运行。稳定做法是先在终端明确调用对应解释器。",[14,1518,221],{"id":221},[162,1520,1521,1524],{},[40,1522,1523],{},"指出“源代码、解释器、终端输出”在执行链路中的先后顺序。",[40,1525,1526],{},"把示例文字改成自己的学习目标并重新运行。",[10,1528,232],{},[14,1530,235],{"id":235},[10,1532,1533],{},"本篇目标是理解源代码、解释器和输出之间的关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,1535,242],{},{"title":69,"searchDepth":82,"depth":82,"links":1537},[1538,1539,1540,1541,1542,1543,1544,1545],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F01-python-source-to-output",{"title":1423,"description":1428},"python-source-to-output","posts\u002F20260817\u002F01-python-source-to-output","面向按顺序学习 Python 的初学者，本篇在零基础上，帮助读者理解源代码、解释器和输出之间的关系。",[255,1418,1553],"解释器","GTRMiEOeg14C0nE2QUE2P408mg12X3wSZ8Mh_7JV2nM",{"id":1556,"title":1557,"body":1558,"category":255,"cover":256,"description":1562,"extension":257,"meta":1698,"navigation":85,"path":1699,"pinned":260,"publishedAt":261,"seo":1700,"slug":1701,"stem":1702,"summary":1703,"tags":1704,"updatedAt":261,"visible":85,"__hash__":1706},"posts\u002Fposts\u002F20260817\u002F02-python-macos-installation.md","02｜在 macOS 安装并确认 Python 3 环境",{"type":7,"value":1559,"toc":1688},[1560,1563,1565,1568,1570,1576,1582,1584,1599,1601,1604,1624,1626,1632,1634,1636,1649,1651,1665,1667,1678,1680,1682,1685],[10,1561,1562],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01 篇。学完后，你应该能够在 macOS 中确认 Python 3.14 和 pip 是否可用。",[14,1564,16],{"id":16},[10,1566,1567],{},"本篇只处理“在 macOS 安装并确认 Python 3 环境”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1569,22],{"id":22},[10,1571,1572],{},[26,1573],{"alt":1574,"src":1575},"终端如何找到 Python","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F02-path-interpreter.svg",[10,1577,1578,1579,1581],{},"终端收到 ",[49,1580,720],{}," 后，会按照 PATH 中登记的目录顺序寻找可执行文件。找到哪个解释器，后续代码就由哪个解释器运行。",[14,1583,35],{"id":35},[37,1585,1586,1589,1592],{},[40,1587,1588],{},"先执行版本命令；已有合适的 Python 3 时不必重复安装。",[40,1590,1591],{},"使用 python.org 的 macOS 安装器时，Apple 芯片和 Intel 芯片都可使用 universal2 安装包。",[40,1593,1594,1595,1598],{},"检查 pip 时使用 ",[49,1596,1597],{},"python3 -m pip","，可以明确 pip 属于当前这个解释器。",[14,1600,59],{"id":59},[10,1602,1603],{},"在 macOS 终端执行：",[64,1605,1606],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,1607,1608,1614],{"__ignoreMap":69},[73,1609,1610,1612],{"class":75,"line":76},[73,1611,720],{"class":629},[73,1613,633],{"class":632},[73,1615,1616,1618,1620,1622],{"class":75,"line":82},[73,1617,720],{"class":629},[73,1619,662],{"class":632},[73,1621,666],{"class":665},[73,1623,633],{"class":632},[10,1625,146],{},[64,1627,1630],{"className":1628,"code":1629,"language":152,"meta":69},[150],"Python 3.14.x\npip 版本信息与安装路径\n",[49,1631,1629],{"__ignoreMap":69},[10,1633,157],{},[14,1635,160],{"id":160},[162,1637,1638,1644],{},[40,1639,1640,1643],{},[49,1641,1642],{},"python3 --version"," 只确认解释器能被找到，并报告当前版本。它不代表 pip 一定属于同一个安装。",[40,1645,1646,1648],{},[49,1647,728],{}," 先启动已确认的解释器，再让它加载 pip 模块，因此版本和路径更容易对应。",[14,1650,210],{"id":210},[37,1652,1653,1659],{},[40,1654,1655,1656,1658],{},"看到系统已有 ",[49,1657,720],{}," 就直接假设版本满足课程要求，应先看完整版本号。",[40,1660,1661,1662,1664],{},"为了缩短命令覆盖 macOS 系统命令。课程统一保留 ",[49,1663,720],{},"，不修改系统自带工具。",[14,1666,221],{"id":221},[162,1668,1669,1675],{},[40,1670,967,1671,1674],{},[49,1672,1673],{},"which python3","，记录当前解释器路径。",[40,1676,1677],{},"关闭终端并重新打开，再次检查版本，确认配置持续有效。",[10,1679,232],{},[14,1681,235],{"id":235},[10,1683,1684],{},"本篇目标是在 macOS 中确认 Python 3.14 和 pip 是否可用。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,1686,1687],{},"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":69,"searchDepth":82,"depth":82,"links":1689},[1690,1691,1692,1693,1694,1695,1696,1697],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F02-python-macos-installation",{"title":1557,"description":1562},"python-macos-installation","posts\u002F20260817\u002F02-python-macos-installation","面向按顺序学习 Python 的初学者，本篇在第 01 篇知识上，帮助读者在 macOS 中确认 Python 3.14 和 pip 是否可用。",[255,1705,1081],"macOS","iV0gYKoqqUnobrXy524WUOpgfZG5WmUzlY_rO62WQ-o",{"id":1708,"title":1709,"body":1710,"category":255,"cover":256,"description":1875,"extension":257,"meta":1876,"navigation":85,"path":1877,"pinned":260,"publishedAt":261,"seo":1878,"slug":1879,"stem":1880,"summary":1881,"tags":1882,"updatedAt":261,"visible":85,"__hash__":1885},"posts\u002Fposts\u002F20260817\u002F03-python-repl-and-script.md","03｜交互式解释器和 Python 脚本怎么选择",{"type":7,"value":1711,"toc":1865},[1712,1718,1720,1723,1725,1731,1734,1736,1760,1762,1764,1791,1793,1799,1801,1803,1821,1823,1837,1839,1853,1855,1857,1863],[10,1713,1714,1715,1717],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 ",[49,1716,1200],{}," 脚本。",[14,1719,16],{"id":16},[10,1721,1722],{},"本篇只处理“交互式解释器和 Python 脚本怎么选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1724,22],{"id":22},[10,1726,1727],{},[26,1728],{"alt":1729,"src":1730},"REPL 与脚本的执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F03-repl-vs-script.svg",[10,1732,1733],{},"REPL 每输入一条完整语句就立即执行；脚本先保存多行代码，再从文件开头依次执行。前者适合短验证，后者适合保存和重复运行。",[14,1735,35],{"id":35},[37,1737,1738,1747,1754],{},[40,1739,1740,1741,1743,1744,391],{},"在终端输入 ",[49,1742,720],{}," 进入 REPL，提示符通常是 ",[49,1745,1746],{},">>>",[40,1748,1749,1750,1753],{},"输入 ",[49,1751,1752],{},"exit()"," 或按 Control-D 退出 REPL。",[40,1755,1756,1757,1759],{},"需要保存、复查或多次运行的代码应写入 ",[49,1758,1200],{}," 文件。",[14,1761,59],{"id":59},[10,1763,62],{},[64,1765,1769],{"className":1766,"code":1767,"language":1768,"meta":69,"style":69},"language-pycon shiki shiki-themes github-dark",">>> 2 + 3\n5\n>>> \"python\".upper()\n'PYTHON'\n","pycon",[49,1770,1771,1776,1781,1786],{"__ignoreMap":69},[73,1772,1773],{"class":75,"line":76},[73,1774,1775],{},">>> 2 + 3\n",[73,1777,1778],{"class":75,"line":82},[73,1779,1780],{},"5\n",[73,1782,1783],{"class":75,"line":89},[73,1784,1785],{},">>> \"python\".upper()\n",[73,1787,1788],{"class":75,"line":95},[73,1789,1790],{},"'PYTHON'\n",[10,1792,146],{},[64,1794,1797],{"className":1795,"code":1796,"language":152,"meta":69},[150],"REPL 会直接显示表达式结果\n",[49,1798,1796],{"__ignoreMap":69},[10,1800,157],{},[14,1802,160],{"id":160},[162,1804,1805,1815],{},[40,1806,1807,1808,1811,1812,391],{},"REPL 中输入表达式后，解释器会自动显示表达式的表示形式，所以 ",[49,1809,1810],{},"2 + 3"," 能直接看到 ",[49,1813,1814],{},"5",[40,1816,1817,1818,1820],{},"脚本执行表达式但不会自动显示其结果；需要显式调用 ",[49,1819,1502],{}," 才会写到标准输出。",[14,1822,210],{"id":210},[37,1824,1825,1834],{},[40,1826,1827,1828,1830,1831,1833],{},"把提示符 ",[49,1829,1746],{}," 复制进 ",[49,1832,1200],{}," 文件。它属于 REPL 界面，不是 Python 代码。",[40,1835,1836],{},"在 REPL 中积累很长的实验后无法复现。超过几行并需要保存时就转成脚本。",[14,1838,221],{"id":221},[162,1840,1841,1847],{},[40,1842,1843,1844,391],{},"在 REPL 计算 ",[49,1845,1846],{},"12 * 8",[40,1848,1849,1850,1852],{},"把同一表达式写入脚本；观察脚本中不调用 ",[49,1851,1502],{}," 时是否显示结果。",[10,1854,232],{},[14,1856,235],{"id":235},[10,1858,1859,1860,1862],{},"本篇目标是根据任务选择 REPL 或 ",[49,1861,1200],{}," 脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,1864,242],{},{"title":69,"searchDepth":82,"depth":82,"links":1866},[1867,1868,1869,1870,1871,1872,1873,1874],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},"这套课程按知识依赖排列。本篇的前置知识是：第 02 篇。学完后，你应该能够根据任务选择 REPL 或 .py 脚本。",{},"\u002Fposts\u002F20260817\u002F03-python-repl-and-script",{"title":1709,"description":1875},"python-repl-and-script","posts\u002F20260817\u002F03-python-repl-and-script","面向按顺序学习 Python 的初学者，本篇在第 02 篇知识上，帮助读者根据任务选择 REPL 或 `.py` 脚本。",[255,1883,1884],"REPL","脚本","hvoRAY0WVJOApv5-MWpgMy8uKaL2SGdg99qKexj8ug8",{"id":1887,"title":1888,"body":1889,"category":255,"cover":256,"description":1893,"extension":257,"meta":2064,"navigation":85,"path":2065,"pinned":260,"publishedAt":261,"seo":2066,"slug":2067,"stem":2068,"summary":2069,"tags":2070,"updatedAt":261,"visible":85,"__hash__":2073},"posts\u002Fposts\u002F20260817\u002F04-python-first-project-directory.md","04｜建立第一个 Python 项目目录",{"type":7,"value":1890,"toc":2054},[1891,1894,1896,1899,1901,1907,1913,1915,1933,1935,1937,1982,1984,1990,1992,1994,2016,2018,2030,2032,2044,2046,2048,2051],[10,1892,1893],{},"这套课程按知识依赖排列。本篇的前置知识是：第 03 篇。学完后，你应该能够理解当前目录并正确运行项目脚本。",[14,1895,16],{"id":16},[10,1897,1898],{},"本篇只处理“建立第一个 Python 项目目录”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,1900,22],{"id":22},[10,1902,1903],{},[26,1904],{"alt":1905,"src":1906},"当前目录决定脚本位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F04-working-directory.svg",[10,1908,1909,1912],{},[49,1910,1911],{},"python3 hello.py"," 中的相对路径从终端当前目录开始查找。脚本明明存在却提示找不到时，先检查当前目录，而不是反复安装 Python。",[14,1914,35],{"id":35},[37,1916,1917,1920,1930],{},[40,1918,1919],{},"一个学习项目使用一个独立目录，代码和数据更容易管理。",[40,1921,1922,1925,1926,1929],{},[49,1923,1924],{},"pwd"," 显示当前目录，",[49,1927,1928],{},"ls"," 显示目录里的文件。",[40,1931,1932],{},"命令中的文件名必须与实际文件名一致，macOS 文件系统可能区分大小写。",[14,1934,59],{"id":59},[10,1936,1603],{},[64,1938,1940],{"className":620,"code":1939,"language":622,"meta":69,"style":69},"mkdir python-study\ncd python-study\npwd\nprintf 'print(\"项目已经运行\")\\n' > hello.py\npython3 hello.py\n",[49,1941,1942,1950,1957,1962,1976],{"__ignoreMap":69},[73,1943,1944,1947],{"class":75,"line":76},[73,1945,1946],{"class":629},"mkdir",[73,1948,1949],{"class":665}," python-study\n",[73,1951,1952,1955],{"class":75,"line":82},[73,1953,1954],{"class":632},"cd",[73,1956,1949],{"class":665},[73,1958,1959],{"class":75,"line":89},[73,1960,1961],{"class":632},"pwd\n",[73,1963,1964,1967,1970,1974],{"class":75,"line":95},[73,1965,1966],{"class":632},"printf",[73,1968,1969],{"class":665}," 'print(\"项目已经运行\")\\n'",[73,1971,1973],{"class":1972},"snl16"," >",[73,1975,1244],{"class":665},[73,1977,1978,1980],{"class":75,"line":101},[73,1979,720],{"class":629},[73,1981,1244],{"class":665},[10,1983,146],{},[64,1985,1988],{"className":1986,"code":1987,"language":152,"meta":69},[150],"项目已经运行\n",[49,1989,1987],{"__ignoreMap":69},[10,1991,157],{},[14,1993,160],{"id":160},[162,1995,1996,2007],{},[40,1997,1998,2000,2001,2003,2004,2006],{},[49,1999,1946],{}," 创建目录，",[49,2002,1954],{}," 改变终端当前目录，",[49,2005,1924],{}," 用来确认位置；这三步决定相对路径从哪里开始。",[40,2008,2009,2011,2012,2015],{},[49,2010,1911],{}," 会在当前目录寻找 ",[49,2013,2014],{},"hello.py","。若文件在别处，需要先切换目录或提供正确路径。",[14,2017,210],{"id":210},[37,2019,2020,2027],{},[40,2021,2022,2023,1186,2025,391],{},"脚本存在却报找不到文件时反复安装 Python。此类问题通常先检查 ",[49,2024,1924],{},[49,2026,1928],{},[40,2028,2029],{},"项目目录和文件名混用空格、中文标点或不同大小写，导致复制命令时路径不一致。",[14,2031,221],{"id":221},[162,2033,2034,2041],{},[40,2035,2036,2037,2040],{},"新建 ",[49,2038,2039],{},"lesson01.py"," 并输出课程编号。",[40,2042,2043],{},"先切换到上一级目录运行脚本，观察路径错误，再回到项目目录修正。",[10,2045,232],{},[14,2047,235],{"id":235},[10,2049,2050],{},"本篇目标是理解当前目录并正确运行项目脚本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,2052,2053],{},"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":69,"searchDepth":82,"depth":82,"links":2055},[2056,2057,2058,2059,2060,2061,2062,2063],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F04-python-first-project-directory",{"title":1888,"description":1893},"python-first-project-directory","posts\u002F20260817\u002F04-python-first-project-directory","面向按顺序学习 Python 的初学者，本篇在第 03 篇知识上，帮助读者理解当前目录并正确运行项目脚本。",[255,2071,2072],"项目目录","终端","UsxyR6BgLFF1JbTTJr53MSSSg9lVd6wEKT8DR6PnJUY",{"id":2075,"title":2076,"body":2077,"category":255,"cover":256,"description":2081,"extension":257,"meta":2228,"navigation":85,"path":2229,"pinned":260,"publishedAt":261,"seo":2230,"slug":2231,"stem":2232,"summary":2233,"tags":2234,"updatedAt":261,"visible":85,"__hash__":2236},"posts\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print.md","05｜字面量、表达式与 print 输出",{"type":7,"value":2078,"toc":2218},[2079,2082,2084,2087,2089,2095,2106,2108,2128,2130,2132,2152,2154,2160,2162,2164,2183,2185,2193,2195,2209,2211,2213,2216],[10,2080,2081],{},"这套课程按知识依赖排列。本篇的前置知识是：第 04 篇。学完后，你应该能够读懂最小 Python 表达式并显示求值结果。",[14,2083,16],{"id":16},[10,2085,2086],{},"本篇只处理“字面量、表达式与 print 输出”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2088,22],{"id":22},[10,2090,2091],{},[26,2092],{"alt":2093,"src":2094},"表达式先求值再输出","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F05-expression-evaluation.svg",[10,2096,2097,2098,391,2100,2103,2104,391],{},"Python 先计算表达式，再把得到的对象交给 ",[49,2099,1502],{},[49,2101,2102],{},"print(2 + 3)"," 显示的是加法结果，不是原样显示字符 ",[49,2105,1810],{},[14,2107,35],{"id":35},[37,2109,2110,2116,2125],{},[40,2111,2112,2115],{},[49,2113,2114],{},"42"," 和字符串都是字面量，代码直接写出了它们的值。",[40,2117,2118,2121,2122,391],{},[49,2119,2120],{},"7 + 5"," 是表达式，运行时先求值得到 ",[49,2123,2124],{},"12",[40,2126,2127],{},"字符串文字必须使用配对的引号；中文符号不能替代代码引号。",[14,2129,59],{"id":59},[10,2131,62],{},[64,2133,2135],{"className":66,"code":2134,"language":68,"meta":69,"style":69},"print(42)\nprint(7 + 5)\nprint(\"Python 基础课\")\n",[49,2136,2137,2142,2147],{"__ignoreMap":69},[73,2138,2139],{"class":75,"line":76},[73,2140,2141],{},"print(42)\n",[73,2143,2144],{"class":75,"line":82},[73,2145,2146],{},"print(7 + 5)\n",[73,2148,2149],{"class":75,"line":89},[73,2150,2151],{},"print(\"Python 基础课\")\n",[10,2153,146],{},[64,2155,2158],{"className":2156,"code":2157,"language":152,"meta":69},[150],"42\n12\nPython 基础课\n",[49,2159,2157],{"__ignoreMap":69},[10,2161,157],{},[14,2163,160],{"id":160},[162,2165,2166,2174],{},[40,2167,2168,2171,2172,391],{},[49,2169,2170],{},"print(7 + 5)"," 先计算括号内的加法表达式，得到整数对象 ",[49,2173,2124],{},[40,2175,2176,2178,2179,2182],{},[49,2177,1502],{}," 再把对象转换为适合显示的文本并写出；带引号的 ",[49,2180,2181],{},"\"2 + 3\""," 则只是字符串，不会执行加法。",[14,2184,210],{"id":210},[37,2186,2187,2190],{},[40,2188,2189],{},"混用中文引号、中文括号。Python 源码中的语法符号应使用英文半角字符。",[40,2191,2192],{},"把“表达式结果”和“屏幕上看到的文字”混为一谈；显示是执行链路的最后一步。",[14,2194,221],{"id":221},[162,2196,2197,2200],{},[40,2198,2199],{},"分别输出一个整数、一个小数和一段文本。",[40,2201,2202,2203,52,2205,2208],{},"比较 ",[49,2204,2102],{},[49,2206,2207],{},"print(\"2 + 3\")"," 的结果。",[10,2210,232],{},[14,2212,235],{"id":235},[10,2214,2215],{},"本篇目标是读懂最小 Python 表达式并显示求值结果。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,2217,242],{},{"title":69,"searchDepth":82,"depth":82,"links":2219},[2220,2221,2222,2223,2224,2225,2226,2227],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F05-python-literals-expressions-print",{"title":2076,"description":2081},"python-literals-expressions-print","posts\u002F20260817\u002F05-python-literals-expressions-print","面向按顺序学习 Python 的初学者，本篇在第 04 篇知识上，帮助读者读懂最小 Python 表达式并显示求值结果。",[255,2235,190],"表达式","OUDW6PIRenWK3d3uKcucAiDuyM3W4kSgTMBeqqTPIaU",{"id":2238,"title":2239,"body":2240,"category":255,"cover":256,"description":2244,"extension":257,"meta":2411,"navigation":85,"path":2412,"pinned":260,"publishedAt":261,"seo":2413,"slug":2414,"stem":2415,"summary":2416,"tags":2417,"updatedAt":261,"visible":85,"__hash__":2420},"posts\u002Fposts\u002F20260817\u002F06-python-variable-references.md","06｜Python 变量保存的到底是什么",{"type":7,"value":2241,"toc":2401},[2242,2245,2247,2250,2252,2258,2261,2263,2289,2291,2293,2321,2323,2329,2331,2333,2357,2359,2375,2377,2392,2394,2396,2399],[10,2243,2244],{},"这套课程按知识依赖排列。本篇的前置知识是：第 05 篇。学完后，你应该能够正确理解赋值、重新赋值和变量命名。",[14,2246,16],{"id":16},[10,2248,2249],{},"本篇只处理“Python 变量保存的到底是什么”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2251,22],{"id":22},[10,2253,2254],{},[26,2255],{"alt":2256,"src":2257},"变量名可以改为引用另一个对象","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F06-variable-reference.svg",[10,2259,2260],{},"赋值让变量名引用一个对象。再次赋值时，变量名改为引用另一个对象；它不是把旧整数对象原地改成新数值。",[14,2262,35],{"id":35},[37,2264,2265,2268,2278],{},[40,2266,2267],{},"赋值语句右侧先求值，左侧名字再绑定到结果对象。",[40,2269,2270,2271,52,2274,2277],{},"变量名区分大小写，",[49,2272,2273],{},"score",[49,2275,2276],{},"Score"," 是两个名字。",[40,2279,2280,2281,2284,2285,2288],{},"使用能表达含义的名称；不要用 ",[49,2282,2283],{},"list","、",[49,2286,2287],{},"str"," 等内置名称作为普通变量名。",[14,2290,59],{"id":59},[10,2292,62],{},[64,2294,2296],{"className":66,"code":2295,"language":68,"meta":69,"style":69},"score = 90\nprint(score)\n\nscore = 95\nprint(score)\n",[49,2297,2298,2303,2308,2312,2317],{"__ignoreMap":69},[73,2299,2300],{"class":75,"line":76},[73,2301,2302],{},"score = 90\n",[73,2304,2305],{"class":75,"line":82},[73,2306,2307],{},"print(score)\n",[73,2309,2310],{"class":75,"line":89},[73,2311,86],{"emptyLinePlaceholder":85},[73,2313,2314],{"class":75,"line":95},[73,2315,2316],{},"score = 95\n",[73,2318,2319],{"class":75,"line":101},[73,2320,2307],{},[10,2322,146],{},[64,2324,2327],{"className":2325,"code":2326,"language":152,"meta":69},[150],"90\n95\n",[49,2328,2326],{"__ignoreMap":69},[10,2330,157],{},[14,2332,160],{"id":160},[162,2334,2335,2344],{},[40,2336,967,2337,2340,2341,2343],{},[49,2338,2339],{},"score = 90"," 时，右侧整数对象先准备好，名字 ",[49,2342,2273],{}," 再绑定到它。",[40,2345,967,2346,2349,2350,2353,2354,391],{},[49,2347,2348],{},"score = 95"," 后，名字改为绑定到另一个整数对象；先前的 ",[49,2351,2352],{},"90"," 没有被改造成 ",[49,2355,2356],{},"95",[14,2358,210],{"id":210},[37,2360,2361,2364],{},[40,2362,2363],{},"把变量理解成只能装一种类型的固定盒子。Python 名字可以在不同时间绑定不同类型的对象。",[40,2365,2366,2367,2284,2369,2284,2371,2374],{},"使用 ",[49,2368,2283],{},[49,2370,2287],{},[49,2372,2373],{},"input"," 等内置名称作为变量，导致后面无法正常调用对应内置功能。",[14,2376,221],{"id":221},[162,2378,2379,2389],{},[40,2380,2381,2382,1186,2385,2388],{},"创建 ",[49,2383,2384],{},"course_name",[49,2386,2387],{},"lesson_count"," 两个变量并输出。",[40,2390,2391],{},"让一个变量先引用文本，再重新引用整数，观察 Python 是否允许。",[10,2393,232],{},[14,2395,235],{"id":235},[10,2397,2398],{},"本篇目标是正确理解赋值、重新赋值和变量命名。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,2400,242],{},{"title":69,"searchDepth":82,"depth":82,"links":2402},[2403,2404,2405,2406,2407,2408,2409,2410],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F06-python-variable-references",{"title":2239,"description":2244},"python-variable-references","posts\u002F20260817\u002F06-python-variable-references","面向按顺序学习 Python 的初学者，本篇在第 05 篇知识上，帮助读者正确理解赋值、重新赋值和变量命名。",[255,2418,2419],"变量","对象","4PI2TqJY0YJbxzy-pjkdkbIe4HMCJtPWyVMS9V7wWTM",{"id":2422,"title":2423,"body":2424,"category":255,"cover":256,"description":2428,"extension":257,"meta":2592,"navigation":85,"path":2593,"pinned":260,"publishedAt":261,"seo":2594,"slug":2595,"stem":2596,"summary":2597,"tags":2598,"updatedAt":261,"visible":85,"__hash__":2601},"posts\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic.md","07｜整数、浮点数与算术运算",{"type":7,"value":2425,"toc":2582},[2426,2429,2431,2434,2436,2442,2445,2447,2476,2478,2480,2524,2526,2532,2534,2536,2550,2552,2563,2565,2573,2575,2577,2580],[10,2427,2428],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够完成常见数值计算并理解运算顺序。",[14,2430,16],{"id":16},[10,2432,2433],{},"本篇只处理“整数、浮点数与算术运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2435,22],{"id":22},[10,2437,2438],{},[26,2439],{"alt":2440,"src":2441},"算术表达式的求值顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F07-operator-precedence.svg",[10,2443,2444],{},"同一表达式中，括号优先，然后计算乘除，最后计算加减。读不准顺序时主动加括号，通常比背复杂规则更可靠。",[14,2446,35],{"id":35},[37,2448,2449,2459,2473],{},[40,2450,2451,2454,2455,2458],{},[49,2452,2453],{},"int"," 表示整数，",[49,2456,2457],{},"float"," 表示浮点数。",[40,2460,2461,2464,2465,2468,2469,2472],{},[49,2462,2463],{},"\u002F"," 总是进行真除法；",[49,2466,2467],{},"\u002F\u002F"," 是向下取整除法，",[49,2470,2471],{},"%"," 得到余数。",[40,2474,2475],{},"浮点数采用二进制近似表示，不适合直接承担要求精确小数的财务计算。",[14,2477,59],{"id":59},[10,2479,62],{},[64,2481,2483],{"className":66,"code":2482,"language":68,"meta":69,"style":69},"price = 25\ncount = 4\ndiscount = 0.9\n\ntotal = price * count * discount\naverage = total \u002F count\nprint(total)\nprint(average)\n",[49,2484,2485,2490,2495,2500,2504,2509,2514,2519],{"__ignoreMap":69},[73,2486,2487],{"class":75,"line":76},[73,2488,2489],{},"price = 25\n",[73,2491,2492],{"class":75,"line":82},[73,2493,2494],{},"count = 4\n",[73,2496,2497],{"class":75,"line":89},[73,2498,2499],{},"discount = 0.9\n",[73,2501,2502],{"class":75,"line":95},[73,2503,86],{"emptyLinePlaceholder":85},[73,2505,2506],{"class":75,"line":101},[73,2507,2508],{},"total = price * count * discount\n",[73,2510,2511],{"class":75,"line":106},[73,2512,2513],{},"average = total \u002F count\n",[73,2515,2516],{"class":75,"line":112},[73,2517,2518],{},"print(total)\n",[73,2520,2521],{"class":75,"line":118},[73,2522,2523],{},"print(average)\n",[10,2525,146],{},[64,2527,2530],{"className":2528,"code":2529,"language":152,"meta":69},[150],"90.0\n22.5\n",[49,2531,2529],{"__ignoreMap":69},[10,2533,157],{},[14,2535,160],{"id":160},[162,2537,2538,2544],{},[40,2539,2540,2543],{},[49,2541,2542],{},"price * count * discount"," 中两个乘法优先级相同，按从左到右结合，最终因为包含浮点数得到浮点结果。",[40,2545,2546,2549],{},[49,2547,2548],{},"total \u002F count"," 使用真除法，即使能整除也返回浮点数；商、余数或向下取整需要使用不同运算符。",[14,2551,210],{"id":210},[37,2553,2554,2560],{},[40,2555,2556,2557,391],{},"用二进制浮点数直接表示必须精确到分的金额。真实财务场景应评估整数分或 ",[49,2558,2559],{},"decimal.Decimal",[40,2561,2562],{},"依赖记忆判断长表达式的优先级。含义稍复杂时用括号明确顺序。",[14,2564,221],{"id":221},[162,2566,2567,2570],{},[40,2568,2569],{},"计算 137 除以 10 的商和余数。",[40,2571,2572],{},"给总价表达式加括号，验证结果是否保持一致。",[10,2574,232],{},[14,2576,235],{"id":235},[10,2578,2579],{},"本篇目标是完成常见数值计算并理解运算顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,2581,242],{},{"title":69,"searchDepth":82,"depth":82,"links":2583},[2584,2585,2586,2587,2588,2589,2590,2591],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F07-python-numbers-and-arithmetic",{"title":2423,"description":2428},"python-numbers-and-arithmetic","posts\u002F20260817\u002F07-python-numbers-and-arithmetic","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者完成常见数值计算并理解运算顺序。",[255,2599,2600],"数字","运算符","4z7kRr-EtnqIumEmMgfasJz4tDK-uFbEE6kpQ8ncEzI",{"id":2603,"title":2604,"body":2605,"category":255,"cover":256,"description":2609,"extension":257,"meta":2784,"navigation":85,"path":2785,"pinned":260,"publishedAt":261,"seo":2786,"slug":2787,"stem":2788,"summary":2789,"tags":2790,"updatedAt":261,"visible":85,"__hash__":2793},"posts\u002Fposts\u002F20260817\u002F08-python-string-index-slice.md","08｜字符串的创建、索引与切片",{"type":7,"value":2606,"toc":2772},[2607,2610,2612,2615,2617,2623,2633,2635,2646,2648,2650,2680,2682,2688,2690,2692,2722,2724,2727,2733,2736,2738,2746,2748,2763,2765,2767,2770],[10,2608,2609],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06 篇。学完后，你应该能够读取、截取和组合字符串。",[14,2611,16],{"id":16},[10,2613,2614],{},"本篇只处理“字符串的创建、索引与切片”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2616,22],{"id":22},[10,2618,2619],{},[26,2620],{"alt":2621,"src":2622},"切片使用半开区间","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-string-slice.svg",[10,2624,2625,2626,2629,2630,391],{},"切片 ",[49,2627,2628],{},"[start:stop]"," 包含起点，不包含终点。这个半开区间规则让切片长度容易计算：在步长为 1 时，长度通常是 ",[49,2631,2632],{},"stop - start",[14,2634,35],{"id":35},[37,2636,2637,2640,2643],{},[40,2638,2639],{},"字符串是不可变的字符序列，不能直接替换某个索引位置。",[40,2641,2642],{},"正索引从 0 开始，负索引从 -1 开始反向定位。",[40,2644,2645],{},"切片会创建新的字符串，不会修改原字符串。",[14,2647,59],{"id":59},[10,2649,62],{},[64,2651,2653],{"className":66,"code":2652,"language":68,"meta":69,"style":69},"language = \"Python\"\nprint(language[0])\nprint(language[-1])\nprint(language[0:3])\nprint(language + \" 3.14\")\n",[49,2654,2655,2660,2665,2670,2675],{"__ignoreMap":69},[73,2656,2657],{"class":75,"line":76},[73,2658,2659],{},"language = \"Python\"\n",[73,2661,2662],{"class":75,"line":82},[73,2663,2664],{},"print(language[0])\n",[73,2666,2667],{"class":75,"line":89},[73,2668,2669],{},"print(language[-1])\n",[73,2671,2672],{"class":75,"line":95},[73,2673,2674],{},"print(language[0:3])\n",[73,2676,2677],{"class":75,"line":101},[73,2678,2679],{},"print(language + \" 3.14\")\n",[10,2681,146],{},[64,2683,2686],{"className":2684,"code":2685,"language":152,"meta":69},[150],"P\nn\nPyt\nPython 3.14\n",[49,2687,2685],{"__ignoreMap":69},[10,2689,157],{},[14,2691,160],{"id":160},[162,2693,2694,2708],{},[40,2695,2696,2697,2699,2700,2703,2704,2707],{},"字符串 ",[49,2698,255],{}," 的正索引从 ",[49,2701,2702],{},"P"," 的 0 开始，负索引从末尾 ",[49,2705,2706],{},"n"," 的 -1 开始。",[40,2709,2710,2713,2714,2717,2718,2721],{},[49,2711,2712],{},"language[0:3]"," 依次取得索引 0、1、2，对应 ",[49,2715,2716],{},"Pyt","；索引 3 的 ",[49,2719,2720],{},"h"," 不在结果中。",[193,2723,195],{"id":195},[10,2725,2726],{},"索引和切片的返回结果也容易混淆，可以把两种操作并排看。",[10,2728,2729],{},[26,2730],{"alt":2731,"src":2732},"索引与切片得到不同结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F08-index-vs-slice.svg",[10,2734,2735],{},"索引只取得一个字符；切片按照范围取得新字符串。两者都不会修改原字符串。",[14,2737,210],{"id":210},[37,2739,2740,2743],{},[40,2741,2742],{},"把第一个字符写成索引 1，造成整体偏移一位。",[40,2744,2745],{},"认为切片会修改原字符串。字符串不可变，切片得到的是新字符串对象。",[14,2747,221],{"id":221},[162,2749,2750,2760],{},[40,2751,2752,2753,2756,2757,391],{},"从 ",[49,2754,2755],{},"\"programming\""," 中切出 ",[49,2758,2759],{},"\"gram\"",[40,2761,2762],{},"使用负索引取得字符串倒数第二个字符。",[10,2764,232],{},[14,2766,235],{"id":235},[10,2768,2769],{},"本篇目标是读取、截取和组合字符串。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,2771,242],{},{"title":69,"searchDepth":82,"depth":82,"links":2773},[2774,2775,2776,2777,2778,2781,2782,2783],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":2779},[2780],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F08-python-string-index-slice",{"title":2604,"description":2609},"python-string-index-slice","posts\u002F20260817\u002F08-python-string-index-slice","面向按顺序学习 Python 的初学者，本篇在第 06 篇知识上，帮助读者读取、截取和组合字符串。",[255,2791,2792],"字符串","切片","QhddGVQ3zNhtZD2AUoFwgf2YvN2aLunxHbEeUM-Egsk",{"id":2795,"title":2796,"body":2797,"category":255,"cover":256,"description":2801,"extension":257,"meta":3015,"navigation":85,"path":3016,"pinned":260,"publishedAt":261,"seo":3017,"slug":3018,"stem":3019,"summary":3020,"tags":3021,"updatedAt":261,"visible":85,"__hash__":3024},"posts\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic.md","09｜布尔值、比较运算与逻辑运算",{"type":7,"value":2798,"toc":3003},[2799,2802,2804,2807,2809,2815,2825,2827,2860,2862,2864,2908,2910,2916,2918,2920,2941,2943,2946,2952,2960,2962,2976,2978,2994,2996,2998,3001],[10,2800,2801],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07、08 篇。学完后，你应该能够组合能够得到 True 或 False 的条件。",[14,2803,16],{"id":16},[10,2805,2806],{},"本篇只处理“布尔值、比较运算与逻辑运算”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,2808,22],{"id":22},[10,2810,2811],{},[26,2812],{"alt":2813,"src":2814},"条件如何得到布尔结果","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-boolean-logic.svg",[10,2816,2817,2818,1038,2821,2824],{},"比较表达式先产生 ",[49,2819,2820],{},"True",[49,2822,2823],{},"False","，逻辑运算符再组合这些布尔结果。此时只观察条件本身，还没有进入分支执行。",[14,2826,35],{"id":35},[37,2828,2829,2843,2857],{},[40,2830,2831,2834,2835,2838,2839,2842],{},[49,2832,2833],{},"=="," 判断是否相等，",[49,2836,2837],{},"!="," 判断是否不等；单个 ",[49,2840,2841],{},"="," 是赋值。",[40,2844,2845,2848,2849,2852,2853,2856],{},[49,2846,2847],{},"and"," 要求两侧都为真，",[49,2850,2851],{},"or"," 只需一侧为真，",[49,2854,2855],{},"not"," 取反。",[40,2858,2859],{},"复杂条件用有含义的中间变量拆开，通常比一行堆叠多个运算符更易读。",[14,2861,59],{"id":59},[10,2863,62],{},[64,2865,2867],{"className":66,"code":2866,"language":68,"meta":69,"style":69},"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",[49,2868,2869,2874,2879,2883,2888,2893,2898,2903],{"__ignoreMap":69},[73,2870,2871],{"class":75,"line":76},[73,2872,2873],{},"age = 20\n",[73,2875,2876],{"class":75,"line":82},[73,2877,2878],{},"has_ticket = True\n",[73,2880,2881],{"class":75,"line":89},[73,2882,86],{"emptyLinePlaceholder":85},[73,2884,2885],{"class":75,"line":95},[73,2886,2887],{},"is_adult = age >= 18\n",[73,2889,2890],{"class":75,"line":101},[73,2891,2892],{},"can_enter = is_adult and has_ticket\n",[73,2894,2895],{"class":75,"line":106},[73,2896,2897],{},"print(is_adult)\n",[73,2899,2900],{"class":75,"line":112},[73,2901,2902],{},"print(can_enter)\n",[73,2904,2905],{"class":75,"line":118},[73,2906,2907],{},"print(not has_ticket)\n",[10,2909,146],{},[64,2911,2914],{"className":2912,"code":2913,"language":152,"meta":69},[150],"True\nTrue\nFalse\n",[49,2915,2913],{"__ignoreMap":69},[10,2917,157],{},[14,2919,160],{"id":160},[162,2921,2922,2932],{},[40,2923,2924,2927,2928,2931],{},[49,2925,2926],{},"age >= 18"," 先产生布尔值并绑定给 ",[49,2929,2930],{},"is_adult","，这一步没有任何分支跳转。",[40,2933,2934,2937,2938,2940],{},[49,2935,2936],{},"is_adult and has_ticket"," 只有两侧都为真才得到真；",[49,2939,2855],{}," 只对紧随其后的值取反。",[193,2942,195],{"id":195},[10,2944,2945],{},"两个布尔条件组合时，直接看真值表比凭语感判断更可靠。",[10,2947,2948],{},[26,2949],{"alt":2950,"src":2951},"and 与 or 的关键真假组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F09-and-or-table.svg",[10,2953,2954,2956,2957,2959],{},[49,2955,2847],{}," 只有“真、真”得到真；",[49,2958,2851],{}," 只有“假、假”得到假。先计算比较条件，再查对应组合。",[14,2961,210],{"id":210},[37,2963,2964,2973],{},[40,2965,2966,2967,2969,2970,2972],{},"用单个等号判断相等。",[49,2968,2841],{}," 是赋值，",[49,2971,2833],{}," 才是相等比较。",[40,2974,2975],{},"在同一行混合过多比较和逻辑运算，导致读者难以判断组合顺序；先拆成命名清楚的中间条件。",[14,2977,221],{"id":221},[162,2979,2980,2987],{},[40,2981,2982,2983,2986],{},"判断数字 ",[49,2984,2985],{},"15"," 是否同时大于 10 且小于 20。",[40,2988,2989,2990,2993],{},"分别修改年龄和票据状态，记录 ",[49,2991,2992],{},"can_enter"," 的四种组合结果。",[10,2995,232],{},[14,2997,235],{"id":235},[10,2999,3000],{},"本篇目标是组合能够得到 True 或 False 的条件。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,3002,242],{},{"title":69,"searchDepth":82,"depth":82,"links":3004},[3005,3006,3007,3008,3009,3012,3013,3014],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":3010},[3011],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F09-python-booleans-comparisons-logic",{"title":2796,"description":2801},"python-booleans-comparisons-logic","posts\u002F20260817\u002F09-python-booleans-comparisons-logic","面向按顺序学习 Python 的初学者，本篇在第 07、08 篇知识上，帮助读者组合能够得到 True 或 False 的条件。",[255,3022,3023],"布尔值","逻辑运算","gN0aUhPMb8GvEi6Ws2f85mGLqOOuGxgDpd9nbry4DBo",{"id":3026,"title":3027,"body":3028,"category":255,"cover":256,"description":3032,"extension":257,"meta":3200,"navigation":85,"path":3201,"pinned":260,"publishedAt":261,"seo":3202,"slug":3203,"stem":3204,"summary":3205,"tags":3206,"updatedAt":261,"visible":85,"__hash__":3208},"posts\u002Fposts\u002F20260817\u002F10-python-input-and-conversion.md","10｜使用 input 接收输入并转换类型",{"type":7,"value":3029,"toc":3190},[3030,3033,3035,3038,3040,3046,3064,3066,3079,3081,3083,3117,3119,3125,3127,3129,3151,3153,3165,3167,3181,3183,3185,3188],[10,3031,3032],{},"这套课程按知识依赖排列。本篇的前置知识是：第 07～09 篇。学完后，你应该能够接收用户文本并转换为数值。",[14,3034,16],{"id":16},[10,3036,3037],{},"本篇只处理“使用 input 接收输入并转换类型”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3039,22],{"id":22},[10,3041,3042],{},[26,3043],{"alt":3044,"src":3045},"input 得到文本后再转换","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F10-input-conversion.svg",[10,3047,3048,3051,3052,3055,3056,3059,3060,3063],{},[49,3049,3050],{},"input()"," 的结果始终是字符串。即使键盘输入 ",[49,3053,3054],{},"18","，程序首先得到的也是 ",[49,3057,3058],{},"\"18\"","，需要 ",[49,3061,3062],{},"int()"," 后才能按整数参与计算。",[14,3065,35],{"id":35},[37,3067,3068,3071,3076],{},[40,3069,3070],{},"提示文字应告诉用户需要输入什么。",[40,3072,3073,3075],{},[49,3074,3062],{}," 只能转换符合整数格式的文本；输入其他内容会产生异常，异常处理将在第 33 篇系统讲解。",[40,3077,3078],{},"输入转换和业务计算分开写，定位问题更直接。",[14,3080,59],{"id":59},[10,3082,62],{},[64,3084,3086],{"className":66,"code":3085,"language":68,"meta":69,"style":69},"name = input(\"请输入姓名：\")\nage_text = input(\"请输入年龄：\")\nage = int(age_text)\n\nprint(\"你好，\" + name)\nprint(age + 1)\n",[49,3087,3088,3093,3098,3103,3107,3112],{"__ignoreMap":69},[73,3089,3090],{"class":75,"line":76},[73,3091,3092],{},"name = input(\"请输入姓名：\")\n",[73,3094,3095],{"class":75,"line":82},[73,3096,3097],{},"age_text = input(\"请输入年龄：\")\n",[73,3099,3100],{"class":75,"line":89},[73,3101,3102],{},"age = int(age_text)\n",[73,3104,3105],{"class":75,"line":95},[73,3106,86],{"emptyLinePlaceholder":85},[73,3108,3109],{"class":75,"line":101},[73,3110,3111],{},"print(\"你好，\" + name)\n",[73,3113,3114],{"class":75,"line":106},[73,3115,3116],{},"print(age + 1)\n",[10,3118,146],{},[64,3120,3123],{"className":3121,"code":3122,"language":152,"meta":69},[150],"根据输入显示姓名，并输出下一年的年龄\n",[49,3124,3122],{"__ignoreMap":69},[10,3126,157],{},[14,3128,160],{"id":160},[162,3130,3131,3141],{},[40,3132,3133,3134,3136,3137,3140],{},"两次 ",[49,3135,3050],{}," 都暂停等待输入，并分别返回字符串。变量名 ",[49,3138,3139],{},"age_text"," 用来提醒这仍是文本。",[40,3142,3143,3146,3147,3150],{},[49,3144,3145],{},"int(age_text)"," 创建整数对象，后面的 ",[49,3148,3149],{},"age + 1"," 才执行数值加法；字符串直接加整数会产生类型错误。",[14,3152,210],{"id":210},[37,3154,3155,3162],{},[40,3156,3157,3158,3161],{},"直接计算 ",[49,3159,3160],{},"input(...) + 1","，忽略输入结果是字符串。",[40,3163,3164],{},"假设任何输入都能转换为整数。异常处理在后续课程讲解，本篇先使用符合提示的输入。",[14,3166,221],{"id":221},[162,3168,3169,3172],{},[40,3170,3171],{},"接收两个整数并输出它们的和。",[40,3173,1749,3174,3177,3178,3180],{},[49,3175,3176],{},"18.5"," 给 ",[49,3179,3062],{},"，记录错误类型，但暂时不要尝试忽略错误。",[10,3182,232],{},[14,3184,235],{"id":235},[10,3186,3187],{},"本篇目标是接收用户文本并转换为数值。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,3189,242],{},{"title":69,"searchDepth":82,"depth":82,"links":3191},[3192,3193,3194,3195,3196,3197,3198,3199],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F10-python-input-and-conversion",{"title":3027,"description":3032},"python-input-and-conversion","posts\u002F20260817\u002F10-python-input-and-conversion","面向按顺序学习 Python 的初学者，本篇在第 07～09 篇知识上，帮助读者接收用户文本并转换为数值。",[255,2373,3207],"类型转换","Sjfw0fjJeHUqUCbt442mOTmjSmeY7-8lNol5xlOOFJk",{"id":3210,"title":3211,"body":3212,"category":255,"cover":256,"description":3216,"extension":257,"meta":3376,"navigation":85,"path":3377,"pinned":260,"publishedAt":261,"seo":3378,"slug":3379,"stem":3380,"summary":3381,"tags":3382,"updatedAt":261,"visible":85,"__hash__":3385},"posts\u002Fposts\u002F20260817\u002F11-python-list-basics.md","11｜列表：按顺序保存一组可变数据",{"type":7,"value":3213,"toc":3366},[3214,3217,3219,3222,3224,3230,3237,3239,3253,3255,3257,3296,3298,3304,3306,3308,3327,3329,3344,3346,3357,3359,3361,3364],[10,3215,3216],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、08 篇。学完后，你应该能够创建、读取、修改和追加列表元素。",[14,3218,16],{"id":16},[10,3220,3221],{},"本篇只处理“列表：按顺序保存一组可变数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3223,22],{"id":22},[10,3225,3226],{},[26,3227],{"alt":3228,"src":3229},"列表索引定位元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F11-list-index.svg",[10,3231,3232,3233,3236],{},"列表为元素维护从 0 开始的位置索引。修改 ",[49,3234,3235],{},"scores[1]"," 只把第二个位置改为引用新对象，其他位置保持不变。",[14,3238,35],{"id":35},[37,3240,3241,3244,3247],{},[40,3242,3243],{},"列表使用方括号，元素之间用逗号分隔。",[40,3245,3246],{},"列表可变，可以替换、追加和删除元素。",[40,3248,3249,3250,391],{},"访问不存在的索引会产生 ",[49,3251,3252],{},"IndexError",[14,3254,59],{"id":59},[10,3256,62],{},[64,3258,3260],{"className":66,"code":3259,"language":68,"meta":69,"style":69},"scores = [82, 90, 76]\nprint(scores[0])\n\nscores[1] = 95\nscores.append(88)\nprint(scores)\nprint(len(scores))\n",[49,3261,3262,3267,3272,3276,3281,3286,3291],{"__ignoreMap":69},[73,3263,3264],{"class":75,"line":76},[73,3265,3266],{},"scores = [82, 90, 76]\n",[73,3268,3269],{"class":75,"line":82},[73,3270,3271],{},"print(scores[0])\n",[73,3273,3274],{"class":75,"line":89},[73,3275,86],{"emptyLinePlaceholder":85},[73,3277,3278],{"class":75,"line":95},[73,3279,3280],{},"scores[1] = 95\n",[73,3282,3283],{"class":75,"line":101},[73,3284,3285],{},"scores.append(88)\n",[73,3287,3288],{"class":75,"line":106},[73,3289,3290],{},"print(scores)\n",[73,3292,3293],{"class":75,"line":112},[73,3294,3295],{},"print(len(scores))\n",[10,3297,146],{},[64,3299,3302],{"className":3300,"code":3301,"language":152,"meta":69},[150],"82\n[82, 95, 76, 88]\n4\n",[49,3303,3301],{"__ignoreMap":69},[10,3305,157],{},[14,3307,160],{"id":160},[162,3309,3310,3313],{},[40,3311,3312],{},"列表创建后，每个位置保存对元素对象的引用，索引 0 对应第一项。",[40,3314,3315,3318,3319,3322,3323,3326],{},[49,3316,3317],{},"scores[1] = 95"," 替换第二个位置，",[49,3320,3321],{},"append(88)"," 在末尾增加新位置，",[49,3324,3325],{},"len()"," 因而从 3 变为 4。",[14,3328,210],{"id":210},[37,3330,3331,3341],{},[40,3332,3333,3334,3337,3338,391],{},"访问 ",[49,3335,3336],{},"scores[len(scores)]","。最后一个合法正索引是 ",[49,3339,3340],{},"len(scores) - 1",[40,3342,3343],{},"调用会修改列表的方法后还期待原列表保持不变；修改前先确认是否需要副本。",[14,3345,221],{"id":221},[162,3347,3348,3351],{},[40,3349,3350],{},"建立三项学习任务列表，再追加第四项。",[40,3352,3353,3354,3356],{},"修改第二项，并用 ",[49,3355,3325],{}," 检查元素数量。",[10,3358,232],{},[14,3360,235],{"id":235},[10,3362,3363],{},"本篇目标是创建、读取、修改和追加列表元素。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,3365,242],{},{"title":69,"searchDepth":82,"depth":82,"links":3367},[3368,3369,3370,3371,3372,3373,3374,3375],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F11-python-list-basics",{"title":3211,"description":3216},"python-list-basics","posts\u002F20260817\u002F11-python-list-basics","面向按顺序学习 Python 的初学者，本篇在第 06、08 篇知识上，帮助读者创建、读取、修改和追加列表元素。",[255,3383,3384],"列表","数据结构","DbC8cJb2leXMJkJQ8dEgmDukP94ifvXYDhcWOuDqMg8",{"id":3387,"title":3388,"body":3389,"category":255,"cover":256,"description":3393,"extension":257,"meta":3534,"navigation":85,"path":3535,"pinned":260,"publishedAt":261,"seo":3536,"slug":3537,"stem":3538,"summary":3539,"tags":3540,"updatedAt":261,"visible":85,"__hash__":3542},"posts\u002Fposts\u002F20260817\u002F12-python-tuple-basics.md","12｜元组：保存不应被修改的有序数据",{"type":7,"value":3390,"toc":3524},[3391,3394,3396,3399,3401,3407,3410,3412,3423,3425,3427,3461,3463,3469,3471,3473,3487,3489,3501,3503,3515,3517,3519,3522],[10,3392,3393],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够理解元组与列表的使用边界。",[14,3395,16],{"id":16},[10,3397,3398],{},"本篇只处理“元组：保存不应被修改的有序数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3400,22],{"id":22},[10,3402,3403],{},[26,3404],{"alt":3405,"src":3406},"列表与元组的可变性","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F12-list-tuple.svg",[10,3408,3409],{},"列表和元组都按顺序保存元素，但元组创建后不能替换其中的位置。不可变表示元组结构不变，不代表元组内部引用的每个对象都一定不可变。",[14,3411,35],{"id":35},[37,3413,3414,3417,3420],{},[40,3415,3416],{},"元组常用来表达固定数量、固定含义的一组值。",[40,3418,3419],{},"只有一个元素的元组必须保留尾随逗号。",[40,3421,3422],{},"需要频繁增删元素时使用列表，不要为了“更高级”而选择元组。",[14,3424,59],{"id":59},[10,3426,62],{},[64,3428,3430],{"className":66,"code":3429,"language":68,"meta":69,"style":69},"point = (120, 80)\nprint(point[0])\nprint(point[1])\n\nsingle = (5,)\nprint(single)\n",[49,3431,3432,3437,3442,3447,3451,3456],{"__ignoreMap":69},[73,3433,3434],{"class":75,"line":76},[73,3435,3436],{},"point = (120, 80)\n",[73,3438,3439],{"class":75,"line":82},[73,3440,3441],{},"print(point[0])\n",[73,3443,3444],{"class":75,"line":89},[73,3445,3446],{},"print(point[1])\n",[73,3448,3449],{"class":75,"line":95},[73,3450,86],{"emptyLinePlaceholder":85},[73,3452,3453],{"class":75,"line":101},[73,3454,3455],{},"single = (5,)\n",[73,3457,3458],{"class":75,"line":106},[73,3459,3460],{},"print(single)\n",[10,3462,146],{},[64,3464,3467],{"className":3465,"code":3466,"language":152,"meta":69},[150],"120\n80\n(5,)\n",[49,3468,3466],{"__ignoreMap":69},[10,3470,157],{},[14,3472,160],{"id":160},[162,3474,3475,3481],{},[40,3476,3477,3480],{},[49,3478,3479],{},"point"," 的两个位置在创建后不能被重新赋值，因此适合表达固定结构的坐标。",[40,3482,3483,3486],{},[49,3484,3485],{},"(5,)"," 的逗号决定它是单元素元组；括号本身只起分组作用。",[14,3488,210],{"id":210},[37,3490,3491,3498],{},[40,3492,3493,3494,3497],{},"把 ",[49,3495,3496],{},"(5)"," 当作元组，实际它仍是整数。",[40,3499,3500],{},"把不可变误解为内部一切都不可变；元组中如果引用列表，列表内容仍可能变化。",[14,3502,221],{"id":221},[162,3504,3505,3508],{},[40,3506,3507],{},"用元组表示宽度和高度。",[40,3509,2202,3510,52,3512,3514],{},[49,3511,3496],{},[49,3513,3485],{}," 的类型。",[10,3516,232],{},[14,3518,235],{"id":235},[10,3520,3521],{},"本篇目标是理解元组与列表的使用边界。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,3523,242],{},{"title":69,"searchDepth":82,"depth":82,"links":3525},[3526,3527,3528,3529,3530,3531,3532,3533],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F12-python-tuple-basics",{"title":3388,"description":3393},"python-tuple-basics","posts\u002F20260817\u002F12-python-tuple-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者理解元组与列表的使用边界。",[255,3541,3384],"元组","09U1IgIHcdYMvacWQvXgZYFo_kxDSR_c4lgdQgqKL08",{"id":3544,"title":3545,"body":3546,"category":255,"cover":256,"description":3550,"extension":257,"meta":3705,"navigation":85,"path":3706,"pinned":260,"publishedAt":261,"seo":3707,"slug":3708,"stem":3709,"summary":3710,"tags":3711,"updatedAt":261,"visible":85,"__hash__":3713},"posts\u002Fposts\u002F20260817\u002F13-python-dictionary-basics.md","13｜字典：用键快速找到对应的值",{"type":7,"value":3547,"toc":3695},[3548,3551,3553,3556,3558,3564,3574,3576,3590,3592,3594,3628,3630,3636,3638,3640,3655,3657,3676,3678,3686,3688,3690,3693],[10,3549,3550],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11 篇。学完后，你应该能够创建并增删改查键值对。",[14,3552,16],{"id":16},[10,3554,3555],{},"本篇只处理“字典：用键快速找到对应的值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3557,22],{"id":22},[10,3559,3560],{},[26,3561],{"alt":3562,"src":3563},"字典用键定位值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F13-dict-mapping.svg",[10,3565,3566,3567,3570,3571,3573],{},"字典通过键定位值，不使用连续位置表达含义。",[49,3568,3569],{},"student[\"score\"]"," 读取的是键 ",[49,3572,2273],{}," 对应的值，而不是“第几个元素”。",[14,3575,35],{"id":35},[37,3577,3578,3581,3587],{},[40,3579,3580],{},"字典键必须唯一；再次给同一个键赋值会更新原值。",[40,3582,2366,3583,3586],{},[49,3584,3585],{},"in"," 可以检查键是否存在，但条件分支将在第 16 篇使用。",[40,3588,3589],{},"键应稳定且可哈希，基础场景优先使用字符串、整数或元组。",[14,3591,59],{"id":59},[10,3593,62],{},[64,3595,3597],{"className":66,"code":3596,"language":68,"meta":69,"style":69},"student = {\"name\": \"小郑\", \"score\": 90}\nprint(student[\"name\"])\n\nstudent[\"score\"] = 95\nstudent[\"city\"] = \"郑州\"\nprint(student)\n",[49,3598,3599,3604,3609,3613,3618,3623],{"__ignoreMap":69},[73,3600,3601],{"class":75,"line":76},[73,3602,3603],{},"student = {\"name\": \"小郑\", \"score\": 90}\n",[73,3605,3606],{"class":75,"line":82},[73,3607,3608],{},"print(student[\"name\"])\n",[73,3610,3611],{"class":75,"line":89},[73,3612,86],{"emptyLinePlaceholder":85},[73,3614,3615],{"class":75,"line":95},[73,3616,3617],{},"student[\"score\"] = 95\n",[73,3619,3620],{"class":75,"line":101},[73,3621,3622],{},"student[\"city\"] = \"郑州\"\n",[73,3624,3625],{"class":75,"line":106},[73,3626,3627],{},"print(student)\n",[10,3629,146],{},[64,3631,3634],{"className":3632,"code":3633,"language":152,"meta":69},[150],"小郑\n{'name': '小郑', 'score': 95, 'city': '郑州'}\n",[49,3635,3633],{"__ignoreMap":69},[10,3637,157],{},[14,3639,160],{"id":160},[162,3641,3642,3645],{},[40,3643,3644],{},"字典字面量同时建立两个键值映射；读取时提供键，字典返回对应值。",[40,3646,3647,3648,3650,3651,3654],{},"给已有键 ",[49,3649,2273],{}," 赋值会更新映射，给新键 ",[49,3652,3653],{},"city"," 赋值会增加映射。",[14,3656,210],{"id":210},[37,3658,3659,3666],{},[40,3660,3661,3662,3665],{},"按位置理解字典并尝试 ",[49,3663,3664],{},"student[0]","，而实际键是字符串。",[40,3667,3668,3669,3672,3673,391],{},"直接读取不确定存在的键并忽略 ",[49,3670,3671],{},"KeyError","；后续可根据场景使用成员检查或 ",[49,3674,3675],{},"get()",[14,3677,221],{"id":221},[162,3679,3680,3683],{},[40,3681,3682],{},"建立一本书的标题、作者和页数字典。",[40,3684,3685],{},"添加分类键，再修改页数。",[10,3687,232],{},[14,3689,235],{"id":235},[10,3691,3692],{},"本篇目标是创建并增删改查键值对。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,3694,242],{},{"title":69,"searchDepth":82,"depth":82,"links":3696},[3697,3698,3699,3700,3701,3702,3703,3704],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F13-python-dictionary-basics",{"title":3545,"description":3550},"python-dictionary-basics","posts\u002F20260817\u002F13-python-dictionary-basics","面向按顺序学习 Python 的初学者，本篇在第 06、11 篇知识上，帮助读者创建并增删改查键值对。",[255,3712,3384],"字典","p-xgRkGf2z471a10QJLlKltBVWJ1x_ljUe5U0thqW3Y",{"id":3715,"title":3716,"body":3717,"category":255,"cover":256,"description":3721,"extension":257,"meta":3870,"navigation":85,"path":3871,"pinned":260,"publishedAt":261,"seo":3872,"slug":3873,"stem":3874,"summary":3875,"tags":3876,"updatedAt":261,"visible":85,"__hash__":3878},"posts\u002Fposts\u002F20260817\u002F14-python-set-basics.md","14｜集合：去重并判断成员关系",{"type":7,"value":3718,"toc":3860},[3719,3722,3724,3727,3729,3735,3738,3740,3759,3761,3763,3797,3799,3805,3807,3809,3824,3826,3838,3840,3851,3853,3855,3858],[10,3720,3721],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11 篇。学完后，你应该能够使用集合去重并完成基础集合运算。",[14,3723,16],{"id":16},[10,3725,3726],{},"本篇只处理“集合：去重并判断成员关系”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3728,22],{"id":22},[10,3730,3731],{},[26,3732],{"alt":3733,"src":3734},"集合运算保留哪些元素","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F14-set-operations.svg",[10,3736,3737],{},"交集只保留两边都有的元素，并集收集两边全部不同元素，差集只保留左侧独有元素。集合不靠位置组织数据。",[14,3739,35],{"id":35},[37,3741,3742,3745,3748],{},[40,3743,3744],{},"集合中的元素不重复。",[40,3746,3747],{},"集合是无序容器，不要依赖打印顺序或索引。",[40,3749,3750,3751,3754,3755,3758],{},"创建空集合必须写 ",[49,3752,3753],{},"set()","；",[49,3756,3757],{},"{}"," 创建的是空字典。",[14,3760,59],{"id":59},[10,3762,62],{},[64,3764,3766],{"className":66,"code":3765,"language":68,"meta":69,"style":69},"left = {\"Python\", \"Git\", \"Linux\"}\nright = {\"Python\", \"Docker\"}\n\nprint(left & right)\nprint(left | right)\nprint(\"Git\" in left)\n",[49,3767,3768,3773,3778,3782,3787,3792],{"__ignoreMap":69},[73,3769,3770],{"class":75,"line":76},[73,3771,3772],{},"left = {\"Python\", \"Git\", \"Linux\"}\n",[73,3774,3775],{"class":75,"line":82},[73,3776,3777],{},"right = {\"Python\", \"Docker\"}\n",[73,3779,3780],{"class":75,"line":89},[73,3781,86],{"emptyLinePlaceholder":85},[73,3783,3784],{"class":75,"line":95},[73,3785,3786],{},"print(left & right)\n",[73,3788,3789],{"class":75,"line":101},[73,3790,3791],{},"print(left | right)\n",[73,3793,3794],{"class":75,"line":106},[73,3795,3796],{},"print(\"Git\" in left)\n",[10,3798,146],{},[64,3800,3803],{"className":3801,"code":3802,"language":152,"meta":69},[150],"{'Python'}\n集合包含 Python、Git、Linux、Docker（显示顺序不保证）\nTrue\n",[49,3804,3802],{"__ignoreMap":69},[10,3806,157],{},[14,3808,160],{"id":160},[162,3810,3811,3814],{},[40,3812,3813],{},"集合字面量自动保证元素唯一，成员测试通常只关心“在不在”。",[40,3815,3816,3819,3820,3823],{},[49,3817,3818],{},"&"," 计算交集，",[49,3821,3822],{},"|"," 计算并集；结果显示顺序不应作为程序逻辑的一部分。",[14,3825,210],{"id":210},[37,3827,3828,3835],{},[40,3829,2366,3830,3832,3833,391],{},[49,3831,3757],{}," 创建空集合，实际得到空字典；空集合应写 ",[49,3834,3753],{},[40,3836,3837],{},"依赖集合的显示顺序或尝试通过索引读取元素。",[14,3839,221],{"id":221},[162,3841,3842,3848],{},[40,3843,3844,3845,3847],{},"把包含重复标签的列表交给 ",[49,3846,3753],{}," 去重。",[40,3849,3850],{},"计算两组课程标签的交集和差集。",[10,3852,232],{},[14,3854,235],{"id":235},[10,3856,3857],{},"本篇目标是使用集合去重并完成基础集合运算。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,3859,242],{},{"title":69,"searchDepth":82,"depth":82,"links":3861},[3862,3863,3864,3865,3866,3867,3868,3869],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F14-python-set-basics",{"title":3716,"description":3721},"python-set-basics","posts\u002F20260817\u002F14-python-set-basics","面向按顺序学习 Python 的初学者，本篇在第 11 篇知识上，帮助读者使用集合去重并完成基础集合运算。",[255,3877,3384],"集合","KXOj6NoWOOrTpxvBH_a2NRpI_gZBrOFknr0TFAxKVR0",{"id":3880,"title":3881,"body":3882,"category":255,"cover":256,"description":3886,"extension":257,"meta":4083,"navigation":85,"path":4084,"pinned":260,"publishedAt":261,"seo":4085,"slug":4086,"stem":4087,"summary":4088,"tags":4089,"updatedAt":261,"visible":85,"__hash__":4092},"posts\u002Fposts\u002F20260817\u002F15-python-mutable-copy.md","15｜可变对象、共享引用与浅拷贝",{"type":7,"value":3883,"toc":4071},[3884,3887,3889,3892,3894,3900,3910,3912,3929,3931,3933,3982,3984,3990,3992,3994,4016,4018,4021,4027,4030,4032,4045,4047,4062,4064,4066,4069],[10,3885,3886],{},"这套课程按知识依赖排列。本篇的前置知识是：第 06、11、13 篇。学完后，你应该能够识别共享引用并创建基础浅拷贝。",[14,3888,16],{"id":16},[10,3890,3891],{},"本篇只处理“可变对象、共享引用与浅拷贝”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,3893,22],{"id":22},[10,3895,3896],{},[26,3897],{"alt":3898,"src":3899},"共享引用与浅拷贝","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shared-reference.svg",[10,3901,3902,3905,3906,3909],{},[49,3903,3904],{},"backup = tasks"," 只增加一个指向同一列表的变量名；",[49,3907,3908],{},"tasks.copy()"," 才创建外层新列表。浅拷贝不会递归复制内部嵌套对象。",[14,3911,35],{"id":35},[37,3913,3914,3923,3926],{},[40,3915,3916,3918,3919,3922],{},[49,3917,2833],{}," 比较内容是否相等，",[49,3920,3921],{},"is"," 比较是否为同一个对象。",[40,3924,3925],{},"列表和字典是常见可变对象，修改操作可能通过共享引用被其他变量观察到。",[40,3927,3928],{},"处理嵌套结构时需要明确浅拷贝边界，不要默认所有层级都已独立。",[14,3930,59],{"id":59},[10,3932,62],{},[64,3934,3936],{"className":66,"code":3935,"language":68,"meta":69,"style":69},"tasks = [\"变量\", \"字符串\"]\nshared = tasks\nbackup = tasks.copy()\n\ntasks.append(\"列表\")\nprint(shared)\nprint(backup)\nprint(tasks is shared)\nprint(tasks is backup)\n",[49,3937,3938,3943,3948,3953,3957,3962,3967,3972,3977],{"__ignoreMap":69},[73,3939,3940],{"class":75,"line":76},[73,3941,3942],{},"tasks = [\"变量\", \"字符串\"]\n",[73,3944,3945],{"class":75,"line":82},[73,3946,3947],{},"shared = tasks\n",[73,3949,3950],{"class":75,"line":89},[73,3951,3952],{},"backup = tasks.copy()\n",[73,3954,3955],{"class":75,"line":95},[73,3956,86],{"emptyLinePlaceholder":85},[73,3958,3959],{"class":75,"line":101},[73,3960,3961],{},"tasks.append(\"列表\")\n",[73,3963,3964],{"class":75,"line":106},[73,3965,3966],{},"print(shared)\n",[73,3968,3969],{"class":75,"line":112},[73,3970,3971],{},"print(backup)\n",[73,3973,3974],{"class":75,"line":118},[73,3975,3976],{},"print(tasks is shared)\n",[73,3978,3979],{"class":75,"line":124},[73,3980,3981],{},"print(tasks is backup)\n",[10,3983,146],{},[64,3985,3988],{"className":3986,"code":3987,"language":152,"meta":69},[150],"['变量', '字符串', '列表']\n['变量', '字符串']\nTrue\nFalse\n",[49,3989,3987],{"__ignoreMap":69},[10,3991,157],{},[14,3993,160],{"id":160},[162,3995,3996,4002],{},[40,3997,3998,4001],{},[49,3999,4000],{},"shared = tasks"," 没有创建列表，只让两个名字指向同一个列表对象。",[40,4003,4004,4007,4008,4011,4012,4015],{},[49,4005,4006],{},"backup = tasks.copy()"," 创建新的外层列表；随后向原列表追加元素，",[49,4009,4010],{},"shared"," 能观察到变化，",[49,4013,4014],{},"backup"," 不会。",[193,4017,195],{"id":195},[10,4019,4020],{},"浅拷贝遇到嵌套列表时，外层虽然分开，内部对象仍可能共享。",[10,4022,4023],{},[26,4024],{"alt":4025,"src":4026},"浅拷贝只分离外层列表","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F15-shallow-copy-nested.svg",[10,4028,4029],{},"两边拥有不同的外层列表，但内部课程列表仍是同一个对象。修改内部列表时，两边都能观察到变化。",[14,4031,210],{"id":210},[37,4033,4034,4042],{},[40,4035,4036,4037,4039,4040,391],{},"用 ",[49,4038,2833],{}," 判断是否同一对象。内容相等不代表身份相同，身份比较使用 ",[49,4041,3921],{},[40,4043,4044],{},"把浅拷贝当作递归复制；嵌套列表中的内部对象仍可能被两边共享。",[14,4046,221],{"id":221},[162,4048,4049,4052],{},[40,4050,4051],{},"让两个变量引用同一个字典并修改其中一个。",[40,4053,2366,4054,4057,4058,1186,4060,391],{},[49,4055,4056],{},"copy()"," 创建外层副本，再比较 ",[49,4059,3921],{},[49,4061,2833],{},[10,4063,232],{},[14,4065,235],{"id":235},[10,4067,4068],{},"本篇目标是识别共享引用并创建基础浅拷贝。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,4070,242],{},{"title":69,"searchDepth":82,"depth":82,"links":4072},[4073,4074,4075,4076,4077,4080,4081,4082],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":4078},[4079],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F15-python-mutable-copy",{"title":3881,"description":3886},"python-mutable-copy","posts\u002F20260817\u002F15-python-mutable-copy","面向按顺序学习 Python 的初学者，本篇在第 06、11、13 篇知识上，帮助读者识别共享引用并创建基础浅拷贝。",[255,4090,4091],"可变对象","浅拷贝","vdOQb2defrPnPNgAJhS4q0sbEptSjwNTiVl9Dfnao7Q",{"id":4094,"title":4095,"body":4096,"category":255,"cover":256,"description":4100,"extension":257,"meta":4312,"navigation":85,"path":4313,"pinned":260,"publishedAt":261,"seo":4314,"slug":4315,"stem":4316,"summary":4317,"tags":4318,"updatedAt":261,"visible":85,"__hash__":4320},"posts\u002Fposts\u002F20260817\u002F16-python-if-branches.md","16｜if 条件判断与多分支选择",{"type":7,"value":4097,"toc":4299},[4098,4101,4103,4106,4108,4114,4124,4126,4137,4139,4141,4193,4195,4201,4203,4205,4223,4225,4228,4234,4242,4245,4248,4254,4260,4262,4280,4282,4290,4292,4294,4297],[10,4099,4100],{},"这套课程按知识依赖排列。本篇的前置知识是：第 09、10 篇。学完后，你应该能够根据互斥条件选择一条执行路径。",[14,4102,16],{"id":16},[10,4104,4105],{},"本篇只处理“if 条件判断与多分支选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4107,22],{"id":22},[10,4109,4110],{},[26,4111],{"alt":4112,"src":4113},"if 只选择一条分支","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-if-branch.svg",[10,4115,4116,2284,4118,2284,4121,4123],{},[49,4117,1185],{},[49,4119,4120],{},"elif",[49,4122,1189],{}," 从上到下判断，一旦某个条件成立，就执行对应分支并跳过后面的同级分支。",[14,4125,35],{"id":35},[37,4127,4128,4131,4134],{},[40,4129,4130],{},"冒号表示接下来开始一个代码块。",[40,4132,4133],{},"同一代码块必须保持一致缩进，通常使用四个空格。",[40,4135,4136],{},"多分支条件要从更严格的范围向更宽的范围排列。",[14,4138,59],{"id":59},[10,4140,62],{},[64,4142,4144],{"className":66,"code":4143,"language":68,"meta":69,"style":69},"score = int(input(\"请输入分数：\"))\n\nif score >= 90:\n    level = \"优秀\"\nelif score >= 60:\n    level = \"合格\"\nelse:\n    level = \"需要继续学习\"\n\nprint(level)\n",[49,4145,4146,4151,4155,4160,4165,4170,4175,4179,4184,4188],{"__ignoreMap":69},[73,4147,4148],{"class":75,"line":76},[73,4149,4150],{},"score = int(input(\"请输入分数：\"))\n",[73,4152,4153],{"class":75,"line":82},[73,4154,86],{"emptyLinePlaceholder":85},[73,4156,4157],{"class":75,"line":89},[73,4158,4159],{},"if score >= 90:\n",[73,4161,4162],{"class":75,"line":95},[73,4163,4164],{},"    level = \"优秀\"\n",[73,4166,4167],{"class":75,"line":101},[73,4168,4169],{},"elif score >= 60:\n",[73,4171,4172],{"class":75,"line":106},[73,4173,4174],{},"    level = \"合格\"\n",[73,4176,4177],{"class":75,"line":112},[73,4178,1175],{},[73,4180,4181],{"class":75,"line":118},[73,4182,4183],{},"    level = \"需要继续学习\"\n",[73,4185,4186],{"class":75,"line":124},[73,4187,86],{"emptyLinePlaceholder":85},[73,4189,4190],{"class":75,"line":129},[73,4191,4192],{},"print(level)\n",[10,4194,146],{},[64,4196,4199],{"className":4197,"code":4198,"language":152,"meta":69},[150],"输入 85 时输出：合格\n",[49,4200,4198],{"__ignoreMap":69},[10,4202,157],{},[14,4204,160],{"id":160},[162,4206,4207,4214],{},[40,4208,4209,4210,4213],{},"输入先转换为整数，程序从 ",[49,4211,4212],{},"score >= 90"," 开始判断。输入 85 时第一项为假，继续检查下一项。",[40,4215,4216,4219,4220,4222],{},[49,4217,4218],{},"score >= 60"," 为真后执行“合格”分支，同级的 ",[49,4221,1189],{}," 被跳过；最终三个分支只会选择一个。",[193,4224,195],{"id":195},[10,4226,4227],{},"多分支判断的顺序会改变结果，尤其是范围互相包含时。",[10,4229,4230],{},[26,4231],{"alt":4232,"src":4233},"多分支要先判断更严格范围","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-branch-order.svg",[10,4235,4236,4238,4239,4241],{},[49,4237,4212],{}," 必须放在 ",[49,4240,4218],{}," 前面。更宽的条件如果先成立，后面更严格的分支就没有机会执行。",[193,4243,195],{"id":4244},"再看一个具体细节-1",[10,4246,4247],{},"分支属于哪个条件由缩进决定，不由代码在视觉上的远近决定。",[10,4249,4250],{},[26,4251],{"alt":4252,"src":4253},"缩进决定代码块归属","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F16-indentation-block.svg",[10,4255,4256,4257,4259],{},"同一缩进层级属于同一个代码块；回到 ",[49,4258,1185],{}," 之前的缩进后，语句就位于整条分支结构之外。",[14,4261,210],{"id":210},[37,4263,4264,4270],{},[40,4265,4266,4267,4269],{},"先写 ",[49,4268,4218],{},"，导致 95 也在这一项提前匹配，永远到不了“优秀”。",[40,4271,4272,4273,4275,4276,4279],{},"混用多个独立 ",[49,4274,1185],{}," 表达互斥等级，可能同时执行多个代码块；互斥选择使用同一条 ",[49,4277,4278],{},"if\u002Felif\u002Felse"," 链。",[14,4281,221],{"id":221},[162,4283,4284,4287],{},[40,4285,4286],{},"根据温度输出“冷、适中、热”三个等级。",[40,4288,4289],{},"交换示例中两个条件的顺序，解释为什么结果可能错误。",[10,4291,232],{},[14,4293,235],{"id":235},[10,4295,4296],{},"本篇目标是根据互斥条件选择一条执行路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,4298,242],{},{"title":69,"searchDepth":82,"depth":82,"links":4300},[4301,4302,4303,4304,4305,4309,4310,4311],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":4306},[4307,4308],{"id":195,"depth":89,"text":195},{"id":4244,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F16-python-if-branches",{"title":4095,"description":4100},"python-if-branches","posts\u002F20260817\u002F16-python-if-branches","面向按顺序学习 Python 的初学者，本篇在第 09、10 篇知识上，帮助读者根据互斥条件选择一条执行路径。",[255,1185,4319],"条件判断","bebSP1lcnhhyU-BLVawQhLx9aQej9SKKJKVw_DdO60c",{"id":4322,"title":4323,"body":4324,"category":255,"cover":256,"description":4328,"extension":257,"meta":4494,"navigation":85,"path":4495,"pinned":260,"publishedAt":261,"seo":4496,"slug":4497,"stem":4498,"summary":4499,"tags":4500,"updatedAt":261,"visible":85,"__hash__":4502},"posts\u002Fposts\u002F20260817\u002F17-python-while-loop.md","17｜while 循环与状态更新",{"type":7,"value":4325,"toc":4482},[4326,4329,4331,4334,4336,4342,4348,4350,4365,4367,4369,4407,4409,4415,4417,4419,4434,4436,4439,4445,4451,4453,4461,4463,4473,4475,4477,4480],[10,4327,4328],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16 篇。学完后，你应该能够在条件成立时重复执行并保证循环结束。",[14,4330,16],{"id":16},[10,4332,4333],{},"本篇只处理“while 循环与状态更新”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4335,22],{"id":22},[10,4337,4338],{},[26,4339],{"alt":4340,"src":4341},"while 的条件检查与状态更新循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-while-loop.svg",[10,4343,4344,4347],{},[49,4345,4346],{},"while"," 每轮都经历“检查条件—执行循环体—更新状态—再次检查”。缺少状态更新时，条件可能永远成立，形成无限循环。",[14,4349,35],{"id":35},[37,4351,4352,4355,4358],{},[40,4353,4354],{},"进入循环前先准备参与条件判断的状态。",[40,4356,4357],{},"循环体中必须有机会让条件变为假。",[40,4359,4360,4361,4364],{},"能够预先确定遍历对象时，后续介绍的 ",[49,4362,4363],{},"for"," 通常更直接。",[14,4366,59],{"id":59},[10,4368,62],{},[64,4370,4372],{"className":66,"code":4371,"language":68,"meta":69,"style":69},"count = 1\n\nwhile count \u003C= 3:\n    print(\"第\", count, \"次练习\")\n    count = count + 1\n\nprint(\"练习结束\")\n",[49,4373,4374,4379,4383,4388,4393,4398,4402],{"__ignoreMap":69},[73,4375,4376],{"class":75,"line":76},[73,4377,4378],{},"count = 1\n",[73,4380,4381],{"class":75,"line":82},[73,4382,86],{"emptyLinePlaceholder":85},[73,4384,4385],{"class":75,"line":89},[73,4386,4387],{},"while count \u003C= 3:\n",[73,4389,4390],{"class":75,"line":95},[73,4391,4392],{},"    print(\"第\", count, \"次练习\")\n",[73,4394,4395],{"class":75,"line":101},[73,4396,4397],{},"    count = count + 1\n",[73,4399,4400],{"class":75,"line":106},[73,4401,86],{"emptyLinePlaceholder":85},[73,4403,4404],{"class":75,"line":112},[73,4405,4406],{},"print(\"练习结束\")\n",[10,4408,146],{},[64,4410,4413],{"className":4411,"code":4412,"language":152,"meta":69},[150],"第 1 次练习\n第 2 次练习\n第 3 次练习\n练习结束\n",[49,4414,4412],{"__ignoreMap":69},[10,4416,157],{},[14,4418,160],{"id":160},[162,4420,4421,4428],{},[40,4422,4423,4424,4427],{},"进入循环前 ",[49,4425,4426],{},"count"," 为 1，每轮开头判断它是否仍小于等于 3。",[40,4429,4430,4431,4433],{},"循环体末尾把 ",[49,4432,4426],{}," 增加 1；当它变成 4 时条件为假，解释器跳到循环后的语句。",[193,4435,195],{"id":195},[10,4437,4438],{},"追踪循环时，可以把每轮开始值、判断结果和更新后值写成表格。",[10,4440,4441],{},[26,4442],{"alt":4443,"src":4444},"count 在每轮怎样变化","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F17-loop-trace-table.svg",[10,4446,4447,4448,4450],{},"第4次检查时 ",[49,4449,4426],{}," 已经是4，条件为假，因此不会产生“第4次练习”的输出。",[14,4452,210],{"id":210},[37,4454,4455,4458],{},[40,4456,4457],{},"漏掉状态更新，条件永远为真，只能手动中断程序。",[40,4459,4460],{},"更新方向写反，例如条件要求递增退出却不断递减。设计循环时先写出状态如何接近结束条件。",[14,4462,221],{"id":221},[162,4464,4465,4470],{},[40,4466,2366,4467,4469],{},[49,4468,4346],{}," 输出 1 到 5。",[40,4471,4472],{},"计算 1 到 10 的累加和。",[10,4474,232],{},[14,4476,235],{"id":235},[10,4478,4479],{},"本篇目标是在条件成立时重复执行并保证循环结束。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,4481,242],{},{"title":69,"searchDepth":82,"depth":82,"links":4483},[4484,4485,4486,4487,4488,4491,4492,4493],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":4489},[4490],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F17-python-while-loop",{"title":4323,"description":4328},"python-while-loop","posts\u002F20260817\u002F17-python-while-loop","面向按顺序学习 Python 的初学者，本篇在第 16 篇知识上，帮助读者在条件成立时重复执行并保证循环结束。",[255,4346,4501],"循环","-TrC6KNTG7XCCoQkCsjj0a8RonXSt5TA61HAFQFujg0",{"id":4504,"title":4505,"body":4506,"category":255,"cover":256,"description":4510,"extension":257,"meta":4657,"navigation":85,"path":4658,"pinned":260,"publishedAt":261,"seo":4659,"slug":4660,"stem":4661,"summary":4662,"tags":4663,"updatedAt":261,"visible":85,"__hash__":4665},"posts\u002Fposts\u002F20260817\u002F18-python-for-range.md","18｜for 循环、range 与逐项处理",{"type":7,"value":4507,"toc":4647},[4508,4511,4513,4516,4518,4524,4529,4531,4545,4547,4549,4587,4589,4595,4597,4599,4615,4617,4625,4627,4638,4640,4642,4645],[10,4509,4510],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、17 篇。学完后，你应该能够遍历列表、字符串和整数范围。",[14,4512,16],{"id":16},[10,4514,4515],{},"本篇只处理“for 循环、range 与逐项处理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4517,22],{"id":22},[10,4519,4520],{},[26,4521],{"alt":4522,"src":4523},"for 逐项取得数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F18-for-iteration.svg",[10,4525,4526,4528],{},[49,4527,4363],{}," 每轮从可迭代对象取得一个元素，绑定到循环变量，再执行循环体。循环变量表示当前元素，不是固定的容器索引。",[14,4530,35],{"id":35},[37,4532,4533,4539,4542],{},[40,4534,4535,4538],{},[49,4536,4537],{},"range(1, 4)"," 包含 1，不包含 4。",[40,4540,4541],{},"只需要元素时直接遍历元素，不必手工维护索引。",[40,4543,4544],{},"循环变量应使用单数名称，容器使用复数名称。",[14,4546,59],{"id":59},[10,4548,62],{},[64,4550,4552],{"className":66,"code":4551,"language":68,"meta":69,"style":69},"courses = [\"变量\", \"字符串\", \"列表\"]\n\nfor course in courses:\n    print(course)\n\nfor number in range(1, 4):\n    print(number)\n",[49,4553,4554,4559,4563,4568,4573,4577,4582],{"__ignoreMap":69},[73,4555,4556],{"class":75,"line":76},[73,4557,4558],{},"courses = [\"变量\", \"字符串\", \"列表\"]\n",[73,4560,4561],{"class":75,"line":82},[73,4562,86],{"emptyLinePlaceholder":85},[73,4564,4565],{"class":75,"line":89},[73,4566,4567],{},"for course in courses:\n",[73,4569,4570],{"class":75,"line":95},[73,4571,4572],{},"    print(course)\n",[73,4574,4575],{"class":75,"line":101},[73,4576,86],{"emptyLinePlaceholder":85},[73,4578,4579],{"class":75,"line":106},[73,4580,4581],{},"for number in range(1, 4):\n",[73,4583,4584],{"class":75,"line":112},[73,4585,4586],{},"    print(number)\n",[10,4588,146],{},[64,4590,4593],{"className":4591,"code":4592,"language":152,"meta":69},[150],"变量\n字符串\n列表\n1\n2\n3\n",[49,4594,4592],{"__ignoreMap":69},[10,4596,157],{},[14,4598,160],{"id":160},[162,4600,4601,4610],{},[40,4602,4603,4604,4606,4607,4609],{},"第一个 ",[49,4605,4363],{}," 依次从列表取得字符串，循环变量 ",[49,4608,186],{}," 每轮重新绑定。",[40,4611,4612,4614],{},[49,4613,4537],{}," 产生 1、2、3，不包含终点 4，符合半开区间习惯。",[14,4616,210],{"id":210},[37,4618,4619,4622],{},[40,4620,4621],{},"只需要元素却手工维护索引，增加越界风险。",[40,4623,4624],{},"误以为循环结束后容器被消耗或删除；列表仍然存在，变化只取决于循环体是否修改它。",[14,4626,221],{"id":221},[162,4628,4629,4632],{},[40,4630,4631],{},"逐项输出一个字符串中的字符。",[40,4633,2366,4634,4637],{},[49,4635,4636],{},"range()"," 输出 2、4、6、8。",[10,4639,232],{},[14,4641,235],{"id":235},[10,4643,4644],{},"本篇目标是遍历列表、字符串和整数范围。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,4646,242],{},{"title":69,"searchDepth":82,"depth":82,"links":4648},[4649,4650,4651,4652,4653,4654,4655,4656],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F18-python-for-range",{"title":4505,"description":4510},"python-for-range","posts\u002F20260817\u002F18-python-for-range","面向按顺序学习 Python 的初学者，本篇在第 11、17 篇知识上，帮助读者遍历列表、字符串和整数范围。",[255,4363,4664],"range","ui6q6MZ6cKqxzP4rBtGhogEk5BpvltDxO-0zl4y8kxE",{"id":4667,"title":4668,"body":4669,"category":255,"cover":256,"description":4673,"extension":257,"meta":4847,"navigation":85,"path":4848,"pinned":260,"publishedAt":261,"seo":4849,"slug":4850,"stem":4851,"summary":4852,"tags":4853,"updatedAt":261,"visible":85,"__hash__":4854},"posts\u002Fposts\u002F20260817\u002F19-python-break-continue.md","19｜break、continue 与循环结束条件",{"type":7,"value":4670,"toc":4837},[4671,4674,4676,4679,4681,4687,4697,4699,4718,4720,4722,4774,4776,4782,4784,4786,4800,4802,4818,4820,4828,4830,4832,4835],[10,4672,4673],{},"这套课程按知识依赖排列。本篇的前置知识是：第 17、18 篇。学完后，你应该能够跳过本次迭代或提前结束整个循环。",[14,4675,16],{"id":16},[10,4677,4678],{},"本篇只处理“break、continue 与循环结束条件”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4680,22],{"id":22},[10,4682,4683],{},[26,4684],{"alt":4685,"src":4686},"continue 与 break 的路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F19-loop-control.svg",[10,4688,4689,4692,4693,4696],{},[49,4690,4691],{},"continue"," 只结束当前这一轮，程序回到下一轮判断；",[49,4694,4695],{},"break"," 立即结束整个循环，执行循环后面的代码。",[14,4698,35],{"id":35},[37,4700,4701,4704,4712],{},[40,4702,4703],{},"先写普通循环，再在确有需要时加入流程控制语句。",[40,4705,4706,4708,4709,4711],{},[49,4707,4691],{}," 前要确认不会跳过 ",[49,4710,4346],{}," 循环中的状态更新。",[40,4713,4714,4715,4717],{},"多层嵌套中 ",[49,4716,4695],{}," 只结束它所在的最内层循环。",[14,4719,59],{"id":59},[10,4721,62],{},[64,4723,4725],{"className":66,"code":4724,"language":68,"meta":69,"style":69},"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",[49,4726,4727,4732,4736,4741,4746,4751,4756,4761,4765,4769],{"__ignoreMap":69},[73,4728,4729],{"class":75,"line":76},[73,4730,4731],{},"numbers = [3, -1, 0, 8, 12]\n",[73,4733,4734],{"class":75,"line":82},[73,4735,86],{"emptyLinePlaceholder":85},[73,4737,4738],{"class":75,"line":89},[73,4739,4740],{},"for number in numbers:\n",[73,4742,4743],{"class":75,"line":95},[73,4744,4745],{},"    if number \u003C 0:\n",[73,4747,4748],{"class":75,"line":101},[73,4749,4750],{},"        continue\n",[73,4752,4753],{"class":75,"line":106},[73,4754,4755],{},"    if number == 0:\n",[73,4757,4758],{"class":75,"line":112},[73,4759,4760],{},"        break\n",[73,4762,4763],{"class":75,"line":118},[73,4764,4586],{},[73,4766,4767],{"class":75,"line":124},[73,4768,86],{"emptyLinePlaceholder":85},[73,4770,4771],{"class":75,"line":129},[73,4772,4773],{},"print(\"循环结束\")\n",[10,4775,146],{},[64,4777,4780],{"className":4778,"code":4779,"language":152,"meta":69},[150],"3\n循环结束\n",[49,4781,4779],{"__ignoreMap":69},[10,4783,157],{},[14,4785,160],{"id":160},[162,4787,4788,4794],{},[40,4789,4790,4791,4793],{},"遇到 -1 时 ",[49,4792,4691],{}," 立即结束本轮，后面的判断和输出都不执行。",[40,4795,4796,4797,4799],{},"遇到 0 时 ",[49,4798,4695],{}," 结束整个循环，因此列表后面的 8 和 12 不再处理。",[14,4801,210],{"id":210},[37,4803,4804,4809],{},[40,4805,3493,4806,4808],{},[49,4807,4691],{}," 当作结束循环，实际它只跳到下一轮。",[40,4810,4811,4812,4814,4815,4817],{},"在 ",[49,4813,4346],{}," 中把状态更新放在可能被 ",[49,4816,4691],{}," 跳过的位置，造成无限循环。",[14,4819,221],{"id":221},[162,4821,4822,4825],{},[40,4823,4824],{},"跳过列表中的空字符串并输出其他内容。",[40,4826,4827],{},"在 1 到 100 中找到第一个能被 17 整除的数后结束循环。",[10,4829,232],{},[14,4831,235],{"id":235},[10,4833,4834],{},"本篇目标是跳过本次迭代或提前结束整个循环。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,4836,242],{},{"title":69,"searchDepth":82,"depth":82,"links":4838},[4839,4840,4841,4842,4843,4844,4845,4846],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F19-python-break-continue",{"title":4668,"description":4673},"python-break-continue","posts\u002F20260817\u002F19-python-break-continue","面向按顺序学习 Python 的初学者，本篇在第 17、18 篇知识上，帮助读者跳过本次迭代或提前结束整个循环。",[255,4695,4691],"uEg9Dj4M2Euj0iyjUlLQVeyvcIFHi9IgH2Gz7czOs18",{"id":4856,"title":4857,"body":4858,"category":255,"cover":256,"description":4862,"extension":257,"meta":5033,"navigation":85,"path":5034,"pinned":260,"publishedAt":261,"seo":5035,"slug":5036,"stem":5037,"summary":5038,"tags":5039,"updatedAt":261,"visible":85,"__hash__":5042},"posts\u002Fposts\u002F20260817\u002F20-python-nested-control-flow.md","20｜嵌套判断与嵌套循环怎样保持清晰",{"type":7,"value":4859,"toc":5021},[4860,4863,4865,4868,4870,4876,4879,4881,4905,4907,4909,4943,4945,4951,4953,4955,4972,4974,4977,4983,4986,4988,5002,5004,5012,5014,5016,5019],[10,4861,4862],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够读取二维数据并控制嵌套层级。",[14,4864,16],{"id":16},[10,4866,4867],{},"本篇只处理“嵌套判断与嵌套循环怎样保持清晰”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,4869,22],{"id":22},[10,4871,4872],{},[26,4873],{"alt":4874,"src":4875},"外层一步包含完整内层循环","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-loop.svg",[10,4877,4878],{},"外层循环取得一行后，内层循环会完整处理这一行的各列；内层结束后，外层才取得下一行。",[14,4880,35],{"id":35},[37,4882,4883,4886,4889],{},[40,4884,4885],{},"每增加一层嵌套，阅读成本都会上升。",[40,4887,4888],{},"内层逻辑较长时，学习完函数后应考虑提取函数。",[40,4890,4891,4892,2284,4895,4898,4899,2284,4902,391],{},"变量名使用 ",[49,4893,4894],{},"row",[49,4896,4897],{},"cell"," 等层级含义，避免全部写成 ",[49,4900,4901],{},"i",[49,4903,4904],{},"j",[14,4906,59],{"id":59},[10,4908,62],{},[64,4910,4912],{"className":66,"code":4911,"language":68,"meta":69,"style":69},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n\nfor row in table:\n    for cell in row:\n        print(cell)\n    print(\"一行结束\")\n",[49,4913,4914,4919,4923,4928,4933,4938],{"__ignoreMap":69},[73,4915,4916],{"class":75,"line":76},[73,4917,4918],{},"table = [[\"A1\", \"A2\"], [\"B1\", \"B2\"]]\n",[73,4920,4921],{"class":75,"line":82},[73,4922,86],{"emptyLinePlaceholder":85},[73,4924,4925],{"class":75,"line":89},[73,4926,4927],{},"for row in table:\n",[73,4929,4930],{"class":75,"line":95},[73,4931,4932],{},"    for cell in row:\n",[73,4934,4935],{"class":75,"line":101},[73,4936,4937],{},"        print(cell)\n",[73,4939,4940],{"class":75,"line":106},[73,4941,4942],{},"    print(\"一行结束\")\n",[10,4944,146],{},[64,4946,4949],{"className":4947,"code":4948,"language":152,"meta":69},[150],"A1\nA2\n一行结束\nB1\nB2\n一行结束\n",[49,4950,4948],{"__ignoreMap":69},[10,4952,157],{},[14,4954,160],{"id":160},[162,4956,4957,4969],{},[40,4958,4959,4960,4962,4963,1186,4966,391],{},"外层变量 ",[49,4961,4894],{}," 先引用第一行列表，内层才依次处理 ",[49,4964,4965],{},"A1",[49,4967,4968],{},"A2",[40,4970,4971],{},"内层结束后输出“一行结束”，外层再进入第二行；这解释了输出中的分组顺序。",[193,4973,195],{"id":195},[10,4975,4976],{},"二维列表的输出顺序可以展开成一条时间线。",[10,4978,4979],{},[26,4980],{"alt":4981,"src":4982},"二维列表的实际处理顺序","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F20-nested-iteration-order.svg",[10,4984,4985],{},"内层必须走完当前行，外层才移动到下一行；这就是嵌套循环的执行顺序。",[14,4987,210],{"id":210},[37,4989,4990,4999],{},[40,4991,4992,4993,1038,4996,4998],{},"把两层循环变量都叫 ",[49,4994,4995],{},"item",[49,4997,4901],{},"，难以确认当前层级。",[40,5000,5001],{},"无限增加嵌套层数。逻辑变长后应在第 22 篇函数知识基础上提取职责。",[14,5003,221],{"id":221},[162,5005,5006,5009],{},[40,5007,5008],{},"打印一个 2×3 数字表。",[40,5010,5011],{},"在内层增加条件，只输出大于 3 的元素。",[10,5013,232],{},[14,5015,235],{"id":235},[10,5017,5018],{},"本篇目标是读取二维数据并控制嵌套层级。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,5020,242],{},{"title":69,"searchDepth":82,"depth":82,"links":5022},[5023,5024,5025,5026,5027,5030,5031,5032],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":5028},[5029],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F20-python-nested-control-flow",{"title":4857,"description":4862},"python-nested-control-flow","posts\u002F20260817\u002F20-python-nested-control-flow","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者读取二维数据并控制嵌套层级。",[255,5040,5041],"嵌套循环","控制流","S3olPw7eJ8RmHBhiIb2q0QDklbEB8Mm298qnPCSXcHI",{"id":5044,"title":5045,"body":5046,"category":255,"cover":256,"description":5050,"extension":257,"meta":5188,"navigation":85,"path":5189,"pinned":260,"publishedAt":261,"seo":5190,"slug":5191,"stem":5192,"summary":5193,"tags":5194,"updatedAt":261,"visible":85,"__hash__":5197},"posts\u002Fposts\u002F20260817\u002F21-python-list-comprehension.md","21｜列表推导式：把简单循环写成数据变换",{"type":7,"value":5047,"toc":5178},[5048,5051,5053,5056,5058,5064,5067,5069,5080,5082,5084,5122,5124,5130,5132,5134,5146,5148,5159,5161,5169,5171,5173,5176],[10,5049,5050],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够阅读和编写单层列表推导式。",[14,5052,16],{"id":16},[10,5054,5055],{},"本篇只处理“列表推导式：把简单循环写成数据变换”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5057,22],{"id":22},[10,5059,5060],{},[26,5061],{"alt":5062,"src":5063},"推导式的数据变换管道","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F21-comprehension.svg",[10,5065,5066],{},"推导式从右侧输入序列逐项取值，可选地过滤，再计算左侧表达式，最终形成一个新列表。",[14,5068,35],{"id":35},[37,5070,5071,5074,5077],{},[40,5072,5073],{},"推导式适合“遍历—可选过滤—产生一个新值”的简单流程。",[40,5075,5076],{},"包含多层嵌套或复杂判断时，普通循环通常更清楚。",[40,5078,5079],{},"推导式创建新列表，不修改输入列表。",[14,5081,59],{"id":59},[10,5083,62],{},[64,5085,5087],{"className":66,"code":5086,"language":68,"meta":69,"style":69},"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",[49,5088,5089,5094,5098,5103,5108,5112,5117],{"__ignoreMap":69},[73,5090,5091],{"class":75,"line":76},[73,5092,5093],{},"numbers = [1, 2, 3, 4, 5]\n",[73,5095,5096],{"class":75,"line":82},[73,5097,86],{"emptyLinePlaceholder":85},[73,5099,5100],{"class":75,"line":89},[73,5101,5102],{},"squares = [number * number for number in numbers]\n",[73,5104,5105],{"class":75,"line":95},[73,5106,5107],{},"even_squares = [number * number for number in numbers if number % 2 == 0]\n",[73,5109,5110],{"class":75,"line":101},[73,5111,86],{"emptyLinePlaceholder":85},[73,5113,5114],{"class":75,"line":106},[73,5115,5116],{},"print(squares)\n",[73,5118,5119],{"class":75,"line":112},[73,5120,5121],{},"print(even_squares)\n",[10,5123,146],{},[64,5125,5128],{"className":5126,"code":5127,"language":152,"meta":69},[150],"[1, 4, 9, 16, 25]\n[4, 16]\n",[49,5129,5127],{"__ignoreMap":69},[10,5131,157],{},[14,5133,160],{"id":160},[162,5135,5136,5139],{},[40,5137,5138],{},"第一条推导式对每个数字计算平方，结果按输入顺序放进新列表。",[40,5140,5141,5142,5145],{},"第二条先用 ",[49,5143,5144],{},"number % 2 == 0"," 过滤偶数，只有通过过滤的数字才计算平方。",[14,5147,210],{"id":210},[37,5149,5150,5156],{},[40,5151,5152,5153,5155],{},"把表达式、循环和过滤条件的书写顺序误当作执行顺序；阅读时从 ",[49,5154,4363],{}," 开始找输入。",[40,5157,5158],{},"在推导式中堆叠多层循环和复杂分支，使代码比普通循环更难读。",[14,5160,221],{"id":221},[162,5162,5163,5166],{},[40,5164,5165],{},"把字符串列表转换为长度列表。",[40,5167,5168],{},"筛选 1 到 20 中能被 3 整除的数。",[10,5170,232],{},[14,5172,235],{"id":235},[10,5174,5175],{},"本篇目标是阅读和编写单层列表推导式。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,5177,242],{},{"title":69,"searchDepth":82,"depth":82,"links":5179},[5180,5181,5182,5183,5184,5185,5186,5187],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F21-python-list-comprehension",{"title":5045,"description":5050},"python-list-comprehension","posts\u002F20260817\u002F21-python-list-comprehension","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者阅读和编写单层列表推导式。",[255,5195,5196],"列表推导式","数据变换","DYwY-g7opVkSD48BGebht_TQcw8OOAuqViUZ7Ibzd6Q",{"id":5199,"title":5200,"body":5201,"category":255,"cover":256,"description":5205,"extension":257,"meta":5348,"navigation":85,"path":5349,"pinned":260,"publishedAt":261,"seo":5350,"slug":5351,"stem":5352,"summary":5353,"tags":5354,"updatedAt":261,"visible":85,"__hash__":5357},"posts\u002Fposts\u002F20260817\u002F22-python-function-basics.md","22｜定义并调用第一个函数",{"type":7,"value":5202,"toc":5338},[5203,5206,5208,5211,5213,5219,5222,5224,5235,5237,5239,5278,5280,5286,5288,5290,5305,5307,5315,5317,5329,5331,5333,5336],[10,5204,5205],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、18 篇。学完后，你应该能够把可复用逻辑封装为函数。",[14,5207,16],{"id":16},[10,5209,5210],{},"本篇只处理“定义并调用第一个函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5212,22],{"id":22},[10,5214,5215],{},[26,5216],{"alt":5217,"src":5218},"函数调用后回到原位置","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F22-function-call.svg",[10,5220,5221],{},"程序执行到函数调用时跳入函数体；函数体完成后回到原调用位置，继续执行后面的语句。定义函数本身不会自动运行函数体。",[14,5223,35],{"id":35},[37,5225,5226,5229,5232],{},[40,5227,5228],{},"函数名描述动作，使用小写字母和下划线。",[40,5230,5231],{},"函数定义要先执行，之后才能调用。",[40,5233,5234],{},"函数应围绕一个明确职责，不要把无关步骤塞进同一个函数。",[14,5236,59],{"id":59},[10,5238,62],{},[64,5240,5242],{"className":66,"code":5241,"language":68,"meta":69,"style":69},"def show_progress():\n    print(\"正在学习函数\")\n    print(\"本节完成 50%\")\n\nprint(\"调用前\")\nshow_progress()\nprint(\"调用后\")\n",[49,5243,5244,5249,5254,5259,5263,5268,5273],{"__ignoreMap":69},[73,5245,5246],{"class":75,"line":76},[73,5247,5248],{},"def show_progress():\n",[73,5250,5251],{"class":75,"line":82},[73,5252,5253],{},"    print(\"正在学习函数\")\n",[73,5255,5256],{"class":75,"line":89},[73,5257,5258],{},"    print(\"本节完成 50%\")\n",[73,5260,5261],{"class":75,"line":95},[73,5262,86],{"emptyLinePlaceholder":85},[73,5264,5265],{"class":75,"line":101},[73,5266,5267],{},"print(\"调用前\")\n",[73,5269,5270],{"class":75,"line":106},[73,5271,5272],{},"show_progress()\n",[73,5274,5275],{"class":75,"line":112},[73,5276,5277],{},"print(\"调用后\")\n",[10,5279,146],{},[64,5281,5284],{"className":5282,"code":5283,"language":152,"meta":69},[150],"调用前\n正在学习函数\n本节完成 50%\n调用后\n",[49,5285,5283],{"__ignoreMap":69},[10,5287,157],{},[14,5289,160],{"id":160},[162,5291,5292,5298],{},[40,5293,967,5294,5297],{},[49,5295,5296],{},"def"," 时创建函数对象并绑定名字，函数体此刻不会输出。",[40,5299,5300,5301,5304],{},"运行到 ",[49,5302,5303],{},"show_progress()"," 才进入函数体，执行两次输出，然后回到调用点继续“调用后”。",[14,5306,210],{"id":210},[37,5308,5309,5312],{},[40,5310,5311],{},"定义函数后忘记加括号调用，程序只保存函数而没有执行。",[40,5313,5314],{},"在函数定义之前调用同一名字；脚本按从上到下执行，调用时名字必须已经绑定。",[14,5316,221],{"id":221},[162,5318,5319,5326],{},[40,5320,5321,5322,5325],{},"定义 ",[49,5323,5324],{},"show_plan()"," 输出两行学习计划。",[40,5327,5328],{},"连续调用同一个函数两次，观察执行顺序。",[10,5330,232],{},[14,5332,235],{"id":235},[10,5334,5335],{},"本篇目标是把可复用逻辑封装为函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,5337,242],{},{"title":69,"searchDepth":82,"depth":82,"links":5339},[5340,5341,5342,5343,5344,5345,5346,5347],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F22-python-function-basics",{"title":5200,"description":5205},"python-function-basics","posts\u002F20260817\u002F22-python-function-basics","面向按顺序学习 Python 的初学者，本篇在第 16、18 篇知识上，帮助读者把可复用逻辑封装为函数。",[255,5355,5356],"函数","代码组织","2_F_bE82awC7citzv6RoL0IX_NS-H7QdS7UaGcD_c0g",{"id":5359,"title":5360,"body":5361,"category":255,"cover":256,"description":5365,"extension":257,"meta":5545,"navigation":85,"path":5546,"pinned":260,"publishedAt":261,"seo":5547,"slug":5548,"stem":5549,"summary":5550,"tags":5551,"updatedAt":261,"visible":85,"__hash__":5554},"posts\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope.md","23｜参数、返回值与局部变量",{"type":7,"value":5362,"toc":5533},[5363,5366,5368,5371,5373,5379,5386,5388,5405,5407,5409,5443,5445,5451,5453,5455,5476,5478,5481,5487,5497,5499,5514,5516,5524,5526,5528,5531],[10,5364,5365],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22 篇。学完后，你应该能够设计有输入和输出的函数。",[14,5367,16],{"id":16},[10,5369,5370],{},"本篇只处理“参数、返回值与局部变量”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5372,22],{"id":22},[10,5374,5375],{},[26,5376],{"alt":5377,"src":5378},"参数进入，返回值出来","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-parameter-return.svg",[10,5380,5381,5382,5385],{},"调用时实参绑定到形参，函数在自己的局部范围内计算，",[49,5383,5384],{},"return"," 把结果交还给调用方。打印和返回承担不同职责。",[14,5387,35],{"id":35},[37,5389,5390,5393,5396],{},[40,5391,5392],{},"形参出现在函数定义中，实参出现在函数调用中。",[40,5394,5395],{},"局部变量默认只在函数内部可见。",[40,5397,5398,5399,5401,5402,391],{},"没有显式 ",[49,5400,5384],{}," 的函数会返回 ",[49,5403,5404],{},"None",[14,5406,59],{"id":59},[10,5408,62],{},[64,5410,5412],{"className":66,"code":5411,"language":68,"meta":69,"style":69},"def calculate_total(price, count):\n    total = price * count\n    return total\n\nresult = calculate_total(25, 4)\nprint(result)\n",[49,5413,5414,5419,5424,5429,5433,5438],{"__ignoreMap":69},[73,5415,5416],{"class":75,"line":76},[73,5417,5418],{},"def calculate_total(price, count):\n",[73,5420,5421],{"class":75,"line":82},[73,5422,5423],{},"    total = price * count\n",[73,5425,5426],{"class":75,"line":89},[73,5427,5428],{},"    return total\n",[73,5430,5431],{"class":75,"line":95},[73,5432,86],{"emptyLinePlaceholder":85},[73,5434,5435],{"class":75,"line":101},[73,5436,5437],{},"result = calculate_total(25, 4)\n",[73,5439,5440],{"class":75,"line":106},[73,5441,5442],{},"print(result)\n",[10,5444,146],{},[64,5446,5449],{"className":5447,"code":5448,"language":152,"meta":69},[150],"100\n",[49,5450,5448],{"__ignoreMap":69},[10,5452,157],{},[14,5454,160],{"id":160},[162,5456,5457,5466],{},[40,5458,5459,5460,2284,5463,5465],{},"调用时 25 和 4 分别绑定到 ",[49,5461,5462],{},"price",[49,5464,4426],{},"，它们只在本次函数调用的局部范围中使用。",[40,5467,5468,5471,5472,5475],{},[49,5469,5470],{},"return total"," 把整数 100 交给调用表达式，调用方再把它绑定给 ",[49,5473,5474],{},"result"," 并输出。",[193,5477,195],{"id":195},[10,5479,5480],{},"局部变量只在本次函数调用期间存在，可以用调用范围图理解。",[10,5482,5483],{},[26,5484],{"alt":5485,"src":5486},"局部变量随一次调用存在","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F23-call-frame-lifetime.svg",[10,5488,5489,2284,5491,1186,5493,5496],{},[49,5490,5462],{},[49,5492,4426],{},[49,5494,5495],{},"total"," 属于这次调用的局部范围；返回后，调用方只接收到返回值。",[14,5498,210],{"id":210},[37,5500,5501,5508],{},[40,5502,5503,5504,5507],{},"在函数内部只 ",[49,5505,5506],{},"print(total)","，调用方却期待拿到可继续计算的返回值。",[40,5509,5510,5511,5513],{},"试图在函数外直接访问局部变量 ",[49,5512,5495],{},"，它的名字只在调用期间的局部作用域存在。",[14,5515,221],{"id":221},[162,5517,5518,5521],{},[40,5519,5520],{},"编写计算长方形面积的函数。",[40,5522,5523],{},"让函数返回结果后在调用方加上单位再输出。",[10,5525,232],{},[14,5527,235],{"id":235},[10,5529,5530],{},"本篇目标是设计有输入和输出的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,5532,242],{},{"title":69,"searchDepth":82,"depth":82,"links":5534},[5535,5536,5537,5538,5539,5542,5543,5544],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":5540},[5541],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F23-python-parameters-return-scope",{"title":5360,"description":5365},"python-parameters-return-scope","posts\u002F20260817\u002F23-python-parameters-return-scope","面向按顺序学习 Python 的初学者，本篇在第 22 篇知识上，帮助读者设计有输入和输出的函数。",[255,5552,5553],"参数","返回值","fnkrGFHavlLiT3OqjuGAupN8a6J5QMSFpvHuUCS2smM",{"id":5556,"title":5557,"body":5558,"category":255,"cover":256,"description":5562,"extension":257,"meta":5741,"navigation":85,"path":5742,"pinned":260,"publishedAt":261,"seo":5743,"slug":5744,"stem":5745,"summary":5746,"tags":5747,"updatedAt":261,"visible":85,"__hash__":5750},"posts\u002Fposts\u002F20260817\u002F24-python-function-arguments.md","24｜默认参数、关键字参数与可变参数",{"type":7,"value":5559,"toc":5729},[5560,5563,5565,5568,5570,5576,5579,5581,5598,5600,5602,5654,5656,5662,5664,5666,5683,5685,5688,5694,5697,5699,5710,5712,5720,5722,5724,5727],[10,5561,5562],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23、11、13 篇。学完后，你应该能够理解调用参数与函数签名的绑定规则。",[14,5564,16],{"id":16},[10,5566,5567],{},"本篇只处理“默认参数、关键字参数与可变参数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5569,22],{"id":22},[10,5571,5572],{},[26,5573],{"alt":5574,"src":5575},"调用参数如何绑定签名","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-argument-binding.svg",[10,5577,5578],{},"调用产生的实参需要绑定到函数签名中的形参。位置参数按顺序绑定，关键字参数按名称绑定，缺省位置才使用默认值。",[14,5580,35],{"id":35},[37,5582,5583,5586,5592],{},[40,5584,5585],{},"必需参数应放在有默认值的参数之前。",[40,5587,5588,5591],{},[49,5589,5590],{},"*args"," 在函数内部是元组，适合数量可变的位置参数。",[40,5593,5594,5597],{},[49,5595,5596],{},"**kwargs"," 在函数内部是字典；只在确实需要开放关键字集合时使用。",[14,5599,59],{"id":59},[10,5601,62],{},[64,5603,5605],{"className":66,"code":5604,"language":68,"meta":69,"style":69},"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",[49,5606,5607,5612,5617,5621,5626,5631,5635,5640,5645,5649],{"__ignoreMap":69},[73,5608,5609],{"class":75,"line":76},[73,5610,5611],{},"def build_title(name, level=\"基础\"):\n",[73,5613,5614],{"class":75,"line":82},[73,5615,5616],{},"    return name + \"｜\" + level\n",[73,5618,5619],{"class":75,"line":89},[73,5620,86],{"emptyLinePlaceholder":85},[73,5622,5623],{"class":75,"line":95},[73,5624,5625],{},"print(build_title(\"Python\"))\n",[73,5627,5628],{"class":75,"line":101},[73,5629,5630],{},"print(build_title(name=\"异常处理\", level=\"进阶\"))\n",[73,5632,5633],{"class":75,"line":106},[73,5634,86],{"emptyLinePlaceholder":85},[73,5636,5637],{"class":75,"line":112},[73,5638,5639],{},"def total(*numbers):\n",[73,5641,5642],{"class":75,"line":118},[73,5643,5644],{},"    return sum(numbers)\n",[73,5646,5647],{"class":75,"line":124},[73,5648,86],{"emptyLinePlaceholder":85},[73,5650,5651],{"class":75,"line":129},[73,5652,5653],{},"print(total(10, 20, 30))\n",[10,5655,146],{},[64,5657,5660],{"className":5658,"code":5659,"language":152,"meta":69},[150],"Python｜基础\n异常处理｜进阶\n60\n",[49,5661,5659],{"__ignoreMap":69},[10,5663,157],{},[14,5665,160],{"id":160},[162,5667,5668,5674],{},[40,5669,5670,5671,5673],{},"第一次调用只提供必需参数，",[49,5672,176],{}," 使用默认值；第二次按参数名绑定两个实参。",[40,5675,5676,5679,5680,391],{},[49,5677,5678],{},"*numbers"," 把多个位置实参收集为元组，函数再将元组交给 ",[49,5681,5682],{},"sum()",[193,5684,195],{"id":195},[10,5686,5687],{},"位置参数、关键字参数和默认值的绑定优先级可以拆成三个步骤。",[10,5689,5690],{},[26,5691],{"alt":5692,"src":5693},"实参与形参的绑定步骤","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F24-binding-cases.svg",[10,5695,5696],{},"先绑定调用方明确提供的实参，再检查是否重复或缺失，最后为未绑定的可选参数填入默认值。",[14,5698,210],{"id":210},[37,5700,5701,5707],{},[40,5702,5703,5704,5706],{},"把可变列表直接作为默认参数，导致不同调用共享同一个对象。基础写法优先使用 ",[49,5705,5404],{}," 再在函数内创建。",[40,5708,5709],{},"同时用位置和关键字给同一形参传值，解释器会报告重复绑定。",[14,5711,221],{"id":221},[162,5713,5714,5717],{},[40,5715,5716],{},"给问候函数增加默认称呼。",[40,5718,5719],{},"编写接收任意数量分数并返回总分的函数。",[10,5721,232],{},[14,5723,235],{"id":235},[10,5725,5726],{},"本篇目标是理解调用参数与函数签名的绑定规则。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,5728,242],{},{"title":69,"searchDepth":82,"depth":82,"links":5730},[5731,5732,5733,5734,5735,5738,5739,5740],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":5736},[5737],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F24-python-function-arguments",{"title":5557,"description":5562},"python-function-arguments","posts\u002F20260817\u002F24-python-function-arguments","面向按顺序学习 Python 的初学者，本篇在第 23、11、13 篇知识上，帮助读者理解调用参数与函数签名的绑定规则。",[255,5748,5749],"函数参数","函数签名","abpuuiOuHwpbMIdqL0XMsPQ9EEunRTyOQ594TxtB6N8",{"id":4,"title":5,"body":5752,"category":255,"cover":256,"description":12,"extension":257,"meta":5913,"navigation":85,"path":259,"pinned":260,"publishedAt":261,"seo":5914,"slug":263,"stem":264,"summary":265,"tags":5915,"updatedAt":261,"visible":85,"__hash__":269},{"type":7,"value":5753,"toc":5901},[5754,5756,5758,5760,5762,5766,5768,5770,5782,5784,5786,5838,5840,5845,5847,5849,5867,5869,5871,5875,5877,5879,5885,5887,5893,5895,5897,5899],[10,5755,12],{},[14,5757,16],{"id":16},[10,5759,19],{},[14,5761,22],{"id":22},[10,5763,5764],{},[26,5765],{"alt":28,"src":29},[10,5767,32],{},[14,5769,35],{"id":35},[37,5771,5772,5774,5776],{},[40,5773,42],{},[40,5775,45],{},[40,5777,5778,52,5780,56],{},[49,5779,51],{},[49,5781,55],{},[14,5783,59],{"id":59},[10,5785,62],{},[64,5787,5788],{"className":66,"code":67,"language":68,"meta":69,"style":69},[49,5789,5790,5794,5798,5802,5806,5810,5814,5818,5822,5826,5830,5834],{"__ignoreMap":69},[73,5791,5792],{"class":75,"line":76},[73,5793,79],{},[73,5795,5796],{"class":75,"line":82},[73,5797,86],{"emptyLinePlaceholder":85},[73,5799,5800],{"class":75,"line":89},[73,5801,92],{},[73,5803,5804],{"class":75,"line":95},[73,5805,98],{},[73,5807,5808],{"class":75,"line":101},[73,5809,86],{"emptyLinePlaceholder":85},[73,5811,5812],{"class":75,"line":106},[73,5813,109],{},[73,5815,5816],{"class":75,"line":112},[73,5817,115],{},[73,5819,5820],{"class":75,"line":118},[73,5821,121],{},[73,5823,5824],{"class":75,"line":124},[73,5825,86],{"emptyLinePlaceholder":85},[73,5827,5828],{"class":75,"line":129},[73,5829,132],{},[73,5831,5832],{"class":75,"line":135},[73,5833,86],{"emptyLinePlaceholder":85},[73,5835,5836],{"class":75,"line":140},[73,5837,143],{},[10,5839,146],{},[64,5841,5843],{"className":5842,"code":151,"language":152,"meta":69},[150],[49,5844,151],{"__ignoreMap":69},[10,5846,157],{},[14,5848,160],{"id":160},[162,5850,5851,5861],{},[40,5852,5853,169,5855,173,5857,177,5859,181],{},[49,5854,168],{},[49,5856,172],{},[49,5858,176],{},[49,5860,180],{},[40,5862,5863,187,5865,191],{},[49,5864,186],{},[49,5866,190],{},[193,5868,195],{"id":195},[10,5870,198],{},[10,5872,5873],{},[26,5874],{"alt":203,"src":204},[10,5876,207],{},[14,5878,210],{"id":210},[37,5880,5881,5883],{},[40,5882,215],{},[40,5884,218],{},[14,5886,221],{"id":221},[162,5888,5889,5891],{},[40,5890,226],{},[40,5892,229],{},[10,5894,232],{},[14,5896,235],{"id":235},[10,5898,238],{},[240,5900,242],{},{"title":69,"searchDepth":82,"depth":82,"links":5902},[5903,5904,5905,5906,5907,5910,5911,5912],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":5908},[5909],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5,"description":12},[255,267,268],{"id":5917,"title":5918,"body":5919,"category":255,"cover":256,"description":5923,"extension":257,"meta":6073,"navigation":85,"path":6074,"pinned":260,"publishedAt":261,"seo":6075,"slug":6076,"stem":6077,"summary":6078,"tags":6079,"updatedAt":261,"visible":85,"__hash__":6082},"posts\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints.md","26｜文档字符串与类型注解",{"type":7,"value":5920,"toc":6063},[5921,5924,5926,5929,5931,5937,5940,5942,5961,5963,5965,5999,6001,6007,6009,6011,6026,6028,6040,6042,6054,6056,6058,6061],[10,5922,5923],{},"这套课程按知识依赖排列。本篇的前置知识是：第 23 篇。学完后，你应该能够给函数写清输入、输出和用途。",[14,5925,16],{"id":16},[10,5927,5928],{},"本篇只处理“文档字符串与类型注解”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,5930,22],{"id":22},[10,5932,5933],{},[26,5934],{"alt":5935,"src":5936},"类型注解描述但不强制","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F26-type-hints.svg",[10,5938,5939],{},"类型注解为读者和工具描述预期类型，但 Python 默认不会仅凭注解阻止不同类型的实参进入函数。",[14,5941,35],{"id":35},[37,5943,5944,5947,5950],{},[40,5945,5946],{},"文档字符串紧跟在函数定义后的第一条语句。",[40,5948,5949],{},"注解表达接口意图，不代替输入校验和测试。",[40,5951,5952,5953,2284,5955,2284,5957,5960],{},"基础注解优先使用 ",[49,5954,2287],{},[49,5956,2453],{},[49,5958,5959],{},"list[str]"," 等直接写法。",[14,5962,59],{"id":59},[10,5964,62],{},[64,5966,5968],{"className":66,"code":5967,"language":68,"meta":69,"style":69},"def format_score(name: str, score: int) -> str:\n    \"\"\"返回带姓名的分数文本。\"\"\"\n    return name + \"：\" + str(score)\n\nprint(format_score(\"小郑\", 95))\nprint(format_score.__doc__)\n",[49,5969,5970,5975,5980,5985,5989,5994],{"__ignoreMap":69},[73,5971,5972],{"class":75,"line":76},[73,5973,5974],{},"def format_score(name: str, score: int) -> str:\n",[73,5976,5977],{"class":75,"line":82},[73,5978,5979],{},"    \"\"\"返回带姓名的分数文本。\"\"\"\n",[73,5981,5982],{"class":75,"line":89},[73,5983,5984],{},"    return name + \"：\" + str(score)\n",[73,5986,5987],{"class":75,"line":95},[73,5988,86],{"emptyLinePlaceholder":85},[73,5990,5991],{"class":75,"line":101},[73,5992,5993],{},"print(format_score(\"小郑\", 95))\n",[73,5995,5996],{"class":75,"line":106},[73,5997,5998],{},"print(format_score.__doc__)\n",[10,6000,146],{},[64,6002,6005],{"className":6003,"code":6004,"language":152,"meta":69},[150],"小郑：95\n返回带姓名的分数文本。\n",[49,6006,6004],{"__ignoreMap":69},[10,6008,157],{},[14,6010,160],{"id":160},[162,6012,6013,6023],{},[40,6014,6015,6016,6019,6020,6022],{},"函数签名说明 ",[49,6017,6018],{},"name"," 预期为字符串、",[49,6021,2273],{}," 预期为整数，返回值预期为字符串。",[40,6024,6025],{},"运行时仍按函数体实际表达式执行；注解主要服务读者、编辑器和静态检查工具。",[14,6027,210],{"id":210},[37,6029,6030,6037],{},[40,6031,6032,6033,6036],{},"认为加了 ",[49,6034,6035],{},"score: int"," 后，Python 会自动拒绝字符串。默认运行时不会这样校验。",[40,6038,6039],{},"注解写得比接口本身更复杂，反而增加初学者负担；先准确表达基础容器和可选值。",[14,6041,221],{"id":221},[162,6043,6044,6047],{},[40,6045,6046],{},"为面积函数补充参数和返回值注解。",[40,6048,6049,6050,6053],{},"通过 ",[49,6051,6052],{},"函数名.__doc__"," 查看文档字符串。",[10,6055,232],{},[14,6057,235],{"id":235},[10,6059,6060],{},"本篇目标是给函数写清输入、输出和用途。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,6062,242],{},{"title":69,"searchDepth":82,"depth":82,"links":6064},[6065,6066,6067,6068,6069,6070,6071,6072],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F26-python-docstrings-type-hints",{"title":5918,"description":5923},"python-docstrings-type-hints","posts\u002F20260817\u002F26-python-docstrings-type-hints","面向按顺序学习 Python 的初学者，本篇在第 23 篇知识上，帮助读者给函数写清输入、输出和用途。",[255,6080,6081],"类型注解","文档字符串","EX5IfPAdDzGtNwFnrXw0U7ZKckNBAPGVagcv7YFcPGA",{"id":6084,"title":6085,"body":6086,"category":255,"cover":256,"description":6090,"extension":257,"meta":6317,"navigation":85,"path":6318,"pinned":260,"publishedAt":261,"seo":6319,"slug":6320,"stem":6321,"summary":6322,"tags":6323,"updatedAt":261,"visible":85,"__hash__":6326},"posts\u002Fposts\u002F20260817\u002F27-python-modules-import-name.md","27｜模块、import 与 __name__",{"type":7,"value":6087,"toc":6305},[6088,6091,6093,6099,6101,6107,6118,6120,6138,6140,6147,6176,6183,6202,6211,6213,6219,6221,6223,6246,6248,6251,6257,6263,6265,6281,6283,6296,6298,6300,6303],[10,6089,6090],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、25 篇。学完后，你应该能够把函数拆到不同文件并控制脚本入口。",[14,6092,16],{"id":16},[10,6094,6095,6096,6098],{},"本篇只处理“模块、import 与 ",[324,6097,6018],{},"”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6100,22],{"id":22},[10,6102,6103],{},[26,6104],{"alt":6105,"src":6106},"name 决定入口代码","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-module-name.svg",[10,6108,6109,6110,6113,6114,6117],{},"同一个文件直接运行时 ",[49,6111,6112],{},"__name__"," 等于 ",[49,6115,6116],{},"\"__main__\"","；被其他文件导入时，它等于模块名。入口判断可以避免导入时自动执行演示代码。",[14,6119,35],{"id":35},[37,6121,6122,6128,6131],{},[40,6123,6124,6125,6127],{},"一个 ",[49,6126,1200],{}," 文件就是一个模块。",[40,6129,6130],{},"导入时模块顶层代码会执行一次，因此顶层应以定义和常量为主。",[40,6132,6133,6134,6137],{},"避免使用 ",[49,6135,6136],{},"from module import *","，它会让名字来源不清楚。",[14,6139,59],{"id":59},[10,6141,6142,6143,6146],{},"先在同一个目录中创建两个文件。把函数放进 ",[49,6144,6145],{},"calculator.py","：",[64,6148,6150],{"className":66,"code":6149,"language":68,"meta":69,"style":69},"def add(left, right):\n    return left + right\n\nif __name__ == \"__main__\":\n    print(add(2, 3))\n",[49,6151,6152,6157,6162,6166,6171],{"__ignoreMap":69},[73,6153,6154],{"class":75,"line":76},[73,6155,6156],{},"def add(left, right):\n",[73,6158,6159],{"class":75,"line":82},[73,6160,6161],{},"    return left + right\n",[73,6163,6164],{"class":75,"line":89},[73,6165,86],{"emptyLinePlaceholder":85},[73,6167,6168],{"class":75,"line":95},[73,6169,6170],{},"if __name__ == \"__main__\":\n",[73,6172,6173],{"class":75,"line":101},[73,6174,6175],{},"    print(add(2, 3))\n",[10,6177,6178,6179,6182],{},"再创建 ",[49,6180,6181],{},"app.py","，从模块中导入函数：",[64,6184,6186],{"className":66,"code":6185,"language":68,"meta":69,"style":69},"from calculator import add\n\nprint(add(10, 20))\n",[49,6187,6188,6193,6197],{"__ignoreMap":69},[73,6189,6190],{"class":75,"line":76},[73,6191,6192],{},"from calculator import add\n",[73,6194,6195],{"class":75,"line":82},[73,6196,86],{"emptyLinePlaceholder":85},[73,6198,6199],{"class":75,"line":89},[73,6200,6201],{},"print(add(10, 20))\n",[10,6203,6204,6205,1186,6208,391],{},"分别执行 ",[49,6206,6207],{},"python3 calculator.py",[49,6209,6210],{},"python3 app.py",[10,6212,146],{},[64,6214,6217],{"className":6215,"code":6216,"language":152,"meta":69},[150],"直接运行 calculator.py 输出 5；运行 app.py 输出 30\n",[49,6218,6216],{"__ignoreMap":69},[10,6220,157],{},[14,6222,160],{"id":160},[162,6224,6225,6235],{},[40,6226,6227,6228,6230,6231,6234],{},"直接运行 ",[49,6229,6145],{}," 时，模块名是 ",[49,6232,6233],{},"__main__","，入口代码输出 5。",[40,6236,6237,6239,6240,6242,6243,6245],{},[49,6238,6181],{}," 导入模块时，",[49,6241,6145],{}," 的函数定义会执行，但入口判断为假；随后 ",[49,6244,6181],{}," 调用函数输出 30。",[193,6247,195],{"id":195},[10,6249,6250],{},"同一个模块在“直接运行”和“被导入”两种方式下，入口判断结果不同。",[10,6252,6253],{},[26,6254],{"alt":6255,"src":6256},"直接运行与导入的入口差异","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F27-direct-vs-import.svg",[10,6258,6259,6260,6262],{},"两条路径都会建立函数定义；只有直接运行时才执行 ",[49,6261,6233],{}," 保护下的演示代码。",[14,6264,210],{"id":210},[37,6266,6267,6274],{},[40,6268,6269,6270,1186,6272,391],{},"把两个示例文件粘成一个文件运行。应按注释分别保存为 ",[49,6271,6145],{},[49,6273,6181],{},[40,6275,6276,6277,6280],{},"模块名与标准库或项目其他文件重名，例如命名为 ",[49,6278,6279],{},"json.py","，导致导入目标被遮蔽。",[14,6282,221],{"id":221},[162,6284,6285,6291],{},[40,6286,2381,6287,6290],{},[49,6288,6289],{},"text_tools.py"," 并导出一个格式化函数。",[40,6292,6293,6294,391],{},"分别直接运行模块和从另一个脚本导入，输出 ",[49,6295,6112],{},[10,6297,232],{},[14,6299,235],{"id":235},[10,6301,6302],{},"本篇目标是把函数拆到不同文件并控制脚本入口。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,6304,242],{},{"title":69,"searchDepth":82,"depth":82,"links":6306},[6307,6308,6309,6310,6311,6314,6315,6316],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":6312},[6313],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F27-python-modules-import-name",{"title":6085,"description":6090},"python-modules-import-name","posts\u002F20260817\u002F27-python-modules-import-name","面向按顺序学习 Python 的初学者，本篇在第 22、25 篇知识上，帮助读者把函数拆到不同文件并控制脚本入口。",[255,6324,6325],"模块","import","bhFSv9OJ-GA6ww_aKkbpy7eWz_aFbSkk-d9KegnkiuE",{"id":6328,"title":6329,"body":6330,"category":255,"cover":256,"description":6334,"extension":257,"meta":6499,"navigation":85,"path":6500,"pinned":260,"publishedAt":261,"seo":6501,"slug":6502,"stem":6503,"summary":6504,"tags":6505,"updatedAt":261,"visible":85,"__hash__":6507},"posts\u002Fposts\u002F20260817\u002F28-python-package-venv-pip.md","28｜包、虚拟环境与 pip 依赖管理",{"type":7,"value":6331,"toc":6489},[6332,6335,6337,6340,6342,6348,6351,6353,6367,6369,6371,6417,6419,6425,6427,6429,6455,6457,6467,6469,6480,6482,6484,6487],[10,6333,6334],{},"这套课程按知识依赖排列。本篇的前置知识是：第 02、27 篇。学完后，你应该能够隔离项目解释器和第三方依赖。",[14,6336,16],{"id":16},[10,6338,6339],{},"本篇只处理“包、虚拟环境与 pip 依赖管理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6341,22],{"id":22},[10,6343,6344],{},[26,6345],{"alt":6346,"src":6347},"虚拟环境隔离项目依赖","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F28-venv-boundary.svg",[10,6349,6350],{},"虚拟环境在项目边界内提供独立解释器入口和包目录。激活只是在当前终端调整命令查找顺序，不会改变 Python 语言本身。",[14,6352,35],{"id":35},[37,6354,6355,6361,6364],{},[40,6356,6357,6360],{},[49,6358,6359],{},".venv"," 是常见目录名，不应提交到 Git。",[40,6362,6363],{},"安装包前先确认当前解释器路径，避免装进另一个环境。",[40,6365,6366],{},"本基础系列示例优先使用标准库，不要求安装第三方包。",[14,6368,59],{"id":59},[10,6370,1603],{},[64,6372,6374],{"className":620,"code":6373,"language":622,"meta":69,"style":69},"python3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython --version\npython -m pip --version\ndeactivate\n",[49,6375,6376,6388,6396,6402,6412],{"__ignoreMap":69},[73,6377,6378,6380,6382,6385],{"class":75,"line":76},[73,6379,720],{"class":629},[73,6381,662],{"class":632},[73,6383,6384],{"class":665}," venv",[73,6386,6387],{"class":665}," .venv\n",[73,6389,6390,6393],{"class":75,"line":82},[73,6391,6392],{"class":632},"source",[73,6394,6395],{"class":665}," .venv\u002Fbin\u002Factivate\n",[73,6397,6398,6400],{"class":75,"line":89},[73,6399,68],{"class":629},[73,6401,633],{"class":632},[73,6403,6404,6406,6408,6410],{"class":75,"line":95},[73,6405,68],{"class":629},[73,6407,662],{"class":632},[73,6409,666],{"class":665},[73,6411,633],{"class":632},[73,6413,6414],{"class":75,"line":101},[73,6415,6416],{"class":629},"deactivate\n",[10,6418,146],{},[64,6420,6423],{"className":6421,"code":6422,"language":152,"meta":69},[150],"Python 和 pip 的路径应指向当前项目的 .venv\n",[49,6424,6422],{"__ignoreMap":69},[10,6426,157],{},[14,6428,160],{"id":160},[162,6430,6431,6440],{},[40,6432,6433,6436,6437,6439],{},[49,6434,6435],{},"venv"," 根据当前 ",[49,6438,720],{}," 创建项目自己的环境目录，包含解释器入口和包安装位置。",[40,6441,6442,6443,52,6445,6448,6449,3754,6451,6454],{},"激活后 ",[49,6444,68],{},[49,6446,6447],{},"python -m pip"," 优先指向 ",[49,6450,6359],{},[49,6452,6453],{},"deactivate"," 只恢复当前终端的命令查找。",[14,6456,210],{"id":210},[37,6458,6459,6462],{},[40,6460,6461],{},"创建环境后忘记激活，依赖被安装到全局或另一个环境。",[40,6463,3493,6464,6466],{},[49,6465,6359],{}," 提交到 Git。环境应通过依赖清单重建，不应跨机器复制。",[14,6468,221],{"id":221},[162,6470,6471,6477],{},[40,6472,6473,6474,391],{},"创建虚拟环境并记录激活前后的 ",[49,6475,6476],{},"which python",[40,6478,6479],{},"退出后重新激活，确认项目环境可以重复使用。",[10,6481,232],{},[14,6483,235],{"id":235},[10,6485,6486],{},"本篇目标是隔离项目解释器和第三方依赖。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,6488,1687],{},{"title":69,"searchDepth":82,"depth":82,"links":6490},[6491,6492,6493,6494,6495,6496,6497,6498],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F28-python-package-venv-pip",{"title":6329,"description":6334},"python-package-venv-pip","posts\u002F20260817\u002F28-python-package-venv-pip","面向按顺序学习 Python 的初学者，本篇在第 02、27 篇知识上，帮助读者隔离项目解释器和第三方依赖。",[255,6506,290],"虚拟环境","MahwlwoikelUZdWjVweR9GWO6Wx1jVlyqHWgC6aTSn0",{"id":6509,"title":6510,"body":6511,"category":255,"cover":256,"description":6515,"extension":257,"meta":6703,"navigation":85,"path":6704,"pinned":260,"publishedAt":261,"seo":6705,"slug":6706,"stem":6707,"summary":6708,"tags":6709,"updatedAt":261,"visible":85,"__hash__":6712},"posts\u002Fposts\u002F20260817\u002F29-python-pathlib-paths.md","29｜使用 pathlib 管理文件路径",{"type":7,"value":6512,"toc":6693},[6513,6516,6518,6521,6523,6529,6538,6540,6564,6566,6568,6621,6623,6629,6631,6633,6649,6651,6670,6672,6684,6686,6688,6691],[10,6514,6515],{},"这套课程按知识依赖排列。本篇的前置知识是：第 27 篇。学完后，你应该能够组合、检查和创建跨平台路径。",[14,6517,16],{"id":16},[10,6519,6520],{},"本篇只处理“使用 pathlib 管理文件路径”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6522,22],{"id":22},[10,6524,6525],{},[26,6526],{"alt":6527,"src":6528},"路径由片段逐级组合","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F29-pathlib-parts.svg",[10,6530,6531,6534,6535,6537],{},[49,6532,6533],{},"Path"," 使用 ",[49,6536,2463],{}," 运算符逐级组合路径片段，得到新的路径对象；此时只是在描述位置，不代表文件已经存在。",[14,6539,35],{"id":35},[37,6541,6542,6545,6557],{},[40,6543,6544],{},"路径对象把字符串拼接和平台分隔符细节封装起来。",[40,6546,6547,2284,6550,2284,6553,6556],{},[49,6548,6549],{},"exists()",[49,6551,6552],{},"is_file()",[49,6554,6555],{},"is_dir()"," 检查真实文件系统状态。",[40,6558,6559,6560,6563],{},"创建目录前明确目标；",[49,6561,6562],{},"mkdir(parents=True, exist_ok=True)"," 可创建必要父目录。",[14,6565,59],{"id":59},[10,6567,62],{},[64,6569,6571],{"className":66,"code":6570,"language":68,"meta":69,"style":69},"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",[49,6572,6573,6578,6582,6587,6592,6597,6601,6606,6611,6616],{"__ignoreMap":69},[73,6574,6575],{"class":75,"line":76},[73,6576,6577],{},"from pathlib import Path\n",[73,6579,6580],{"class":75,"line":82},[73,6581,86],{"emptyLinePlaceholder":85},[73,6583,6584],{"class":75,"line":89},[73,6585,6586],{},"project = Path.cwd()\n",[73,6588,6589],{"class":75,"line":95},[73,6590,6591],{},"data_dir = project \u002F \"data\"\n",[73,6593,6594],{"class":75,"line":101},[73,6595,6596],{},"file_path = data_dir \u002F \"records.json\"\n",[73,6598,6599],{"class":75,"line":106},[73,6600,86],{"emptyLinePlaceholder":85},[73,6602,6603],{"class":75,"line":112},[73,6604,6605],{},"print(project)\n",[73,6607,6608],{"class":75,"line":118},[73,6609,6610],{},"print(file_path.name)\n",[73,6612,6613],{"class":75,"line":124},[73,6614,6615],{},"print(file_path.suffix)\n",[73,6617,6618],{"class":75,"line":129},[73,6619,6620],{},"print(file_path.exists())\n",[10,6622,146],{},[64,6624,6627],{"className":6625,"code":6626,"language":152,"meta":69},[150],"显示当前项目路径、records.json、.json 和存在状态\n",[49,6628,6626],{"__ignoreMap":69},[10,6630,157],{},[14,6632,160],{"id":160},[162,6634,6635,6641],{},[40,6636,6637,6640],{},[49,6638,6639],{},"Path.cwd()"," 读取运行脚本时的当前目录，不一定等于脚本文件所在目录。",[40,6642,2366,6643,6645,6646,6648],{},[49,6644,2463],{}," 组合路径片段只创建新的 ",[49,6647,6533],{}," 对象；直到读写或创建操作发生，文件系统才可能变化。",[14,6650,210],{"id":210},[37,6652,6653,6661],{},[40,6654,3493,6655,6657,6658,6660],{},[49,6656,6533],{}," 对象存在当成真实文件存在，仍需调用 ",[49,6659,6549],{}," 等方法确认。",[40,6662,6663,6664,1038,6666,6669],{},"手工拼接 ",[49,6665,2463],{},[49,6667,6668],{},"\\"," 分隔符，降低跨平台可读性。",[14,6671,221],{"id":221},[162,6673,6674,6681],{},[40,6675,6676,6677,6680],{},"组合 ",[49,6678,6679],{},"output\u002Freport.txt"," 路径但先不创建文件。",[40,6682,6683],{},"输出路径的父目录、文件名和扩展名。",[10,6685,232],{},[14,6687,235],{"id":235},[10,6689,6690],{},"本篇目标是组合、检查和创建跨平台路径。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,6692,242],{},{"title":69,"searchDepth":82,"depth":82,"links":6694},[6695,6696,6697,6698,6699,6700,6701,6702],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F29-python-pathlib-paths",{"title":6510,"description":6515},"python-pathlib-paths","posts\u002F20260817\u002F29-python-pathlib-paths","面向按顺序学习 Python 的初学者，本篇在第 27 篇知识上，帮助读者组合、检查和创建跨平台路径。",[255,6710,6711],"pathlib","文件路径","PHuyO5r-joDw7vGk9b5F3e-BXQ5bfH82oSi1nU4RwYM",{"id":6714,"title":6715,"body":6716,"category":255,"cover":256,"description":6720,"extension":257,"meta":6898,"navigation":85,"path":6899,"pinned":260,"publishedAt":261,"seo":6900,"slug":6901,"stem":6902,"summary":6903,"tags":6904,"updatedAt":261,"visible":85,"__hash__":6907},"posts\u002Fposts\u002F20260817\u002F30-python-text-files-encoding.md","30｜文本文件读写与字符编码",{"type":7,"value":6717,"toc":6888},[6718,6721,6723,6726,6728,6734,6737,6739,6767,6769,6771,6828,6830,6836,6838,6840,6851,6853,6866,6868,6879,6881,6883,6886],[10,6719,6720],{},"这套课程按知识依赖排列。本篇的前置知识是：第 29、22 篇。学完后，你应该能够显式使用 UTF-8 安全读写文本。",[14,6722,16],{"id":16},[10,6724,6725],{},"本篇只处理“文本文件读写与字符编码”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6727,22],{"id":22},[10,6729,6730],{},[26,6731],{"alt":6732,"src":6733},"字符通过编码变成文件字节","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F30-text-encoding.svg",[10,6735,6736],{},"Python 字符串写入文件前按 UTF-8 编码成字节，读取时再把字节解码成字符串。读写双方编码不一致会产生乱码或解码错误。",[14,6738,35],{"id":35},[37,6740,6741,6747,6756],{},[40,6742,6743,6746],{},[49,6744,6745],{},"w"," 模式会截断原文件，写入前必须确认目标。",[40,6748,6749,6752,6753,391],{},[49,6750,6751],{},"r"," 模式读取不存在文件会产生 ",[49,6754,6755],{},"FileNotFoundError",[40,6757,6758,6759,6762,6763,6766],{},"本篇显式调用 ",[49,6760,6761],{},"close()","；第 34 篇会用 ",[49,6764,6765],{},"with"," 更可靠地管理关闭动作。",[14,6768,59],{"id":59},[10,6770,62],{},[64,6772,6774],{"className":66,"code":6773,"language":68,"meta":69,"style":69},"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",[49,6775,6776,6780,6784,6789,6794,6799,6804,6808,6813,6818,6823],{"__ignoreMap":69},[73,6777,6778],{"class":75,"line":76},[73,6779,6577],{},[73,6781,6782],{"class":75,"line":82},[73,6783,86],{"emptyLinePlaceholder":85},[73,6785,6786],{"class":75,"line":89},[73,6787,6788],{},"file_path = Path(\"notes.txt\")\n",[73,6790,6791],{"class":75,"line":95},[73,6792,6793],{},"writer = file_path.open(\"w\", encoding=\"utf-8\")\n",[73,6795,6796],{"class":75,"line":101},[73,6797,6798],{},"writer.write(\"变量\\n循环\\n函数\\n\")\n",[73,6800,6801],{"class":75,"line":106},[73,6802,6803],{},"writer.close()\n",[73,6805,6806],{"class":75,"line":112},[73,6807,86],{"emptyLinePlaceholder":85},[73,6809,6810],{"class":75,"line":118},[73,6811,6812],{},"reader = file_path.open(\"r\", encoding=\"utf-8\")\n",[73,6814,6815],{"class":75,"line":124},[73,6816,6817],{},"content = reader.read()\n",[73,6819,6820],{"class":75,"line":129},[73,6821,6822],{},"reader.close()\n",[73,6824,6825],{"class":75,"line":135},[73,6826,6827],{},"print(content)\n",[10,6829,146],{},[64,6831,6834],{"className":6832,"code":6833,"language":152,"meta":69},[150],"变量\n循环\n函数\n",[49,6835,6833],{"__ignoreMap":69},[10,6837,157],{},[14,6839,160],{"id":160},[162,6841,6842,6848],{},[40,6843,6844,6845,6847],{},"写入端以 UTF-8 把三个中文字符串和换行编码为字节，",[49,6846,6761],{}," 确保缓冲内容交给文件系统。",[40,6849,6850],{},"读取端用相同编码把字节还原为字符串；显式关闭后才结束资源占用。",[14,6852,210],{"id":210},[37,6854,6855,6860],{},[40,6856,2366,6857,6859],{},[49,6858,6745],{}," 模式打开重要文件却未确认覆盖风险。",[40,6861,6862,6863,391],{},"依赖系统默认编码；跨机器或跨工具交换中文文件时应显式写 ",[49,6864,6865],{},"encoding=\"utf-8\"",[14,6867,221],{"id":221},[162,6869,6870,6873],{},[40,6871,6872],{},"写入三行学习记录并读取。",[40,6874,6875,6876,6878],{},"改用 ",[49,6877,365],{}," 模式追加一行，确认原内容仍保留。",[10,6880,232],{},[14,6882,235],{"id":235},[10,6884,6885],{},"本篇目标是显式使用 UTF-8 安全读写文本。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,6887,242],{},{"title":69,"searchDepth":82,"depth":82,"links":6889},[6890,6891,6892,6893,6894,6895,6896,6897],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F30-python-text-files-encoding",{"title":6715,"description":6720},"python-text-files-encoding","posts\u002F20260817\u002F30-python-text-files-encoding","面向按顺序学习 Python 的初学者，本篇在第 29、22 篇知识上，帮助读者显式使用 UTF-8 安全读写文本。",[255,6905,6906],"文件读写","UTF-8","qWTwAdOJwuDSNmawyrgtgB7vwnPnhvZoMJfWrx_G_co",{"id":6909,"title":6910,"body":6911,"category":255,"cover":256,"description":6915,"extension":257,"meta":7082,"navigation":85,"path":7083,"pinned":260,"publishedAt":261,"seo":7084,"slug":7085,"stem":7086,"summary":7087,"tags":7088,"updatedAt":261,"visible":85,"__hash__":7091},"posts\u002Fposts\u002F20260817\u002F31-python-json-data.md","31｜使用 JSON 保存结构化数据",{"type":7,"value":6912,"toc":7072},[6913,6916,6918,6921,6923,6929,6939,6941,6955,6957,6959,7019,7021,7027,7029,7031,7043,7045,7053,7055,7063,7065,7067,7070],[10,6914,6915],{},"这套课程按知识依赖排列。本篇的前置知识是：第 13、30 篇。学完后，你应该能够在 Python 对象和 JSON 文本之间转换。",[14,6917,16],{"id":16},[10,6919,6920],{},"本篇只处理“使用 JSON 保存结构化数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,6922,22],{"id":22},[10,6924,6925],{},[26,6926],{"alt":6927,"src":6928},"Python 对象与 JSON 文本互转","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F31-json-roundtrip.svg",[10,6930,6931,6934,6935,6938],{},[49,6932,6933],{},"json.dump"," 把字典和列表序列化为 JSON 文本，",[49,6936,6937],{},"json.load"," 再把文本解析回 Python 对象。它们不是简单的字符串替换。",[14,6940,35],{"id":35},[37,6942,6943,6946,6952],{},[40,6944,6945],{},"JSON 对象对应 Python 字典，JSON 数组对应列表。",[40,6947,6948,6951],{},[49,6949,6950],{},"ensure_ascii=False"," 让中文以可读字符写入。",[40,6953,6954],{},"JSON 不支持任意 Python 对象；日期和自定义类需要先转换为基础结构。",[14,6956,59],{"id":59},[10,6958,62],{},[64,6960,6962],{"className":66,"code":6961,"language":68,"meta":69,"style":69},"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",[49,6963,6964,6969,6973,6978,6982,6987,6992,6996,7000,7005,7010,7014],{"__ignoreMap":69},[73,6965,6966],{"class":75,"line":76},[73,6967,6968],{},"import json\n",[73,6970,6971],{"class":75,"line":82},[73,6972,86],{"emptyLinePlaceholder":85},[73,6974,6975],{"class":75,"line":89},[73,6976,6977],{},"record = {\"course\": \"Python\", \"progress\": 60, \"done\": False}\n",[73,6979,6980],{"class":75,"line":95},[73,6981,86],{"emptyLinePlaceholder":85},[73,6983,6984],{"class":75,"line":101},[73,6985,6986],{},"writer = open(\"record.json\", \"w\", encoding=\"utf-8\")\n",[73,6988,6989],{"class":75,"line":106},[73,6990,6991],{},"json.dump(record, writer, ensure_ascii=False, indent=2)\n",[73,6993,6994],{"class":75,"line":112},[73,6995,6803],{},[73,6997,6998],{"class":75,"line":118},[73,6999,86],{"emptyLinePlaceholder":85},[73,7001,7002],{"class":75,"line":124},[73,7003,7004],{},"reader = open(\"record.json\", \"r\", encoding=\"utf-8\")\n",[73,7006,7007],{"class":75,"line":129},[73,7008,7009],{},"loaded = json.load(reader)\n",[73,7011,7012],{"class":75,"line":135},[73,7013,6822],{},[73,7015,7016],{"class":75,"line":140},[73,7017,7018],{},"print(loaded[\"course\"], loaded[\"progress\"])\n",[10,7020,146],{},[64,7022,7025],{"className":7023,"code":7024,"language":152,"meta":69},[150],"Python 60\n",[49,7026,7024],{"__ignoreMap":69},[10,7028,157],{},[14,7030,160],{"id":160},[162,7032,7033,7038],{},[40,7034,7035,7037],{},[49,7036,6933],{}," 遍历字典的基础类型，把它们写成符合 JSON 语法的文本。",[40,7039,7040,7042],{},[49,7041,6937],{}," 从文件解析文本，重新创建 Python 字典；读取结果不是原对象本身。",[14,7044,210],{"id":210},[37,7046,7047,7050],{},[40,7048,7049],{},"把 JSON 当作可以保存任意 Python 对象的格式，自定义类和日期需要先转换。",[40,7051,7052],{},"手工字符串拼接 JSON，容易产生转义、逗号和引号错误。",[14,7054,221],{"id":221},[162,7056,7057,7060],{},[40,7058,7059],{},"保存包含两条学习记录的列表。",[40,7061,7062],{},"读取后修改进度，再重新写回文件。",[10,7064,232],{},[14,7066,235],{"id":235},[10,7068,7069],{},"本篇目标是在 Python 对象和 JSON 文本之间转换。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,7071,242],{},{"title":69,"searchDepth":82,"depth":82,"links":7073},[7074,7075,7076,7077,7078,7079,7080,7081],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F31-python-json-data",{"title":6910,"description":6915},"python-json-data","posts\u002F20260817\u002F31-python-json-data","面向按顺序学习 Python 的初学者，本篇在第 13、30 篇知识上，帮助读者在 Python 对象和 JSON 文本之间转换。",[255,7089,7090],"JSON","数据持久化","cItgMs1zYJYeKM7m24IW9h-zqbQx1OyffwsrwNhyhYk",{"id":7093,"title":7094,"body":7095,"category":255,"cover":256,"description":7099,"extension":257,"meta":7283,"navigation":85,"path":7284,"pinned":260,"publishedAt":261,"seo":7285,"slug":7286,"stem":7287,"summary":7288,"tags":7289,"updatedAt":261,"visible":85,"__hash__":7292},"posts\u002Fposts\u002F20260817\u002F32-python-csv-tables.md","32｜使用 CSV 读写表格数据",{"type":7,"value":7096,"toc":7273},[7097,7100,7102,7105,7107,7113,7119,7121,7143,7145,7147,7210,7212,7218,7220,7222,7238,7240,7254,7256,7264,7266,7268,7271],[10,7098,7099],{},"这套课程按知识依赖排列。本篇的前置知识是：第 11、13、30 篇。学完后，你应该能够按表头字段读写简单二维数据。",[14,7101,16],{"id":16},[10,7103,7104],{},"本篇只处理“使用 CSV 读写表格数据”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7106,22],{"id":22},[10,7108,7109],{},[26,7110],{"alt":7111,"src":7112},"CSV 表头映射每行字段","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F32-csv-rows.svg",[10,7114,7115,7118],{},[49,7116,7117],{},"DictReader"," 使用第一行表头作为键，把后续每一行映射成字典。CSV 单元格读入后默认都是字符串。",[14,7120,35],{"id":35},[37,7122,7123,7133,7140],{},[40,7124,2366,7125,7128,7129,7132],{},[49,7126,7127],{},"newline=\"\""," 让 ",[49,7130,7131],{},"csv"," 模块正确处理换行。",[40,7134,7135,7136,7139],{},"字段顺序由 ",[49,7137,7138],{},"fieldnames"," 决定，字典键需要与字段名一致。",[40,7141,7142],{},"复杂嵌套数据更适合 JSON，规则二维表更适合 CSV。",[14,7144,59],{"id":59},[10,7146,62],{},[64,7148,7150],{"className":66,"code":7149,"language":68,"meta":69,"style":69},"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",[49,7151,7152,7157,7161,7166,7171,7176,7181,7186,7190,7195,7200,7205],{"__ignoreMap":69},[73,7153,7154],{"class":75,"line":76},[73,7155,7156],{},"import csv\n",[73,7158,7159],{"class":75,"line":82},[73,7160,86],{"emptyLinePlaceholder":85},[73,7162,7163],{"class":75,"line":89},[73,7164,7165],{},"writer_file = open(\"scores.csv\", \"w\", encoding=\"utf-8\", newline=\"\")\n",[73,7167,7168],{"class":75,"line":95},[73,7169,7170],{},"writer = csv.DictWriter(writer_file, fieldnames=[\"name\", \"score\"])\n",[73,7172,7173],{"class":75,"line":101},[73,7174,7175],{},"writer.writeheader()\n",[73,7177,7178],{"class":75,"line":106},[73,7179,7180],{},"writer.writerow({\"name\": \"小郑\", \"score\": 95})\n",[73,7182,7183],{"class":75,"line":112},[73,7184,7185],{},"writer_file.close()\n",[73,7187,7188],{"class":75,"line":118},[73,7189,86],{"emptyLinePlaceholder":85},[73,7191,7192],{"class":75,"line":124},[73,7193,7194],{},"reader_file = open(\"scores.csv\", \"r\", encoding=\"utf-8\", newline=\"\")\n",[73,7196,7197],{"class":75,"line":129},[73,7198,7199],{},"for row in csv.DictReader(reader_file):\n",[73,7201,7202],{"class":75,"line":135},[73,7203,7204],{},"    print(row[\"name\"], row[\"score\"])\n",[73,7206,7207],{"class":75,"line":140},[73,7208,7209],{},"reader_file.close()\n",[10,7211,146],{},[64,7213,7216],{"className":7214,"code":7215,"language":152,"meta":69},[150],"小郑 95\n",[49,7217,7215],{"__ignoreMap":69},[10,7219,157],{},[14,7221,160],{"id":160},[162,7223,7224,7233],{},[40,7225,7226,7229,7230,7232],{},[49,7227,7228],{},"DictWriter"," 按 ",[49,7231,7138],{}," 写表头，再按同一字段顺序取出字典值形成数据行。",[40,7234,7235,7237],{},[49,7236,7117],{}," 读取表头，并把每行单元格映射为字符串值的字典。",[14,7239,210],{"id":210},[37,7241,7242,7245],{},[40,7243,7244],{},"假设分数字段读取后自动成为整数，CSV 没有这种类型信息。",[40,7246,7247,7248,7250,7251,7253],{},"在 macOS 以外环境忽略 ",[49,7249,7127],{}," 可能出现额外空行；统一交给 ",[49,7252,7131],{}," 模块管理换行。",[14,7255,221],{"id":221},[162,7257,7258,7261],{},[40,7259,7260],{},"写入三名学习者的课程和分数。",[40,7262,7263],{},"读取 CSV 后把分数字符串转换为整数。",[10,7265,232],{},[14,7267,235],{"id":235},[10,7269,7270],{},"本篇目标是按表头字段读写简单二维数据。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,7272,242],{},{"title":69,"searchDepth":82,"depth":82,"links":7274},[7275,7276,7277,7278,7279,7280,7281,7282],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F32-python-csv-tables",{"title":7094,"description":7099},"python-csv-tables","posts\u002F20260817\u002F32-python-csv-tables","面向按顺序学习 Python 的初学者，本篇在第 11、13、30 篇知识上，帮助读者按表头字段读写简单二维数据。",[255,7290,7291],"CSV","表格数据","60GY8huX9TNwur3EjQ2eQNuZAfg16XjFP7H_4hGk_K8",{"id":7294,"title":7295,"body":7296,"category":255,"cover":256,"description":7300,"extension":257,"meta":7573,"navigation":85,"path":7574,"pinned":260,"publishedAt":261,"seo":7575,"slug":7576,"stem":7577,"summary":7578,"tags":7579,"updatedAt":261,"visible":85,"__hash__":7582},"posts\u002Fposts\u002F20260817\u002F33-python-exceptions.md","33｜异常捕获、抛出与清理",{"type":7,"value":7297,"toc":7560},[7298,7301,7303,7306,7308,7314,7325,7327,7344,7346,7348,7423,7425,7431,7433,7435,7460,7462,7471,7477,7488,7490,7496,7502,7511,7513,7528,7530,7551,7553,7555,7558],[10,7299,7300],{},"这套课程按知识依赖排列。本篇的前置知识是：第 16、22、30 篇。学完后，你应该能够处理可预期错误并保留明确失败信息。",[14,7302,16],{"id":16},[10,7304,7305],{},"本篇只处理“异常捕获、抛出与清理”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7307,22],{"id":22},[10,7309,7310],{},[26,7311],{"alt":7312,"src":7313},"异常改变正常执行路径","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-exception-flow.svg",[10,7315,7316,7317,7320,7321,7324],{},"异常发生后，当前正常路径停止，解释器寻找匹配的 ",[49,7318,7319],{},"except","；无论是否异常，",[49,7322,7323],{},"finally"," 都会在离开结构前执行。",[14,7326,35],{"id":35},[37,7328,7329,7335,7341],{},[40,7330,7331,7332,7334],{},"只捕获能够处理的具体异常，不使用空的 ",[49,7333,7319],{}," 吞掉全部错误。",[40,7336,7337,7340],{},[49,7338,7339],{},"raise"," 用于明确拒绝不符合函数约定的数据。",[40,7342,7343],{},"异常信息应说明失败原因，但不泄露密钥、用户隐私或内部路径。",[14,7345,59],{"id":59},[10,7347,62],{},[64,7349,7351],{"className":66,"code":7350,"language":68,"meta":69,"style":69},"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",[49,7352,7353,7358,7363,7368,7373,7378,7382,7387,7392,7397,7402,7406,7411,7417],{"__ignoreMap":69},[73,7354,7355],{"class":75,"line":76},[73,7356,7357],{},"def parse_age(text):\n",[73,7359,7360],{"class":75,"line":82},[73,7361,7362],{},"    age = int(text)\n",[73,7364,7365],{"class":75,"line":89},[73,7366,7367],{},"    if age \u003C 0:\n",[73,7369,7370],{"class":75,"line":95},[73,7371,7372],{},"        raise ValueError(\"年龄不能为负数\")\n",[73,7374,7375],{"class":75,"line":101},[73,7376,7377],{},"    return age\n",[73,7379,7380],{"class":75,"line":106},[73,7381,86],{"emptyLinePlaceholder":85},[73,7383,7384],{"class":75,"line":112},[73,7385,7386],{},"try:\n",[73,7388,7389],{"class":75,"line":118},[73,7390,7391],{},"    age = parse_age(\"18\")\n",[73,7393,7394],{"class":75,"line":124},[73,7395,7396],{},"except ValueError as error:\n",[73,7398,7399],{"class":75,"line":129},[73,7400,7401],{},"    print(\"输入错误：\", error)\n",[73,7403,7404],{"class":75,"line":135},[73,7405,1175],{},[73,7407,7408],{"class":75,"line":140},[73,7409,7410],{},"    print(\"年龄：\", age)\n",[73,7412,7414],{"class":75,"line":7413},13,[73,7415,7416],{},"finally:\n",[73,7418,7420],{"class":75,"line":7419},14,[73,7421,7422],{},"    print(\"处理结束\")\n",[10,7424,146],{},[64,7426,7429],{"className":7427,"code":7428,"language":152,"meta":69},[150],"年龄： 18\n处理结束\n",[49,7430,7428],{"__ignoreMap":69},[10,7432,157],{},[14,7434,160],{"id":160},[162,7436,7437,7449],{},[40,7438,7439,7441,7442,7444,7445,7448],{},[49,7440,3062],{}," 或主动 ",[49,7443,7339],{}," 都可能产生 ",[49,7446,7447],{},"ValueError","，控制流立即离开当前正常路径。",[40,7450,7451,7452,7454,7455,7457,7458,391],{},"有异常时进入匹配的 ",[49,7453,7319],{},"；没有异常时执行 ",[49,7456,1189],{},"；两种情况最后都会执行 ",[49,7459,7323],{},[193,7461,195],{"id":195},[10,7463,7464,2284,7466,1186,7468,7470],{},[49,7465,7319],{},[49,7467,1189],{},[49,7469,7323],{}," 的职责不同，不能只看它们出现的顺序。",[10,7472,7473],{},[26,7474],{"alt":7475,"src":7476},"异常结构的三种职责","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-try-parts.svg",[10,7478,7479,7481,7482,7484,7485,7487],{},[49,7480,7319],{}," 处理匹配异常，",[49,7483,1189],{}," 只在无异常时运行，",[49,7486,7323],{}," 负责两条路径都需要的清理动作。",[193,7489,195],{"id":4244},[10,7491,7492,7495],{},[49,7493,7494],{},"try"," 范围越大，越难判断究竟允许哪一步失败。",[10,7497,7498],{},[26,7499],{"alt":7500,"src":7501},"缩小 try 才能看清失败边界","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F33-narrow-try.svg",[10,7503,7504,7505,7507,7508,7510],{},"只把可能产生预期异常的操作放进 ",[49,7506,7494],{},"，后续正常业务放进 ",[49,7509,1189],{},"，错误边界会更清楚。",[14,7512,210],{"id":210},[37,7514,7515,7522],{},[40,7516,7517,7518,7521],{},"使用裸 ",[49,7519,7520],{},"except:"," 后什么也不做，真实编程错误也会被隐藏。",[40,7523,7524,7525,7527],{},"把整个程序包在一个巨大 ",[49,7526,7494],{}," 中，无法判断究竟哪一步允许失败。",[14,7529,221],{"id":221},[162,7531,7532,7545],{},[40,7533,7534,7535,7538,7539,1186,7542,391],{},"让 ",[49,7536,7537],{},"parse_age"," 分别处理 ",[49,7540,7541],{},"\"abc\"",[49,7543,7544],{},"\"-1\"",[40,7546,7547,7548,7550],{},"为文件读取捕获 ",[49,7549,6755],{}," 并给出清晰提示。",[10,7552,232],{},[14,7554,235],{"id":235},[10,7556,7557],{},"本篇目标是处理可预期错误并保留明确失败信息。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,7559,242],{},{"title":69,"searchDepth":82,"depth":82,"links":7561},[7562,7563,7564,7565,7566,7570,7571,7572],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":7567},[7568,7569],{"id":195,"depth":89,"text":195},{"id":4244,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F33-python-exceptions",{"title":7295,"description":7300},"python-exceptions","posts\u002F20260817\u002F33-python-exceptions","面向按顺序学习 Python 的初学者，本篇在第 16、22、30 篇知识上，帮助读者处理可预期错误并保留明确失败信息。",[255,7580,7581],"异常处理","错误","0qlq5G_4gAA2CmeWsYEcOlF6y0lQx7FrmSsDzRvhnIo",{"id":7584,"title":7585,"body":7586,"category":255,"cover":256,"description":7590,"extension":257,"meta":7766,"navigation":85,"path":7767,"pinned":260,"publishedAt":261,"seo":7768,"slug":7769,"stem":7770,"summary":7771,"tags":7772,"updatedAt":261,"visible":85,"__hash__":7774},"posts\u002Fposts\u002F20260817\u002F34-python-with-context-manager.md","34｜with 上下文管理器为什么能自动关闭资源",{"type":7,"value":7587,"toc":7756},[7588,7591,7593,7596,7598,7604,7610,7612,7628,7630,7632,7686,7688,7694,7696,7698,7711,7713,7726,7728,7747,7749,7751,7754],[10,7589,7590],{},"这套课程按知识依赖排列。本篇的前置知识是：第 30、33 篇。学完后，你应该能够使用上下文管理器可靠释放文件资源。",[14,7592,16],{"id":16},[10,7594,7595],{},"本篇只处理“with 上下文管理器为什么能自动关闭资源”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7597,22],{"id":22},[10,7599,7600],{},[26,7601],{"alt":7602,"src":7603},"with 管理资源生命周期","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F34-context-manager.svg",[10,7605,7606,7607,7609],{},"进入 ",[49,7608,6765],{}," 时取得资源，代码块结束时执行退出逻辑。即使块内发生异常，文件也会得到关闭机会。",[14,7611,35],{"id":35},[37,7613,7614,7619,7625],{},[40,7615,7616,7618],{},[49,7617,6765],{}," 把资源获取和释放配成一个清晰边界。",[40,7620,7621,7624],{},[49,7622,7623],{},"as file"," 得到的是上下文返回的资源对象。",[40,7626,7627],{},"文件、锁和数据库连接等资源常提供上下文管理协议。",[14,7629,59],{"id":59},[10,7631,62],{},[64,7633,7635],{"className":66,"code":7634,"language":68,"meta":69,"style":69},"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",[49,7636,7637,7641,7645,7649,7653,7658,7663,7667,7672,7677,7681],{"__ignoreMap":69},[73,7638,7639],{"class":75,"line":76},[73,7640,6577],{},[73,7642,7643],{"class":75,"line":82},[73,7644,86],{"emptyLinePlaceholder":85},[73,7646,7647],{"class":75,"line":89},[73,7648,6788],{},[73,7650,7651],{"class":75,"line":95},[73,7652,86],{"emptyLinePlaceholder":85},[73,7654,7655],{"class":75,"line":101},[73,7656,7657],{},"with file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[73,7659,7660],{"class":75,"line":106},[73,7661,7662],{},"    file.write(\"上下文管理器\\n\")\n",[73,7664,7665],{"class":75,"line":112},[73,7666,86],{"emptyLinePlaceholder":85},[73,7668,7669],{"class":75,"line":118},[73,7670,7671],{},"with file_path.open(\"r\", encoding=\"utf-8\") as file:\n",[73,7673,7674],{"class":75,"line":124},[73,7675,7676],{},"    print(file.read())\n",[73,7678,7679],{"class":75,"line":129},[73,7680,86],{"emptyLinePlaceholder":85},[73,7682,7683],{"class":75,"line":135},[73,7684,7685],{},"print(file.closed)\n",[10,7687,146],{},[64,7689,7692],{"className":7690,"code":7691,"language":152,"meta":69},[150],"上下文管理器\n\nTrue\n",[49,7693,7691],{"__ignoreMap":69},[10,7695,157],{},[14,7697,160],{"id":160},[162,7699,7700,7708],{},[40,7701,7606,7702,7704,7705,391],{},[49,7703,6765],{}," 时，文件对象的上下文协议返回可用资源并绑定到 ",[49,7706,7707],{},"file",[40,7709,7710],{},"离开代码块时自动执行退出逻辑；即使块内抛出异常，也会尝试关闭文件。",[14,7712,210],{"id":210},[37,7714,7715,7720],{},[40,7716,4811,7717,7719],{},[49,7718,6765],{}," 代码块外继续读写已经关闭的文件对象。",[40,7721,7722,7723,7725],{},"误以为 ",[49,7724,6765],{}," 会自动处理所有业务异常；它只保证执行资源退出协议。",[14,7727,221],{"id":221},[162,7729,7730,7739],{},[40,7731,7732,7733,7736,7737,391],{},"把第 30 篇的手动 ",[49,7734,7735],{},"open\u002Fclose"," 改写为 ",[49,7738,6765],{},[40,7740,4811,7741,7743,7744,391],{},[49,7742,6765],{}," 块后检查 ",[49,7745,7746],{},"file.closed",[10,7748,232],{},[14,7750,235],{"id":235},[10,7752,7753],{},"本篇目标是使用上下文管理器可靠释放文件资源。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,7755,242],{},{"title":69,"searchDepth":82,"depth":82,"links":7757},[7758,7759,7760,7761,7762,7763,7764,7765],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F34-python-with-context-manager",{"title":7585,"description":7590},"python-with-context-manager","posts\u002F20260817\u002F34-python-with-context-manager","面向按顺序学习 Python 的初学者，本篇在第 30、33 篇知识上，帮助读者使用上下文管理器可靠释放文件资源。",[255,6765,7773],"上下文管理器","S5YJxtf_fX6TJCTMoZjcqE_ozIqVP8ZqfyTUI2beo20",{"id":7776,"title":7777,"body":7778,"category":255,"cover":256,"description":7782,"extension":257,"meta":7994,"navigation":85,"path":7995,"pinned":260,"publishedAt":261,"seo":7996,"slug":7997,"stem":7998,"summary":7999,"tags":8000,"updatedAt":261,"visible":85,"__hash__":8003},"posts\u002Fposts\u002F20260817\u002F35-python-class-object.md","35｜类、对象、属性与方法",{"type":7,"value":7779,"toc":7982},[7780,7783,7785,7788,7790,7796,7799,7801,7818,7820,7822,7890,7892,7898,7900,7902,7927,7929,7932,7938,7947,7949,7960,7962,7973,7975,7977,7980],[10,7781,7782],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、13 篇。学完后，你应该能够使用类组织一组相关状态和行为。",[14,7784,16],{"id":16},[10,7786,7787],{},"本篇只处理“类、对象、属性与方法”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,7789,22],{"id":22},[10,7791,7792],{},[26,7793],{"alt":7794,"src":7795},"类创建对象并组织状态行为","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-instance.svg",[10,7797,7798],{},"类定义对象应具有哪些属性和方法；调用类创建实例后，每个实例保存自己的状态，通过方法读取或更新状态。",[14,7800,35],{"id":35},[37,7802,7803,7809,7815],{},[40,7804,7805,7808],{},[49,7806,7807],{},"self"," 表示当前实例，由方法调用自动传入。",[40,7810,7811,7814],{},[49,7812,7813],{},"__init__"," 在实例创建过程中初始化属性。",[40,7816,7817],{},"只有数据和行为确实属于同一概念时才需要类，简单数据仍可使用字典。",[14,7819,59],{"id":59},[10,7821,62],{},[64,7823,7825],{"className":66,"code":7824,"language":68,"meta":69,"style":69},"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",[49,7826,7827,7832,7837,7842,7847,7851,7856,7861,7866,7871,7875,7880,7885],{"__ignoreMap":69},[73,7828,7829],{"class":75,"line":76},[73,7830,7831],{},"class LearningRecord:\n",[73,7833,7834],{"class":75,"line":82},[73,7835,7836],{},"    def __init__(self, course, progress=0):\n",[73,7838,7839],{"class":75,"line":89},[73,7840,7841],{},"        self.course = course\n",[73,7843,7844],{"class":75,"line":95},[73,7845,7846],{},"        self.progress = progress\n",[73,7848,7849],{"class":75,"line":101},[73,7850,86],{"emptyLinePlaceholder":85},[73,7852,7853],{"class":75,"line":106},[73,7854,7855],{},"    def advance(self, amount):\n",[73,7857,7858],{"class":75,"line":112},[73,7859,7860],{},"        self.progress = self.progress + amount\n",[73,7862,7863],{"class":75,"line":118},[73,7864,7865],{},"        if self.progress > 100:\n",[73,7867,7868],{"class":75,"line":124},[73,7869,7870],{},"            self.progress = 100\n",[73,7872,7873],{"class":75,"line":129},[73,7874,86],{"emptyLinePlaceholder":85},[73,7876,7877],{"class":75,"line":135},[73,7878,7879],{},"record = LearningRecord(\"Python\", 40)\n",[73,7881,7882],{"class":75,"line":140},[73,7883,7884],{},"record.advance(15)\n",[73,7886,7887],{"class":75,"line":7413},[73,7888,7889],{},"print(record.course, record.progress)\n",[10,7891,146],{},[64,7893,7896],{"className":7894,"code":7895,"language":152,"meta":69},[150],"Python 55\n",[49,7897,7895],{"__ignoreMap":69},[10,7899,157],{},[14,7901,160],{"id":160},[162,7903,7904,7914],{},[40,7905,7906,7907,7910,7911,7913],{},"调用 ",[49,7908,7909],{},"LearningRecord(\"Python\", 40)"," 创建实例，",[49,7912,7813],{}," 把课程和进度保存在该实例属性中。",[40,7915,7916,7919,7920,7923,7924,7926],{},[49,7917,7918],{},"record.advance(15)"," 自动把 ",[49,7921,7922],{},"record"," 作为 ",[49,7925,7807],{},"，方法更新同一实例的进度并限制上限。",[193,7928,195],{"id":195},[10,7930,7931],{},"类是共同定义，实例则各自保存状态。",[10,7933,7934],{},[26,7935],{"alt":7936,"src":7937},"两个实例各自保存状态","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F35-class-two-instances.svg",[10,7939,7940,7941,1186,7943,7946],{},"两个实例共享同一套方法定义，但 ",[49,7942,186],{},[49,7944,7945],{},"progress"," 属性分别属于各自实例，修改一边不会自动修改另一边。",[14,7948,210],{"id":210},[37,7950,7951,7957],{},[40,7952,7953,7954,7956],{},"调用实例方法时手工再传一次 ",[49,7955,7807],{},"。通过实例调用时 Python 会自动绑定。",[40,7958,7959],{},"只为了存两三个没有行为的数据就创建复杂类；字典或数据类可能更合适。",[14,7961,221],{"id":221},[162,7963,7964,7970],{},[40,7965,5321,7966,7969],{},[49,7967,7968],{},"Book"," 类，保存标题和阅读页数。",[40,7971,7972],{},"增加方法更新阅读页数，并限制它不超过总页数。",[10,7974,232],{},[14,7976,235],{"id":235},[10,7978,7979],{},"本篇目标是使用类组织一组相关状态和行为。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,7981,242],{},{"title":69,"searchDepth":82,"depth":82,"links":7983},[7984,7985,7986,7987,7988,7991,7992,7993],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":7989},[7990],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F35-python-class-object",{"title":7777,"description":7782},"python-class-object","posts\u002F20260817\u002F35-python-class-object","面向按顺序学习 Python 的初学者，本篇在第 22、23、13 篇知识上，帮助读者使用类组织一组相关状态和行为。",[255,8001,8002],"类","面向对象","YQC-FSgTSA9jUT7E_pT2JpIRPDS_q69fILmYywcvbvU",{"id":8005,"title":8006,"body":8007,"category":255,"cover":256,"description":8011,"extension":257,"meta":8189,"navigation":85,"path":8190,"pinned":260,"publishedAt":261,"seo":8191,"slug":8192,"stem":8193,"summary":8194,"tags":8195,"updatedAt":261,"visible":85,"__hash__":8198},"posts\u002Fposts\u002F20260817\u002F36-python-composition-inheritance.md","36｜封装、组合与继承怎样选择",{"type":7,"value":8008,"toc":8179},[8009,8012,8014,8017,8019,8025,8028,8030,8041,8043,8045,8112,8114,8120,8122,8124,8143,8145,8153,8155,8170,8172,8174,8177],[10,8010,8011],{},"这套课程按知识依赖排列。本篇的前置知识是：第 35 篇。学完后，你应该能够区分拥有关系和属于关系。",[14,8013,16],{"id":16},[10,8015,8016],{},"本篇只处理“封装、组合与继承怎样选择”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8018,22],{"id":22},[10,8020,8021],{},[26,8022],{"alt":8023,"src":8024},"组合与继承表达不同关系","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F36-composition-inheritance.svg",[10,8026,8027],{},"组合表达“一个对象拥有另一个对象”，继承表达“子类属于父类的一种”。复用代码不是使用继承的充分理由。",[14,8029,35],{"id":35},[37,8031,8032,8035,8038],{},[40,8033,8034],{},"封装让对象通过方法维护自己的有效状态。",[40,8036,8037],{},"组合通常更灵活：外部对象只依赖协作对象提供的行为。",[40,8039,8040],{},"继承适合稳定的“是一种”关系，并且子类应能替代父类。",[14,8042,59],{"id":59},[10,8044,62],{},[64,8046,8048],{"className":66,"code":8047,"language":68,"meta":69,"style":69},"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",[49,8049,8050,8055,8060,8065,8069,8074,8079,8084,8088,8093,8098,8102,8107],{"__ignoreMap":69},[73,8051,8052],{"class":75,"line":76},[73,8053,8054],{},"class Storage:\n",[73,8056,8057],{"class":75,"line":82},[73,8058,8059],{},"    def save(self, text):\n",[73,8061,8062],{"class":75,"line":89},[73,8063,8064],{},"        print(\"保存：\", text)\n",[73,8066,8067],{"class":75,"line":95},[73,8068,86],{"emptyLinePlaceholder":85},[73,8070,8071],{"class":75,"line":101},[73,8072,8073],{},"class LearningService:\n",[73,8075,8076],{"class":75,"line":106},[73,8077,8078],{},"    def __init__(self, storage):\n",[73,8080,8081],{"class":75,"line":112},[73,8082,8083],{},"        self.storage = storage\n",[73,8085,8086],{"class":75,"line":118},[73,8087,86],{"emptyLinePlaceholder":85},[73,8089,8090],{"class":75,"line":124},[73,8091,8092],{},"    def finish_lesson(self, title):\n",[73,8094,8095],{"class":75,"line":129},[73,8096,8097],{},"        self.storage.save(title)\n",[73,8099,8100],{"class":75,"line":135},[73,8101,86],{"emptyLinePlaceholder":85},[73,8103,8104],{"class":75,"line":140},[73,8105,8106],{},"service = LearningService(Storage())\n",[73,8108,8109],{"class":75,"line":7413},[73,8110,8111],{},"service.finish_lesson(\"异常处理\")\n",[10,8113,146],{},[64,8115,8118],{"className":8116,"code":8117,"language":152,"meta":69},[150],"保存： 异常处理\n",[49,8119,8117],{"__ignoreMap":69},[10,8121,157],{},[14,8123,160],{"id":160},[162,8125,8126,8136],{},[40,8127,8128,8131,8132,8135],{},[49,8129,8130],{},"LearningService"," 不负责具体保存细节，只保存一个实现 ",[49,8133,8134],{},"save()"," 的协作对象。",[40,8137,8138,8139,8142],{},"调用业务方法时，服务把保存动作委托给 ",[49,8140,8141],{},"Storage","；替换存储实现不要求改变课程完成逻辑。",[14,8144,210],{"id":210},[37,8146,8147,8150],{},[40,8148,8149],{},"为了复用一两个方法就建立不符合“是一种”关系的继承层次。",[40,8151,8152],{},"把组合理解为简单嵌套数据；关键在于对象通过清晰接口协作。",[14,8154,221],{"id":221},[162,8156,8157,8167],{},[40,8158,8159,8160,8163,8164,391],{},"用组合让 ",[49,8161,8162],{},"OrderService"," 使用一个 ",[49,8165,8166],{},"Notifier",[40,8168,8169],{},"为“学生属于用户”设计简单继承，再说明它成立的前提。",[10,8171,232],{},[14,8173,235],{"id":235},[10,8175,8176],{},"本篇目标是区分拥有关系和属于关系。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,8178,242],{},{"title":69,"searchDepth":82,"depth":82,"links":8180},[8181,8182,8183,8184,8185,8186,8187,8188],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F36-python-composition-inheritance",{"title":8006,"description":8011},"python-composition-inheritance","posts\u002F20260817\u002F36-python-composition-inheritance","面向按顺序学习 Python 的初学者，本篇在第 35 篇知识上，帮助读者区分拥有关系和属于关系。",[255,8196,8197],"组合","继承","BmuWDyClCSAOvr10btQdH7RJoZUyjSPjRIz5BQygaYI",{"id":8200,"title":8201,"body":8202,"category":255,"cover":256,"description":8206,"extension":257,"meta":8409,"navigation":85,"path":8410,"pinned":260,"publishedAt":261,"seo":8411,"slug":8412,"stem":8413,"summary":8414,"tags":8415,"updatedAt":261,"visible":85,"__hash__":8418},"posts\u002Fposts\u002F20260817\u002F37-python-iterator-generator.md","37｜迭代器与生成器的按需取值",{"type":7,"value":8203,"toc":8397},[8204,8207,8209,8212,8214,8220,8227,8229,8254,8256,8258,8310,8312,8318,8320,8322,8343,8345,8351,8357,8363,8365,8373,8375,8388,8390,8392,8395],[10,8205,8206],{},"这套课程按知识依赖排列。本篇的前置知识是：第 18、22、35 篇。学完后，你应该能够理解 iter、next 和 yield 的执行状态。",[14,8208,16],{"id":16},[10,8210,8211],{},"本篇只处理“迭代器与生成器的按需取值”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8213,22],{"id":22},[10,8215,8216],{},[26,8217],{"alt":8218,"src":8219},"生成器每次只产生一个值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-generator-state.svg",[10,8221,8222,8223,8226],{},"生成器运行到 ",[49,8224,8225],{},"yield"," 产生一个值并暂停，下一次请求时从暂停位置继续，而不是重新从函数第一行开始。",[14,8228,35],{"id":35},[37,8230,8231,8241,8251],{},[40,8232,8233,8236,8237,8240],{},[49,8234,8235],{},"iter()"," 从可迭代对象取得迭代器，",[49,8238,8239],{},"next()"," 请求下一个值。",[40,8242,8243,8244,8247,8248,8250],{},"没有更多值时迭代器抛出 ",[49,8245,8246],{},"StopIteration","，",[49,8249,4363],{}," 会自动处理。",[40,8252,8253],{},"生成器适合按需产生数据，但不是所有列表都需要改成生成器。",[14,8255,59],{"id":59},[10,8257,62],{},[64,8259,8261],{"className":66,"code":8260,"language":68,"meta":69,"style":69},"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",[49,8262,8263,8268,8273,8278,8283,8288,8292,8297,8302,8306],{"__ignoreMap":69},[73,8264,8265],{"class":75,"line":76},[73,8266,8267],{},"def countdown(start):\n",[73,8269,8270],{"class":75,"line":82},[73,8271,8272],{},"    current = start\n",[73,8274,8275],{"class":75,"line":89},[73,8276,8277],{},"    while current > 0:\n",[73,8279,8280],{"class":75,"line":95},[73,8281,8282],{},"        yield current\n",[73,8284,8285],{"class":75,"line":101},[73,8286,8287],{},"        current = current - 1\n",[73,8289,8290],{"class":75,"line":106},[73,8291,86],{"emptyLinePlaceholder":85},[73,8293,8294],{"class":75,"line":112},[73,8295,8296],{},"iterator = countdown(3)\n",[73,8298,8299],{"class":75,"line":118},[73,8300,8301],{},"print(next(iterator))\n",[73,8303,8304],{"class":75,"line":124},[73,8305,8301],{},[73,8307,8308],{"class":75,"line":129},[73,8309,8301],{},[10,8311,146],{},[64,8313,8316],{"className":8314,"code":8315,"language":152,"meta":69},[150],"3\n2\n1\n",[49,8317,8315],{"__ignoreMap":69},[10,8319,157],{},[14,8321,160],{"id":160},[162,8323,8324,8330],{},[40,8325,7906,8326,8329],{},[49,8327,8328],{},"countdown(3)"," 返回生成器对象，函数体还未运行。",[40,8331,8332,8333,8335,8336,8338,8339,8342],{},"每次 ",[49,8334,8239],{}," 运行到下一个 ",[49,8337,8225],{}," 并暂停，局部变量 ",[49,8340,8341],{},"current"," 和执行位置被保留。",[193,8344,195],{"id":195},[10,8346,8347,8348,8350],{},"生成器的暂停位置可以展开成多次 ",[49,8349,8239],{}," 的时间线。",[10,8352,8353],{},[26,8354],{"alt":8355,"src":8356},"多次 next 推进同一个生成器","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F37-yield-timeline.svg",[10,8358,8359,8360,8362],{},"每次请求只推进到下一个 ",[49,8361,8225],{},"；局部变量保留，代码不会从函数开头重新运行。",[14,8364,210],{"id":210},[37,8366,8367,8370],{},[40,8368,8369],{},"把生成器当列表重复遍历；多数生成器消耗后不能自动回到开头。",[40,8371,8372],{},"在需要随机访问和多次读取的小数据上强行使用生成器，增加理解成本。",[14,8374,221],{"id":221},[162,8376,8377,8380],{},[40,8378,8379],{},"编写产生 1 到指定上限偶数的生成器。",[40,8381,4036,8382,8384,8385,8387],{},[49,8383,4363],{}," 遍历生成器，比较手动 ",[49,8386,8239],{}," 的差异。",[10,8389,232],{},[14,8391,235],{"id":235},[10,8393,8394],{},"本篇目标是理解 iter、next 和 yield 的执行状态。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,8396,242],{},{"title":69,"searchDepth":82,"depth":82,"links":8398},[8399,8400,8401,8402,8403,8406,8407,8408],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":8404},[8405],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F37-python-iterator-generator",{"title":8201,"description":8206},"python-iterator-generator","posts\u002F20260817\u002F37-python-iterator-generator","面向按顺序学习 Python 的初学者，本篇在第 18、22、35 篇知识上，帮助读者理解 iter、next 和 yield 的执行状态。",[255,8416,8417],"迭代器","生成器","PLaXEzD8SCCu_elhZ--26uGzVf5BTC7EahT6HztcvIc",{"id":8420,"title":8421,"body":8422,"category":255,"cover":256,"description":8426,"extension":257,"meta":8650,"navigation":85,"path":8651,"pinned":260,"publishedAt":261,"seo":8652,"slug":8653,"stem":8654,"summary":8655,"tags":8656,"updatedAt":261,"visible":85,"__hash__":8658},"posts\u002Fposts\u002F20260817\u002F38-python-decorator-basics.md","38｜装饰器如何包装函数",{"type":7,"value":8423,"toc":8638},[8424,8427,8429,8432,8434,8440,8443,8445,8465,8467,8469,8551,8553,8559,8561,8563,8585,8587,8590,8596,8603,8605,8615,8617,8629,8631,8633,8636],[10,8425,8426],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、23、27 篇。学完后，你应该能够理解函数被包装后的调用顺序。",[14,8428,16],{"id":16},[10,8430,8431],{},"本篇只处理“装饰器如何包装函数”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8433,22],{"id":22},[10,8435,8436],{},[26,8437],{"alt":8438,"src":8439},"装饰器把函数包在外层","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-wrap.svg",[10,8441,8442],{},"装饰器接收原函数并返回包装函数。名称重新绑定后，调用看似仍是原函数名，实际会先进入包装层，再决定何时调用原函数。",[14,8444,35],{"id":35},[37,8446,8447,8456,8459],{},[40,8448,8449,8452,8453,391],{},[49,8450,8451],{},"@trace"," 等价于 ",[49,8454,8455],{},"add = trace(add)",[40,8457,8458],{},"包装函数必须返回原函数结果，否则调用语义会被改变。",[40,8460,8461,8464],{},[49,8462,8463],{},"functools.wraps"," 保留原函数名称和文档信息。",[14,8466,59],{"id":59},[10,8468,62],{},[64,8470,8472],{"className":66,"code":8471,"language":68,"meta":69,"style":69},"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",[49,8473,8474,8479,8483,8488,8493,8498,8503,8508,8513,8518,8523,8527,8532,8536,8540,8545],{"__ignoreMap":69},[73,8475,8476],{"class":75,"line":76},[73,8477,8478],{},"from functools import wraps\n",[73,8480,8481],{"class":75,"line":82},[73,8482,86],{"emptyLinePlaceholder":85},[73,8484,8485],{"class":75,"line":89},[73,8486,8487],{},"def trace(function):\n",[73,8489,8490],{"class":75,"line":95},[73,8491,8492],{},"    @wraps(function)\n",[73,8494,8495],{"class":75,"line":101},[73,8496,8497],{},"    def wrapper(*args, **kwargs):\n",[73,8499,8500],{"class":75,"line":106},[73,8501,8502],{},"        print(\"开始：\", function.__name__)\n",[73,8504,8505],{"class":75,"line":112},[73,8506,8507],{},"        result = function(*args, **kwargs)\n",[73,8509,8510],{"class":75,"line":118},[73,8511,8512],{},"        print(\"结束：\", function.__name__)\n",[73,8514,8515],{"class":75,"line":124},[73,8516,8517],{},"        return result\n",[73,8519,8520],{"class":75,"line":129},[73,8521,8522],{},"    return wrapper\n",[73,8524,8525],{"class":75,"line":135},[73,8526,86],{"emptyLinePlaceholder":85},[73,8528,8529],{"class":75,"line":140},[73,8530,8531],{},"@trace\n",[73,8533,8534],{"class":75,"line":7413},[73,8535,6156],{},[73,8537,8538],{"class":75,"line":7419},[73,8539,6161],{},[73,8541,8543],{"class":75,"line":8542},15,[73,8544,86],{"emptyLinePlaceholder":85},[73,8546,8548],{"class":75,"line":8547},16,[73,8549,8550],{},"print(add(2, 3))\n",[10,8552,146],{},[64,8554,8557],{"className":8555,"code":8556,"language":152,"meta":69},[150],"开始： add\n结束： add\n5\n",[49,8558,8556],{"__ignoreMap":69},[10,8560,157],{},[14,8562,160],{"id":160},[162,8564,8565,8582],{},[40,8566,8567,8568,8571,8572,8575,8576,8579,8580,391],{},"解释器执行定义时，把原 ",[49,8569,8570],{},"add"," 函数交给 ",[49,8573,8574],{},"trace","，返回的 ",[49,8577,8578],{},"wrapper"," 重新绑定到名字 ",[49,8581,8570],{},[40,8583,8584],{},"调用时先进入包装函数，包装函数再调用原函数、取得结果并原样返回。",[193,8586,195],{"id":195},[10,8588,8589],{},"装饰器语法看起来特殊，但可以还原成普通赋值。",[10,8591,8592],{},[26,8593],{"alt":8594,"src":8595},"装饰器语法可以还原成赋值","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F38-decorator-equivalence.svg",[10,8597,8598,8600,8601,391],{},[49,8599,8451],{}," 位于函数定义上方，效果等价于定义结束后执行 ",[49,8602,8455],{},[14,8604,210],{"id":210},[37,8606,8607,8612],{},[40,8608,8609,8610,391],{},"包装函数忘记返回原函数结果，调用方得到 ",[49,8611,5404],{},[40,8613,8614],{},"装饰器叠加过多且修改隐藏行为，使调用路径难以追踪；基础项目优先保持层数少。",[14,8616,221],{"id":221},[162,8618,8619,8622],{},[40,8620,8621],{},"编写只记录调用次数的简单装饰器。",[40,8623,8624,8625,8628],{},"删除包装函数的 ",[49,8626,8627],{},"return result","，观察调用方得到什么。",[10,8630,232],{},[14,8632,235],{"id":235},[10,8634,8635],{},"本篇目标是理解函数被包装后的调用顺序。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,8637,242],{},{"title":69,"searchDepth":82,"depth":82,"links":8639},[8640,8641,8642,8643,8644,8647,8648,8649],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":8645},[8646],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F38-python-decorator-basics",{"title":8421,"description":8426},"python-decorator-basics","posts\u002F20260817\u002F38-python-decorator-basics","面向按顺序学习 Python 的初学者，本篇在第 22、23、27 篇知识上，帮助读者理解函数被包装后的调用顺序。",[255,8657,5355],"装饰器","BW4I6sQnQvDdRxzTQmwH4CiSFSOJoPrLpl7Z_3OF_KY",{"id":8660,"title":8661,"body":8662,"category":255,"cover":256,"description":8666,"extension":257,"meta":8853,"navigation":85,"path":8854,"pinned":260,"publishedAt":261,"seo":8855,"slug":8856,"stem":8857,"summary":8858,"tags":8859,"updatedAt":261,"visible":85,"__hash__":8862},"posts\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing.md","39｜调试、日志与自动化测试入门",{"type":7,"value":8663,"toc":8841},[8664,8667,8669,8672,8674,8680,8683,8685,8696,8698,8700,8775,8777,8783,8785,8787,8798,8800,8803,8809,8812,8814,8822,8824,8832,8834,8836,8839],[10,8665,8666],{},"这套课程按知识依赖排列。本篇的前置知识是：第 22、27、33 篇。学完后，你应该能够把失败缩小到可重复验证的函数。",[14,8668,16],{"id":16},[10,8670,8671],{},"本篇只处理“调试、日志与自动化测试入门”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8673,22],{"id":22},[10,8675,8676],{},[26,8677],{"alt":8678,"src":8679},"从失败现象缩小到可测试单元","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-debug-test.svg",[10,8681,8682],{},"先稳定复现失败，再通过日志或断点确定出错范围，最后把问题缩小为有明确输入输出的函数，用测试固定正确行为。",[14,8684,35],{"id":35},[37,8686,8687,8690,8693],{},[40,8688,8689],{},"调试先追求稳定复现，不要同时修改多个无关位置。",[40,8691,8692],{},"日志记录运行状态，测试判断结果是否符合约定。",[40,8694,8695],{},"测试名称描述场景；边界值通常比只测普通值更有价值。",[14,8697,59],{"id":59},[10,8699,62],{},[64,8701,8703],{"className":66,"code":8702,"language":68,"meta":69,"style":69},"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",[49,8704,8705,8710,8715,8719,8724,8728,8733,8738,8743,8747,8752,8757,8762,8766,8770],{"__ignoreMap":69},[73,8706,8707],{"class":75,"line":76},[73,8708,8709],{},"import logging\n",[73,8711,8712],{"class":75,"line":82},[73,8713,8714],{},"import unittest\n",[73,8716,8717],{"class":75,"line":89},[73,8718,86],{"emptyLinePlaceholder":85},[73,8720,8721],{"class":75,"line":95},[73,8722,8723],{},"logging.basicConfig(level=logging.INFO)\n",[73,8725,8726],{"class":75,"line":101},[73,8727,86],{"emptyLinePlaceholder":85},[73,8729,8730],{"class":75,"line":106},[73,8731,8732],{},"def clamp_progress(value):\n",[73,8734,8735],{"class":75,"line":112},[73,8736,8737],{},"    logging.info(\"检查进度：%s\", value)\n",[73,8739,8740],{"class":75,"line":118},[73,8741,8742],{},"    return max(0, min(100, value))\n",[73,8744,8745],{"class":75,"line":124},[73,8746,86],{"emptyLinePlaceholder":85},[73,8748,8749],{"class":75,"line":129},[73,8750,8751],{},"class ProgressTest(unittest.TestCase):\n",[73,8753,8754],{"class":75,"line":135},[73,8755,8756],{},"    def test_upper_limit(self):\n",[73,8758,8759],{"class":75,"line":140},[73,8760,8761],{},"        self.assertEqual(clamp_progress(120), 100)\n",[73,8763,8764],{"class":75,"line":7413},[73,8765,86],{"emptyLinePlaceholder":85},[73,8767,8768],{"class":75,"line":7419},[73,8769,6170],{},[73,8771,8772],{"class":75,"line":8542},[73,8773,8774],{},"    unittest.main()\n",[10,8776,146],{},[64,8778,8781],{"className":8779,"code":8780,"language":152,"meta":69},[150],"测试通过时显示 Ran 1 test 和 OK；日志格式可能包含级别与模块名\n",[49,8782,8780],{"__ignoreMap":69},[10,8784,157],{},[14,8786,160],{"id":160},[162,8788,8789,8795],{},[40,8790,8791,8794],{},[49,8792,8793],{},"clamp_progress"," 把输入限制在 0 到 100，并用日志记录本次检查值。",[40,8796,8797],{},"测试直接给出边界外输入 120，断言返回值必须是 100；实现变化后可以重复运行同一约定。",[193,8799,195],{"id":195},[10,8801,8802],{},"一个小测试可以拆成准备、执行和断言三个部分。",[10,8804,8805],{},[26,8806],{"alt":8807,"src":8808},"测试的准备、执行与断言","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F39-test-arrange-act-assert.svg",[10,8810,8811],{},"准备输入，调用被测函数，再比较实际值与期望值；失败信息才能明确指出哪项约定被破坏。",[14,8813,210],{"id":210},[37,8815,8816,8819],{},[40,8817,8818],{},"只看日志里“没有报错”就认为结果正确；测试需要明确比较期望值。",[40,8820,8821],{},"测试依赖真实网络、当前时间或共享文件却不隔离，造成结果不稳定。",[14,8823,221],{"id":221},[162,8825,8826,8829],{},[40,8827,8828],{},"为负数进度增加测试。",[40,8830,8831],{},"故意把上限改成 90，观察失败信息如何定位差异。",[10,8833,232],{},[14,8835,235],{"id":235},[10,8837,8838],{},"本篇目标是把失败缩小到可重复验证的函数。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,8840,242],{},{"title":69,"searchDepth":82,"depth":82,"links":8842},[8843,8844,8845,8846,8847,8850,8851,8852],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":8848},[8849],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F39-python-debug-logging-testing",{"title":8661,"description":8666},"python-debug-logging-testing","posts\u002F20260817\u002F39-python-debug-logging-testing","面向按顺序学习 Python 的初学者，本篇在第 22、27、33 篇知识上，帮助读者把失败缩小到可重复验证的函数。",[255,8860,8861],"调试","测试","1q4QSFr3NdSaLRU8qXqBZXNVD8NnlzWFL-avknhvr98",{"id":8864,"title":8865,"body":8866,"category":255,"cover":256,"description":8870,"extension":257,"meta":9170,"navigation":85,"path":9171,"pinned":260,"publishedAt":261,"seo":9172,"slug":9173,"stem":9174,"summary":9175,"tags":9176,"updatedAt":261,"visible":85,"__hash__":9179},"posts\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project.md","40｜综合项目：命令行学习记录管理器",{"type":7,"value":8867,"toc":9157},[8868,8871,8873,8876,8878,8884,8887,8889,8904,8906,8908,9055,9057,9063,9065,9067,9080,9082,9085,9091,9094,9096,9099,9105,9112,9114,9125,9127,9148,9150,9152,9155],[10,8869,8870],{},"这套课程按知识依赖排列。本篇的前置知识是：第 01～39 篇。学完后，你应该能够综合函数、类、JSON、异常和文件路径完成小项目。",[14,8872,16],{"id":16},[10,8874,8875],{},"本篇只处理“综合项目：命令行学习记录管理器”这一件事。示例基于 Python 3.14.6，在 macOS 环境核验；除明确标注的终端命令外，代码本身只使用 Python 标准能力。",[14,8877,22],{"id":22},[10,8879,8880],{},[26,8881],{"alt":8882,"src":8883},"命令行项目的一次完整请求","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-project-flow.svg",[10,8885,8886],{},"一次命令从用户输入开始，先解析和校验，再交给业务对象处理，随后持久化为 JSON，最后向用户显示结果。每一层只承担一种职责。",[14,8888,35],{"id":35},[37,8890,8891,8894,8897],{},[40,8892,8893],{},"输入层负责接收文本，业务层负责校验与状态，存储层负责 JSON 文件。",[40,8895,8896],{},"综合项目先完成最小可运行主流程，再增加读取、列表展示和完成状态。",[40,8898,8899,8900,8903],{},"实际扩展前先为 ",[49,8901,8902],{},"add()"," 和存储边界补充测试。",[14,8905,59],{"id":59},[10,8907,62],{},[64,8909,8911],{"className":66,"code":8910,"language":68,"meta":69,"style":69},"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",[49,8912,8913,8917,8921,8925,8930,8935,8940,8945,8949,8954,8959,8964,8969,8974,8978,8983,8988,8994,8999,9005,9010,9015,9021,9027,9033,9038,9044,9049],{"__ignoreMap":69},[73,8914,8915],{"class":75,"line":76},[73,8916,6968],{},[73,8918,8919],{"class":75,"line":82},[73,8920,6577],{},[73,8922,8923],{"class":75,"line":89},[73,8924,86],{"emptyLinePlaceholder":85},[73,8926,8927],{"class":75,"line":95},[73,8928,8929],{},"class LearningRecords:\n",[73,8931,8932],{"class":75,"line":101},[73,8933,8934],{},"    def __init__(self, file_path):\n",[73,8936,8937],{"class":75,"line":106},[73,8938,8939],{},"        self.file_path = Path(file_path)\n",[73,8941,8942],{"class":75,"line":112},[73,8943,8944],{},"        self.items = []\n",[73,8946,8947],{"class":75,"line":118},[73,8948,86],{"emptyLinePlaceholder":85},[73,8950,8951],{"class":75,"line":124},[73,8952,8953],{},"    def add(self, title):\n",[73,8955,8956],{"class":75,"line":129},[73,8957,8958],{},"        title = title.strip()\n",[73,8960,8961],{"class":75,"line":135},[73,8962,8963],{},"        if not title:\n",[73,8965,8966],{"class":75,"line":140},[73,8967,8968],{},"            raise ValueError(\"课程名称不能为空\")\n",[73,8970,8971],{"class":75,"line":7413},[73,8972,8973],{},"        self.items.append({\"title\": title, \"done\": False})\n",[73,8975,8976],{"class":75,"line":7419},[73,8977,86],{"emptyLinePlaceholder":85},[73,8979,8980],{"class":75,"line":8542},[73,8981,8982],{},"    def save(self):\n",[73,8984,8985],{"class":75,"line":8547},[73,8986,8987],{},"        with self.file_path.open(\"w\", encoding=\"utf-8\") as file:\n",[73,8989,8991],{"class":75,"line":8990},17,[73,8992,8993],{},"            json.dump(self.items, file, ensure_ascii=False, indent=2)\n",[73,8995,8997],{"class":75,"line":8996},18,[73,8998,86],{"emptyLinePlaceholder":85},[73,9000,9002],{"class":75,"line":9001},19,[73,9003,9004],{},"records = LearningRecords(\"learning-records.json\")\n",[73,9006,9008],{"class":75,"line":9007},20,[73,9009,86],{"emptyLinePlaceholder":85},[73,9011,9013],{"class":75,"line":9012},21,[73,9014,7386],{},[73,9016,9018],{"class":75,"line":9017},22,[73,9019,9020],{},"    title = input(\"输入已学习课程：\")\n",[73,9022,9024],{"class":75,"line":9023},23,[73,9025,9026],{},"    records.add(title)\n",[73,9028,9030],{"class":75,"line":9029},24,[73,9031,9032],{},"    records.save()\n",[73,9034,9036],{"class":75,"line":9035},25,[73,9037,7396],{},[73,9039,9041],{"class":75,"line":9040},26,[73,9042,9043],{},"    print(\"无法保存：\", error)\n",[73,9045,9047],{"class":75,"line":9046},27,[73,9048,1175],{},[73,9050,9052],{"class":75,"line":9051},28,[73,9053,9054],{},"    print(\"已保存 1 条学习记录\")\n",[10,9056,146],{},[64,9058,9061],{"className":9059,"code":9060,"language":152,"meta":69},[150],"输入有效课程名后创建 learning-records.json，并显示已保存 1 条记录\n",[49,9062,9060],{"__ignoreMap":69},[10,9064,157],{},[14,9066,160],{"id":160},[162,9068,9069,9075],{},[40,9070,9071,9072,9074],{},"输入层取得课程名后，",[49,9073,8902],{}," 去除两端空白并验证非空，再把基础字典加入内存列表。",[40,9076,9077,9079],{},[49,9078,8134],{}," 只负责把当前列表写入 JSON；异常路径显示原因，成功路径确认保存结果。",[193,9081,195],{"id":195},[10,9083,9084],{},"综合项目先把职责拆开，避免所有代码堆进输入循环。",[10,9086,9087],{},[26,9088],{"alt":9089,"src":9090},"项目按职责传递数据","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-layer-responsibilities.svg",[10,9092,9093],{},"输入层只接收命令，业务层维护有效状态，存储层读写 JSON；层与层之间通过明确数据交接。",[193,9095,195],{"id":4244},[10,9097,9098],{},"内存列表和 JSON 文件是两个不同时间点的状态。",[10,9100,9101],{},[26,9102],{"alt":9103,"src":9104},"内存状态与文件状态需要同步","https:\u002F\u002Fimg.zhengzaihun.com\u002Fzhengzaihun\u002Fblog\u002Fimage\u002Fposts\u002F20260817\u002Fpython-course\u002F40-memory-file-state.svg",[10,9106,9107,9108,9111],{},"业务操作先修改内存，保存后文件才同步；程序重新启动时还需要 ",[49,9109,9110],{},"load()"," 把文件状态恢复到内存。",[14,9113,210],{"id":210},[37,9115,9116,9119],{},[40,9117,9118],{},"把输入、校验、业务处理和文件写入全塞进一个长循环，后续难以测试。",[40,9120,9121,9122,9124],{},"每次启动都用空列表覆盖旧文件。本示例是最小版本，练习中的 ",[49,9123,9110],{}," 是下一项必要扩展。",[14,9126,221],{"id":221},[162,9128,9129,9135,9138],{},[40,9130,9131,9132,9134],{},"增加 ",[49,9133,9110],{},"，文件不存在时从空列表开始。",[40,9136,9137],{},"增加按序号标记完成的功能，并校验序号范围。",[40,9139,9140,9141,9144,9145,9147],{},"把输入循环放进 ",[49,9142,9143],{},"main()","，通过 ",[49,9146,6112],{}," 控制程序入口。",[10,9149,232],{},[14,9151,235],{"id":235},[10,9153,9154],{},"本篇目标是综合函数、类、JSON、异常和文件路径完成小项目。没有展开的高级机制会放到后续课程；先确保能够解释示例中每一行代码，再进入下一篇。",[240,9156,242],{},{"title":69,"searchDepth":82,"depth":82,"links":9158},[9159,9160,9161,9162,9163,9167,9168,9169],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":9164},[9165,9166],{"id":195,"depth":89,"text":195},{"id":4244,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},"\u002Fposts\u002F20260817\u002F40-python-learning-record-cli-project",{"title":8865,"description":8870},"python-learning-record-cli-project","posts\u002F20260817\u002F40-python-learning-record-cli-project","面向按顺序学习 Python 的初学者，本篇在第 01～39 篇知识上，帮助读者综合函数、类、JSON、异常和文件路径完成小项目。",[255,9177,9178],"项目实战","命令行","lraO40z6BM-5T--hiXBLKXtq1ZhERUKJqy8X1LOlpP4",[9181,9284,9403,9534,9677,9802,9939,10076,10217,10386,10523,10656,10779,10908,11035,11198,11374,11515,11644,11793,11936,12057,12180,12329,12482,12647,12774,12955,13098,13255,13406,13553,13708,13926,14081,14256,14407,14574,14761,14924,15166,15406],{"id":1422,"title":1423,"body":9182,"category":255,"cover":256,"description":1428,"extension":257,"meta":9281,"navigation":85,"path":1547,"pinned":260,"publishedAt":261,"seo":9282,"slug":1549,"stem":1550,"summary":1551,"tags":9283,"updatedAt":261,"visible":85,"__hash__":1554},{"type":7,"value":9183,"toc":9271},[9184,9186,9188,9190,9192,9196,9200,9202,9212,9214,9216,9224,9226,9231,9233,9235,9245,9247,9255,9257,9263,9265,9267,9269],[10,9185,1428],{},[14,9187,16],{"id":16},[10,9189,1433],{},[14,9191,22],{"id":22},[10,9193,9194],{},[26,9195],{"alt":1440,"src":1441},[10,9197,9198,1446],{},[49,9199,1200],{},[14,9201,35],{"id":35},[37,9203,9204,9208,9210],{},[40,9205,1453,9206,1456],{},[49,9207,1200],{},[40,9209,1459],{},[40,9211,1462],{},[14,9213,59],{"id":59},[10,9215,62],{},[64,9217,9218],{"className":66,"code":1469,"language":68,"meta":69,"style":69},[49,9219,9220],{"__ignoreMap":69},[73,9221,9222],{"class":75,"line":76},[73,9223,1469],{},[10,9225,146],{},[64,9227,9229],{"className":9228,"code":1481,"language":152,"meta":69},[150],[49,9230,1481],{"__ignoreMap":69},[10,9232,157],{},[14,9234,160],{"id":160},[162,9236,9237,9241],{},[40,9238,1492,9239,1496],{},[49,9240,1495],{},[40,9242,1499,9243,1503],{},[49,9244,1502],{},[14,9246,210],{"id":210},[37,9248,9249,9251],{},[40,9250,1510],{},[40,9252,1513,9253,1516],{},[49,9254,1200],{},[14,9256,221],{"id":221},[162,9258,9259,9261],{},[40,9260,1523],{},[40,9262,1526],{},[10,9264,232],{},[14,9266,235],{"id":235},[10,9268,1533],{},[240,9270,242],{},{"title":69,"searchDepth":82,"depth":82,"links":9272},[9273,9274,9275,9276,9277,9278,9279,9280],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":1423,"description":1428},[255,1418,1553],{"id":1556,"title":1557,"body":9285,"category":255,"cover":256,"description":1562,"extension":257,"meta":9400,"navigation":85,"path":1699,"pinned":260,"publishedAt":261,"seo":9401,"slug":1701,"stem":1702,"summary":1703,"tags":9402,"updatedAt":261,"visible":85,"__hash__":1706},{"type":7,"value":9286,"toc":9390},[9287,9289,9291,9293,9295,9299,9303,9305,9315,9317,9319,9339,9341,9346,9348,9350,9360,9362,9372,9374,9382,9384,9386,9388],[10,9288,1562],{},[14,9290,16],{"id":16},[10,9292,1567],{},[14,9294,22],{"id":22},[10,9296,9297],{},[26,9298],{"alt":1574,"src":1575},[10,9300,1578,9301,1581],{},[49,9302,720],{},[14,9304,35],{"id":35},[37,9306,9307,9309,9311],{},[40,9308,1588],{},[40,9310,1591],{},[40,9312,1594,9313,1598],{},[49,9314,1597],{},[14,9316,59],{"id":59},[10,9318,1603],{},[64,9320,9321],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,9322,9323,9329],{"__ignoreMap":69},[73,9324,9325,9327],{"class":75,"line":76},[73,9326,720],{"class":629},[73,9328,633],{"class":632},[73,9330,9331,9333,9335,9337],{"class":75,"line":82},[73,9332,720],{"class":629},[73,9334,662],{"class":632},[73,9336,666],{"class":665},[73,9338,633],{"class":632},[10,9340,146],{},[64,9342,9344],{"className":9343,"code":1629,"language":152,"meta":69},[150],[49,9345,1629],{"__ignoreMap":69},[10,9347,157],{},[14,9349,160],{"id":160},[162,9351,9352,9356],{},[40,9353,9354,1643],{},[49,9355,1642],{},[40,9357,9358,1648],{},[49,9359,728],{},[14,9361,210],{"id":210},[37,9363,9364,9368],{},[40,9365,1655,9366,1658],{},[49,9367,720],{},[40,9369,1661,9370,1664],{},[49,9371,720],{},[14,9373,221],{"id":221},[162,9375,9376,9380],{},[40,9377,967,9378,1674],{},[49,9379,1673],{},[40,9381,1677],{},[10,9383,232],{},[14,9385,235],{"id":235},[10,9387,1684],{},[240,9389,1687],{},{"title":69,"searchDepth":82,"depth":82,"links":9391},[9392,9393,9394,9395,9396,9397,9398,9399],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":1557,"description":1562},[255,1705,1081],{"id":1708,"title":1709,"body":9404,"category":255,"cover":256,"description":1875,"extension":257,"meta":9531,"navigation":85,"path":1877,"pinned":260,"publishedAt":261,"seo":9532,"slug":1879,"stem":1880,"summary":1881,"tags":9533,"updatedAt":261,"visible":85,"__hash__":1885},{"type":7,"value":9405,"toc":9521},[9406,9410,9412,9414,9416,9420,9422,9424,9440,9442,9444,9464,9466,9471,9473,9475,9487,9489,9499,9501,9511,9513,9515,9519],[10,9407,1714,9408,1717],{},[49,9409,1200],{},[14,9411,16],{"id":16},[10,9413,1722],{},[14,9415,22],{"id":22},[10,9417,9418],{},[26,9419],{"alt":1729,"src":1730},[10,9421,1733],{},[14,9423,35],{"id":35},[37,9425,9426,9432,9436],{},[40,9427,1740,9428,1743,9430,391],{},[49,9429,720],{},[49,9431,1746],{},[40,9433,1749,9434,1753],{},[49,9435,1752],{},[40,9437,1756,9438,1759],{},[49,9439,1200],{},[14,9441,59],{"id":59},[10,9443,62],{},[64,9445,9446],{"className":1766,"code":1767,"language":1768,"meta":69,"style":69},[49,9447,9448,9452,9456,9460],{"__ignoreMap":69},[73,9449,9450],{"class":75,"line":76},[73,9451,1775],{},[73,9453,9454],{"class":75,"line":82},[73,9455,1780],{},[73,9457,9458],{"class":75,"line":89},[73,9459,1785],{},[73,9461,9462],{"class":75,"line":95},[73,9463,1790],{},[10,9465,146],{},[64,9467,9469],{"className":9468,"code":1796,"language":152,"meta":69},[150],[49,9470,1796],{"__ignoreMap":69},[10,9472,157],{},[14,9474,160],{"id":160},[162,9476,9477,9483],{},[40,9478,1807,9479,1811,9481,391],{},[49,9480,1810],{},[49,9482,1814],{},[40,9484,1817,9485,1820],{},[49,9486,1502],{},[14,9488,210],{"id":210},[37,9490,9491,9497],{},[40,9492,1827,9493,1830,9495,1833],{},[49,9494,1746],{},[49,9496,1200],{},[40,9498,1836],{},[14,9500,221],{"id":221},[162,9502,9503,9507],{},[40,9504,1843,9505,391],{},[49,9506,1846],{},[40,9508,1849,9509,1852],{},[49,9510,1502],{},[10,9512,232],{},[14,9514,235],{"id":235},[10,9516,1859,9517,1862],{},[49,9518,1200],{},[240,9520,242],{},{"title":69,"searchDepth":82,"depth":82,"links":9522},[9523,9524,9525,9526,9527,9528,9529,9530],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":1709,"description":1875},[255,1883,1884],{"id":1887,"title":1888,"body":9535,"category":255,"cover":256,"description":1893,"extension":257,"meta":9674,"navigation":85,"path":2065,"pinned":260,"publishedAt":261,"seo":9675,"slug":2067,"stem":2068,"summary":2069,"tags":9676,"updatedAt":261,"visible":85,"__hash__":2073},{"type":7,"value":9536,"toc":9664},[9537,9539,9541,9543,9545,9549,9553,9555,9567,9569,9571,9607,9609,9614,9616,9618,9634,9636,9646,9648,9656,9658,9660,9662],[10,9538,1893],{},[14,9540,16],{"id":16},[10,9542,1898],{},[14,9544,22],{"id":22},[10,9546,9547],{},[26,9548],{"alt":1905,"src":1906},[10,9550,9551,1912],{},[49,9552,1911],{},[14,9554,35],{"id":35},[37,9556,9557,9559,9565],{},[40,9558,1919],{},[40,9560,9561,1925,9563,1929],{},[49,9562,1924],{},[49,9564,1928],{},[40,9566,1932],{},[14,9568,59],{"id":59},[10,9570,1603],{},[64,9572,9573],{"className":620,"code":1939,"language":622,"meta":69,"style":69},[49,9574,9575,9581,9587,9591,9601],{"__ignoreMap":69},[73,9576,9577,9579],{"class":75,"line":76},[73,9578,1946],{"class":629},[73,9580,1949],{"class":665},[73,9582,9583,9585],{"class":75,"line":82},[73,9584,1954],{"class":632},[73,9586,1949],{"class":665},[73,9588,9589],{"class":75,"line":89},[73,9590,1961],{"class":632},[73,9592,9593,9595,9597,9599],{"class":75,"line":95},[73,9594,1966],{"class":632},[73,9596,1969],{"class":665},[73,9598,1973],{"class":1972},[73,9600,1244],{"class":665},[73,9602,9603,9605],{"class":75,"line":101},[73,9604,720],{"class":629},[73,9606,1244],{"class":665},[10,9608,146],{},[64,9610,9612],{"className":9611,"code":1987,"language":152,"meta":69},[150],[49,9613,1987],{"__ignoreMap":69},[10,9615,157],{},[14,9617,160],{"id":160},[162,9619,9620,9628],{},[40,9621,9622,2000,9624,2003,9626,2006],{},[49,9623,1946],{},[49,9625,1954],{},[49,9627,1924],{},[40,9629,9630,2011,9632,2015],{},[49,9631,1911],{},[49,9633,2014],{},[14,9635,210],{"id":210},[37,9637,9638,9644],{},[40,9639,2022,9640,1186,9642,391],{},[49,9641,1924],{},[49,9643,1928],{},[40,9645,2029],{},[14,9647,221],{"id":221},[162,9649,9650,9654],{},[40,9651,2036,9652,2040],{},[49,9653,2039],{},[40,9655,2043],{},[10,9657,232],{},[14,9659,235],{"id":235},[10,9661,2050],{},[240,9663,2053],{},{"title":69,"searchDepth":82,"depth":82,"links":9665},[9666,9667,9668,9669,9670,9671,9672,9673],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":1888,"description":1893},[255,2071,2072],{"id":2075,"title":2076,"body":9678,"category":255,"cover":256,"description":2081,"extension":257,"meta":9799,"navigation":85,"path":2229,"pinned":260,"publishedAt":261,"seo":9800,"slug":2231,"stem":2232,"summary":2233,"tags":9801,"updatedAt":261,"visible":85,"__hash__":2236},{"type":7,"value":9679,"toc":9789},[9680,9682,9684,9686,9688,9692,9700,9702,9716,9718,9720,9736,9738,9743,9745,9747,9761,9763,9769,9771,9781,9783,9785,9787],[10,9681,2081],{},[14,9683,16],{"id":16},[10,9685,2086],{},[14,9687,22],{"id":22},[10,9689,9690],{},[26,9691],{"alt":2093,"src":2094},[10,9693,2097,9694,391,9696,2103,9698,391],{},[49,9695,1502],{},[49,9697,2102],{},[49,9699,1810],{},[14,9701,35],{"id":35},[37,9703,9704,9708,9714],{},[40,9705,9706,2115],{},[49,9707,2114],{},[40,9709,9710,2121,9712,391],{},[49,9711,2120],{},[49,9713,2124],{},[40,9715,2127],{},[14,9717,59],{"id":59},[10,9719,62],{},[64,9721,9722],{"className":66,"code":2134,"language":68,"meta":69,"style":69},[49,9723,9724,9728,9732],{"__ignoreMap":69},[73,9725,9726],{"class":75,"line":76},[73,9727,2141],{},[73,9729,9730],{"class":75,"line":82},[73,9731,2146],{},[73,9733,9734],{"class":75,"line":89},[73,9735,2151],{},[10,9737,146],{},[64,9739,9741],{"className":9740,"code":2157,"language":152,"meta":69},[150],[49,9742,2157],{"__ignoreMap":69},[10,9744,157],{},[14,9746,160],{"id":160},[162,9748,9749,9755],{},[40,9750,9751,2171,9753,391],{},[49,9752,2170],{},[49,9754,2124],{},[40,9756,9757,2178,9759,2182],{},[49,9758,1502],{},[49,9760,2181],{},[14,9762,210],{"id":210},[37,9764,9765,9767],{},[40,9766,2189],{},[40,9768,2192],{},[14,9770,221],{"id":221},[162,9772,9773,9775],{},[40,9774,2199],{},[40,9776,2202,9777,52,9779,2208],{},[49,9778,2102],{},[49,9780,2207],{},[10,9782,232],{},[14,9784,235],{"id":235},[10,9786,2215],{},[240,9788,242],{},{"title":69,"searchDepth":82,"depth":82,"links":9790},[9791,9792,9793,9794,9795,9796,9797,9798],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":2076,"description":2081},[255,2235,190],{"id":2238,"title":2239,"body":9803,"category":255,"cover":256,"description":2244,"extension":257,"meta":9936,"navigation":85,"path":2412,"pinned":260,"publishedAt":261,"seo":9937,"slug":2414,"stem":2415,"summary":2416,"tags":9938,"updatedAt":261,"visible":85,"__hash__":2420},{"type":7,"value":9804,"toc":9926},[9805,9807,9809,9811,9813,9817,9819,9821,9837,9839,9841,9865,9867,9872,9874,9876,9892,9894,9906,9908,9918,9920,9922,9924],[10,9806,2244],{},[14,9808,16],{"id":16},[10,9810,2249],{},[14,9812,22],{"id":22},[10,9814,9815],{},[26,9816],{"alt":2256,"src":2257},[10,9818,2260],{},[14,9820,35],{"id":35},[37,9822,9823,9825,9831],{},[40,9824,2267],{},[40,9826,2270,9827,52,9829,2277],{},[49,9828,2273],{},[49,9830,2276],{},[40,9832,2280,9833,2284,9835,2288],{},[49,9834,2283],{},[49,9836,2287],{},[14,9838,59],{"id":59},[10,9840,62],{},[64,9842,9843],{"className":66,"code":2295,"language":68,"meta":69,"style":69},[49,9844,9845,9849,9853,9857,9861],{"__ignoreMap":69},[73,9846,9847],{"class":75,"line":76},[73,9848,2302],{},[73,9850,9851],{"class":75,"line":82},[73,9852,2307],{},[73,9854,9855],{"class":75,"line":89},[73,9856,86],{"emptyLinePlaceholder":85},[73,9858,9859],{"class":75,"line":95},[73,9860,2316],{},[73,9862,9863],{"class":75,"line":101},[73,9864,2307],{},[10,9866,146],{},[64,9868,9870],{"className":9869,"code":2326,"language":152,"meta":69},[150],[49,9871,2326],{"__ignoreMap":69},[10,9873,157],{},[14,9875,160],{"id":160},[162,9877,9878,9884],{},[40,9879,967,9880,2340,9882,2343],{},[49,9881,2339],{},[49,9883,2273],{},[40,9885,967,9886,2349,9888,2353,9890,391],{},[49,9887,2348],{},[49,9889,2352],{},[49,9891,2356],{},[14,9893,210],{"id":210},[37,9895,9896,9898],{},[40,9897,2363],{},[40,9899,2366,9900,2284,9902,2284,9904,2374],{},[49,9901,2283],{},[49,9903,2287],{},[49,9905,2373],{},[14,9907,221],{"id":221},[162,9909,9910,9916],{},[40,9911,2381,9912,1186,9914,2388],{},[49,9913,2384],{},[49,9915,2387],{},[40,9917,2391],{},[10,9919,232],{},[14,9921,235],{"id":235},[10,9923,2398],{},[240,9925,242],{},{"title":69,"searchDepth":82,"depth":82,"links":9927},[9928,9929,9930,9931,9932,9933,9934,9935],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":2239,"description":2244},[255,2418,2419],{"id":2422,"title":2423,"body":9940,"category":255,"cover":256,"description":2428,"extension":257,"meta":10073,"navigation":85,"path":2593,"pinned":260,"publishedAt":261,"seo":10074,"slug":2595,"stem":2596,"summary":2597,"tags":10075,"updatedAt":261,"visible":85,"__hash__":2601},{"type":7,"value":9941,"toc":10063},[9942,9944,9946,9948,9950,9954,9956,9958,9976,9978,9980,10016,10018,10023,10025,10027,10037,10039,10047,10049,10055,10057,10059,10061],[10,9943,2428],{},[14,9945,16],{"id":16},[10,9947,2433],{},[14,9949,22],{"id":22},[10,9951,9952],{},[26,9953],{"alt":2440,"src":2441},[10,9955,2444],{},[14,9957,35],{"id":35},[37,9959,9960,9966,9974],{},[40,9961,9962,2454,9964,2458],{},[49,9963,2453],{},[49,9965,2457],{},[40,9967,9968,2464,9970,2468,9972,2472],{},[49,9969,2463],{},[49,9971,2467],{},[49,9973,2471],{},[40,9975,2475],{},[14,9977,59],{"id":59},[10,9979,62],{},[64,9981,9982],{"className":66,"code":2482,"language":68,"meta":69,"style":69},[49,9983,9984,9988,9992,9996,10000,10004,10008,10012],{"__ignoreMap":69},[73,9985,9986],{"class":75,"line":76},[73,9987,2489],{},[73,9989,9990],{"class":75,"line":82},[73,9991,2494],{},[73,9993,9994],{"class":75,"line":89},[73,9995,2499],{},[73,9997,9998],{"class":75,"line":95},[73,9999,86],{"emptyLinePlaceholder":85},[73,10001,10002],{"class":75,"line":101},[73,10003,2508],{},[73,10005,10006],{"class":75,"line":106},[73,10007,2513],{},[73,10009,10010],{"class":75,"line":112},[73,10011,2518],{},[73,10013,10014],{"class":75,"line":118},[73,10015,2523],{},[10,10017,146],{},[64,10019,10021],{"className":10020,"code":2529,"language":152,"meta":69},[150],[49,10022,2529],{"__ignoreMap":69},[10,10024,157],{},[14,10026,160],{"id":160},[162,10028,10029,10033],{},[40,10030,10031,2543],{},[49,10032,2542],{},[40,10034,10035,2549],{},[49,10036,2548],{},[14,10038,210],{"id":210},[37,10040,10041,10045],{},[40,10042,2556,10043,391],{},[49,10044,2559],{},[40,10046,2562],{},[14,10048,221],{"id":221},[162,10050,10051,10053],{},[40,10052,2569],{},[40,10054,2572],{},[10,10056,232],{},[14,10058,235],{"id":235},[10,10060,2579],{},[240,10062,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10064},[10065,10066,10067,10068,10069,10070,10071,10072],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":2423,"description":2428},[255,2599,2600],{"id":2603,"title":2604,"body":10077,"category":255,"cover":256,"description":2609,"extension":257,"meta":10214,"navigation":85,"path":2785,"pinned":260,"publishedAt":261,"seo":10215,"slug":2787,"stem":2788,"summary":2789,"tags":10216,"updatedAt":261,"visible":85,"__hash__":2793},{"type":7,"value":10078,"toc":10202},[10079,10081,10083,10085,10087,10091,10097,10099,10107,10109,10111,10135,10137,10142,10144,10146,10164,10166,10168,10172,10174,10176,10182,10184,10194,10196,10198,10200],[10,10080,2609],{},[14,10082,16],{"id":16},[10,10084,2614],{},[14,10086,22],{"id":22},[10,10088,10089],{},[26,10090],{"alt":2621,"src":2622},[10,10092,2625,10093,2629,10095,391],{},[49,10094,2628],{},[49,10096,2632],{},[14,10098,35],{"id":35},[37,10100,10101,10103,10105],{},[40,10102,2639],{},[40,10104,2642],{},[40,10106,2645],{},[14,10108,59],{"id":59},[10,10110,62],{},[64,10112,10113],{"className":66,"code":2652,"language":68,"meta":69,"style":69},[49,10114,10115,10119,10123,10127,10131],{"__ignoreMap":69},[73,10116,10117],{"class":75,"line":76},[73,10118,2659],{},[73,10120,10121],{"class":75,"line":82},[73,10122,2664],{},[73,10124,10125],{"class":75,"line":89},[73,10126,2669],{},[73,10128,10129],{"class":75,"line":95},[73,10130,2674],{},[73,10132,10133],{"class":75,"line":101},[73,10134,2679],{},[10,10136,146],{},[64,10138,10140],{"className":10139,"code":2685,"language":152,"meta":69},[150],[49,10141,2685],{"__ignoreMap":69},[10,10143,157],{},[14,10145,160],{"id":160},[162,10147,10148,10156],{},[40,10149,2696,10150,2699,10152,2703,10154,2707],{},[49,10151,255],{},[49,10153,2702],{},[49,10155,2706],{},[40,10157,10158,2713,10160,2717,10162,2721],{},[49,10159,2712],{},[49,10161,2716],{},[49,10163,2720],{},[193,10165,195],{"id":195},[10,10167,2726],{},[10,10169,10170],{},[26,10171],{"alt":2731,"src":2732},[10,10173,2735],{},[14,10175,210],{"id":210},[37,10177,10178,10180],{},[40,10179,2742],{},[40,10181,2745],{},[14,10183,221],{"id":221},[162,10185,10186,10192],{},[40,10187,2752,10188,2756,10190,391],{},[49,10189,2755],{},[49,10191,2759],{},[40,10193,2762],{},[10,10195,232],{},[14,10197,235],{"id":235},[10,10199,2769],{},[240,10201,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10203},[10204,10205,10206,10207,10208,10211,10212,10213],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":10209},[10210],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":2604,"description":2609},[255,2791,2792],{"id":2795,"title":2796,"body":10218,"category":255,"cover":256,"description":2801,"extension":257,"meta":10383,"navigation":85,"path":3016,"pinned":260,"publishedAt":261,"seo":10384,"slug":3018,"stem":3019,"summary":3020,"tags":10385,"updatedAt":261,"visible":85,"__hash__":3024},{"type":7,"value":10219,"toc":10371},[10220,10222,10224,10226,10228,10232,10238,10240,10260,10262,10264,10300,10302,10307,10309,10311,10325,10327,10329,10333,10339,10341,10351,10353,10363,10365,10367,10369],[10,10221,2801],{},[14,10223,16],{"id":16},[10,10225,2806],{},[14,10227,22],{"id":22},[10,10229,10230],{},[26,10231],{"alt":2813,"src":2814},[10,10233,2817,10234,1038,10236,2824],{},[49,10235,2820],{},[49,10237,2823],{},[14,10239,35],{"id":35},[37,10241,10242,10250,10258],{},[40,10243,10244,2834,10246,2838,10248,2842],{},[49,10245,2833],{},[49,10247,2837],{},[49,10249,2841],{},[40,10251,10252,2848,10254,2852,10256,2856],{},[49,10253,2847],{},[49,10255,2851],{},[49,10257,2855],{},[40,10259,2859],{},[14,10261,59],{"id":59},[10,10263,62],{},[64,10265,10266],{"className":66,"code":2866,"language":68,"meta":69,"style":69},[49,10267,10268,10272,10276,10280,10284,10288,10292,10296],{"__ignoreMap":69},[73,10269,10270],{"class":75,"line":76},[73,10271,2873],{},[73,10273,10274],{"class":75,"line":82},[73,10275,2878],{},[73,10277,10278],{"class":75,"line":89},[73,10279,86],{"emptyLinePlaceholder":85},[73,10281,10282],{"class":75,"line":95},[73,10283,2887],{},[73,10285,10286],{"class":75,"line":101},[73,10287,2892],{},[73,10289,10290],{"class":75,"line":106},[73,10291,2897],{},[73,10293,10294],{"class":75,"line":112},[73,10295,2902],{},[73,10297,10298],{"class":75,"line":118},[73,10299,2907],{},[10,10301,146],{},[64,10303,10305],{"className":10304,"code":2913,"language":152,"meta":69},[150],[49,10306,2913],{"__ignoreMap":69},[10,10308,157],{},[14,10310,160],{"id":160},[162,10312,10313,10319],{},[40,10314,10315,2927,10317,2931],{},[49,10316,2926],{},[49,10318,2930],{},[40,10320,10321,2937,10323,2940],{},[49,10322,2936],{},[49,10324,2855],{},[193,10326,195],{"id":195},[10,10328,2945],{},[10,10330,10331],{},[26,10332],{"alt":2950,"src":2951},[10,10334,10335,2956,10337,2959],{},[49,10336,2847],{},[49,10338,2851],{},[14,10340,210],{"id":210},[37,10342,10343,10349],{},[40,10344,2966,10345,2969,10347,2972],{},[49,10346,2841],{},[49,10348,2833],{},[40,10350,2975],{},[14,10352,221],{"id":221},[162,10354,10355,10359],{},[40,10356,2982,10357,2986],{},[49,10358,2985],{},[40,10360,2989,10361,2993],{},[49,10362,2992],{},[10,10364,232],{},[14,10366,235],{"id":235},[10,10368,3000],{},[240,10370,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10372},[10373,10374,10375,10376,10377,10380,10381,10382],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":10378},[10379],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":2796,"description":2801},[255,3022,3023],{"id":3026,"title":3027,"body":10387,"category":255,"cover":256,"description":3032,"extension":257,"meta":10520,"navigation":85,"path":3201,"pinned":260,"publishedAt":261,"seo":10521,"slug":3203,"stem":3204,"summary":3205,"tags":10522,"updatedAt":261,"visible":85,"__hash__":3208},{"type":7,"value":10388,"toc":10510},[10389,10391,10393,10395,10397,10401,10411,10413,10423,10425,10427,10455,10457,10462,10464,10466,10480,10482,10490,10492,10502,10504,10506,10508],[10,10390,3032],{},[14,10392,16],{"id":16},[10,10394,3037],{},[14,10396,22],{"id":22},[10,10398,10399],{},[26,10400],{"alt":3044,"src":3045},[10,10402,10403,3051,10405,3055,10407,3059,10409,3063],{},[49,10404,3050],{},[49,10406,3054],{},[49,10408,3058],{},[49,10410,3062],{},[14,10412,35],{"id":35},[37,10414,10415,10417,10421],{},[40,10416,3070],{},[40,10418,10419,3075],{},[49,10420,3062],{},[40,10422,3078],{},[14,10424,59],{"id":59},[10,10426,62],{},[64,10428,10429],{"className":66,"code":3085,"language":68,"meta":69,"style":69},[49,10430,10431,10435,10439,10443,10447,10451],{"__ignoreMap":69},[73,10432,10433],{"class":75,"line":76},[73,10434,3092],{},[73,10436,10437],{"class":75,"line":82},[73,10438,3097],{},[73,10440,10441],{"class":75,"line":89},[73,10442,3102],{},[73,10444,10445],{"class":75,"line":95},[73,10446,86],{"emptyLinePlaceholder":85},[73,10448,10449],{"class":75,"line":101},[73,10450,3111],{},[73,10452,10453],{"class":75,"line":106},[73,10454,3116],{},[10,10456,146],{},[64,10458,10460],{"className":10459,"code":3122,"language":152,"meta":69},[150],[49,10461,3122],{"__ignoreMap":69},[10,10463,157],{},[14,10465,160],{"id":160},[162,10467,10468,10474],{},[40,10469,3133,10470,3136,10472,3140],{},[49,10471,3050],{},[49,10473,3139],{},[40,10475,10476,3146,10478,3150],{},[49,10477,3145],{},[49,10479,3149],{},[14,10481,210],{"id":210},[37,10483,10484,10488],{},[40,10485,3157,10486,3161],{},[49,10487,3160],{},[40,10489,3164],{},[14,10491,221],{"id":221},[162,10493,10494,10496],{},[40,10495,3171],{},[40,10497,1749,10498,3177,10500,3180],{},[49,10499,3176],{},[49,10501,3062],{},[10,10503,232],{},[14,10505,235],{"id":235},[10,10507,3187],{},[240,10509,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10511},[10512,10513,10514,10515,10516,10517,10518,10519],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":3027,"description":3032},[255,2373,3207],{"id":3210,"title":3211,"body":10524,"category":255,"cover":256,"description":3216,"extension":257,"meta":10653,"navigation":85,"path":3377,"pinned":260,"publishedAt":261,"seo":10654,"slug":3379,"stem":3380,"summary":3381,"tags":10655,"updatedAt":261,"visible":85,"__hash__":3385},{"type":7,"value":10525,"toc":10643},[10526,10528,10530,10532,10534,10538,10542,10544,10554,10556,10558,10590,10592,10597,10599,10601,10613,10615,10625,10627,10635,10637,10639,10641],[10,10527,3216],{},[14,10529,16],{"id":16},[10,10531,3221],{},[14,10533,22],{"id":22},[10,10535,10536],{},[26,10537],{"alt":3228,"src":3229},[10,10539,3232,10540,3236],{},[49,10541,3235],{},[14,10543,35],{"id":35},[37,10545,10546,10548,10550],{},[40,10547,3243],{},[40,10549,3246],{},[40,10551,3249,10552,391],{},[49,10553,3252],{},[14,10555,59],{"id":59},[10,10557,62],{},[64,10559,10560],{"className":66,"code":3259,"language":68,"meta":69,"style":69},[49,10561,10562,10566,10570,10574,10578,10582,10586],{"__ignoreMap":69},[73,10563,10564],{"class":75,"line":76},[73,10565,3266],{},[73,10567,10568],{"class":75,"line":82},[73,10569,3271],{},[73,10571,10572],{"class":75,"line":89},[73,10573,86],{"emptyLinePlaceholder":85},[73,10575,10576],{"class":75,"line":95},[73,10577,3280],{},[73,10579,10580],{"class":75,"line":101},[73,10581,3285],{},[73,10583,10584],{"class":75,"line":106},[73,10585,3290],{},[73,10587,10588],{"class":75,"line":112},[73,10589,3295],{},[10,10591,146],{},[64,10593,10595],{"className":10594,"code":3301,"language":152,"meta":69},[150],[49,10596,3301],{"__ignoreMap":69},[10,10598,157],{},[14,10600,160],{"id":160},[162,10602,10603,10605],{},[40,10604,3312],{},[40,10606,10607,3318,10609,3322,10611,3326],{},[49,10608,3317],{},[49,10610,3321],{},[49,10612,3325],{},[14,10614,210],{"id":210},[37,10616,10617,10623],{},[40,10618,3333,10619,3337,10621,391],{},[49,10620,3336],{},[49,10622,3340],{},[40,10624,3343],{},[14,10626,221],{"id":221},[162,10628,10629,10631],{},[40,10630,3350],{},[40,10632,3353,10633,3356],{},[49,10634,3325],{},[10,10636,232],{},[14,10638,235],{"id":235},[10,10640,3363],{},[240,10642,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10644},[10645,10646,10647,10648,10649,10650,10651,10652],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":3211,"description":3216},[255,3383,3384],{"id":3387,"title":3388,"body":10657,"category":255,"cover":256,"description":3393,"extension":257,"meta":10776,"navigation":85,"path":3535,"pinned":260,"publishedAt":261,"seo":10777,"slug":3537,"stem":3538,"summary":3539,"tags":10778,"updatedAt":261,"visible":85,"__hash__":3542},{"type":7,"value":10658,"toc":10766},[10659,10661,10663,10665,10667,10671,10673,10675,10683,10685,10687,10715,10717,10722,10724,10726,10736,10738,10746,10748,10758,10760,10762,10764],[10,10660,3393],{},[14,10662,16],{"id":16},[10,10664,3398],{},[14,10666,22],{"id":22},[10,10668,10669],{},[26,10670],{"alt":3405,"src":3406},[10,10672,3409],{},[14,10674,35],{"id":35},[37,10676,10677,10679,10681],{},[40,10678,3416],{},[40,10680,3419],{},[40,10682,3422],{},[14,10684,59],{"id":59},[10,10686,62],{},[64,10688,10689],{"className":66,"code":3429,"language":68,"meta":69,"style":69},[49,10690,10691,10695,10699,10703,10707,10711],{"__ignoreMap":69},[73,10692,10693],{"class":75,"line":76},[73,10694,3436],{},[73,10696,10697],{"class":75,"line":82},[73,10698,3441],{},[73,10700,10701],{"class":75,"line":89},[73,10702,3446],{},[73,10704,10705],{"class":75,"line":95},[73,10706,86],{"emptyLinePlaceholder":85},[73,10708,10709],{"class":75,"line":101},[73,10710,3455],{},[73,10712,10713],{"class":75,"line":106},[73,10714,3460],{},[10,10716,146],{},[64,10718,10720],{"className":10719,"code":3466,"language":152,"meta":69},[150],[49,10721,3466],{"__ignoreMap":69},[10,10723,157],{},[14,10725,160],{"id":160},[162,10727,10728,10732],{},[40,10729,10730,3480],{},[49,10731,3479],{},[40,10733,10734,3486],{},[49,10735,3485],{},[14,10737,210],{"id":210},[37,10739,10740,10744],{},[40,10741,3493,10742,3497],{},[49,10743,3496],{},[40,10745,3500],{},[14,10747,221],{"id":221},[162,10749,10750,10752],{},[40,10751,3507],{},[40,10753,2202,10754,52,10756,3514],{},[49,10755,3496],{},[49,10757,3485],{},[10,10759,232],{},[14,10761,235],{"id":235},[10,10763,3521],{},[240,10765,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10767},[10768,10769,10770,10771,10772,10773,10774,10775],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":3388,"description":3393},[255,3541,3384],{"id":3544,"title":3545,"body":10780,"category":255,"cover":256,"description":3550,"extension":257,"meta":10905,"navigation":85,"path":3706,"pinned":260,"publishedAt":261,"seo":10906,"slug":3708,"stem":3709,"summary":3710,"tags":10907,"updatedAt":261,"visible":85,"__hash__":3713},{"type":7,"value":10781,"toc":10895},[10782,10784,10786,10788,10790,10794,10800,10802,10812,10814,10816,10844,10846,10851,10853,10855,10865,10867,10879,10881,10887,10889,10891,10893],[10,10783,3550],{},[14,10785,16],{"id":16},[10,10787,3555],{},[14,10789,22],{"id":22},[10,10791,10792],{},[26,10793],{"alt":3562,"src":3563},[10,10795,3566,10796,3570,10798,3573],{},[49,10797,3569],{},[49,10799,2273],{},[14,10801,35],{"id":35},[37,10803,10804,10806,10810],{},[40,10805,3580],{},[40,10807,2366,10808,3586],{},[49,10809,3585],{},[40,10811,3589],{},[14,10813,59],{"id":59},[10,10815,62],{},[64,10817,10818],{"className":66,"code":3596,"language":68,"meta":69,"style":69},[49,10819,10820,10824,10828,10832,10836,10840],{"__ignoreMap":69},[73,10821,10822],{"class":75,"line":76},[73,10823,3603],{},[73,10825,10826],{"class":75,"line":82},[73,10827,3608],{},[73,10829,10830],{"class":75,"line":89},[73,10831,86],{"emptyLinePlaceholder":85},[73,10833,10834],{"class":75,"line":95},[73,10835,3617],{},[73,10837,10838],{"class":75,"line":101},[73,10839,3622],{},[73,10841,10842],{"class":75,"line":106},[73,10843,3627],{},[10,10845,146],{},[64,10847,10849],{"className":10848,"code":3633,"language":152,"meta":69},[150],[49,10850,3633],{"__ignoreMap":69},[10,10852,157],{},[14,10854,160],{"id":160},[162,10856,10857,10859],{},[40,10858,3644],{},[40,10860,3647,10861,3650,10863,3654],{},[49,10862,2273],{},[49,10864,3653],{},[14,10866,210],{"id":210},[37,10868,10869,10873],{},[40,10870,3661,10871,3665],{},[49,10872,3664],{},[40,10874,3668,10875,3672,10877,391],{},[49,10876,3671],{},[49,10878,3675],{},[14,10880,221],{"id":221},[162,10882,10883,10885],{},[40,10884,3682],{},[40,10886,3685],{},[10,10888,232],{},[14,10890,235],{"id":235},[10,10892,3692],{},[240,10894,242],{},{"title":69,"searchDepth":82,"depth":82,"links":10896},[10897,10898,10899,10900,10901,10902,10903,10904],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":3545,"description":3550},[255,3712,3384],{"id":3715,"title":3716,"body":10909,"category":255,"cover":256,"description":3721,"extension":257,"meta":11032,"navigation":85,"path":3871,"pinned":260,"publishedAt":261,"seo":11033,"slug":3873,"stem":3874,"summary":3875,"tags":11034,"updatedAt":261,"visible":85,"__hash__":3878},{"type":7,"value":10910,"toc":11022},[10911,10913,10915,10917,10919,10923,10925,10927,10939,10941,10943,10971,10973,10978,10980,10982,10992,10994,11004,11006,11014,11016,11018,11020],[10,10912,3721],{},[14,10914,16],{"id":16},[10,10916,3726],{},[14,10918,22],{"id":22},[10,10920,10921],{},[26,10922],{"alt":3733,"src":3734},[10,10924,3737],{},[14,10926,35],{"id":35},[37,10928,10929,10931,10933],{},[40,10930,3744],{},[40,10932,3747],{},[40,10934,3750,10935,3754,10937,3758],{},[49,10936,3753],{},[49,10938,3757],{},[14,10940,59],{"id":59},[10,10942,62],{},[64,10944,10945],{"className":66,"code":3765,"language":68,"meta":69,"style":69},[49,10946,10947,10951,10955,10959,10963,10967],{"__ignoreMap":69},[73,10948,10949],{"class":75,"line":76},[73,10950,3772],{},[73,10952,10953],{"class":75,"line":82},[73,10954,3777],{},[73,10956,10957],{"class":75,"line":89},[73,10958,86],{"emptyLinePlaceholder":85},[73,10960,10961],{"class":75,"line":95},[73,10962,3786],{},[73,10964,10965],{"class":75,"line":101},[73,10966,3791],{},[73,10968,10969],{"class":75,"line":106},[73,10970,3796],{},[10,10972,146],{},[64,10974,10976],{"className":10975,"code":3802,"language":152,"meta":69},[150],[49,10977,3802],{"__ignoreMap":69},[10,10979,157],{},[14,10981,160],{"id":160},[162,10983,10984,10986],{},[40,10985,3813],{},[40,10987,10988,3819,10990,3823],{},[49,10989,3818],{},[49,10991,3822],{},[14,10993,210],{"id":210},[37,10995,10996,11002],{},[40,10997,2366,10998,3832,11000,391],{},[49,10999,3757],{},[49,11001,3753],{},[40,11003,3837],{},[14,11005,221],{"id":221},[162,11007,11008,11012],{},[40,11009,3844,11010,3847],{},[49,11011,3753],{},[40,11013,3850],{},[10,11015,232],{},[14,11017,235],{"id":235},[10,11019,3857],{},[240,11021,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11023},[11024,11025,11026,11027,11028,11029,11030,11031],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":3716,"description":3721},[255,3877,3384],{"id":3880,"title":3881,"body":11036,"category":255,"cover":256,"description":3886,"extension":257,"meta":11195,"navigation":85,"path":4084,"pinned":260,"publishedAt":261,"seo":11196,"slug":4086,"stem":4087,"summary":4088,"tags":11197,"updatedAt":261,"visible":85,"__hash__":4092},{"type":7,"value":11037,"toc":11183},[11038,11040,11042,11044,11046,11050,11056,11058,11070,11072,11074,11114,11116,11121,11123,11125,11139,11141,11143,11147,11149,11151,11161,11163,11175,11177,11179,11181],[10,11039,3886],{},[14,11041,16],{"id":16},[10,11043,3891],{},[14,11045,22],{"id":22},[10,11047,11048],{},[26,11049],{"alt":3898,"src":3899},[10,11051,11052,3905,11054,3909],{},[49,11053,3904],{},[49,11055,3908],{},[14,11057,35],{"id":35},[37,11059,11060,11066,11068],{},[40,11061,11062,3918,11064,3922],{},[49,11063,2833],{},[49,11065,3921],{},[40,11067,3925],{},[40,11069,3928],{},[14,11071,59],{"id":59},[10,11073,62],{},[64,11075,11076],{"className":66,"code":3935,"language":68,"meta":69,"style":69},[49,11077,11078,11082,11086,11090,11094,11098,11102,11106,11110],{"__ignoreMap":69},[73,11079,11080],{"class":75,"line":76},[73,11081,3942],{},[73,11083,11084],{"class":75,"line":82},[73,11085,3947],{},[73,11087,11088],{"class":75,"line":89},[73,11089,3952],{},[73,11091,11092],{"class":75,"line":95},[73,11093,86],{"emptyLinePlaceholder":85},[73,11095,11096],{"class":75,"line":101},[73,11097,3961],{},[73,11099,11100],{"class":75,"line":106},[73,11101,3966],{},[73,11103,11104],{"class":75,"line":112},[73,11105,3971],{},[73,11107,11108],{"class":75,"line":118},[73,11109,3976],{},[73,11111,11112],{"class":75,"line":124},[73,11113,3981],{},[10,11115,146],{},[64,11117,11119],{"className":11118,"code":3987,"language":152,"meta":69},[150],[49,11120,3987],{"__ignoreMap":69},[10,11122,157],{},[14,11124,160],{"id":160},[162,11126,11127,11131],{},[40,11128,11129,4001],{},[49,11130,4000],{},[40,11132,11133,4007,11135,4011,11137,4015],{},[49,11134,4006],{},[49,11136,4010],{},[49,11138,4014],{},[193,11140,195],{"id":195},[10,11142,4020],{},[10,11144,11145],{},[26,11146],{"alt":4025,"src":4026},[10,11148,4029],{},[14,11150,210],{"id":210},[37,11152,11153,11159],{},[40,11154,4036,11155,4039,11157,391],{},[49,11156,2833],{},[49,11158,3921],{},[40,11160,4044],{},[14,11162,221],{"id":221},[162,11164,11165,11167],{},[40,11166,4051],{},[40,11168,2366,11169,4057,11171,1186,11173,391],{},[49,11170,4056],{},[49,11172,3921],{},[49,11174,2833],{},[10,11176,232],{},[14,11178,235],{"id":235},[10,11180,4068],{},[240,11182,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11184},[11185,11186,11187,11188,11189,11192,11193,11194],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":11190},[11191],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":3881,"description":3886},[255,4090,4091],{"id":4094,"title":4095,"body":11199,"category":255,"cover":256,"description":4100,"extension":257,"meta":11371,"navigation":85,"path":4313,"pinned":260,"publishedAt":261,"seo":11372,"slug":4315,"stem":4316,"summary":4317,"tags":11373,"updatedAt":261,"visible":85,"__hash__":4320},{"type":7,"value":11200,"toc":11358},[11201,11203,11205,11207,11209,11213,11221,11223,11231,11233,11235,11279,11281,11286,11288,11290,11302,11304,11306,11310,11316,11318,11320,11324,11328,11330,11342,11344,11350,11352,11354,11356],[10,11202,4100],{},[14,11204,16],{"id":16},[10,11206,4105],{},[14,11208,22],{"id":22},[10,11210,11211],{},[26,11212],{"alt":4112,"src":4113},[10,11214,11215,2284,11217,2284,11219,4123],{},[49,11216,1185],{},[49,11218,4120],{},[49,11220,1189],{},[14,11222,35],{"id":35},[37,11224,11225,11227,11229],{},[40,11226,4130],{},[40,11228,4133],{},[40,11230,4136],{},[14,11232,59],{"id":59},[10,11234,62],{},[64,11236,11237],{"className":66,"code":4143,"language":68,"meta":69,"style":69},[49,11238,11239,11243,11247,11251,11255,11259,11263,11267,11271,11275],{"__ignoreMap":69},[73,11240,11241],{"class":75,"line":76},[73,11242,4150],{},[73,11244,11245],{"class":75,"line":82},[73,11246,86],{"emptyLinePlaceholder":85},[73,11248,11249],{"class":75,"line":89},[73,11250,4159],{},[73,11252,11253],{"class":75,"line":95},[73,11254,4164],{},[73,11256,11257],{"class":75,"line":101},[73,11258,4169],{},[73,11260,11261],{"class":75,"line":106},[73,11262,4174],{},[73,11264,11265],{"class":75,"line":112},[73,11266,1175],{},[73,11268,11269],{"class":75,"line":118},[73,11270,4183],{},[73,11272,11273],{"class":75,"line":124},[73,11274,86],{"emptyLinePlaceholder":85},[73,11276,11277],{"class":75,"line":129},[73,11278,4192],{},[10,11280,146],{},[64,11282,11284],{"className":11283,"code":4198,"language":152,"meta":69},[150],[49,11285,4198],{"__ignoreMap":69},[10,11287,157],{},[14,11289,160],{"id":160},[162,11291,11292,11296],{},[40,11293,4209,11294,4213],{},[49,11295,4212],{},[40,11297,11298,4219,11300,4222],{},[49,11299,4218],{},[49,11301,1189],{},[193,11303,195],{"id":195},[10,11305,4227],{},[10,11307,11308],{},[26,11309],{"alt":4232,"src":4233},[10,11311,11312,4238,11314,4241],{},[49,11313,4212],{},[49,11315,4218],{},[193,11317,195],{"id":4244},[10,11319,4247],{},[10,11321,11322],{},[26,11323],{"alt":4252,"src":4253},[10,11325,4256,11326,4259],{},[49,11327,1185],{},[14,11329,210],{"id":210},[37,11331,11332,11336],{},[40,11333,4266,11334,4269],{},[49,11335,4218],{},[40,11337,4272,11338,4275,11340,4279],{},[49,11339,1185],{},[49,11341,4278],{},[14,11343,221],{"id":221},[162,11345,11346,11348],{},[40,11347,4286],{},[40,11349,4289],{},[10,11351,232],{},[14,11353,235],{"id":235},[10,11355,4296],{},[240,11357,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11359},[11360,11361,11362,11363,11364,11368,11369,11370],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":11365},[11366,11367],{"id":195,"depth":89,"text":195},{"id":4244,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":4095,"description":4100},[255,1185,4319],{"id":4322,"title":4323,"body":11375,"category":255,"cover":256,"description":4328,"extension":257,"meta":11512,"navigation":85,"path":4495,"pinned":260,"publishedAt":261,"seo":11513,"slug":4497,"stem":4498,"summary":4499,"tags":11514,"updatedAt":261,"visible":85,"__hash__":4502},{"type":7,"value":11376,"toc":11500},[11377,11379,11381,11383,11385,11389,11393,11395,11405,11407,11409,11441,11443,11448,11450,11452,11462,11464,11466,11470,11474,11476,11482,11484,11492,11494,11496,11498],[10,11378,4328],{},[14,11380,16],{"id":16},[10,11382,4333],{},[14,11384,22],{"id":22},[10,11386,11387],{},[26,11388],{"alt":4340,"src":4341},[10,11390,11391,4347],{},[49,11392,4346],{},[14,11394,35],{"id":35},[37,11396,11397,11399,11401],{},[40,11398,4354],{},[40,11400,4357],{},[40,11402,4360,11403,4364],{},[49,11404,4363],{},[14,11406,59],{"id":59},[10,11408,62],{},[64,11410,11411],{"className":66,"code":4371,"language":68,"meta":69,"style":69},[49,11412,11413,11417,11421,11425,11429,11433,11437],{"__ignoreMap":69},[73,11414,11415],{"class":75,"line":76},[73,11416,4378],{},[73,11418,11419],{"class":75,"line":82},[73,11420,86],{"emptyLinePlaceholder":85},[73,11422,11423],{"class":75,"line":89},[73,11424,4387],{},[73,11426,11427],{"class":75,"line":95},[73,11428,4392],{},[73,11430,11431],{"class":75,"line":101},[73,11432,4397],{},[73,11434,11435],{"class":75,"line":106},[73,11436,86],{"emptyLinePlaceholder":85},[73,11438,11439],{"class":75,"line":112},[73,11440,4406],{},[10,11442,146],{},[64,11444,11446],{"className":11445,"code":4412,"language":152,"meta":69},[150],[49,11447,4412],{"__ignoreMap":69},[10,11449,157],{},[14,11451,160],{"id":160},[162,11453,11454,11458],{},[40,11455,4423,11456,4427],{},[49,11457,4426],{},[40,11459,4430,11460,4433],{},[49,11461,4426],{},[193,11463,195],{"id":195},[10,11465,4438],{},[10,11467,11468],{},[26,11469],{"alt":4443,"src":4444},[10,11471,4447,11472,4450],{},[49,11473,4426],{},[14,11475,210],{"id":210},[37,11477,11478,11480],{},[40,11479,4457],{},[40,11481,4460],{},[14,11483,221],{"id":221},[162,11485,11486,11490],{},[40,11487,2366,11488,4469],{},[49,11489,4346],{},[40,11491,4472],{},[10,11493,232],{},[14,11495,235],{"id":235},[10,11497,4479],{},[240,11499,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11501},[11502,11503,11504,11505,11506,11509,11510,11511],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":11507},[11508],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":4323,"description":4328},[255,4346,4501],{"id":4504,"title":4505,"body":11516,"category":255,"cover":256,"description":4510,"extension":257,"meta":11641,"navigation":85,"path":4658,"pinned":260,"publishedAt":261,"seo":11642,"slug":4660,"stem":4661,"summary":4662,"tags":11643,"updatedAt":261,"visible":85,"__hash__":4665},{"type":7,"value":11517,"toc":11631},[11518,11520,11522,11524,11526,11530,11534,11536,11546,11548,11550,11582,11584,11589,11591,11593,11605,11607,11613,11615,11623,11625,11627,11629],[10,11519,4510],{},[14,11521,16],{"id":16},[10,11523,4515],{},[14,11525,22],{"id":22},[10,11527,11528],{},[26,11529],{"alt":4522,"src":4523},[10,11531,11532,4528],{},[49,11533,4363],{},[14,11535,35],{"id":35},[37,11537,11538,11542,11544],{},[40,11539,11540,4538],{},[49,11541,4537],{},[40,11543,4541],{},[40,11545,4544],{},[14,11547,59],{"id":59},[10,11549,62],{},[64,11551,11552],{"className":66,"code":4551,"language":68,"meta":69,"style":69},[49,11553,11554,11558,11562,11566,11570,11574,11578],{"__ignoreMap":69},[73,11555,11556],{"class":75,"line":76},[73,11557,4558],{},[73,11559,11560],{"class":75,"line":82},[73,11561,86],{"emptyLinePlaceholder":85},[73,11563,11564],{"class":75,"line":89},[73,11565,4567],{},[73,11567,11568],{"class":75,"line":95},[73,11569,4572],{},[73,11571,11572],{"class":75,"line":101},[73,11573,86],{"emptyLinePlaceholder":85},[73,11575,11576],{"class":75,"line":106},[73,11577,4581],{},[73,11579,11580],{"class":75,"line":112},[73,11581,4586],{},[10,11583,146],{},[64,11585,11587],{"className":11586,"code":4592,"language":152,"meta":69},[150],[49,11588,4592],{"__ignoreMap":69},[10,11590,157],{},[14,11592,160],{"id":160},[162,11594,11595,11601],{},[40,11596,4603,11597,4606,11599,4609],{},[49,11598,4363],{},[49,11600,186],{},[40,11602,11603,4614],{},[49,11604,4537],{},[14,11606,210],{"id":210},[37,11608,11609,11611],{},[40,11610,4621],{},[40,11612,4624],{},[14,11614,221],{"id":221},[162,11616,11617,11619],{},[40,11618,4631],{},[40,11620,2366,11621,4637],{},[49,11622,4636],{},[10,11624,232],{},[14,11626,235],{"id":235},[10,11628,4644],{},[240,11630,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11632},[11633,11634,11635,11636,11637,11638,11639,11640],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":4505,"description":4510},[255,4363,4664],{"id":4667,"title":4668,"body":11645,"category":255,"cover":256,"description":4673,"extension":257,"meta":11790,"navigation":85,"path":4848,"pinned":260,"publishedAt":261,"seo":11791,"slug":4850,"stem":4851,"summary":4852,"tags":11792,"updatedAt":261,"visible":85,"__hash__":4854},{"type":7,"value":11646,"toc":11780},[11647,11649,11651,11653,11655,11659,11665,11667,11681,11683,11685,11729,11731,11736,11738,11740,11750,11752,11764,11766,11772,11774,11776,11778],[10,11648,4673],{},[14,11650,16],{"id":16},[10,11652,4678],{},[14,11654,22],{"id":22},[10,11656,11657],{},[26,11658],{"alt":4685,"src":4686},[10,11660,11661,4692,11663,4696],{},[49,11662,4691],{},[49,11664,4695],{},[14,11666,35],{"id":35},[37,11668,11669,11671,11677],{},[40,11670,4703],{},[40,11672,11673,4708,11675,4711],{},[49,11674,4691],{},[49,11676,4346],{},[40,11678,4714,11679,4717],{},[49,11680,4695],{},[14,11682,59],{"id":59},[10,11684,62],{},[64,11686,11687],{"className":66,"code":4724,"language":68,"meta":69,"style":69},[49,11688,11689,11693,11697,11701,11705,11709,11713,11717,11721,11725],{"__ignoreMap":69},[73,11690,11691],{"class":75,"line":76},[73,11692,4731],{},[73,11694,11695],{"class":75,"line":82},[73,11696,86],{"emptyLinePlaceholder":85},[73,11698,11699],{"class":75,"line":89},[73,11700,4740],{},[73,11702,11703],{"class":75,"line":95},[73,11704,4745],{},[73,11706,11707],{"class":75,"line":101},[73,11708,4750],{},[73,11710,11711],{"class":75,"line":106},[73,11712,4755],{},[73,11714,11715],{"class":75,"line":112},[73,11716,4760],{},[73,11718,11719],{"class":75,"line":118},[73,11720,4586],{},[73,11722,11723],{"class":75,"line":124},[73,11724,86],{"emptyLinePlaceholder":85},[73,11726,11727],{"class":75,"line":129},[73,11728,4773],{},[10,11730,146],{},[64,11732,11734],{"className":11733,"code":4779,"language":152,"meta":69},[150],[49,11735,4779],{"__ignoreMap":69},[10,11737,157],{},[14,11739,160],{"id":160},[162,11741,11742,11746],{},[40,11743,4790,11744,4793],{},[49,11745,4691],{},[40,11747,4796,11748,4799],{},[49,11749,4695],{},[14,11751,210],{"id":210},[37,11753,11754,11758],{},[40,11755,3493,11756,4808],{},[49,11757,4691],{},[40,11759,4811,11760,4814,11762,4817],{},[49,11761,4346],{},[49,11763,4691],{},[14,11765,221],{"id":221},[162,11767,11768,11770],{},[40,11769,4824],{},[40,11771,4827],{},[10,11773,232],{},[14,11775,235],{"id":235},[10,11777,4834],{},[240,11779,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11781},[11782,11783,11784,11785,11786,11787,11788,11789],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":4668,"description":4673},[255,4695,4691],{"id":4856,"title":4857,"body":11794,"category":255,"cover":256,"description":4862,"extension":257,"meta":11933,"navigation":85,"path":5034,"pinned":260,"publishedAt":261,"seo":11934,"slug":5036,"stem":5037,"summary":5038,"tags":11935,"updatedAt":261,"visible":85,"__hash__":5042},{"type":7,"value":11795,"toc":11921},[11796,11798,11800,11802,11804,11808,11810,11812,11828,11830,11832,11860,11862,11867,11869,11871,11883,11885,11887,11891,11893,11895,11905,11907,11913,11915,11917,11919],[10,11797,4862],{},[14,11799,16],{"id":16},[10,11801,4867],{},[14,11803,22],{"id":22},[10,11805,11806],{},[26,11807],{"alt":4874,"src":4875},[10,11809,4878],{},[14,11811,35],{"id":35},[37,11813,11814,11816,11818],{},[40,11815,4885],{},[40,11817,4888],{},[40,11819,4891,11820,2284,11822,4898,11824,2284,11826,391],{},[49,11821,4894],{},[49,11823,4897],{},[49,11825,4901],{},[49,11827,4904],{},[14,11829,59],{"id":59},[10,11831,62],{},[64,11833,11834],{"className":66,"code":4911,"language":68,"meta":69,"style":69},[49,11835,11836,11840,11844,11848,11852,11856],{"__ignoreMap":69},[73,11837,11838],{"class":75,"line":76},[73,11839,4918],{},[73,11841,11842],{"class":75,"line":82},[73,11843,86],{"emptyLinePlaceholder":85},[73,11845,11846],{"class":75,"line":89},[73,11847,4927],{},[73,11849,11850],{"class":75,"line":95},[73,11851,4932],{},[73,11853,11854],{"class":75,"line":101},[73,11855,4937],{},[73,11857,11858],{"class":75,"line":106},[73,11859,4942],{},[10,11861,146],{},[64,11863,11865],{"className":11864,"code":4948,"language":152,"meta":69},[150],[49,11866,4948],{"__ignoreMap":69},[10,11868,157],{},[14,11870,160],{"id":160},[162,11872,11873,11881],{},[40,11874,4959,11875,4962,11877,1186,11879,391],{},[49,11876,4894],{},[49,11878,4965],{},[49,11880,4968],{},[40,11882,4971],{},[193,11884,195],{"id":195},[10,11886,4976],{},[10,11888,11889],{},[26,11890],{"alt":4981,"src":4982},[10,11892,4985],{},[14,11894,210],{"id":210},[37,11896,11897,11903],{},[40,11898,4992,11899,1038,11901,4998],{},[49,11900,4995],{},[49,11902,4901],{},[40,11904,5001],{},[14,11906,221],{"id":221},[162,11908,11909,11911],{},[40,11910,5008],{},[40,11912,5011],{},[10,11914,232],{},[14,11916,235],{"id":235},[10,11918,5018],{},[240,11920,242],{},{"title":69,"searchDepth":82,"depth":82,"links":11922},[11923,11924,11925,11926,11927,11930,11931,11932],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":11928},[11929],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":4857,"description":4862},[255,5040,5041],{"id":5044,"title":5045,"body":11937,"category":255,"cover":256,"description":5050,"extension":257,"meta":12054,"navigation":85,"path":5189,"pinned":260,"publishedAt":261,"seo":12055,"slug":5191,"stem":5192,"summary":5193,"tags":12056,"updatedAt":261,"visible":85,"__hash__":5197},{"type":7,"value":11938,"toc":12044},[11939,11941,11943,11945,11947,11951,11953,11955,11963,11965,11967,11999,12001,12006,12008,12010,12018,12020,12028,12030,12036,12038,12040,12042],[10,11940,5050],{},[14,11942,16],{"id":16},[10,11944,5055],{},[14,11946,22],{"id":22},[10,11948,11949],{},[26,11950],{"alt":5062,"src":5063},[10,11952,5066],{},[14,11954,35],{"id":35},[37,11956,11957,11959,11961],{},[40,11958,5073],{},[40,11960,5076],{},[40,11962,5079],{},[14,11964,59],{"id":59},[10,11966,62],{},[64,11968,11969],{"className":66,"code":5086,"language":68,"meta":69,"style":69},[49,11970,11971,11975,11979,11983,11987,11991,11995],{"__ignoreMap":69},[73,11972,11973],{"class":75,"line":76},[73,11974,5093],{},[73,11976,11977],{"class":75,"line":82},[73,11978,86],{"emptyLinePlaceholder":85},[73,11980,11981],{"class":75,"line":89},[73,11982,5102],{},[73,11984,11985],{"class":75,"line":95},[73,11986,5107],{},[73,11988,11989],{"class":75,"line":101},[73,11990,86],{"emptyLinePlaceholder":85},[73,11992,11993],{"class":75,"line":106},[73,11994,5116],{},[73,11996,11997],{"class":75,"line":112},[73,11998,5121],{},[10,12000,146],{},[64,12002,12004],{"className":12003,"code":5127,"language":152,"meta":69},[150],[49,12005,5127],{"__ignoreMap":69},[10,12007,157],{},[14,12009,160],{"id":160},[162,12011,12012,12014],{},[40,12013,5138],{},[40,12015,5141,12016,5145],{},[49,12017,5144],{},[14,12019,210],{"id":210},[37,12021,12022,12026],{},[40,12023,5152,12024,5155],{},[49,12025,4363],{},[40,12027,5158],{},[14,12029,221],{"id":221},[162,12031,12032,12034],{},[40,12033,5165],{},[40,12035,5168],{},[10,12037,232],{},[14,12039,235],{"id":235},[10,12041,5175],{},[240,12043,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12045},[12046,12047,12048,12049,12050,12051,12052,12053],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5045,"description":5050},[255,5195,5196],{"id":5199,"title":5200,"body":12058,"category":255,"cover":256,"description":5205,"extension":257,"meta":12177,"navigation":85,"path":5349,"pinned":260,"publishedAt":261,"seo":12178,"slug":5351,"stem":5352,"summary":5353,"tags":12179,"updatedAt":261,"visible":85,"__hash__":5357},{"type":7,"value":12059,"toc":12167},[12060,12062,12064,12066,12068,12072,12074,12076,12084,12086,12088,12120,12122,12127,12129,12131,12141,12143,12149,12151,12159,12161,12163,12165],[10,12061,5205],{},[14,12063,16],{"id":16},[10,12065,5210],{},[14,12067,22],{"id":22},[10,12069,12070],{},[26,12071],{"alt":5217,"src":5218},[10,12073,5221],{},[14,12075,35],{"id":35},[37,12077,12078,12080,12082],{},[40,12079,5228],{},[40,12081,5231],{},[40,12083,5234],{},[14,12085,59],{"id":59},[10,12087,62],{},[64,12089,12090],{"className":66,"code":5241,"language":68,"meta":69,"style":69},[49,12091,12092,12096,12100,12104,12108,12112,12116],{"__ignoreMap":69},[73,12093,12094],{"class":75,"line":76},[73,12095,5248],{},[73,12097,12098],{"class":75,"line":82},[73,12099,5253],{},[73,12101,12102],{"class":75,"line":89},[73,12103,5258],{},[73,12105,12106],{"class":75,"line":95},[73,12107,86],{"emptyLinePlaceholder":85},[73,12109,12110],{"class":75,"line":101},[73,12111,5267],{},[73,12113,12114],{"class":75,"line":106},[73,12115,5272],{},[73,12117,12118],{"class":75,"line":112},[73,12119,5277],{},[10,12121,146],{},[64,12123,12125],{"className":12124,"code":5283,"language":152,"meta":69},[150],[49,12126,5283],{"__ignoreMap":69},[10,12128,157],{},[14,12130,160],{"id":160},[162,12132,12133,12137],{},[40,12134,967,12135,5297],{},[49,12136,5296],{},[40,12138,5300,12139,5304],{},[49,12140,5303],{},[14,12142,210],{"id":210},[37,12144,12145,12147],{},[40,12146,5311],{},[40,12148,5314],{},[14,12150,221],{"id":221},[162,12152,12153,12157],{},[40,12154,5321,12155,5325],{},[49,12156,5324],{},[40,12158,5328],{},[10,12160,232],{},[14,12162,235],{"id":235},[10,12164,5335],{},[240,12166,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12168},[12169,12170,12171,12172,12173,12174,12175,12176],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5200,"description":5205},[255,5355,5356],{"id":5359,"title":5360,"body":12181,"category":255,"cover":256,"description":5365,"extension":257,"meta":12326,"navigation":85,"path":5546,"pinned":260,"publishedAt":261,"seo":12327,"slug":5548,"stem":5549,"summary":5550,"tags":12328,"updatedAt":261,"visible":85,"__hash__":5554},{"type":7,"value":12182,"toc":12314},[12183,12185,12187,12189,12191,12195,12199,12201,12213,12215,12217,12245,12247,12252,12254,12256,12270,12272,12274,12278,12286,12288,12298,12300,12306,12308,12310,12312],[10,12184,5365],{},[14,12186,16],{"id":16},[10,12188,5370],{},[14,12190,22],{"id":22},[10,12192,12193],{},[26,12194],{"alt":5377,"src":5378},[10,12196,5381,12197,5385],{},[49,12198,5384],{},[14,12200,35],{"id":35},[37,12202,12203,12205,12207],{},[40,12204,5392],{},[40,12206,5395],{},[40,12208,5398,12209,5401,12211,391],{},[49,12210,5384],{},[49,12212,5404],{},[14,12214,59],{"id":59},[10,12216,62],{},[64,12218,12219],{"className":66,"code":5411,"language":68,"meta":69,"style":69},[49,12220,12221,12225,12229,12233,12237,12241],{"__ignoreMap":69},[73,12222,12223],{"class":75,"line":76},[73,12224,5418],{},[73,12226,12227],{"class":75,"line":82},[73,12228,5423],{},[73,12230,12231],{"class":75,"line":89},[73,12232,5428],{},[73,12234,12235],{"class":75,"line":95},[73,12236,86],{"emptyLinePlaceholder":85},[73,12238,12239],{"class":75,"line":101},[73,12240,5437],{},[73,12242,12243],{"class":75,"line":106},[73,12244,5442],{},[10,12246,146],{},[64,12248,12250],{"className":12249,"code":5448,"language":152,"meta":69},[150],[49,12251,5448],{"__ignoreMap":69},[10,12253,157],{},[14,12255,160],{"id":160},[162,12257,12258,12264],{},[40,12259,5459,12260,2284,12262,5465],{},[49,12261,5462],{},[49,12263,4426],{},[40,12265,12266,5471,12268,5475],{},[49,12267,5470],{},[49,12269,5474],{},[193,12271,195],{"id":195},[10,12273,5480],{},[10,12275,12276],{},[26,12277],{"alt":5485,"src":5486},[10,12279,12280,2284,12282,1186,12284,5496],{},[49,12281,5462],{},[49,12283,4426],{},[49,12285,5495],{},[14,12287,210],{"id":210},[37,12289,12290,12294],{},[40,12291,5503,12292,5507],{},[49,12293,5506],{},[40,12295,5510,12296,5513],{},[49,12297,5495],{},[14,12299,221],{"id":221},[162,12301,12302,12304],{},[40,12303,5520],{},[40,12305,5523],{},[10,12307,232],{},[14,12309,235],{"id":235},[10,12311,5530],{},[240,12313,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12315},[12316,12317,12318,12319,12320,12323,12324,12325],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":12321},[12322],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5360,"description":5365},[255,5552,5553],{"id":5556,"title":5557,"body":12330,"category":255,"cover":256,"description":5562,"extension":257,"meta":12479,"navigation":85,"path":5742,"pinned":260,"publishedAt":261,"seo":12480,"slug":5744,"stem":5745,"summary":5746,"tags":12481,"updatedAt":261,"visible":85,"__hash__":5750},{"type":7,"value":12331,"toc":12467},[12332,12334,12336,12338,12340,12344,12346,12348,12360,12362,12364,12408,12410,12415,12417,12419,12431,12433,12435,12439,12441,12443,12451,12453,12459,12461,12463,12465],[10,12333,5562],{},[14,12335,16],{"id":16},[10,12337,5567],{},[14,12339,22],{"id":22},[10,12341,12342],{},[26,12343],{"alt":5574,"src":5575},[10,12345,5578],{},[14,12347,35],{"id":35},[37,12349,12350,12352,12356],{},[40,12351,5585],{},[40,12353,12354,5591],{},[49,12355,5590],{},[40,12357,12358,5597],{},[49,12359,5596],{},[14,12361,59],{"id":59},[10,12363,62],{},[64,12365,12366],{"className":66,"code":5604,"language":68,"meta":69,"style":69},[49,12367,12368,12372,12376,12380,12384,12388,12392,12396,12400,12404],{"__ignoreMap":69},[73,12369,12370],{"class":75,"line":76},[73,12371,5611],{},[73,12373,12374],{"class":75,"line":82},[73,12375,5616],{},[73,12377,12378],{"class":75,"line":89},[73,12379,86],{"emptyLinePlaceholder":85},[73,12381,12382],{"class":75,"line":95},[73,12383,5625],{},[73,12385,12386],{"class":75,"line":101},[73,12387,5630],{},[73,12389,12390],{"class":75,"line":106},[73,12391,86],{"emptyLinePlaceholder":85},[73,12393,12394],{"class":75,"line":112},[73,12395,5639],{},[73,12397,12398],{"class":75,"line":118},[73,12399,5644],{},[73,12401,12402],{"class":75,"line":124},[73,12403,86],{"emptyLinePlaceholder":85},[73,12405,12406],{"class":75,"line":129},[73,12407,5653],{},[10,12409,146],{},[64,12411,12413],{"className":12412,"code":5659,"language":152,"meta":69},[150],[49,12414,5659],{"__ignoreMap":69},[10,12416,157],{},[14,12418,160],{"id":160},[162,12420,12421,12425],{},[40,12422,5670,12423,5673],{},[49,12424,176],{},[40,12426,12427,5679,12429,391],{},[49,12428,5678],{},[49,12430,5682],{},[193,12432,195],{"id":195},[10,12434,5687],{},[10,12436,12437],{},[26,12438],{"alt":5692,"src":5693},[10,12440,5696],{},[14,12442,210],{"id":210},[37,12444,12445,12449],{},[40,12446,5703,12447,5706],{},[49,12448,5404],{},[40,12450,5709],{},[14,12452,221],{"id":221},[162,12454,12455,12457],{},[40,12456,5716],{},[40,12458,5719],{},[10,12460,232],{},[14,12462,235],{"id":235},[10,12464,5726],{},[240,12466,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12468},[12469,12470,12471,12472,12473,12476,12477,12478],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":12474},[12475],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5557,"description":5562},[255,5748,5749],{"id":4,"title":5,"body":12483,"category":255,"cover":256,"description":12,"extension":257,"meta":12644,"navigation":85,"path":259,"pinned":260,"publishedAt":261,"seo":12645,"slug":263,"stem":264,"summary":265,"tags":12646,"updatedAt":261,"visible":85,"__hash__":269},{"type":7,"value":12484,"toc":12632},[12485,12487,12489,12491,12493,12497,12499,12501,12513,12515,12517,12569,12571,12576,12578,12580,12598,12600,12602,12606,12608,12610,12616,12618,12624,12626,12628,12630],[10,12486,12],{},[14,12488,16],{"id":16},[10,12490,19],{},[14,12492,22],{"id":22},[10,12494,12495],{},[26,12496],{"alt":28,"src":29},[10,12498,32],{},[14,12500,35],{"id":35},[37,12502,12503,12505,12507],{},[40,12504,42],{},[40,12506,45],{},[40,12508,12509,52,12511,56],{},[49,12510,51],{},[49,12512,55],{},[14,12514,59],{"id":59},[10,12516,62],{},[64,12518,12519],{"className":66,"code":67,"language":68,"meta":69,"style":69},[49,12520,12521,12525,12529,12533,12537,12541,12545,12549,12553,12557,12561,12565],{"__ignoreMap":69},[73,12522,12523],{"class":75,"line":76},[73,12524,79],{},[73,12526,12527],{"class":75,"line":82},[73,12528,86],{"emptyLinePlaceholder":85},[73,12530,12531],{"class":75,"line":89},[73,12532,92],{},[73,12534,12535],{"class":75,"line":95},[73,12536,98],{},[73,12538,12539],{"class":75,"line":101},[73,12540,86],{"emptyLinePlaceholder":85},[73,12542,12543],{"class":75,"line":106},[73,12544,109],{},[73,12546,12547],{"class":75,"line":112},[73,12548,115],{},[73,12550,12551],{"class":75,"line":118},[73,12552,121],{},[73,12554,12555],{"class":75,"line":124},[73,12556,86],{"emptyLinePlaceholder":85},[73,12558,12559],{"class":75,"line":129},[73,12560,132],{},[73,12562,12563],{"class":75,"line":135},[73,12564,86],{"emptyLinePlaceholder":85},[73,12566,12567],{"class":75,"line":140},[73,12568,143],{},[10,12570,146],{},[64,12572,12574],{"className":12573,"code":151,"language":152,"meta":69},[150],[49,12575,151],{"__ignoreMap":69},[10,12577,157],{},[14,12579,160],{"id":160},[162,12581,12582,12592],{},[40,12583,12584,169,12586,173,12588,177,12590,181],{},[49,12585,168],{},[49,12587,172],{},[49,12589,176],{},[49,12591,180],{},[40,12593,12594,187,12596,191],{},[49,12595,186],{},[49,12597,190],{},[193,12599,195],{"id":195},[10,12601,198],{},[10,12603,12604],{},[26,12605],{"alt":203,"src":204},[10,12607,207],{},[14,12609,210],{"id":210},[37,12611,12612,12614],{},[40,12613,215],{},[40,12615,218],{},[14,12617,221],{"id":221},[162,12619,12620,12622],{},[40,12621,226],{},[40,12623,229],{},[10,12625,232],{},[14,12627,235],{"id":235},[10,12629,238],{},[240,12631,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12633},[12634,12635,12636,12637,12638,12641,12642,12643],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":12639},[12640],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5,"description":12},[255,267,268],{"id":5917,"title":5918,"body":12648,"category":255,"cover":256,"description":5923,"extension":257,"meta":12771,"navigation":85,"path":6074,"pinned":260,"publishedAt":261,"seo":12772,"slug":6076,"stem":6077,"summary":6078,"tags":12773,"updatedAt":261,"visible":85,"__hash__":6082},{"type":7,"value":12649,"toc":12761},[12650,12652,12654,12656,12658,12662,12664,12666,12680,12682,12684,12712,12714,12719,12721,12723,12733,12735,12743,12745,12753,12755,12757,12759],[10,12651,5923],{},[14,12653,16],{"id":16},[10,12655,5928],{},[14,12657,22],{"id":22},[10,12659,12660],{},[26,12661],{"alt":5935,"src":5936},[10,12663,5939],{},[14,12665,35],{"id":35},[37,12667,12668,12670,12672],{},[40,12669,5946],{},[40,12671,5949],{},[40,12673,5952,12674,2284,12676,2284,12678,5960],{},[49,12675,2287],{},[49,12677,2453],{},[49,12679,5959],{},[14,12681,59],{"id":59},[10,12683,62],{},[64,12685,12686],{"className":66,"code":5967,"language":68,"meta":69,"style":69},[49,12687,12688,12692,12696,12700,12704,12708],{"__ignoreMap":69},[73,12689,12690],{"class":75,"line":76},[73,12691,5974],{},[73,12693,12694],{"class":75,"line":82},[73,12695,5979],{},[73,12697,12698],{"class":75,"line":89},[73,12699,5984],{},[73,12701,12702],{"class":75,"line":95},[73,12703,86],{"emptyLinePlaceholder":85},[73,12705,12706],{"class":75,"line":101},[73,12707,5993],{},[73,12709,12710],{"class":75,"line":106},[73,12711,5998],{},[10,12713,146],{},[64,12715,12717],{"className":12716,"code":6004,"language":152,"meta":69},[150],[49,12718,6004],{"__ignoreMap":69},[10,12720,157],{},[14,12722,160],{"id":160},[162,12724,12725,12731],{},[40,12726,6015,12727,6019,12729,6022],{},[49,12728,6018],{},[49,12730,2273],{},[40,12732,6025],{},[14,12734,210],{"id":210},[37,12736,12737,12741],{},[40,12738,6032,12739,6036],{},[49,12740,6035],{},[40,12742,6039],{},[14,12744,221],{"id":221},[162,12746,12747,12749],{},[40,12748,6046],{},[40,12750,6049,12751,6053],{},[49,12752,6052],{},[10,12754,232],{},[14,12756,235],{"id":235},[10,12758,6060],{},[240,12760,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12762},[12763,12764,12765,12766,12767,12768,12769,12770],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":5918,"description":5923},[255,6080,6081],{"id":6084,"title":6085,"body":12775,"category":255,"cover":256,"description":6090,"extension":257,"meta":12952,"navigation":85,"path":6318,"pinned":260,"publishedAt":261,"seo":12953,"slug":6320,"stem":6321,"summary":6322,"tags":12954,"updatedAt":261,"visible":85,"__hash__":6326},{"type":7,"value":12776,"toc":12940},[12777,12779,12781,12785,12787,12791,12797,12799,12811,12813,12817,12841,12845,12861,12867,12869,12874,12876,12878,12894,12896,12898,12902,12906,12908,12920,12922,12932,12934,12936,12938],[10,12778,6090],{},[14,12780,16],{"id":16},[10,12782,6095,12783,6098],{},[324,12784,6018],{},[14,12786,22],{"id":22},[10,12788,12789],{},[26,12790],{"alt":6105,"src":6106},[10,12792,6109,12793,6113,12795,6117],{},[49,12794,6112],{},[49,12796,6116],{},[14,12798,35],{"id":35},[37,12800,12801,12805,12807],{},[40,12802,6124,12803,6127],{},[49,12804,1200],{},[40,12806,6130],{},[40,12808,6133,12809,6137],{},[49,12810,6136],{},[14,12812,59],{"id":59},[10,12814,6142,12815,6146],{},[49,12816,6145],{},[64,12818,12819],{"className":66,"code":6149,"language":68,"meta":69,"style":69},[49,12820,12821,12825,12829,12833,12837],{"__ignoreMap":69},[73,12822,12823],{"class":75,"line":76},[73,12824,6156],{},[73,12826,12827],{"class":75,"line":82},[73,12828,6161],{},[73,12830,12831],{"class":75,"line":89},[73,12832,86],{"emptyLinePlaceholder":85},[73,12834,12835],{"class":75,"line":95},[73,12836,6170],{},[73,12838,12839],{"class":75,"line":101},[73,12840,6175],{},[10,12842,6178,12843,6182],{},[49,12844,6181],{},[64,12846,12847],{"className":66,"code":6185,"language":68,"meta":69,"style":69},[49,12848,12849,12853,12857],{"__ignoreMap":69},[73,12850,12851],{"class":75,"line":76},[73,12852,6192],{},[73,12854,12855],{"class":75,"line":82},[73,12856,86],{"emptyLinePlaceholder":85},[73,12858,12859],{"class":75,"line":89},[73,12860,6201],{},[10,12862,6204,12863,1186,12865,391],{},[49,12864,6207],{},[49,12866,6210],{},[10,12868,146],{},[64,12870,12872],{"className":12871,"code":6216,"language":152,"meta":69},[150],[49,12873,6216],{"__ignoreMap":69},[10,12875,157],{},[14,12877,160],{"id":160},[162,12879,12880,12886],{},[40,12881,6227,12882,6230,12884,6234],{},[49,12883,6145],{},[49,12885,6233],{},[40,12887,12888,6239,12890,6242,12892,6245],{},[49,12889,6181],{},[49,12891,6145],{},[49,12893,6181],{},[193,12895,195],{"id":195},[10,12897,6250],{},[10,12899,12900],{},[26,12901],{"alt":6255,"src":6256},[10,12903,6259,12904,6262],{},[49,12905,6233],{},[14,12907,210],{"id":210},[37,12909,12910,12916],{},[40,12911,6269,12912,1186,12914,391],{},[49,12913,6145],{},[49,12915,6181],{},[40,12917,6276,12918,6280],{},[49,12919,6279],{},[14,12921,221],{"id":221},[162,12923,12924,12928],{},[40,12925,2381,12926,6290],{},[49,12927,6289],{},[40,12929,6293,12930,391],{},[49,12931,6112],{},[10,12933,232],{},[14,12935,235],{"id":235},[10,12937,6302],{},[240,12939,242],{},{"title":69,"searchDepth":82,"depth":82,"links":12941},[12942,12943,12944,12945,12946,12949,12950,12951],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":12947},[12948],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":6085,"description":6090},[255,6324,6325],{"id":6328,"title":6329,"body":12956,"category":255,"cover":256,"description":6334,"extension":257,"meta":13095,"navigation":85,"path":6500,"pinned":260,"publishedAt":261,"seo":13096,"slug":6502,"stem":6503,"summary":6504,"tags":13097,"updatedAt":261,"visible":85,"__hash__":6507},{"type":7,"value":12957,"toc":13085},[12958,12960,12962,12964,12966,12970,12972,12974,12984,12986,12988,13028,13030,13035,13037,13039,13057,13059,13067,13069,13077,13079,13081,13083],[10,12959,6334],{},[14,12961,16],{"id":16},[10,12963,6339],{},[14,12965,22],{"id":22},[10,12967,12968],{},[26,12969],{"alt":6346,"src":6347},[10,12971,6350],{},[14,12973,35],{"id":35},[37,12975,12976,12980,12982],{},[40,12977,12978,6360],{},[49,12979,6359],{},[40,12981,6363],{},[40,12983,6366],{},[14,12985,59],{"id":59},[10,12987,1603],{},[64,12989,12990],{"className":620,"code":6373,"language":622,"meta":69,"style":69},[49,12991,12992,13002,13008,13014,13024],{"__ignoreMap":69},[73,12993,12994,12996,12998,13000],{"class":75,"line":76},[73,12995,720],{"class":629},[73,12997,662],{"class":632},[73,12999,6384],{"class":665},[73,13001,6387],{"class":665},[73,13003,13004,13006],{"class":75,"line":82},[73,13005,6392],{"class":632},[73,13007,6395],{"class":665},[73,13009,13010,13012],{"class":75,"line":89},[73,13011,68],{"class":629},[73,13013,633],{"class":632},[73,13015,13016,13018,13020,13022],{"class":75,"line":95},[73,13017,68],{"class":629},[73,13019,662],{"class":632},[73,13021,666],{"class":665},[73,13023,633],{"class":632},[73,13025,13026],{"class":75,"line":101},[73,13027,6416],{"class":629},[10,13029,146],{},[64,13031,13033],{"className":13032,"code":6422,"language":152,"meta":69},[150],[49,13034,6422],{"__ignoreMap":69},[10,13036,157],{},[14,13038,160],{"id":160},[162,13040,13041,13047],{},[40,13042,13043,6436,13045,6439],{},[49,13044,6435],{},[49,13046,720],{},[40,13048,6442,13049,52,13051,6448,13053,3754,13055,6454],{},[49,13050,68],{},[49,13052,6447],{},[49,13054,6359],{},[49,13056,6453],{},[14,13058,210],{"id":210},[37,13060,13061,13063],{},[40,13062,6461],{},[40,13064,3493,13065,6466],{},[49,13066,6359],{},[14,13068,221],{"id":221},[162,13070,13071,13075],{},[40,13072,6473,13073,391],{},[49,13074,6476],{},[40,13076,6479],{},[10,13078,232],{},[14,13080,235],{"id":235},[10,13082,6486],{},[240,13084,1687],{},{"title":69,"searchDepth":82,"depth":82,"links":13086},[13087,13088,13089,13090,13091,13092,13093,13094],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":6329,"description":6334},[255,6506,290],{"id":6509,"title":6510,"body":13099,"category":255,"cover":256,"description":6515,"extension":257,"meta":13252,"navigation":85,"path":6704,"pinned":260,"publishedAt":261,"seo":13253,"slug":6706,"stem":6707,"summary":6708,"tags":13254,"updatedAt":261,"visible":85,"__hash__":6712},{"type":7,"value":13100,"toc":13242},[13101,13103,13105,13107,13109,13113,13119,13121,13137,13139,13141,13185,13187,13192,13194,13196,13208,13210,13224,13226,13234,13236,13238,13240],[10,13102,6515],{},[14,13104,16],{"id":16},[10,13106,6520],{},[14,13108,22],{"id":22},[10,13110,13111],{},[26,13112],{"alt":6527,"src":6528},[10,13114,13115,6534,13117,6537],{},[49,13116,6533],{},[49,13118,2463],{},[14,13120,35],{"id":35},[37,13122,13123,13125,13133],{},[40,13124,6544],{},[40,13126,13127,2284,13129,2284,13131,6556],{},[49,13128,6549],{},[49,13130,6552],{},[49,13132,6555],{},[40,13134,6559,13135,6563],{},[49,13136,6562],{},[14,13138,59],{"id":59},[10,13140,62],{},[64,13142,13143],{"className":66,"code":6570,"language":68,"meta":69,"style":69},[49,13144,13145,13149,13153,13157,13161,13165,13169,13173,13177,13181],{"__ignoreMap":69},[73,13146,13147],{"class":75,"line":76},[73,13148,6577],{},[73,13150,13151],{"class":75,"line":82},[73,13152,86],{"emptyLinePlaceholder":85},[73,13154,13155],{"class":75,"line":89},[73,13156,6586],{},[73,13158,13159],{"class":75,"line":95},[73,13160,6591],{},[73,13162,13163],{"class":75,"line":101},[73,13164,6596],{},[73,13166,13167],{"class":75,"line":106},[73,13168,86],{"emptyLinePlaceholder":85},[73,13170,13171],{"class":75,"line":112},[73,13172,6605],{},[73,13174,13175],{"class":75,"line":118},[73,13176,6610],{},[73,13178,13179],{"class":75,"line":124},[73,13180,6615],{},[73,13182,13183],{"class":75,"line":129},[73,13184,6620],{},[10,13186,146],{},[64,13188,13190],{"className":13189,"code":6626,"language":152,"meta":69},[150],[49,13191,6626],{"__ignoreMap":69},[10,13193,157],{},[14,13195,160],{"id":160},[162,13197,13198,13202],{},[40,13199,13200,6640],{},[49,13201,6639],{},[40,13203,2366,13204,6645,13206,6648],{},[49,13205,2463],{},[49,13207,6533],{},[14,13209,210],{"id":210},[37,13211,13212,13218],{},[40,13213,3493,13214,6657,13216,6660],{},[49,13215,6533],{},[49,13217,6549],{},[40,13219,6663,13220,1038,13222,6669],{},[49,13221,2463],{},[49,13223,6668],{},[14,13225,221],{"id":221},[162,13227,13228,13232],{},[40,13229,6676,13230,6680],{},[49,13231,6679],{},[40,13233,6683],{},[10,13235,232],{},[14,13237,235],{"id":235},[10,13239,6690],{},[240,13241,242],{},{"title":69,"searchDepth":82,"depth":82,"links":13243},[13244,13245,13246,13247,13248,13249,13250,13251],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":6510,"description":6515},[255,6710,6711],{"id":6714,"title":6715,"body":13256,"category":255,"cover":256,"description":6720,"extension":257,"meta":13403,"navigation":85,"path":6899,"pinned":260,"publishedAt":261,"seo":13404,"slug":6901,"stem":6902,"summary":6903,"tags":13405,"updatedAt":261,"visible":85,"__hash__":6907},{"type":7,"value":13257,"toc":13393},[13258,13260,13262,13264,13266,13270,13272,13274,13292,13294,13296,13344,13346,13351,13353,13355,13363,13365,13375,13377,13385,13387,13389,13391],[10,13259,6720],{},[14,13261,16],{"id":16},[10,13263,6725],{},[14,13265,22],{"id":22},[10,13267,13268],{},[26,13269],{"alt":6732,"src":6733},[10,13271,6736],{},[14,13273,35],{"id":35},[37,13275,13276,13280,13286],{},[40,13277,13278,6746],{},[49,13279,6745],{},[40,13281,13282,6752,13284,391],{},[49,13283,6751],{},[49,13285,6755],{},[40,13287,6758,13288,6762,13290,6766],{},[49,13289,6761],{},[49,13291,6765],{},[14,13293,59],{"id":59},[10,13295,62],{},[64,13297,13298],{"className":66,"code":6773,"language":68,"meta":69,"style":69},[49,13299,13300,13304,13308,13312,13316,13320,13324,13328,13332,13336,13340],{"__ignoreMap":69},[73,13301,13302],{"class":75,"line":76},[73,13303,6577],{},[73,13305,13306],{"class":75,"line":82},[73,13307,86],{"emptyLinePlaceholder":85},[73,13309,13310],{"class":75,"line":89},[73,13311,6788],{},[73,13313,13314],{"class":75,"line":95},[73,13315,6793],{},[73,13317,13318],{"class":75,"line":101},[73,13319,6798],{},[73,13321,13322],{"class":75,"line":106},[73,13323,6803],{},[73,13325,13326],{"class":75,"line":112},[73,13327,86],{"emptyLinePlaceholder":85},[73,13329,13330],{"class":75,"line":118},[73,13331,6812],{},[73,13333,13334],{"class":75,"line":124},[73,13335,6817],{},[73,13337,13338],{"class":75,"line":129},[73,13339,6822],{},[73,13341,13342],{"class":75,"line":135},[73,13343,6827],{},[10,13345,146],{},[64,13347,13349],{"className":13348,"code":6833,"language":152,"meta":69},[150],[49,13350,6833],{"__ignoreMap":69},[10,13352,157],{},[14,13354,160],{"id":160},[162,13356,13357,13361],{},[40,13358,6844,13359,6847],{},[49,13360,6761],{},[40,13362,6850],{},[14,13364,210],{"id":210},[37,13366,13367,13371],{},[40,13368,2366,13369,6859],{},[49,13370,6745],{},[40,13372,6862,13373,391],{},[49,13374,6865],{},[14,13376,221],{"id":221},[162,13378,13379,13381],{},[40,13380,6872],{},[40,13382,6875,13383,6878],{},[49,13384,365],{},[10,13386,232],{},[14,13388,235],{"id":235},[10,13390,6885],{},[240,13392,242],{},{"title":69,"searchDepth":82,"depth":82,"links":13394},[13395,13396,13397,13398,13399,13400,13401,13402],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":6715,"description":6720},[255,6905,6906],{"id":6909,"title":6910,"body":13407,"category":255,"cover":256,"description":6915,"extension":257,"meta":13550,"navigation":85,"path":7083,"pinned":260,"publishedAt":261,"seo":13551,"slug":7085,"stem":7086,"summary":7087,"tags":13552,"updatedAt":261,"visible":85,"__hash__":7091},{"type":7,"value":13408,"toc":13540},[13409,13411,13413,13415,13417,13421,13427,13429,13439,13441,13443,13495,13497,13502,13504,13506,13516,13518,13524,13526,13532,13534,13536,13538],[10,13410,6915],{},[14,13412,16],{"id":16},[10,13414,6920],{},[14,13416,22],{"id":22},[10,13418,13419],{},[26,13420],{"alt":6927,"src":6928},[10,13422,13423,6934,13425,6938],{},[49,13424,6933],{},[49,13426,6937],{},[14,13428,35],{"id":35},[37,13430,13431,13433,13437],{},[40,13432,6945],{},[40,13434,13435,6951],{},[49,13436,6950],{},[40,13438,6954],{},[14,13440,59],{"id":59},[10,13442,62],{},[64,13444,13445],{"className":66,"code":6961,"language":68,"meta":69,"style":69},[49,13446,13447,13451,13455,13459,13463,13467,13471,13475,13479,13483,13487,13491],{"__ignoreMap":69},[73,13448,13449],{"class":75,"line":76},[73,13450,6968],{},[73,13452,13453],{"class":75,"line":82},[73,13454,86],{"emptyLinePlaceholder":85},[73,13456,13457],{"class":75,"line":89},[73,13458,6977],{},[73,13460,13461],{"class":75,"line":95},[73,13462,86],{"emptyLinePlaceholder":85},[73,13464,13465],{"class":75,"line":101},[73,13466,6986],{},[73,13468,13469],{"class":75,"line":106},[73,13470,6991],{},[73,13472,13473],{"class":75,"line":112},[73,13474,6803],{},[73,13476,13477],{"class":75,"line":118},[73,13478,86],{"emptyLinePlaceholder":85},[73,13480,13481],{"class":75,"line":124},[73,13482,7004],{},[73,13484,13485],{"class":75,"line":129},[73,13486,7009],{},[73,13488,13489],{"class":75,"line":135},[73,13490,6822],{},[73,13492,13493],{"class":75,"line":140},[73,13494,7018],{},[10,13496,146],{},[64,13498,13500],{"className":13499,"code":7024,"language":152,"meta":69},[150],[49,13501,7024],{"__ignoreMap":69},[10,13503,157],{},[14,13505,160],{"id":160},[162,13507,13508,13512],{},[40,13509,13510,7037],{},[49,13511,6933],{},[40,13513,13514,7042],{},[49,13515,6937],{},[14,13517,210],{"id":210},[37,13519,13520,13522],{},[40,13521,7049],{},[40,13523,7052],{},[14,13525,221],{"id":221},[162,13527,13528,13530],{},[40,13529,7059],{},[40,13531,7062],{},[10,13533,232],{},[14,13535,235],{"id":235},[10,13537,7069],{},[240,13539,242],{},{"title":69,"searchDepth":82,"depth":82,"links":13541},[13542,13543,13544,13545,13546,13547,13548,13549],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":6910,"description":6915},[255,7089,7090],{"id":7093,"title":7094,"body":13554,"category":255,"cover":256,"description":7099,"extension":257,"meta":13705,"navigation":85,"path":7284,"pinned":260,"publishedAt":261,"seo":13706,"slug":7286,"stem":7287,"summary":7288,"tags":13707,"updatedAt":261,"visible":85,"__hash__":7292},{"type":7,"value":13555,"toc":13695},[13556,13558,13560,13562,13564,13568,13572,13574,13588,13590,13592,13644,13646,13651,13653,13655,13667,13669,13679,13681,13687,13689,13691,13693],[10,13557,7099],{},[14,13559,16],{"id":16},[10,13561,7104],{},[14,13563,22],{"id":22},[10,13565,13566],{},[26,13567],{"alt":7111,"src":7112},[10,13569,13570,7118],{},[49,13571,7117],{},[14,13573,35],{"id":35},[37,13575,13576,13582,13586],{},[40,13577,2366,13578,7128,13580,7132],{},[49,13579,7127],{},[49,13581,7131],{},[40,13583,7135,13584,7139],{},[49,13585,7138],{},[40,13587,7142],{},[14,13589,59],{"id":59},[10,13591,62],{},[64,13593,13594],{"className":66,"code":7149,"language":68,"meta":69,"style":69},[49,13595,13596,13600,13604,13608,13612,13616,13620,13624,13628,13632,13636,13640],{"__ignoreMap":69},[73,13597,13598],{"class":75,"line":76},[73,13599,7156],{},[73,13601,13602],{"class":75,"line":82},[73,13603,86],{"emptyLinePlaceholder":85},[73,13605,13606],{"class":75,"line":89},[73,13607,7165],{},[73,13609,13610],{"class":75,"line":95},[73,13611,7170],{},[73,13613,13614],{"class":75,"line":101},[73,13615,7175],{},[73,13617,13618],{"class":75,"line":106},[73,13619,7180],{},[73,13621,13622],{"class":75,"line":112},[73,13623,7185],{},[73,13625,13626],{"class":75,"line":118},[73,13627,86],{"emptyLinePlaceholder":85},[73,13629,13630],{"class":75,"line":124},[73,13631,7194],{},[73,13633,13634],{"class":75,"line":129},[73,13635,7199],{},[73,13637,13638],{"class":75,"line":135},[73,13639,7204],{},[73,13641,13642],{"class":75,"line":140},[73,13643,7209],{},[10,13645,146],{},[64,13647,13649],{"className":13648,"code":7215,"language":152,"meta":69},[150],[49,13650,7215],{"__ignoreMap":69},[10,13652,157],{},[14,13654,160],{"id":160},[162,13656,13657,13663],{},[40,13658,13659,7229,13661,7232],{},[49,13660,7228],{},[49,13662,7138],{},[40,13664,13665,7237],{},[49,13666,7117],{},[14,13668,210],{"id":210},[37,13670,13671,13673],{},[40,13672,7244],{},[40,13674,7247,13675,7250,13677,7253],{},[49,13676,7127],{},[49,13678,7131],{},[14,13680,221],{"id":221},[162,13682,13683,13685],{},[40,13684,7260],{},[40,13686,7263],{},[10,13688,232],{},[14,13690,235],{"id":235},[10,13692,7270],{},[240,13694,242],{},{"title":69,"searchDepth":82,"depth":82,"links":13696},[13697,13698,13699,13700,13701,13702,13703,13704],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":7094,"description":7099},[255,7290,7291],{"id":7294,"title":7295,"body":13709,"category":255,"cover":256,"description":7300,"extension":257,"meta":13923,"navigation":85,"path":7574,"pinned":260,"publishedAt":261,"seo":13924,"slug":7576,"stem":7577,"summary":7578,"tags":13925,"updatedAt":261,"visible":85,"__hash__":7582},{"type":7,"value":13710,"toc":13910},[13711,13713,13715,13717,13719,13723,13729,13731,13743,13745,13747,13807,13809,13814,13816,13818,13836,13838,13846,13850,13858,13860,13864,13868,13874,13876,13886,13888,13902,13904,13906,13908],[10,13712,7300],{},[14,13714,16],{"id":16},[10,13716,7305],{},[14,13718,22],{"id":22},[10,13720,13721],{},[26,13722],{"alt":7312,"src":7313},[10,13724,7316,13725,7320,13727,7324],{},[49,13726,7319],{},[49,13728,7323],{},[14,13730,35],{"id":35},[37,13732,13733,13737,13741],{},[40,13734,7331,13735,7334],{},[49,13736,7319],{},[40,13738,13739,7340],{},[49,13740,7339],{},[40,13742,7343],{},[14,13744,59],{"id":59},[10,13746,62],{},[64,13748,13749],{"className":66,"code":7350,"language":68,"meta":69,"style":69},[49,13750,13751,13755,13759,13763,13767,13771,13775,13779,13783,13787,13791,13795,13799,13803],{"__ignoreMap":69},[73,13752,13753],{"class":75,"line":76},[73,13754,7357],{},[73,13756,13757],{"class":75,"line":82},[73,13758,7362],{},[73,13760,13761],{"class":75,"line":89},[73,13762,7367],{},[73,13764,13765],{"class":75,"line":95},[73,13766,7372],{},[73,13768,13769],{"class":75,"line":101},[73,13770,7377],{},[73,13772,13773],{"class":75,"line":106},[73,13774,86],{"emptyLinePlaceholder":85},[73,13776,13777],{"class":75,"line":112},[73,13778,7386],{},[73,13780,13781],{"class":75,"line":118},[73,13782,7391],{},[73,13784,13785],{"class":75,"line":124},[73,13786,7396],{},[73,13788,13789],{"class":75,"line":129},[73,13790,7401],{},[73,13792,13793],{"class":75,"line":135},[73,13794,1175],{},[73,13796,13797],{"class":75,"line":140},[73,13798,7410],{},[73,13800,13801],{"class":75,"line":7413},[73,13802,7416],{},[73,13804,13805],{"class":75,"line":7419},[73,13806,7422],{},[10,13808,146],{},[64,13810,13812],{"className":13811,"code":7428,"language":152,"meta":69},[150],[49,13813,7428],{"__ignoreMap":69},[10,13815,157],{},[14,13817,160],{"id":160},[162,13819,13820,13828],{},[40,13821,13822,7441,13824,7444,13826,7448],{},[49,13823,3062],{},[49,13825,7339],{},[49,13827,7447],{},[40,13829,7451,13830,7454,13832,7457,13834,391],{},[49,13831,7319],{},[49,13833,1189],{},[49,13835,7323],{},[193,13837,195],{"id":195},[10,13839,13840,2284,13842,1186,13844,7470],{},[49,13841,7319],{},[49,13843,1189],{},[49,13845,7323],{},[10,13847,13848],{},[26,13849],{"alt":7475,"src":7476},[10,13851,13852,7481,13854,7484,13856,7487],{},[49,13853,7319],{},[49,13855,1189],{},[49,13857,7323],{},[193,13859,195],{"id":4244},[10,13861,13862,7495],{},[49,13863,7494],{},[10,13865,13866],{},[26,13867],{"alt":7500,"src":7501},[10,13869,7504,13870,7507,13872,7510],{},[49,13871,7494],{},[49,13873,1189],{},[14,13875,210],{"id":210},[37,13877,13878,13882],{},[40,13879,7517,13880,7521],{},[49,13881,7520],{},[40,13883,7524,13884,7527],{},[49,13885,7494],{},[14,13887,221],{"id":221},[162,13889,13890,13898],{},[40,13891,7534,13892,7538,13894,1186,13896,391],{},[49,13893,7537],{},[49,13895,7541],{},[49,13897,7544],{},[40,13899,7547,13900,7550],{},[49,13901,6755],{},[10,13903,232],{},[14,13905,235],{"id":235},[10,13907,7557],{},[240,13909,242],{},{"title":69,"searchDepth":82,"depth":82,"links":13911},[13912,13913,13914,13915,13916,13920,13921,13922],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":13917},[13918,13919],{"id":195,"depth":89,"text":195},{"id":4244,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":7295,"description":7300},[255,7580,7581],{"id":7584,"title":7585,"body":13927,"category":255,"cover":256,"description":7590,"extension":257,"meta":14078,"navigation":85,"path":7767,"pinned":260,"publishedAt":261,"seo":14079,"slug":7769,"stem":7770,"summary":7771,"tags":14080,"updatedAt":261,"visible":85,"__hash__":7774},{"type":7,"value":13928,"toc":14068},[13929,13931,13933,13935,13937,13941,13945,13947,13959,13961,13963,14011,14013,14018,14020,14022,14032,14034,14044,14046,14060,14062,14064,14066],[10,13930,7590],{},[14,13932,16],{"id":16},[10,13934,7595],{},[14,13936,22],{"id":22},[10,13938,13939],{},[26,13940],{"alt":7602,"src":7603},[10,13942,7606,13943,7609],{},[49,13944,6765],{},[14,13946,35],{"id":35},[37,13948,13949,13953,13957],{},[40,13950,13951,7618],{},[49,13952,6765],{},[40,13954,13955,7624],{},[49,13956,7623],{},[40,13958,7627],{},[14,13960,59],{"id":59},[10,13962,62],{},[64,13964,13965],{"className":66,"code":7634,"language":68,"meta":69,"style":69},[49,13966,13967,13971,13975,13979,13983,13987,13991,13995,13999,14003,14007],{"__ignoreMap":69},[73,13968,13969],{"class":75,"line":76},[73,13970,6577],{},[73,13972,13973],{"class":75,"line":82},[73,13974,86],{"emptyLinePlaceholder":85},[73,13976,13977],{"class":75,"line":89},[73,13978,6788],{},[73,13980,13981],{"class":75,"line":95},[73,13982,86],{"emptyLinePlaceholder":85},[73,13984,13985],{"class":75,"line":101},[73,13986,7657],{},[73,13988,13989],{"class":75,"line":106},[73,13990,7662],{},[73,13992,13993],{"class":75,"line":112},[73,13994,86],{"emptyLinePlaceholder":85},[73,13996,13997],{"class":75,"line":118},[73,13998,7671],{},[73,14000,14001],{"class":75,"line":124},[73,14002,7676],{},[73,14004,14005],{"class":75,"line":129},[73,14006,86],{"emptyLinePlaceholder":85},[73,14008,14009],{"class":75,"line":135},[73,14010,7685],{},[10,14012,146],{},[64,14014,14016],{"className":14015,"code":7691,"language":152,"meta":69},[150],[49,14017,7691],{"__ignoreMap":69},[10,14019,157],{},[14,14021,160],{"id":160},[162,14023,14024,14030],{},[40,14025,7606,14026,7704,14028,391],{},[49,14027,6765],{},[49,14029,7707],{},[40,14031,7710],{},[14,14033,210],{"id":210},[37,14035,14036,14040],{},[40,14037,4811,14038,7719],{},[49,14039,6765],{},[40,14041,7722,14042,7725],{},[49,14043,6765],{},[14,14045,221],{"id":221},[162,14047,14048,14054],{},[40,14049,7732,14050,7736,14052,391],{},[49,14051,7735],{},[49,14053,6765],{},[40,14055,4811,14056,7743,14058,391],{},[49,14057,6765],{},[49,14059,7746],{},[10,14061,232],{},[14,14063,235],{"id":235},[10,14065,7753],{},[240,14067,242],{},{"title":69,"searchDepth":82,"depth":82,"links":14069},[14070,14071,14072,14073,14074,14075,14076,14077],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":7585,"description":7590},[255,6765,7773],{"id":7776,"title":7777,"body":14082,"category":255,"cover":256,"description":7782,"extension":257,"meta":14253,"navigation":85,"path":7995,"pinned":260,"publishedAt":261,"seo":14254,"slug":7997,"stem":7998,"summary":7999,"tags":14255,"updatedAt":261,"visible":85,"__hash__":8003},{"type":7,"value":14083,"toc":14241},[14084,14086,14088,14090,14092,14096,14098,14100,14112,14114,14116,14172,14174,14179,14181,14183,14199,14201,14203,14207,14213,14215,14223,14225,14233,14235,14237,14239],[10,14085,7782],{},[14,14087,16],{"id":16},[10,14089,7787],{},[14,14091,22],{"id":22},[10,14093,14094],{},[26,14095],{"alt":7794,"src":7795},[10,14097,7798],{},[14,14099,35],{"id":35},[37,14101,14102,14106,14110],{},[40,14103,14104,7808],{},[49,14105,7807],{},[40,14107,14108,7814],{},[49,14109,7813],{},[40,14111,7817],{},[14,14113,59],{"id":59},[10,14115,62],{},[64,14117,14118],{"className":66,"code":7824,"language":68,"meta":69,"style":69},[49,14119,14120,14124,14128,14132,14136,14140,14144,14148,14152,14156,14160,14164,14168],{"__ignoreMap":69},[73,14121,14122],{"class":75,"line":76},[73,14123,7831],{},[73,14125,14126],{"class":75,"line":82},[73,14127,7836],{},[73,14129,14130],{"class":75,"line":89},[73,14131,7841],{},[73,14133,14134],{"class":75,"line":95},[73,14135,7846],{},[73,14137,14138],{"class":75,"line":101},[73,14139,86],{"emptyLinePlaceholder":85},[73,14141,14142],{"class":75,"line":106},[73,14143,7855],{},[73,14145,14146],{"class":75,"line":112},[73,14147,7860],{},[73,14149,14150],{"class":75,"line":118},[73,14151,7865],{},[73,14153,14154],{"class":75,"line":124},[73,14155,7870],{},[73,14157,14158],{"class":75,"line":129},[73,14159,86],{"emptyLinePlaceholder":85},[73,14161,14162],{"class":75,"line":135},[73,14163,7879],{},[73,14165,14166],{"class":75,"line":140},[73,14167,7884],{},[73,14169,14170],{"class":75,"line":7413},[73,14171,7889],{},[10,14173,146],{},[64,14175,14177],{"className":14176,"code":7895,"language":152,"meta":69},[150],[49,14178,7895],{"__ignoreMap":69},[10,14180,157],{},[14,14182,160],{"id":160},[162,14184,14185,14191],{},[40,14186,7906,14187,7910,14189,7913],{},[49,14188,7909],{},[49,14190,7813],{},[40,14192,14193,7919,14195,7923,14197,7926],{},[49,14194,7918],{},[49,14196,7922],{},[49,14198,7807],{},[193,14200,195],{"id":195},[10,14202,7931],{},[10,14204,14205],{},[26,14206],{"alt":7936,"src":7937},[10,14208,7940,14209,1186,14211,7946],{},[49,14210,186],{},[49,14212,7945],{},[14,14214,210],{"id":210},[37,14216,14217,14221],{},[40,14218,7953,14219,7956],{},[49,14220,7807],{},[40,14222,7959],{},[14,14224,221],{"id":221},[162,14226,14227,14231],{},[40,14228,5321,14229,7969],{},[49,14230,7968],{},[40,14232,7972],{},[10,14234,232],{},[14,14236,235],{"id":235},[10,14238,7979],{},[240,14240,242],{},{"title":69,"searchDepth":82,"depth":82,"links":14242},[14243,14244,14245,14246,14247,14250,14251,14252],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":14248},[14249],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":7777,"description":7782},[255,8001,8002],{"id":8005,"title":8006,"body":14257,"category":255,"cover":256,"description":8011,"extension":257,"meta":14404,"navigation":85,"path":8190,"pinned":260,"publishedAt":261,"seo":14405,"slug":8192,"stem":8193,"summary":8194,"tags":14406,"updatedAt":261,"visible":85,"__hash__":8198},{"type":7,"value":14258,"toc":14394},[14259,14261,14263,14265,14267,14271,14273,14275,14283,14285,14287,14343,14345,14350,14352,14354,14366,14368,14374,14376,14386,14388,14390,14392],[10,14260,8011],{},[14,14262,16],{"id":16},[10,14264,8016],{},[14,14266,22],{"id":22},[10,14268,14269],{},[26,14270],{"alt":8023,"src":8024},[10,14272,8027],{},[14,14274,35],{"id":35},[37,14276,14277,14279,14281],{},[40,14278,8034],{},[40,14280,8037],{},[40,14282,8040],{},[14,14284,59],{"id":59},[10,14286,62],{},[64,14288,14289],{"className":66,"code":8047,"language":68,"meta":69,"style":69},[49,14290,14291,14295,14299,14303,14307,14311,14315,14319,14323,14327,14331,14335,14339],{"__ignoreMap":69},[73,14292,14293],{"class":75,"line":76},[73,14294,8054],{},[73,14296,14297],{"class":75,"line":82},[73,14298,8059],{},[73,14300,14301],{"class":75,"line":89},[73,14302,8064],{},[73,14304,14305],{"class":75,"line":95},[73,14306,86],{"emptyLinePlaceholder":85},[73,14308,14309],{"class":75,"line":101},[73,14310,8073],{},[73,14312,14313],{"class":75,"line":106},[73,14314,8078],{},[73,14316,14317],{"class":75,"line":112},[73,14318,8083],{},[73,14320,14321],{"class":75,"line":118},[73,14322,86],{"emptyLinePlaceholder":85},[73,14324,14325],{"class":75,"line":124},[73,14326,8092],{},[73,14328,14329],{"class":75,"line":129},[73,14330,8097],{},[73,14332,14333],{"class":75,"line":135},[73,14334,86],{"emptyLinePlaceholder":85},[73,14336,14337],{"class":75,"line":140},[73,14338,8106],{},[73,14340,14341],{"class":75,"line":7413},[73,14342,8111],{},[10,14344,146],{},[64,14346,14348],{"className":14347,"code":8117,"language":152,"meta":69},[150],[49,14349,8117],{"__ignoreMap":69},[10,14351,157],{},[14,14353,160],{"id":160},[162,14355,14356,14362],{},[40,14357,14358,8131,14360,8135],{},[49,14359,8130],{},[49,14361,8134],{},[40,14363,8138,14364,8142],{},[49,14365,8141],{},[14,14367,210],{"id":210},[37,14369,14370,14372],{},[40,14371,8149],{},[40,14373,8152],{},[14,14375,221],{"id":221},[162,14377,14378,14384],{},[40,14379,8159,14380,8163,14382,391],{},[49,14381,8162],{},[49,14383,8166],{},[40,14385,8169],{},[10,14387,232],{},[14,14389,235],{"id":235},[10,14391,8176],{},[240,14393,242],{},{"title":69,"searchDepth":82,"depth":82,"links":14395},[14396,14397,14398,14399,14400,14401,14402,14403],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":8006,"description":8011},[255,8196,8197],{"id":8200,"title":8201,"body":14408,"category":255,"cover":256,"description":8206,"extension":257,"meta":14571,"navigation":85,"path":8410,"pinned":260,"publishedAt":261,"seo":14572,"slug":8412,"stem":8413,"summary":8414,"tags":14573,"updatedAt":261,"visible":85,"__hash__":8418},{"type":7,"value":14409,"toc":14559},[14410,14412,14414,14416,14418,14422,14426,14428,14444,14446,14448,14492,14494,14499,14501,14503,14517,14519,14523,14527,14531,14533,14539,14541,14551,14553,14555,14557],[10,14411,8206],{},[14,14413,16],{"id":16},[10,14415,8211],{},[14,14417,22],{"id":22},[10,14419,14420],{},[26,14421],{"alt":8218,"src":8219},[10,14423,8222,14424,8226],{},[49,14425,8225],{},[14,14427,35],{"id":35},[37,14429,14430,14436,14442],{},[40,14431,14432,8236,14434,8240],{},[49,14433,8235],{},[49,14435,8239],{},[40,14437,8243,14438,8247,14440,8250],{},[49,14439,8246],{},[49,14441,4363],{},[40,14443,8253],{},[14,14445,59],{"id":59},[10,14447,62],{},[64,14449,14450],{"className":66,"code":8260,"language":68,"meta":69,"style":69},[49,14451,14452,14456,14460,14464,14468,14472,14476,14480,14484,14488],{"__ignoreMap":69},[73,14453,14454],{"class":75,"line":76},[73,14455,8267],{},[73,14457,14458],{"class":75,"line":82},[73,14459,8272],{},[73,14461,14462],{"class":75,"line":89},[73,14463,8277],{},[73,14465,14466],{"class":75,"line":95},[73,14467,8282],{},[73,14469,14470],{"class":75,"line":101},[73,14471,8287],{},[73,14473,14474],{"class":75,"line":106},[73,14475,86],{"emptyLinePlaceholder":85},[73,14477,14478],{"class":75,"line":112},[73,14479,8296],{},[73,14481,14482],{"class":75,"line":118},[73,14483,8301],{},[73,14485,14486],{"class":75,"line":124},[73,14487,8301],{},[73,14489,14490],{"class":75,"line":129},[73,14491,8301],{},[10,14493,146],{},[64,14495,14497],{"className":14496,"code":8315,"language":152,"meta":69},[150],[49,14498,8315],{"__ignoreMap":69},[10,14500,157],{},[14,14502,160],{"id":160},[162,14504,14505,14509],{},[40,14506,7906,14507,8329],{},[49,14508,8328],{},[40,14510,8332,14511,8335,14513,8338,14515,8342],{},[49,14512,8239],{},[49,14514,8225],{},[49,14516,8341],{},[193,14518,195],{"id":195},[10,14520,8347,14521,8350],{},[49,14522,8239],{},[10,14524,14525],{},[26,14526],{"alt":8355,"src":8356},[10,14528,8359,14529,8362],{},[49,14530,8225],{},[14,14532,210],{"id":210},[37,14534,14535,14537],{},[40,14536,8369],{},[40,14538,8372],{},[14,14540,221],{"id":221},[162,14542,14543,14545],{},[40,14544,8379],{},[40,14546,4036,14547,8384,14549,8387],{},[49,14548,4363],{},[49,14550,8239],{},[10,14552,232],{},[14,14554,235],{"id":235},[10,14556,8394],{},[240,14558,242],{},{"title":69,"searchDepth":82,"depth":82,"links":14560},[14561,14562,14563,14564,14565,14568,14569,14570],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":14566},[14567],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":8201,"description":8206},[255,8416,8417],{"id":8420,"title":8421,"body":14575,"category":255,"cover":256,"description":8426,"extension":257,"meta":14758,"navigation":85,"path":8651,"pinned":260,"publishedAt":261,"seo":14759,"slug":8653,"stem":8654,"summary":8655,"tags":14760,"updatedAt":261,"visible":85,"__hash__":8658},{"type":7,"value":14576,"toc":14746},[14577,14579,14581,14583,14585,14589,14591,14593,14607,14609,14611,14679,14681,14686,14688,14690,14704,14706,14708,14712,14718,14720,14728,14730,14738,14740,14742,14744],[10,14578,8426],{},[14,14580,16],{"id":16},[10,14582,8431],{},[14,14584,22],{"id":22},[10,14586,14587],{},[26,14588],{"alt":8438,"src":8439},[10,14590,8442],{},[14,14592,35],{"id":35},[37,14594,14595,14601,14603],{},[40,14596,14597,8452,14599,391],{},[49,14598,8451],{},[49,14600,8455],{},[40,14602,8458],{},[40,14604,14605,8464],{},[49,14606,8463],{},[14,14608,59],{"id":59},[10,14610,62],{},[64,14612,14613],{"className":66,"code":8471,"language":68,"meta":69,"style":69},[49,14614,14615,14619,14623,14627,14631,14635,14639,14643,14647,14651,14655,14659,14663,14667,14671,14675],{"__ignoreMap":69},[73,14616,14617],{"class":75,"line":76},[73,14618,8478],{},[73,14620,14621],{"class":75,"line":82},[73,14622,86],{"emptyLinePlaceholder":85},[73,14624,14625],{"class":75,"line":89},[73,14626,8487],{},[73,14628,14629],{"class":75,"line":95},[73,14630,8492],{},[73,14632,14633],{"class":75,"line":101},[73,14634,8497],{},[73,14636,14637],{"class":75,"line":106},[73,14638,8502],{},[73,14640,14641],{"class":75,"line":112},[73,14642,8507],{},[73,14644,14645],{"class":75,"line":118},[73,14646,8512],{},[73,14648,14649],{"class":75,"line":124},[73,14650,8517],{},[73,14652,14653],{"class":75,"line":129},[73,14654,8522],{},[73,14656,14657],{"class":75,"line":135},[73,14658,86],{"emptyLinePlaceholder":85},[73,14660,14661],{"class":75,"line":140},[73,14662,8531],{},[73,14664,14665],{"class":75,"line":7413},[73,14666,6156],{},[73,14668,14669],{"class":75,"line":7419},[73,14670,6161],{},[73,14672,14673],{"class":75,"line":8542},[73,14674,86],{"emptyLinePlaceholder":85},[73,14676,14677],{"class":75,"line":8547},[73,14678,8550],{},[10,14680,146],{},[64,14682,14684],{"className":14683,"code":8556,"language":152,"meta":69},[150],[49,14685,8556],{"__ignoreMap":69},[10,14687,157],{},[14,14689,160],{"id":160},[162,14691,14692,14702],{},[40,14693,8567,14694,8571,14696,8575,14698,8579,14700,391],{},[49,14695,8570],{},[49,14697,8574],{},[49,14699,8578],{},[49,14701,8570],{},[40,14703,8584],{},[193,14705,195],{"id":195},[10,14707,8589],{},[10,14709,14710],{},[26,14711],{"alt":8594,"src":8595},[10,14713,14714,8600,14716,391],{},[49,14715,8451],{},[49,14717,8455],{},[14,14719,210],{"id":210},[37,14721,14722,14726],{},[40,14723,8609,14724,391],{},[49,14725,5404],{},[40,14727,8614],{},[14,14729,221],{"id":221},[162,14731,14732,14734],{},[40,14733,8621],{},[40,14735,8624,14736,8628],{},[49,14737,8627],{},[10,14739,232],{},[14,14741,235],{"id":235},[10,14743,8635],{},[240,14745,242],{},{"title":69,"searchDepth":82,"depth":82,"links":14747},[14748,14749,14750,14751,14752,14755,14756,14757],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":14753},[14754],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":8421,"description":8426},[255,8657,5355],{"id":8660,"title":8661,"body":14762,"category":255,"cover":256,"description":8666,"extension":257,"meta":14921,"navigation":85,"path":8854,"pinned":260,"publishedAt":261,"seo":14922,"slug":8856,"stem":8857,"summary":8858,"tags":14923,"updatedAt":261,"visible":85,"__hash__":8862},{"type":7,"value":14763,"toc":14909},[14764,14766,14768,14770,14772,14776,14778,14780,14788,14790,14792,14856,14858,14863,14865,14867,14875,14877,14879,14883,14885,14887,14893,14895,14901,14903,14905,14907],[10,14765,8666],{},[14,14767,16],{"id":16},[10,14769,8671],{},[14,14771,22],{"id":22},[10,14773,14774],{},[26,14775],{"alt":8678,"src":8679},[10,14777,8682],{},[14,14779,35],{"id":35},[37,14781,14782,14784,14786],{},[40,14783,8689],{},[40,14785,8692],{},[40,14787,8695],{},[14,14789,59],{"id":59},[10,14791,62],{},[64,14793,14794],{"className":66,"code":8702,"language":68,"meta":69,"style":69},[49,14795,14796,14800,14804,14808,14812,14816,14820,14824,14828,14832,14836,14840,14844,14848,14852],{"__ignoreMap":69},[73,14797,14798],{"class":75,"line":76},[73,14799,8709],{},[73,14801,14802],{"class":75,"line":82},[73,14803,8714],{},[73,14805,14806],{"class":75,"line":89},[73,14807,86],{"emptyLinePlaceholder":85},[73,14809,14810],{"class":75,"line":95},[73,14811,8723],{},[73,14813,14814],{"class":75,"line":101},[73,14815,86],{"emptyLinePlaceholder":85},[73,14817,14818],{"class":75,"line":106},[73,14819,8732],{},[73,14821,14822],{"class":75,"line":112},[73,14823,8737],{},[73,14825,14826],{"class":75,"line":118},[73,14827,8742],{},[73,14829,14830],{"class":75,"line":124},[73,14831,86],{"emptyLinePlaceholder":85},[73,14833,14834],{"class":75,"line":129},[73,14835,8751],{},[73,14837,14838],{"class":75,"line":135},[73,14839,8756],{},[73,14841,14842],{"class":75,"line":140},[73,14843,8761],{},[73,14845,14846],{"class":75,"line":7413},[73,14847,86],{"emptyLinePlaceholder":85},[73,14849,14850],{"class":75,"line":7419},[73,14851,6170],{},[73,14853,14854],{"class":75,"line":8542},[73,14855,8774],{},[10,14857,146],{},[64,14859,14861],{"className":14860,"code":8780,"language":152,"meta":69},[150],[49,14862,8780],{"__ignoreMap":69},[10,14864,157],{},[14,14866,160],{"id":160},[162,14868,14869,14873],{},[40,14870,14871,8794],{},[49,14872,8793],{},[40,14874,8797],{},[193,14876,195],{"id":195},[10,14878,8802],{},[10,14880,14881],{},[26,14882],{"alt":8807,"src":8808},[10,14884,8811],{},[14,14886,210],{"id":210},[37,14888,14889,14891],{},[40,14890,8818],{},[40,14892,8821],{},[14,14894,221],{"id":221},[162,14896,14897,14899],{},[40,14898,8828],{},[40,14900,8831],{},[10,14902,232],{},[14,14904,235],{"id":235},[10,14906,8838],{},[240,14908,242],{},{"title":69,"searchDepth":82,"depth":82,"links":14910},[14911,14912,14913,14914,14915,14918,14919,14920],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":14916},[14917],{"id":195,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":8661,"description":8666},[255,8860,8861],{"id":8864,"title":8865,"body":14925,"category":255,"cover":256,"description":8870,"extension":257,"meta":15163,"navigation":85,"path":9171,"pinned":260,"publishedAt":261,"seo":15164,"slug":9173,"stem":9174,"summary":9175,"tags":15165,"updatedAt":261,"visible":85,"__hash__":9179},{"type":7,"value":14926,"toc":15150},[14927,14929,14931,14933,14935,14939,14941,14943,14953,14955,14957,15073,15075,15080,15082,15084,15094,15096,15098,15102,15104,15106,15108,15112,15116,15118,15126,15128,15142,15144,15146,15148],[10,14928,8870],{},[14,14930,16],{"id":16},[10,14932,8875],{},[14,14934,22],{"id":22},[10,14936,14937],{},[26,14938],{"alt":8882,"src":8883},[10,14940,8886],{},[14,14942,35],{"id":35},[37,14944,14945,14947,14949],{},[40,14946,8893],{},[40,14948,8896],{},[40,14950,8899,14951,8903],{},[49,14952,8902],{},[14,14954,59],{"id":59},[10,14956,62],{},[64,14958,14959],{"className":66,"code":8910,"language":68,"meta":69,"style":69},[49,14960,14961,14965,14969,14973,14977,14981,14985,14989,14993,14997,15001,15005,15009,15013,15017,15021,15025,15029,15033,15037,15041,15045,15049,15053,15057,15061,15065,15069],{"__ignoreMap":69},[73,14962,14963],{"class":75,"line":76},[73,14964,6968],{},[73,14966,14967],{"class":75,"line":82},[73,14968,6577],{},[73,14970,14971],{"class":75,"line":89},[73,14972,86],{"emptyLinePlaceholder":85},[73,14974,14975],{"class":75,"line":95},[73,14976,8929],{},[73,14978,14979],{"class":75,"line":101},[73,14980,8934],{},[73,14982,14983],{"class":75,"line":106},[73,14984,8939],{},[73,14986,14987],{"class":75,"line":112},[73,14988,8944],{},[73,14990,14991],{"class":75,"line":118},[73,14992,86],{"emptyLinePlaceholder":85},[73,14994,14995],{"class":75,"line":124},[73,14996,8953],{},[73,14998,14999],{"class":75,"line":129},[73,15000,8958],{},[73,15002,15003],{"class":75,"line":135},[73,15004,8963],{},[73,15006,15007],{"class":75,"line":140},[73,15008,8968],{},[73,15010,15011],{"class":75,"line":7413},[73,15012,8973],{},[73,15014,15015],{"class":75,"line":7419},[73,15016,86],{"emptyLinePlaceholder":85},[73,15018,15019],{"class":75,"line":8542},[73,15020,8982],{},[73,15022,15023],{"class":75,"line":8547},[73,15024,8987],{},[73,15026,15027],{"class":75,"line":8990},[73,15028,8993],{},[73,15030,15031],{"class":75,"line":8996},[73,15032,86],{"emptyLinePlaceholder":85},[73,15034,15035],{"class":75,"line":9001},[73,15036,9004],{},[73,15038,15039],{"class":75,"line":9007},[73,15040,86],{"emptyLinePlaceholder":85},[73,15042,15043],{"class":75,"line":9012},[73,15044,7386],{},[73,15046,15047],{"class":75,"line":9017},[73,15048,9020],{},[73,15050,15051],{"class":75,"line":9023},[73,15052,9026],{},[73,15054,15055],{"class":75,"line":9029},[73,15056,9032],{},[73,15058,15059],{"class":75,"line":9035},[73,15060,7396],{},[73,15062,15063],{"class":75,"line":9040},[73,15064,9043],{},[73,15066,15067],{"class":75,"line":9046},[73,15068,1175],{},[73,15070,15071],{"class":75,"line":9051},[73,15072,9054],{},[10,15074,146],{},[64,15076,15078],{"className":15077,"code":9060,"language":152,"meta":69},[150],[49,15079,9060],{"__ignoreMap":69},[10,15081,157],{},[14,15083,160],{"id":160},[162,15085,15086,15090],{},[40,15087,9071,15088,9074],{},[49,15089,8902],{},[40,15091,15092,9079],{},[49,15093,8134],{},[193,15095,195],{"id":195},[10,15097,9084],{},[10,15099,15100],{},[26,15101],{"alt":9089,"src":9090},[10,15103,9093],{},[193,15105,195],{"id":4244},[10,15107,9098],{},[10,15109,15110],{},[26,15111],{"alt":9103,"src":9104},[10,15113,9107,15114,9111],{},[49,15115,9110],{},[14,15117,210],{"id":210},[37,15119,15120,15122],{},[40,15121,9118],{},[40,15123,9121,15124,9124],{},[49,15125,9110],{},[14,15127,221],{"id":221},[162,15129,15130,15134,15136],{},[40,15131,9131,15132,9134],{},[49,15133,9110],{},[40,15135,9137],{},[40,15137,9140,15138,9144,15140,9147],{},[49,15139,9143],{},[49,15141,6112],{},[10,15143,232],{},[14,15145,235],{"id":235},[10,15147,9154],{},[240,15149,242],{},{"title":69,"searchDepth":82,"depth":82,"links":15151},[15152,15153,15154,15155,15156,15160,15161,15162],{"id":16,"depth":82,"text":16},{"id":22,"depth":82,"text":22},{"id":35,"depth":82,"text":35},{"id":59,"depth":82,"text":59},{"id":160,"depth":82,"text":160,"children":15157},[15158,15159],{"id":195,"depth":89,"text":195},{"id":4244,"depth":89,"text":195},{"id":210,"depth":82,"text":210},{"id":221,"depth":82,"text":221},{"id":235,"depth":82,"text":235},{},{"title":8865,"description":8870},[255,9177,9178],{"id":1085,"title":1086,"body":15167,"category":255,"cover":1094,"description":69,"extension":257,"meta":15403,"navigation":85,"path":1411,"pinned":260,"publishedAt":1412,"seo":15404,"slug":1414,"stem":1415,"summary":1416,"tags":15405,"updatedAt":1412,"visible":85,"__hash__":1420},{"type":7,"value":15168,"toc":15388},[15169,15173,15175,15177,15179,15181,15201,15203,15208,15210,15212,15240,15246,15248,15252,15254,15274,15276,15286,15288,15290,15292,15294,15296,15298,15300,15302,15304,15324,15326,15328,15332,15334,15336,15338,15340,15344,15346,15364,15366,15368,15370,15372,15374,15376,15378,15380,15382,15384,15386],[10,15170,15171],{},[26,15172],{"alt":1093,"src":1094},[10,15174,1097],{},[10,15176,1100],{},[14,15178,1104],{"id":1103},[10,15180,1107],{},[64,15182,15183],{"className":66,"code":1110,"language":68,"meta":69,"style":69},[49,15184,15185,15189,15193,15197],{"__ignoreMap":69},[73,15186,15187],{"class":75,"line":76},[73,15188,1117],{},[73,15190,15191],{"class":75,"line":82},[73,15192,1122],{},[73,15194,15195],{"class":75,"line":89},[73,15196,86],{"emptyLinePlaceholder":85},[73,15198,15199],{"class":75,"line":95},[73,15200,1131],{},[10,15202,1134],{},[64,15204,15206],{"className":15205,"code":1138,"language":152,"meta":69},[150],[49,15207,1138],{"__ignoreMap":69},[10,15209,1143],{},[10,15211,1146],{},[64,15213,15214],{"className":66,"code":1149,"language":68,"meta":69,"style":69},[49,15215,15216,15220,15224,15228,15232,15236],{"__ignoreMap":69},[73,15217,15218],{"class":75,"line":76},[73,15219,1156],{},[73,15221,15222],{"class":75,"line":82},[73,15223,86],{"emptyLinePlaceholder":85},[73,15225,15226],{"class":75,"line":89},[73,15227,1165],{},[73,15229,15230],{"class":75,"line":95},[73,15231,1170],{},[73,15233,15234],{"class":75,"line":101},[73,15235,1175],{},[73,15237,15238],{"class":75,"line":106},[73,15239,1180],{},[10,15241,15242,1186,15244,1190],{},[49,15243,1185],{},[49,15245,1189],{},[14,15247,1194],{"id":1193},[10,15249,1197,15250,1201],{},[49,15251,1200],{},[10,15253,1204],{},[64,15255,15256],{"className":66,"code":1207,"language":68,"meta":69,"style":69},[49,15257,15258,15262,15266,15270],{"__ignoreMap":69},[73,15259,15260],{"class":75,"line":76},[73,15261,1214],{},[73,15263,15264],{"class":75,"line":82},[73,15265,1219],{},[73,15267,15268],{"class":75,"line":89},[73,15269,1224],{},[73,15271,15272],{"class":75,"line":95},[73,15273,1229],{},[10,15275,1232],{},[64,15277,15278],{"className":620,"code":1235,"language":622,"meta":69,"style":69},[49,15279,15280],{"__ignoreMap":69},[73,15281,15282,15284],{"class":75,"line":76},[73,15283,720],{"class":629},[73,15285,1244],{"class":665},[10,15287,1247],{},[14,15289,1251],{"id":1250},[193,15291,1254],{"id":1254},[10,15293,1257],{},[193,15295,1260],{"id":1260},[10,15297,1263],{},[193,15299,1266],{"id":1266},[10,15301,1269],{},[10,15303,1272],{},[64,15305,15306],{"className":66,"code":1275,"language":68,"meta":69,"style":69},[49,15307,15308,15312,15316,15320],{"__ignoreMap":69},[73,15309,15310],{"class":75,"line":76},[73,15311,1282],{},[73,15313,15314],{"class":75,"line":82},[73,15315,86],{"emptyLinePlaceholder":85},[73,15317,15318],{"class":75,"line":89},[73,15319,1291],{},[73,15321,15322],{"class":75,"line":95},[73,15323,1296],{},[10,15325,1299],{},[193,15327,1302],{"id":1302},[10,15329,1305,15330,1308],{},[49,15331,290],{},[10,15333,1311],{},[193,15335,1314],{"id":1314},[10,15337,1317],{},[14,15339,1321],{"id":1320},[10,15341,15342],{},[26,15343],{"alt":1326,"src":1327},[10,15345,1330],{},[37,15347,15348,15350,15352,15354,15356,15358,15360,15362],{},[40,15349,1335],{},[40,15351,1338],{},[40,15353,1341],{},[40,15355,1344],{},[40,15357,1347],{},[40,15359,1350],{},[40,15361,1353],{},[40,15363,1356],{},[10,15365,1359],{},[14,15367,1363],{"id":1362},[10,15369,1366],{},[10,15371,1369],{},[14,15373,1373],{"id":1372},[10,15375,1376],{},[10,15377,1379],{},[10,15379,1382],{},[14,15381,1385],{"id":1385},[10,15383,1388],{},[10,15385,1391],{},[240,15387,1394],{},{"title":69,"searchDepth":82,"depth":82,"links":15389},[15390,15391,15392,15399,15400,15401,15402],{"id":1103,"depth":82,"text":1104},{"id":1193,"depth":82,"text":1194},{"id":1250,"depth":82,"text":1251,"children":15393},[15394,15395,15396,15397,15398],{"id":1254,"depth":89,"text":1254},{"id":1260,"depth":89,"text":1260},{"id":1266,"depth":89,"text":1266},{"id":1302,"depth":89,"text":1302},{"id":1314,"depth":89,"text":1314},{"id":1320,"depth":82,"text":1321},{"id":1362,"depth":82,"text":1363},{"id":1372,"depth":82,"text":1373},{"id":1385,"depth":82,"text":1385},{},{"title":1086,"description":69},[255,1418,1419],{"id":272,"title":273,"body":15407,"category":255,"cover":256,"description":69,"extension":257,"meta":15986,"navigation":85,"path":1074,"pinned":260,"publishedAt":1075,"seo":15987,"slug":1077,"stem":1078,"summary":1079,"tags":15988,"updatedAt":1075,"visible":85,"__hash__":1083},{"type":7,"value":15408,"toc":15962},[15409,15411,15413,15415,15419,15421,15423,15447,15459,15461,15463,15468,15472,15476,15488,15492,15496,15500,15502,15536,15538,15542,15546,15548,15570,15600,15612,15622,15630,15632,15638,15648,15650,15655,15659,15661,15675,15681,15701,15703,15705,15707,15717,15721,15723,15732,15736,15738,15740,15760,15764,15766,15768,15770,15772,15792,15794,15796,15798,15824,15826,15842,15844,15860,15864,15866,15868,15888,15890,15892,15894,15898,15908,15910,15912,15914,15924,15932,15934,15936,15950,15960],[14,15410,278],{"id":278},[10,15412,281],{},[10,15414,284],{},[10,15416,287,15417,291],{},[49,15418,290],{},[14,15420,294],{"id":294},[10,15422,297],{},[299,15424,15425,15427],{},[10,15426,303],{},[299,15428,15429,15435,15437,15441,15443],{},[10,15430,308,15431,312,15433,316],{},[49,15432,311],{},[49,15434,315],{},[10,15436,319],{},[10,15438,322,15439,327],{},[324,15440,326],{},[10,15442,330],{},[10,15444,15445],{},[26,15446],{"alt":335,"src":336},[299,15448,15449,15451],{},[10,15450,341],{},[299,15452,15453,15455],{},[10,15454,346],{},[10,15456,15457],{},[26,15458],{"alt":351,"src":352},[14,15460,356],{"id":355},[193,15462,360],{"id":359},[10,15464,363,15465,371],{},[365,15466,370],{"href":367,"rel":15467},[369],[299,15469,15470],{},[10,15471,376],{},[10,15473,15474],{},[26,15475],{"alt":381,"src":382},[37,15477,15478,15482,15486],{},[40,15479,387,15480,391],{},[324,15481,390],{},[40,15483,394,15484,391],{},[324,15485,397],{},[40,15487,400],{},[10,15489,15490],{},[26,15491],{"alt":405,"src":406},[299,15493,15494],{},[10,15495,411],{},[10,15497,15498],{},[26,15499],{"alt":416,"src":417},[193,15501,421],{"id":420},[299,15503,15504,15508,15512,15532],{},[299,15505,15506],{},[10,15507,428],{},[10,15509,431,15510,435],{},[324,15511,434],{},[64,15513,15514],{"className":66,"code":438,"language":68,"meta":69,"style":69},[49,15515,15516,15520,15524,15528],{"__ignoreMap":69},[73,15517,15518],{"class":75,"line":76},[73,15519,445],{},[73,15521,15522],{"class":75,"line":82},[73,15523,450],{},[73,15525,15526],{"class":75,"line":89},[73,15527,455],{},[73,15529,15530],{"class":75,"line":95},[73,15531,460],{},[10,15533,463,15534,467],{},[324,15535,466],{},[10,15537,470],{},[10,15539,473,15540,476],{},[49,15541,68],{},[10,15543,15544],{},[26,15545],{"alt":481,"src":482},[10,15547,485],{},[299,15549,15550,15552,15556],{},[10,15551,490],{},[10,15553,15554],{},[324,15555,495],{},[299,15557,15558,15562,15566],{},[10,15559,500,15560,503],{},[49,15561,68],{},[10,15563,506,15564,509],{},[49,15565,68],{},[10,15567,512,15568,516],{},[324,15569,515],{},[299,15571,15572,15574,15578],{},[10,15573,521],{},[10,15575,15576],{},[324,15577,526],{},[299,15579,15580,15586,15594,15596],{},[10,15581,15582,534,15584,538],{},[49,15583,533],{},[49,15585,537],{},[10,15587,541,15588,544,15590,548,15592,552],{},[49,15589,533],{},[324,15591,547],{},[324,15593,551],{},[10,15595,555],{},[10,15597,15598,561],{},[324,15599,560],{},[299,15601,15602,15604],{},[10,15603,566],{},[299,15605,15606,15610],{},[10,15607,571,15608,575],{},[324,15609,574],{},[10,15611,578],{},[299,15613,15614,15618],{},[10,15615,583,15616],{},[324,15617,586],{},[10,15619,15620],{},[26,15621],{"alt":591,"src":592},[299,15623,15624,15626],{},[10,15625,597],{},[10,15627,15628],{},[26,15629],{"alt":591,"src":602},[193,15631,606],{"id":605},[10,15633,609,15634,613,15636,617],{},[49,15635,612],{},[49,15637,616],{},[64,15639,15640],{"className":620,"code":621,"language":622,"meta":69,"style":69},[49,15641,15642],{"__ignoreMap":69},[73,15643,15644,15646],{"class":75,"line":76},[73,15645,68],{"class":629},[73,15647,633],{"class":632},[10,15649,636],{},[64,15651,15653],{"className":15652,"code":640,"language":152,"meta":69},[150],[49,15654,640],{"__ignoreMap":69},[10,15656,15657],{},[26,15658],{"alt":591,"src":647},[10,15660,650],{},[64,15662,15663],{"className":620,"code":653,"language":622,"meta":69,"style":69},[49,15664,15665],{"__ignoreMap":69},[73,15666,15667,15669,15671,15673],{"class":75,"line":76},[73,15668,68],{"class":629},[73,15670,662],{"class":632},[73,15672,666],{"class":665},[73,15674,633],{"class":632},[10,15676,671,15677,674,15679,678],{},[49,15678,68],{},[49,15680,677],{},[64,15682,15683],{"className":620,"code":681,"language":622,"meta":69,"style":69},[49,15684,15685,15691],{"__ignoreMap":69},[73,15686,15687,15689],{"class":75,"line":76},[73,15688,537],{"class":629},[73,15690,633],{"class":632},[73,15692,15693,15695,15697,15699],{"class":75,"line":82},[73,15694,537],{"class":629},[73,15696,662],{"class":632},[73,15698,666],{"class":665},[73,15700,633],{"class":632},[14,15702,703],{"id":702},[193,15704,707],{"id":706},[10,15706,710],{},[64,15708,15709],{"className":620,"code":713,"language":622,"meta":69,"style":69},[49,15710,15711],{"__ignoreMap":69},[73,15712,15713,15715],{"class":75,"line":76},[73,15714,720],{"class":629},[73,15716,633],{"class":632},[10,15718,725,15719,729],{},[49,15720,728],{},[193,15722,733],{"id":732},[10,15724,363,15725,741,15728,391,15730,748],{},[365,15726,740],{"href":738,"rel":15727},[369],[324,15729,744],{},[49,15731,747],{},[10,15733,751,15734,755],{},[49,15735,754],{},[193,15737,759],{"id":758},[10,15739,762],{},[64,15741,15742],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,15743,15744,15750],{"__ignoreMap":69},[73,15745,15746,15748],{"class":75,"line":76},[73,15747,720],{"class":629},[73,15749,633],{"class":632},[73,15751,15752,15754,15756,15758],{"class":75,"line":82},[73,15753,720],{"class":629},[73,15755,662],{"class":632},[73,15757,666],{"class":665},[73,15759,633],{"class":632},[10,15761,786,15762,789],{},[49,15763,720],{},[14,15765,793],{"id":792},[10,15767,796],{},[193,15769,800],{"id":799},[10,15771,803],{},[64,15773,15774],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,15775,15776,15782],{"__ignoreMap":69},[73,15777,15778,15780],{"class":75,"line":76},[73,15779,720],{"class":629},[73,15781,633],{"class":632},[73,15783,15784,15786,15788,15790],{"class":75,"line":82},[73,15785,720],{"class":629},[73,15787,662],{"class":632},[73,15789,666],{"class":665},[73,15791,633],{"class":632},[10,15793,826],{},[193,15795,830],{"id":829},[10,15797,833],{},[64,15799,15800],{"className":620,"code":836,"language":622,"meta":69,"style":69},[49,15801,15802,15810],{"__ignoreMap":69},[73,15803,15804,15806,15808],{"class":75,"line":76},[73,15805,843],{"class":629},[73,15807,846],{"class":665},[73,15809,849],{"class":665},[73,15811,15812,15814,15816,15818,15820,15822],{"class":75,"line":82},[73,15813,843],{"class":629},[73,15815,846],{"class":665},[73,15817,858],{"class":665},[73,15819,861],{"class":665},[73,15821,864],{"class":665},[73,15823,867],{"class":665},[10,15825,870],{},[64,15827,15828],{"className":620,"code":873,"language":622,"meta":69,"style":69},[49,15829,15830],{"__ignoreMap":69},[73,15831,15832,15834,15836,15838,15840],{"class":75,"line":76},[73,15833,843],{"class":629},[73,15835,882],{"class":665},[73,15837,858],{"class":665},[73,15839,861],{"class":665},[73,15841,889],{"class":665},[10,15843,892],{},[64,15845,15846],{"className":620,"code":895,"language":622,"meta":69,"style":69},[49,15847,15848],{"__ignoreMap":69},[73,15849,15850,15852,15854,15856,15858],{"class":75,"line":76},[73,15851,843],{"class":629},[73,15853,904],{"class":665},[73,15855,907],{"class":632},[73,15857,910],{"class":665},[73,15859,913],{"class":665},[10,15861,15862,918],{},[49,15863,843],{},[193,15865,922],{"id":921},[10,15867,925],{},[64,15869,15870],{"className":620,"code":765,"language":622,"meta":69,"style":69},[49,15871,15872,15878],{"__ignoreMap":69},[73,15873,15874,15876],{"class":75,"line":76},[73,15875,720],{"class":629},[73,15877,633],{"class":632},[73,15879,15880,15882,15884,15886],{"class":75,"line":82},[73,15881,720],{"class":629},[73,15883,662],{"class":632},[73,15885,666],{"class":665},[73,15887,633],{"class":632},[10,15889,948],{},[14,15891,951],{"id":951},[193,15893,955],{"id":954},[10,15895,958,15896,962],{},[49,15897,961],{},[162,15899,15900,15904,15906],{},[40,15901,967,15902,970],{},[49,15903,677],{},[40,15905,973],{},[40,15907,976],{},[10,15909,979],{},[193,15911,983],{"id":982},[10,15913,986],{},[64,15915,15916],{"className":620,"code":713,"language":622,"meta":69,"style":69},[49,15917,15918],{"__ignoreMap":69},[73,15919,15920,15922],{"class":75,"line":76},[73,15921,720],{"class":629},[73,15923,633],{"class":632},[10,15925,999,15926,1002,15928,1005,15930,391],{},[49,15927,720],{},[49,15929,68],{},[49,15931,720],{},[193,15933,1011],{"id":1010},[10,15935,1014],{},[64,15937,15938],{"className":620,"code":1017,"language":622,"meta":69,"style":69},[49,15939,15940],{"__ignoreMap":69},[73,15941,15942,15944,15946,15948],{"class":75,"line":76},[73,15943,720],{"class":629},[73,15945,662],{"class":632},[73,15947,666],{"class":665},[73,15949,633],{"class":632},[10,15951,1032,15952,1035,15954,1038,15956,1041,15958,1045],{},[49,15953,720],{},[49,15955,68],{},[49,15957,537],{},[49,15959,1044],{},[240,15961,1048],{},{"title":69,"searchDepth":82,"depth":82,"links":15963},[15964,15965,15966,15971,15976,15981],{"id":278,"depth":82,"text":278},{"id":294,"depth":82,"text":294},{"id":355,"depth":82,"text":356,"children":15967},[15968,15969,15970],{"id":359,"depth":89,"text":360},{"id":420,"depth":89,"text":421},{"id":605,"depth":89,"text":606},{"id":702,"depth":82,"text":703,"children":15972},[15973,15974,15975],{"id":706,"depth":89,"text":707},{"id":732,"depth":89,"text":733},{"id":758,"depth":89,"text":759},{"id":792,"depth":82,"text":793,"children":15977},[15978,15979,15980],{"id":799,"depth":89,"text":800},{"id":829,"depth":89,"text":830},{"id":921,"depth":89,"text":922},{"id":951,"depth":82,"text":951,"children":15982},[15983,15984,15985],{"id":954,"depth":89,"text":955},{"id":982,"depth":89,"text":983},{"id":1010,"depth":89,"text":1011},{},{"title":273,"description":69},[255,1081,1082],1786973365409]